Author: Alexis Engelke Date: 2026-06-22T14:11:07+02:00 New Revision: 7b0b025d704f8ad1cb514f66b035fda992452ef2
URL: https://github.com/llvm/llvm-project/commit/7b0b025d704f8ad1cb514f66b035fda992452ef2 DIFF: https://github.com/llvm/llvm-project/commit/7b0b025d704f8ad1cb514f66b035fda992452ef2.diff LOG: Revert "[Allocator] Keep bump pointer at a minimum alignment (#203718)" This reverts commit b95e1e890c025ab4eee3583b7b1e2497991145db. Added: Modified: llvm/include/llvm/Support/Allocator.h llvm/unittests/Support/AllocatorTest.cpp Removed: ################################################################################ diff --git a/llvm/include/llvm/Support/Allocator.h b/llvm/include/llvm/Support/Allocator.h index e0185bb3a88e6..fffcbd9f3c1d8 100644 --- a/llvm/include/llvm/Support/Allocator.h +++ b/llvm/include/llvm/Support/Allocator.h @@ -59,16 +59,11 @@ LLVM_ABI void printBumpPtrAllocatorStats(unsigned NumSlabs, /// /// The GrowthDelay specifies after how many allocated slabs the allocator /// increases the size of the slabs. -/// -/// MinAlign keeps the bump pointer aligned between allocations: each size is -/// rounded up to a multiple of MinAlign so the fast path can skip realigning -/// CurPtr when the requested alignment is no greater than MinAlign. template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096, - size_t SizeThreshold = SlabSize, size_t GrowthDelay = 128, - size_t MinAlign = 8> + size_t SizeThreshold = SlabSize, size_t GrowthDelay = 128> class BumpPtrAllocatorImpl - : public AllocatorBase<BumpPtrAllocatorImpl< - AllocatorT, SlabSize, SizeThreshold, GrowthDelay, MinAlign>>, + : public AllocatorBase<BumpPtrAllocatorImpl<AllocatorT, SlabSize, + SizeThreshold, GrowthDelay>>, private detail::AllocatorHolder<AllocatorT> { using AllocTy = detail::AllocatorHolder<AllocatorT>; @@ -80,10 +75,6 @@ class BumpPtrAllocatorImpl static_assert(GrowthDelay > 0, "GrowthDelay must be at least 1 which already increases the" "slab size after each allocated slab."); - static_assert(MinAlign > 0 && (MinAlign & (MinAlign - 1)) == 0, - "MinAlign must be a power of two"); - static_assert(MinAlign <= alignof(std::max_align_t), - "MinAlign must not exceed the alignment of fresh slabs"); BumpPtrAllocatorImpl() = default; @@ -159,33 +150,30 @@ class BumpPtrAllocatorImpl // Keep track of how many bytes we've allocated. BytesAllocated += Size; + uintptr_t AlignedPtr = alignAddr(CurPtr, Alignment); + size_t SizeToAllocate = Size; #if LLVM_ADDRESS_SANITIZER_BUILD // Add trailing bytes as a "red zone" under ASan. SizeToAllocate += RedZoneSize; #endif - SizeToAllocate = alignToPowerOf2(SizeToAllocate, MinAlign); - // CurPtr is already MinAlign-aligned, so only a stricter request realigns. - char *Ptr = CurPtr; - if (Alignment.value() > MinAlign) - Ptr = reinterpret_cast<char *>(alignAddr(Ptr, Alignment)); - char *NewCurPtr = Ptr + SizeToAllocate; - assert(NewCurPtr >= Ptr && "Alignment + Size must not overflow"); + uintptr_t AllocEndPtr = AlignedPtr + SizeToAllocate; + assert(AllocEndPtr >= uintptr_t(CurPtr) && + "Alignment + Size must not overflow"); // Check if we have enough space. - if (LLVM_LIKELY( - uintptr_t(NewCurPtr) <= uintptr_t(End) && - // We can't return nullptr even for a zero-sized allocation! - CurPtr != nullptr)) { - CurPtr = NewCurPtr; + if (LLVM_LIKELY(AllocEndPtr <= uintptr_t(End) + // We can't return nullptr even for a zero-sized allocation! + && CurPtr != nullptr)) { + CurPtr = reinterpret_cast<char *>(AllocEndPtr); // Update the allocation point of this memory block in MemorySanitizer. // Without this, MemorySanitizer messages for values originated from here // will point to the allocation of the entire slab. - __msan_allocated_memory(Ptr, Size); + __msan_allocated_memory(reinterpret_cast<char *>(AlignedPtr), Size); // Similarly, tell ASan about this space. - __asan_unpoison_memory_region(Ptr, Size); - return Ptr; + __asan_unpoison_memory_region(reinterpret_cast<char *>(AlignedPtr), Size); + return reinterpret_cast<char *>(AlignedPtr); } return AllocateSlow(Size, SizeToAllocate, Alignment); @@ -400,13 +388,7 @@ using BumpPtrAllocator = BumpPtrAllocatorImpl<>; /// This allows calling the destructor in DestroyAll() and when the allocator is /// destroyed. template <typename T> class SpecificBumpPtrAllocator { - // DestroyAll() walks objects at a fixed sizeof(T) stride, so it needs tight - // packing: MinAlign=1 disables the size rounding. (alignof(T) would pack just - // as tightly and reuse the default instantiation, but T may be incomplete - // here, e.g. SpecificBumpPtrAllocator<MCSectionELF>.) - using BumpPtrAllocatorTy = - BumpPtrAllocatorImpl<MallocAllocator, 4096, 4096, 128, /*MinAlign=*/1>; - BumpPtrAllocatorTy Allocator; + BumpPtrAllocator Allocator; public: SpecificBumpPtrAllocator() { @@ -435,7 +417,7 @@ template <typename T> class SpecificBumpPtrAllocator { for (auto I = Allocator.Slabs.begin(), E = Allocator.Slabs.end(); I != E; ++I) { - size_t AllocatedSlabSize = BumpPtrAllocatorTy::computeSlabSize( + size_t AllocatedSlabSize = BumpPtrAllocator::computeSlabSize( std::distance(Allocator.Slabs.begin(), I)); char *Begin = (char *)alignAddr(*I, Align::Of<T>()); char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr @@ -455,14 +437,7 @@ template <typename T> class SpecificBumpPtrAllocator { } /// Allocate space for an array of objects without constructing them. - T *Allocate(size_t num = 1) { - // Slabs are max_align_t-aligned and every size is a multiple of alignof(T), - // so the bump pointer is already alignof(T)-aligned. Request alignment 1 so - // the fast path skips realigning CurPtr; over-aligned T still needs it. - if constexpr (alignof(T) <= alignof(std::max_align_t)) - return static_cast<T *>(Allocator.Allocate(num * sizeof(T), Align())); - return Allocator.Allocate<T>(num); - } + T *Allocate(size_t num = 1) { return Allocator.Allocate<T>(num); } /// \return An index uniquely and reproducibly identifying /// an input pointer \p Ptr in the given allocator. @@ -475,19 +450,20 @@ template <typename T> class SpecificBumpPtrAllocator { } // end namespace llvm template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold, - size_t GrowthDelay, size_t MinAlign> + size_t GrowthDelay> void * operator new(size_t Size, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold, - GrowthDelay, MinAlign> &Allocator) { - return Allocator.Allocate( - Size, std::min(llvm::bit_ceil(Size), alignof(std::max_align_t))); + GrowthDelay> &Allocator) { + return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size), + alignof(std::max_align_t))); } template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold, - size_t GrowthDelay, size_t MinAlign> -void operator delete( - void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold, - GrowthDelay, MinAlign> &) {} + size_t GrowthDelay> +void operator delete(void *, + llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, + SizeThreshold, GrowthDelay> &) { +} #endif // LLVM_SUPPORT_ALLOCATOR_H diff --git a/llvm/unittests/Support/AllocatorTest.cpp b/llvm/unittests/Support/AllocatorTest.cpp index d6f80e0948dc4..2337f34143bad 100644 --- a/llvm/unittests/Support/AllocatorTest.cpp +++ b/llvm/unittests/Support/AllocatorTest.cpp @@ -279,23 +279,4 @@ TEST(AllocatorTest, TestBigAlignment) { EXPECT_GT(MockSlabAllocator::GetLastSlabSize(), 4096u); } -// Over-aligned element type: Allocate() honors alignof(T) > MinAlign and -// DestroyAll() runs every destructor. -TEST(AllocatorTest, TestOverAlignedSpecific) { - unsigned NumDtorCalls = 0; - struct alignas(32) S { - unsigned *Calls; - ~S() { ++*Calls; } - }; - { - SpecificBumpPtrAllocator<S> Alloc; - for (int I = 0; I != 4; ++I) { - S *P = Alloc.Allocate(); - EXPECT_EQ(0u, reinterpret_cast<uintptr_t>(P) & 31u); - P->Calls = &NumDtorCalls; - } - } - EXPECT_EQ(4u, NumDtorCalls); -} - } // anonymous namespace _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
