[llvm] e646fa6 - [Allocator] Drop the fast-path null check via a sentinel End (#205485)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 24 04:25:41 PDT 2026
Author: Fangrui Song
Date: 2026-06-24T04:25:36-07:00
New Revision: e646fa6c1cebdddc4bdb81703c95ad5ef61c286d
URL: https://github.com/llvm/llvm-project/commit/e646fa6c1cebdddc4bdb81703c95ad5ef61c286d
DIFF: https://github.com/llvm/llvm-project/commit/e646fa6c1cebdddc4bdb81703c95ad5ef61c286d.diff
LOG: [Allocator] Drop the fast-path null check via a sentinel End (#205485)
Follow-up to #203718. Store `End` as the slab end plus 1 (and 0 for an
empty or moved-from allocator). This removes one condition from the fast
path.
For lld/ELF SymbolTable.cpp (clang++ -O3), the inlined `make<T>()` fast
path loses its `test rax, rax; je` pair; the whole TU's .text shrinks
from 14037 to 13800 bytes.
Aided by Claude Opus 4.8
Added:
Modified:
llvm/include/llvm/Support/Allocator.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/Allocator.h b/llvm/include/llvm/Support/Allocator.h
index f58f73227a2a9..92027cceea3bf 100644
--- a/llvm/include/llvm/Support/Allocator.h
+++ b/llvm/include/llvm/Support/Allocator.h
@@ -95,10 +95,11 @@ class BumpPtrAllocatorImpl
// slabs as a matter of correctness.
BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
: AllocTy(std::move(Old.getAllocator())), CurPtr(Old.CurPtr),
- End(Old.End), Slabs(std::move(Old.Slabs)),
+ EndSentinel(Old.EndSentinel), Slabs(std::move(Old.Slabs)),
CustomSizedSlabs(std::move(Old.CustomSizedSlabs)),
BytesAllocated(Old.BytesAllocated), RedZoneSize(Old.RedZoneSize) {
- Old.CurPtr = Old.End = nullptr;
+ Old.CurPtr = nullptr;
+ Old.EndSentinel = 0;
Old.BytesAllocated = 0;
Old.Slabs.clear();
Old.CustomSizedSlabs.clear();
@@ -114,14 +115,15 @@ class BumpPtrAllocatorImpl
DeallocateCustomSizedSlabs();
CurPtr = RHS.CurPtr;
- End = RHS.End;
+ EndSentinel = RHS.EndSentinel;
BytesAllocated = RHS.BytesAllocated;
RedZoneSize = RHS.RedZoneSize;
Slabs = std::move(RHS.Slabs);
CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
AllocTy::operator=(std::move(RHS.getAllocator()));
- RHS.CurPtr = RHS.End = nullptr;
+ RHS.CurPtr = nullptr;
+ RHS.EndSentinel = 0;
RHS.BytesAllocated = 0;
RHS.Slabs.clear();
RHS.CustomSizedSlabs.clear();
@@ -141,7 +143,7 @@ class BumpPtrAllocatorImpl
// Reset the state.
BytesAllocated = 0;
CurPtr = (char *)Slabs.front();
- End = CurPtr + SlabSize;
+ EndSentinel = uintptr_t(CurPtr) + SlabSize + 1;
__asan_poison_memory_region(*Slabs.begin(), computeSlabSize(0));
DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
@@ -174,10 +176,9 @@ class BumpPtrAllocatorImpl
assert(AllocEndPtr >= uintptr_t(CurPtr) &&
"Alignment + Size must not overflow");
- // Check if we have enough space.
- if (LLVM_LIKELY(AllocEndPtr <= uintptr_t(End)
- // We can't return nullptr even for a zero-sized allocation!
- && CurPtr != nullptr)) {
+ // Check if we have enough space. `EndSentinel` is 0 for an empty allocator,
+ // so this also rejects a null CurPtr when `SizeToAllocate` is 0.
+ if (LLVM_LIKELY(AllocEndPtr < EndSentinel)) {
CurPtr = reinterpret_cast<char *>(AllocEndPtr);
// Update the allocation point of this memory block in MemorySanitizer.
// Without this, MemorySanitizer messages for values originated from here
@@ -214,7 +215,7 @@ class BumpPtrAllocatorImpl
// Otherwise, start a new slab and try again.
StartNewSlab();
uintptr_t AlignedAddr = alignAddr(CurPtr, Alignment);
- assert(AlignedAddr + SizeToAllocate <= (uintptr_t)End &&
+ assert(AlignedAddr + SizeToAllocate < EndSentinel &&
"Unable to allocate memory!");
char *AlignedPtr = (char*)AlignedAddr;
CurPtr = AlignedPtr + SizeToAllocate;
@@ -324,8 +325,9 @@ class BumpPtrAllocatorImpl
/// This points to the next free byte in the slab.
char *CurPtr = nullptr;
- /// The end of the current slab.
- char *End = nullptr;
+ /// One past the slab end (0 when there is no slab). +1 is so that the fast
+ /// path condition also rejects a empty allocator with a 0-size allocation.
+ uintptr_t EndSentinel = 0;
/// The slabs allocated so far.
SmallVector<void *, 4> Slabs;
@@ -352,7 +354,7 @@ class BumpPtrAllocatorImpl
}
/// Allocate a new slab and move the bump pointers over into the new
- /// slab, modifying CurPtr and End.
+ /// slab, modifying CurPtr and EndSentinel.
void StartNewSlab() {
size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
@@ -364,7 +366,7 @@ class BumpPtrAllocatorImpl
Slabs.push_back(NewSlab);
CurPtr = (char *)(NewSlab);
- End = ((char *)NewSlab) + AllocatedSlabSize;
+ EndSentinel = uintptr_t(NewSlab) + AllocatedSlabSize + 1;
}
/// Deallocate a sequence of slabs.
More information about the llvm-commits
mailing list