LLVM 22.0.0git
AllocatorBase.h
Go to the documentation of this file.
1//===- AllocatorBase.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 MallocAllocator. MallocAllocator conforms to the LLVM
11/// "Allocator" concept which consists of an Allocate method accepting a size
12/// and alignment, and a Deallocate accepting a pointer and size. Further, the
13/// LLVM "Allocator" concept has overloads of Allocate and Deallocate for
14/// setting size and alignment based on the final type. These overloads are
15/// typically provided by a base class template \c AllocatorBase.
16///
17//===----------------------------------------------------------------------===//
18
19#ifndef LLVM_SUPPORT_ALLOCATORBASE_H
20#define LLVM_SUPPORT_ALLOCATORBASE_H
21
22#ifdef _MSC_VER
23#define LLVM_ALLOCATORHOLDER_EMPTYBASE __declspec(empty_bases)
24#else
25#define LLVM_ALLOCATORHOLDER_EMPTYBASE
26#endif // _MSC_VER
27
30#include <type_traits>
31#include <utility>
32
33namespace llvm {
34
35/// CRTP base class providing obvious overloads for the core \c
36/// Allocate() methods of LLVM-style allocators.
37///
38/// This base class both documents the full public interface exposed by all
39/// LLVM-style allocators, and redirects all of the overloads to a single core
40/// set of methods which the derived class must define.
41template <typename DerivedT> class AllocatorBase {
42public:
43 /// Allocate \a Size bytes of \a Alignment aligned memory. This method
44 /// must be implemented by \c DerivedT.
45 void *Allocate(size_t Size, size_t Alignment) {
46#ifdef __clang__
47 static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
49 static_cast<void *(DerivedT::*)(size_t, size_t)>(
50 &DerivedT::Allocate),
51 "Class derives from AllocatorBase without implementing the "
52 "core Allocate(size_t, size_t) overload!");
53#endif
54 return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
55 }
56
57 /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
58 /// allocator.
59 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
60#ifdef __clang__
61 static_assert(
62 static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
64 static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
65 &DerivedT::Deallocate),
66 "Class derives from AllocatorBase without implementing the "
67 "core Deallocate(void *) overload!");
68#endif
69 return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
70 }
71
72 // The rest of these methods are helpers that redirect to one of the above
73 // core methods.
74
75 /// Allocate space for a sequence of objects without constructing them.
76 template <typename T> T *Allocate(size_t Num = 1) {
77 return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
78 }
79
80 /// Deallocate space for a sequence of objects without constructing them.
81 template <typename T>
82 std::enable_if_t<!std::is_same_v<std::remove_cv_t<T>, void>, void>
83 Deallocate(T *Ptr, size_t Num = 1) {
84 Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
85 }
86};
87
88class MallocAllocator : public AllocatorBase<MallocAllocator> {
89public:
90 void Reset() {}
91
92 LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
93 return allocate_buffer(Size, Alignment);
94 }
95
96 // Pull in base class overloads.
98
99 void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
100 deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
101 }
102
103 // Pull in base class overloads.
105
106 void PrintStats() const {}
107};
108
109namespace detail {
110
111template <typename Alloc> class AllocatorHolder : Alloc {
112public:
113 AllocatorHolder() = default;
116 Alloc &getAllocator() { return *this; }
117 const Alloc &getAllocator() const { return *this; }
118};
119
120template <typename Alloc> class AllocatorHolder<Alloc &> {
121 Alloc &A;
122
123public:
124 AllocatorHolder(Alloc &A) : A(A) {}
125 Alloc &getAllocator() { return A; }
126 const Alloc &getAllocator() const { return A; }
127};
128
129} // namespace detail
130
131} // namespace llvm
132
133#endif // LLVM_SUPPORT_ALLOCATORBASE_H
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ATTRIBUTE_RETURNS_NONNULL
Definition Compiler.h:373
This file defines counterparts of C library allocation functions defined in the namespace 'std'.
#define T
CRTP base class providing obvious overloads for the core Allocate() methods of LLVM-style allocators.
void * Allocate(size_t Size, size_t Alignment)
Allocate Size bytes of Alignment aligned memory.
T * Allocate(size_t Num=1)
Allocate space for a sequence of objects without constructing them.
void Deallocate(const void *Ptr, size_t Size, size_t Alignment)
Deallocate Ptr to Size bytes of memory allocated by this allocator.
std::enable_if_t<!std::is_same_v< std::remove_cv_t< T >, void >, void > Deallocate(T *Ptr, size_t Num=1)
Deallocate space for a sequence of objects without constructing them.
void Deallocate(const void *Ptr, size_t Size, size_t Alignment)
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, size_t Alignment)
const Alloc & getAllocator() const
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * allocate_buffer(size_t Size, size_t Alignment)
Allocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:15
LLVM_ABI void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment)
Deallocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:27
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:1847
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870