LLVM: include/llvm/Support/TrailingObjects.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H
47#define LLVM_SUPPORT_TRAILINGOBJECTS_H
48
54#include
55#include <type_traits>
56
57namespace llvm {
58
59namespace trailing_objects_internal {
60
61
63private:
64 enum {
65 FirstAlignment = alignof(First),
67 };
68
69public:
70 enum {
71 Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment
72 };
73};
74
76public:
77 enum { Alignment = alignof(First) };
78};
79
80
82protected:
83
84
85
86
87
89};
90
91
92
93
96};
97
98
99
100
101
102
103
104
105
106template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,
107 typename... MoreTys>
109
110
111};
112
113template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy,
114 typename NextTy, typename... MoreTys>
116 MoreTys...>
118 MoreTys...> {
119
122
123 struct RequiresRealignment {
124 static const bool value = alignof(PrevTy) < alignof(NextTy);
125 };
126
127 static constexpr bool requiresRealignment() {
128 return RequiresRealignment::value;
129 }
130
131protected:
132
133 using ParentType::getTrailingObjectsImpl;
134
135
136
137
138
139
140
141
142
143
144 static const NextTy *
147 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(
149 TopTrailingObj::callNumTrailingObjects(
151
152 if (requiresRealignment())
153 return reinterpret_cast<const NextTy *>(
155 else
156 return reinterpret_cast<const NextTy *>(Ptr);
157 }
158
159 static NextTy *
162 auto *Ptr = TopTrailingObj::getTrailingObjectsImpl(
164 TopTrailingObj::callNumTrailingObjects(
166
167 if (requiresRealignment())
168 return reinterpret_cast<NextTy *>(alignAddr(Ptr, Align::Of()));
169 else
170 return reinterpret_cast<NextTy *>(Ptr);
171 }
172
173
174
175
177 size_t SizeSoFar, size_t Count1,
179 return ParentType::additionalSizeToAllocImpl(
180 (requiresRealignment() ? llvm::alignTo<alignof(NextTy)>(SizeSoFar)
181 : SizeSoFar) +
182 sizeof(NextTy) * Count1,
183 MoreCounts...);
184 }
185};
186
187
188
189template <int Align, typename BaseTy, typename TopTrailingObj, typename PrevTy>
192protected:
193
194
195
197
199 return SizeSoFar;
200 }
201
203};
204
205}
206
207
208
209
210
211template <typename BaseTy, typename... TrailingTys>
213 trailing_objects_internal::AlignmentCalcHelper<
214 TrailingTys...>::Alignment,
215 BaseTy, TrailingObjects<BaseTy, TrailingTys...>,
216 BaseTy, TrailingTys...> {
217
218 template <int A, typename B, typename T, typename P, typename... M>
220
221 template <typename... Tys> class Foo {};
222
226 ParentType;
228
229 using ParentType::getTrailingObjectsImpl;
230
231
232
233
234
235 static void verifyTrailingObjectsAssertions() {
236 static_assert(std::is_final(), "BaseTy must be final.");
237 }
238
239
240 static const BaseTy *
241 getTrailingObjectsImpl(const BaseTy *Obj,
242 TrailingObjectsBase::OverloadToken) {
243 return Obj;
244 }
245
247 getTrailingObjectsImpl(BaseTy *Obj,
248 TrailingObjectsBase::OverloadToken) {
249 return Obj;
250 }
251
252
253
254
255
256
257
258
259 static size_t
260 callNumTrailingObjects(const BaseTy *Obj,
261 TrailingObjectsBase::OverloadToken) {
262 return 1;
263 }
264
265 template
266 static size_t callNumTrailingObjects(const BaseTy *Obj,
267 TrailingObjectsBase::OverloadToken) {
268 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken());
269 }
270
271public:
272
273#ifndef _MSC_VER
274 using ParentType::OverloadToken;
275#else
276
277
278 template
279 using OverloadToken = typename ParentType::template OverloadToken;
280#endif
281
282
283
284
286 verifyTrailingObjectsAssertions();
287
288
289 return this->getTrailingObjectsImpl(
290 static_cast<const BaseTy *>(this),
292 }
293
294
295
296
298 verifyTrailingObjectsAssertions();
299
300
301 return this->getTrailingObjectsImpl(
303 }
304
305
306
307
308
309
310
311 template <typename... Tys>
312 static constexpr std::enable_if_t<
313 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, size_t>
315 TrailingTys, size_t>::type... Counts) {
316 return ParentType::additionalSizeToAllocImpl(0, Counts...);
317 }
318
319
320
321
322
323 template <typename... Tys>
324 static constexpr std::enable_if_t<
325 std::is_same_v<Foo<TrailingTys...>, Foo<Tys...>>, size_t>
327 TrailingTys, size_t>::type... Counts) {
328 return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
329 }
330
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
354 enum { Size = totalSizeToAlloc<Tys...>(Counts...) };
357 };
358 };
359 };
360
361
363 public:
366 assert(p && "FixedSizeStorageOwner owns null?");
367 p->~BaseTy();
368 }
369
372
373 private:
378
380 };
381};
382
383}
384
385#endif
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Given that RA is a live value
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A type that acts as the owner for an object placed into fixed storage.
FixedSizeStorageOwner(BaseTy *p)
const BaseTy * get() const
See the file comment for details on the usage of the TrailingObjects type.
TrailingObjects & operator=(TrailingObjects &&)=delete
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
Returns the total size of an object if it were allocated with the given trailing object counts.
TrailingObjects & operator=(const TrailingObjects &)=delete
static constexpr std::enable_if_t< std::is_same_v< Foo< TrailingTys... >, Foo< Tys... > >, size_t > additionalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType< TrailingTys, size_t >::type... Counts)
Returns the size of the trailing data, if an object were allocated with the given counts (The counts ...
TrailingObjects(TrailingObjects &&)=delete
T * getTrailingObjects()
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
const T * getTrailingObjects() const
Returns a pointer to the trailing object array of the given type (which must be one of those specifie...
TrailingObjects()=default
TrailingObjects(const TrailingObjects &)=delete
Helper template to calculate the max alignment requirement for a set of objects.
The base class for TrailingObjects* classes.
static const NextTy * getTrailingObjectsImpl(const BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar, size_t Count1, typename ExtractSecondType< MoreTys, size_t >::type... MoreCounts)
static NextTy * getTrailingObjectsImpl(BaseTy *Obj, TrailingObjectsBase::OverloadToken< NextTy >)
static void getTrailingObjectsImpl()
static constexpr size_t additionalSizeToAllocImpl(size_t SizeSoFar)
static void verifyTrailingObjectsAlignment()
This is an optimization pass for GlobalISel generic memory operations.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.
This struct is a compact representation of a valid (non-zero power of two) alignment.
A type where its ::with_counts template member has a ::type member suitable for use as uninitialized ...
OverloadToken's purpose is to allow specifying function overloads for different types,...