Use returns_nonnull in BumpPtrAllocator and MallocAllocator to avoid null-check in...
authorHans Wennborg <hans@hanshq.net>
Thu, 21 Aug 2014 17:10:00 +0000 (17:10 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 21 Aug 2014 17:10:00 +0000 (17:10 +0000)
commiteeb828f02915e0a0f9d907bc4e242da06c1e0f7b
tree11a457b4ae23abb9bd4fdf700c822a6a6720d7de
parent69ec09b61f4c23ca6a650b8aae4f6f1bdad4f8dc
Use returns_nonnull in BumpPtrAllocator and MallocAllocator to avoid null-check in placement new

In both Clang and LLVM, this is a common pattern:

  Size = sizeof(DeclRefExpr) + SomeExtraStuff;
  void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
  return new (Mem) DeclRefExpr(...);

The annoying thing is that because the default placement-new operator has a
nothrow specification, the compiler will insert a null check of Mem before
calling the DeclRefExpr constructor. This null check is redundant for us,
because we expect the allocation functions to never return null.

By annotating the allocator functions with returns_nonnull, we can optimize
away these checks. Compiling clang with a recent version of Clang and measuring
with:

  $ perf stat -r20 bin/clang.patch -fsyntax-only -w gcc.c && perf stat -r20 bin/clang.orig -fsyntax-only -w gcc.c

Shows a 2.4% speed-up (+- 0.8%).

The pattern occurs in LLVM too. Measuring with -O3 (and now using bzip2.c
instead, because it's smaller):

  $ perf stat -r20 bin/clang.patch -O3 -w bzip2.c  &&  perf stat -r20 bin/clang.orig -O3 -w bzip2.c

Shows 4.4 % speed-up (+- 1%).

If anyone knows of a similar attribute we can use for MSVC, or some other
technique to get rid off the null check there, please let me know.

Differential Revision: http://reviews.llvm.org/D4989

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216192 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/Support/Allocator.h
include/llvm/Support/Compiler.h