This is an archive of the discontinued LLVM Phabricator instance.

Use returns_nonnull in BumpPtrAllocator and MallocAllocator to avoid null-check in placement new
ClosedPublic

Authored by hans on Aug 20 2014, 11:06 AM.

Details

Summary

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 /tmp/gcc.c && perf stat -r20 bin/clang.orig -fsyntax-only -w /tmp/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 /tmp/bzip2.c  &&  perf stat -r20 bin/clang.orig -O3 -w /tmp/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.

Diff Detail

Repository
rL LLVM

Event Timeline

hans updated this revision to Diff 12707.Aug 20 2014, 11:06 AM
hans retitled this revision from to Use returns_nonnull in BumpPtrAllocator and MallocAllocator to avoid null-check in placement new.
hans updated this object.
hans edited the test plan for this revision. (Show Details)
hans added reviewers: majnemer, chandlerc.
hans added subscribers: Unknown Object (MLST), hansw.
chandlerc accepted this revision.Aug 21 2014, 10:00 AM
chandlerc edited edge metadata.

Regardless of whether we can add more portable tricks, this seems like a strict improvement in the allocation API. Awesome speedups too!

include/llvm/Support/Allocator.h
93 ↗(On Diff #12707)

Why is this attribute in a different location?

This revision is now accepted and ready to land.Aug 21 2014, 10:00 AM
hans added inline comments.Aug 21 2014, 10:18 AM
include/llvm/Support/Allocator.h
93 ↗(On Diff #12707)

Oops, that was not intentional.

hans closed this revision.Aug 21 2014, 10:19 AM
hans updated this revision to Diff 12786.

Closed by commit rL216192 (authored by @hans).