LLVM 24.0.0git
Allocator.h
Go to the documentation of this file.
1//===- Allocator.h - Simple memory allocation abstraction -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file defines the BumpPtrAllocator interface. BumpPtrAllocator conforms
11/// to the LLVM "Allocator" concept and is similar to MallocAllocator, but
12/// objects cannot be deallocated. Their lifetime is tied to the lifetime of the
13/// allocator.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_SUPPORT_ALLOCATOR_H
18#define LLVM_SUPPORT_ALLOCATOR_H
19
21#include "llvm/Config/abi-breaking.h"
26#include <algorithm>
27#include <cassert>
28#include <cstddef>
29#include <cstdint>
30#include <iterator>
31#include <new>
32#include <optional>
33#include <utility>
34
35namespace llvm {
36
37namespace detail {
38
39// We call out to an external function to actually print the message as the
40// printing code uses Allocator.h in its implementation.
41LLVM_ABI void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t TotalMemory);
42
43} // end namespace detail
44
45/// Allocate memory in an ever growing pool, as if by bump-pointer.
46///
47/// This isn't strictly a bump-pointer allocator as it uses backing slabs of
48/// memory rather than relying on a boundless contiguous heap. However, it has
49/// bump-pointer semantics in that it is a monotonically growing pool of memory
50/// where every allocation is found by merely allocating the next N bytes in
51/// the slab, or the next N bytes in the next slab.
52///
53/// Note that this also has a threshold for forcing allocations above a certain
54/// size into their own slab.
55///
56/// The BumpPtrAllocatorImpl template defaults to using a MallocAllocator
57/// object, which wraps malloc, to allocate memory, but it can be changed to
58/// use a custom allocator.
59///
60/// The GrowthDelay specifies after how many allocated slabs the allocator
61/// increases the size of the slabs.
62///
63/// MinAlign keeps the bump pointer aligned between allocations: each size is
64/// rounded up to a multiple of MinAlign so the fast path can skip realigning
65/// CurPtr when the requested alignment is no greater than MinAlign.
66template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096,
67 size_t SizeThreshold = SlabSize, size_t GrowthDelay = 128,
68 size_t MinAlign = 8>
70 : public AllocatorBase<BumpPtrAllocatorImpl<
71 AllocatorT, SlabSize, SizeThreshold, GrowthDelay, MinAlign>>,
72 private detail::AllocatorHolder<AllocatorT> {
74
75public:
76 static_assert(SizeThreshold <= SlabSize,
77 "The SizeThreshold must be at most the SlabSize to ensure "
78 "that objects larger than a slab go into their own memory "
79 "allocation.");
80 static_assert(GrowthDelay > 0,
81 "GrowthDelay must be at least 1 which already increases the"
82 "slab size after each allocated slab.");
83 static_assert(MinAlign > 0 && (MinAlign & (MinAlign - 1)) == 0,
84 "MinAlign must be a power of two");
85 static_assert(MinAlign <= alignof(std::max_align_t),
86 "MinAlign must not exceed the alignment of fresh slabs");
87
89
90 template <typename T>
92 : AllocTy(std::forward<T &&>(Allocator)) {}
93
94 // Manually implement a move constructor as we must clear the old allocator's
95 // slabs as a matter of correctness.
97 : AllocTy(std::move(Old.getAllocator())), CurPtr(Old.CurPtr),
98 EndSentinel(Old.EndSentinel), Slabs(std::move(Old.Slabs)),
99 CustomSizedSlabs(std::move(Old.CustomSizedSlabs)) {
100#if LLVM_ENABLE_ABI_BREAKING_CHECKS
101 RedZoneSize = Old.RedZoneSize;
102#endif
103 Old.CurPtr = nullptr;
104 Old.EndSentinel = 0;
105 Old.Slabs.clear();
106 Old.CustomSizedSlabs.clear();
107 }
108
110 DeallocateSlabs(Slabs.begin(), Slabs.end());
111 DeallocateCustomSizedSlabs();
112 }
113
115 DeallocateSlabs(Slabs.begin(), Slabs.end());
116 DeallocateCustomSizedSlabs();
117
118 CurPtr = RHS.CurPtr;
119 EndSentinel = RHS.EndSentinel;
120#if LLVM_ENABLE_ABI_BREAKING_CHECKS
121 RedZoneSize = RHS.RedZoneSize;
122#endif
123 Slabs = std::move(RHS.Slabs);
124 CustomSizedSlabs = std::move(RHS.CustomSizedSlabs);
125 AllocTy::operator=(std::move(RHS.getAllocator()));
126
127 RHS.CurPtr = nullptr;
128 RHS.EndSentinel = 0;
129 RHS.Slabs.clear();
130 RHS.CustomSizedSlabs.clear();
131 return *this;
132 }
133
134 /// Deallocate all but the current slab and reset the current pointer
135 /// to the beginning of it, freeing all memory allocated so far.
136 void Reset() {
137 // Deallocate all but the first slab, and deallocate all custom-sized slabs.
138 DeallocateCustomSizedSlabs();
139 CustomSizedSlabs.clear();
140
141 if (Slabs.empty())
142 return;
143
144 // Reset the state.
145 CurPtr = (char *)Slabs.front();
146 EndSentinel = uintptr_t(CurPtr) + SlabSize + 1;
147
148 __asan_poison_memory_region(*Slabs.begin(), computeSlabSize(0));
149 DeallocateSlabs(std::next(Slabs.begin()), Slabs.end());
150 Slabs.erase(std::next(Slabs.begin()), Slabs.end());
151 }
152
153 /// Allocate space at the specified alignment.
154 // This method is *not* marked noalias, because
155 // SpecificBumpPtrAllocator::DestroyAll() loops over all allocations, and
156 // that loop is not based on the Allocate() return value.
157 //
158 // Allocate(0, N) is valid, it returns a non-null pointer (which should not
159 // be dereferenced).
161 size_t SizeToAllocate = Size;
162#if LLVM_ADDRESS_SANITIZER_BUILD && LLVM_ENABLE_ABI_BREAKING_CHECKS
163 // Add trailing bytes as a "red zone" under ASan. RedZoneSize only exists
164 // when both conditions are true.
165 SizeToAllocate += RedZoneSize;
166#endif
167 SizeToAllocate = alignToPowerOf2(SizeToAllocate, MinAlign);
168
169 // CurPtr is already MinAlign-aligned, so only a stricter request realigns.
170 uintptr_t AlignedPtr = uintptr_t(CurPtr);
171 if (Alignment.value() > MinAlign)
172 AlignedPtr = alignAddr(CurPtr, Alignment);
173 uintptr_t AllocEndPtr = AlignedPtr + SizeToAllocate;
174 assert(AllocEndPtr >= uintptr_t(CurPtr) &&
175 "Alignment + Size must not overflow");
176
177 // Check if we have enough space. `EndSentinel` is 0 for an empty allocator,
178 // so this also rejects a null CurPtr when `SizeToAllocate` is 0.
179 if (LLVM_LIKELY(AllocEndPtr < EndSentinel)) {
180 CurPtr = reinterpret_cast<char *>(AllocEndPtr);
181 // Update the allocation point of this memory block in MemorySanitizer.
182 // Without this, MemorySanitizer messages for values originated from here
183 // will point to the allocation of the entire slab.
184 __msan_allocated_memory(reinterpret_cast<char *>(AlignedPtr), Size);
185 // Similarly, tell ASan about this space.
186 __asan_unpoison_memory_region(reinterpret_cast<char *>(AlignedPtr), Size);
187 return reinterpret_cast<char *>(AlignedPtr);
188 }
189
190 return AllocateSlow(Size, SizeToAllocate, Alignment);
191 }
192
194 AllocateSlow(size_t Size, size_t SizeToAllocate, Align Alignment) {
195 // If Size is really big, allocate a separate slab for it.
196 size_t PaddedSize = SizeToAllocate + Alignment.value() - 1;
197 if (PaddedSize > SizeThreshold) {
198 void *NewSlab =
199 this->getAllocator().Allocate(PaddedSize, alignof(std::max_align_t));
200 // We own the new slab and don't want anyone reading anyting other than
201 // pieces returned from this method. So poison the whole slab.
202 __asan_poison_memory_region(NewSlab, PaddedSize);
203 CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize));
204
205 uintptr_t AlignedAddr = alignAddr(NewSlab, Alignment);
206 assert(AlignedAddr + Size <= (uintptr_t)NewSlab + PaddedSize);
207 char *AlignedPtr = (char*)AlignedAddr;
208 __msan_allocated_memory(AlignedPtr, Size);
210 return AlignedPtr;
211 }
212
213 // Otherwise, start a new slab and try again.
214 StartNewSlab();
215 uintptr_t AlignedAddr = alignAddr(CurPtr, Alignment);
216 assert(AlignedAddr + SizeToAllocate < EndSentinel &&
217 "Unable to allocate memory!");
218 char *AlignedPtr = (char*)AlignedAddr;
219 CurPtr = AlignedPtr + SizeToAllocate;
220 __msan_allocated_memory(AlignedPtr, Size);
222 return AlignedPtr;
223 }
224
226 Allocate(size_t Size, size_t Alignment) {
227 assert(Alignment > 0 && "0-byte alignment is not allowed. Use 1 instead.");
228 return Allocate(Size, Align(Alignment));
229 }
230
231 // Pull in base class overloads.
233
234 // Bump pointer allocators are expected to never free their storage; and
235 // clients expect pointers to remain valid for non-dereferencing uses even
236 // after deallocation.
237 void Deallocate(const void *Ptr, size_t Size, size_t /*Alignment*/) {
239 }
240
241 // Pull in base class overloads.
243
244 size_t GetNumSlabs() const { return Slabs.size() + CustomSizedSlabs.size(); }
245
246 /// \return An index uniquely and reproducibly identifying
247 /// an input pointer \p Ptr in the given allocator.
248 /// The returned value is negative iff the object is inside a custom-size
249 /// slab.
250 /// Returns an empty optional if the pointer is not found in the allocator.
251 std::optional<int64_t> identifyObject(const void *Ptr) {
252 const char *P = static_cast<const char *>(Ptr);
253 int64_t InSlabIdx = 0;
254 for (size_t Idx = 0, E = Slabs.size(); Idx < E; Idx++) {
255 const char *S = static_cast<const char *>(Slabs[Idx]);
256 if (P >= S && P < S + computeSlabSize(Idx))
257 return InSlabIdx + static_cast<int64_t>(P - S);
258 InSlabIdx += static_cast<int64_t>(computeSlabSize(Idx));
259 }
260
261 // Use negative index to denote custom sized slabs.
262 int64_t InCustomSizedSlabIdx = -1;
263 for (const auto &Slab : CustomSizedSlabs) {
264 const char *S = static_cast<const char *>(Slab.first);
265 size_t Size = Slab.second;
266 if (P >= S && P < S + Size)
267 return InCustomSizedSlabIdx - static_cast<int64_t>(P - S);
268 InCustomSizedSlabIdx -= static_cast<int64_t>(Size);
269 }
270 return std::nullopt;
271 }
272
273 /// A wrapper around identifyObject that additionally asserts that
274 /// the object is indeed within the allocator.
275 /// \return An index uniquely and reproducibly identifying
276 /// an input pointer \p Ptr in the given allocator.
277 int64_t identifyKnownObject(const void *Ptr) {
278 std::optional<int64_t> Out = identifyObject(Ptr);
279 assert(Out && "Wrong allocator used");
280 return *Out;
281 }
282
283 /// A wrapper around identifyKnownObject. Accepts type information
284 /// about the object and produces a smaller identifier by relying on
285 /// the alignment information. Note that sub-classes may have different
286 /// alignment, so the most base class should be passed as template parameter
287 /// in order to obtain correct results. For that reason automatic template
288 /// parameter deduction is disabled.
289 /// \return An index uniquely and reproducibly identifying
290 /// an input pointer \p Ptr in the given allocator. This identifier is
291 /// different from the ones produced by identifyObject and
292 /// identifyAlignedObject.
293 template <typename T>
294 int64_t identifyKnownAlignedObject(const void *Ptr) {
295 int64_t Out = identifyKnownObject(Ptr);
296 assert(Out % alignof(T) == 0 && "Wrong alignment information");
297 return Out / alignof(T);
298 }
299
300 size_t getTotalMemory() const {
301 size_t TotalMemory = 0;
302 for (auto I = Slabs.begin(), E = Slabs.end(); I != E; ++I)
303 TotalMemory += computeSlabSize(std::distance(Slabs.begin(), I));
304 for (const auto &PtrAndSize : CustomSizedSlabs)
305 TotalMemory += PtrAndSize.second;
306 return TotalMemory;
307 }
308
309 void setRedZoneSize([[maybe_unused]] size_t NewSize) {
310#if LLVM_ENABLE_ABI_BREAKING_CHECKS
311 RedZoneSize = NewSize;
312#endif
313 }
314
315 void PrintStats() const {
317 }
318
319private:
320 /// The current pointer into the current slab.
321 ///
322 /// This points to the next free byte in the slab.
323 char *CurPtr = nullptr;
324
325 /// One past the slab end (0 when there is no slab). +1 is so that the fast
326 /// path condition also rejects a empty allocator with a 0-size allocation.
327 uintptr_t EndSentinel = 0;
328
329 /// The slabs allocated so far.
331
332 /// Custom-sized slabs allocated for too-large allocation requests.
333 SmallVector<std::pair<void *, size_t>, 0> CustomSizedSlabs;
334
335#if LLVM_ENABLE_ABI_BREAKING_CHECKS
336 /// The number of bytes to put between allocations when running under a
337 /// sanitizer.
338 size_t RedZoneSize = 1;
339#endif
340
341 static size_t computeSlabSize(unsigned SlabIdx) {
342 // Scale the actual allocated slab size based on the number of slabs
343 // allocated. Every GrowthDelay slabs allocated, we double
344 // the allocated size to reduce allocation frequency, but saturate at
345 // multiplying the slab size by 2^30.
346 return SlabSize *
347 ((size_t)1 << std::min<size_t>(30, SlabIdx / GrowthDelay));
348 }
349
350 /// Allocate a new slab and move the bump pointers over into the new
351 /// slab, modifying CurPtr and EndSentinel.
352 void StartNewSlab() {
353 size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
354
355 void *NewSlab = this->getAllocator().Allocate(AllocatedSlabSize,
356 alignof(std::max_align_t));
357 // We own the new slab and don't want anyone reading anything other than
358 // pieces returned from this method. So poison the whole slab.
359 __asan_poison_memory_region(NewSlab, AllocatedSlabSize);
360
361 Slabs.push_back(NewSlab);
362 CurPtr = (char *)(NewSlab);
363 EndSentinel = uintptr_t(NewSlab) + AllocatedSlabSize + 1;
364 }
365
366 /// Deallocate a sequence of slabs.
367 void DeallocateSlabs(SmallVectorImpl<void *>::iterator I,
369 for (; I != E; ++I) {
370 size_t AllocatedSlabSize =
371 computeSlabSize(std::distance(Slabs.begin(), I));
372 this->getAllocator().Deallocate(*I, AllocatedSlabSize,
373 alignof(std::max_align_t));
374 }
375 }
376
377 /// Deallocate all memory for custom sized slabs.
378 void DeallocateCustomSizedSlabs() {
379 for (auto &PtrAndSize : CustomSizedSlabs) {
380 void *Ptr = PtrAndSize.first;
381 size_t Size = PtrAndSize.second;
382 this->getAllocator().Deallocate(Ptr, Size, alignof(std::max_align_t));
383 }
384 }
385
386 template <typename T> friend class SpecificBumpPtrAllocator;
387};
388
389/// The standard BumpPtrAllocator which just uses the default template
390/// parameters.
391using BumpPtrAllocator = BumpPtrAllocatorImpl<>;
392
393/// A BumpPtrAllocator that allows only elements of a specific type to be
394/// allocated.
395///
396/// This allows calling the destructor in DestroyAll() and when the allocator is
397/// destroyed.
398template <typename T> class SpecificBumpPtrAllocator {
399 // DestroyAll() walks objects at a fixed sizeof(T) stride, so it needs tight
400 // packing: MinAlign=1 disables the size rounding. (alignof(T) would pack just
401 // as tightly and reuse the default instantiation, but T may be incomplete
402 // here, e.g. SpecificBumpPtrAllocator<MCSectionELF>.)
403 using BumpPtrAllocatorTy =
404 BumpPtrAllocatorImpl<MallocAllocator, 4096, 4096, 128, /*MinAlign=*/1>;
405 BumpPtrAllocatorTy Allocator;
406
407public:
409 // Because SpecificBumpPtrAllocator walks the memory to call destructors,
410 // it can't have red zones between allocations.
411 Allocator.setRedZoneSize(0);
412 }
414 : Allocator(std::move(Old.Allocator)) {}
416
418 DestroyAll();
419 Allocator = std::move(RHS.Allocator);
420 return *this;
421 }
422
423 /// Call the destructor of each allocated object and deallocate all but the
424 /// current slab and reset the current pointer to the beginning of it, freeing
425 /// all memory allocated so far.
426 void DestroyAll() {
427 auto DestroyElements = [](char *Begin, char *End) {
428 assert(Begin == (char *)alignAddr(Begin, Align::Of<T>()));
429 for (char *Ptr = Begin; Ptr + sizeof(T) <= End; Ptr += sizeof(T))
430 reinterpret_cast<T *>(Ptr)->~T();
431 };
432
433 for (auto I = Allocator.Slabs.begin(), E = Allocator.Slabs.end(); I != E;
434 ++I) {
435 size_t AllocatedSlabSize = BumpPtrAllocatorTy::computeSlabSize(
436 std::distance(Allocator.Slabs.begin(), I));
437 char *Begin = (char *)alignAddr(*I, Align::Of<T>());
438 char *End = *I == Allocator.Slabs.back() ? Allocator.CurPtr
439 : (char *)*I + AllocatedSlabSize;
440
441 DestroyElements(Begin, End);
442 }
443
444 for (auto &PtrAndSize : Allocator.CustomSizedSlabs) {
445 void *Ptr = PtrAndSize.first;
446 size_t Size = PtrAndSize.second;
447 DestroyElements((char *)alignAddr(Ptr, Align::Of<T>()),
448 (char *)Ptr + Size);
449 }
450
451 Allocator.Reset();
452 }
453
454 /// Allocate space for an array of objects without constructing them.
455 T *Allocate(size_t num = 1) {
456 // Slabs are max_align_t-aligned and every size is a multiple of alignof(T),
457 // so the bump pointer is already alignof(T)-aligned. Request alignment 1 so
458 // the fast path skips realigning CurPtr; over-aligned T still needs it.
459 if constexpr (alignof(T) <= alignof(std::max_align_t))
460 return static_cast<T *>(Allocator.Allocate(num * sizeof(T), Align()));
461 return Allocator.Allocate<T>(num);
462 }
463
464 /// \return An index uniquely and reproducibly identifying
465 /// an input pointer \p Ptr in the given allocator.
466 /// Returns an empty optional if the pointer is not found in the allocator.
467 std::optional<int64_t> identifyObject(const void *Ptr) {
468 return Allocator.identifyObject(Ptr);
469 }
470};
471
472} // end namespace llvm
473
474template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,
475 size_t GrowthDelay, size_t MinAlign>
476void *
477operator new(size_t Size,
478 llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
479 GrowthDelay, MinAlign> &Allocator) {
480 // alignof(T) is unknown but Size%alignof(T)==0, so the lowest set bit of Size
481 // bounds it. Types with alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__ use the
482 // align_val_t overload below.
483 auto S = Size | __STDCPP_DEFAULT_NEW_ALIGNMENT__;
484 return Allocator.Allocate(Size, llvm::Align(S & -S));
485}
486
487template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,
488 size_t GrowthDelay, size_t MinAlign>
489void *
490operator new(size_t Size, std::align_val_t Alignment,
491 llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
492 GrowthDelay, MinAlign> &Allocator) {
493 return Allocator.Allocate(Size, llvm::Align(static_cast<size_t>(Alignment)));
494}
495
496template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,
497 size_t GrowthDelay, size_t MinAlign>
498void operator delete(
499 void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
500 GrowthDelay, MinAlign> &) {}
501
502#endif // LLVM_SUPPORT_ALLOCATOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines MallocAllocator.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define __asan_poison_memory_region(p, size)
Definition Compiler.h:616
#define __asan_unpoison_memory_region(p, size)
Definition Compiler.h:617
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Definition Compiler.h:362
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
Definition Compiler.h:398
#define __msan_allocated_memory(p, size)
Definition Compiler.h:591
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:351
#define I(x, y, z)
Definition MD5.cpp:57
#define T
#define P(N)
Basic Register Allocator
This file defines the SmallVector class.
Value * RHS
CRTP base class providing obvious overloads for the core Allocate() methods of LLVM-style allocators.
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition Allocator.h:72
int64_t identifyKnownObject(const void *Ptr)
A wrapper around identifyObject that additionally asserts that the object is indeed within the alloca...
Definition Allocator.h:277
BumpPtrAllocatorImpl(T &&Allocator)
Definition Allocator.h:91
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_NOINLINE void * AllocateSlow(size_t Size, size_t SizeToAllocate, Align Alignment)
Definition Allocator.h:194
BumpPtrAllocatorImpl & operator=(BumpPtrAllocatorImpl &&RHS)
Definition Allocator.h:114
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
Definition Allocator.h:160
void Deallocate(const void *Ptr, size_t Size, size_t)
Definition Allocator.h:237
BumpPtrAllocatorImpl(BumpPtrAllocatorImpl &&Old)
Definition Allocator.h:96
size_t GetNumSlabs() const
Definition Allocator.h:244
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
Definition Allocator.h:136
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, size_t Alignment)
Definition Allocator.h:226
void setRedZoneSize(size_t NewSize)
Definition Allocator.h:309
int64_t identifyKnownAlignedObject(const void *Ptr)
A wrapper around identifyKnownObject.
Definition Allocator.h:294
size_t getTotalMemory() const
Definition Allocator.h:300
std::optional< int64_t > identifyObject(const void *Ptr)
Definition Allocator.h:251
void Deallocate(const void *Ptr, size_t Size, size_t Alignment)
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, size_t Alignment)
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::optional< int64_t > identifyObject(const void *Ptr)
Definition Allocator.h:467
SpecificBumpPtrAllocator(SpecificBumpPtrAllocator &&Old)
Definition Allocator.h:413
T * Allocate(size_t num=1)
Allocate space for an array of objects without constructing them.
Definition Allocator.h:455
void DestroyAll()
Call the destructor of each allocated object and deallocate all but the current slab and reset the cu...
Definition Allocator.h:426
SpecificBumpPtrAllocator & operator=(SpecificBumpPtrAllocator &&RHS)
Definition Allocator.h:417
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
Definition ADL.h:123
LLVM_ABI void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t TotalMemory)
Definition Allocator.cpp:23
This is an optimization pass for GlobalISel generic memory operations.
constexpr T MinAlign(U A, V B)
A and B are either alignments or offsets.
Definition MathExtras.h:352
constexpr T alignToPowerOf2(U Value, V Align)
Will overflow only if result is not representable in T.
Definition MathExtras.h:488
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
Definition Alignment.h:181
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static constexpr Align Of()
Allow constructions of constexpr Align from types.
Definition Alignment.h:99