46#ifndef LLVM_SUPPORT_TRAILINGOBJECTS_H
47#define LLVM_SUPPORT_TRAILINGOBJECTS_H
59namespace trailing_objects_internal {
65 FirstAlignment =
alignof(
First),
71 Alignment = FirstAlignment > RestAlignment ? FirstAlignment : RestAlignment
77 enum { Alignment =
alignof(
First) };
106template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy,
113template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy,
114 typename NextTy,
typename... MoreTys>
123 struct RequiresRealignment {
124 static const bool value =
alignof(PrevTy) <
alignof(NextTy);
127 static constexpr bool requiresRealignment() {
128 return RequiresRealignment::value;
133 using ParentType::getTrailingObjectsImpl;
144 static const NextTy *
147 auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
149 TopTrailingObj::callNumTrailingObjects(
152 if (requiresRealignment())
153 return reinterpret_cast<const NextTy *
>(
156 return reinterpret_cast<const NextTy *
>(
Ptr);
162 auto *
Ptr = TopTrailingObj::getTrailingObjectsImpl(
164 TopTrailingObj::callNumTrailingObjects(
167 if (requiresRealignment())
168 return reinterpret_cast<NextTy *
>(
alignAddr(
Ptr, Align::Of<NextTy>()));
170 return reinterpret_cast<NextTy *
>(
Ptr);
177 size_t SizeSoFar,
size_t Count1,
179 return ParentType::additionalSizeToAllocImpl(
180 (requiresRealignment() ?
llvm::alignTo<
alignof(NextTy)>(SizeSoFar)
182 sizeof(NextTy) * Count1,
189template <
int Align,
typename BaseTy,
typename TopTrailingObj,
typename PrevTy>
211template <
typename BaseTy,
typename... TrailingTys>
213 trailing_objects_internal::AlignmentCalcHelper<
214 TrailingTys...>::Alignment,
215 BaseTy, TrailingObjects<BaseTy, TrailingTys...>,
216 BaseTy, TrailingTys...> {
218 template <
int A,
typename B,
typename T,
typename P,
typename... M>
221 template <
typename... Tys>
class Foo {};
229 using ParentType::getTrailingObjectsImpl;
235 static void verifyTrailingObjectsAssertions() {
236 static_assert(std::is_final<BaseTy>(),
"BaseTy must be final.");
241 getTrailingObjectsImpl(
const BaseTy *Obj,
242 TrailingObjectsBase::OverloadToken<BaseTy>) {
247 getTrailingObjectsImpl(
BaseTy *Obj,
248 TrailingObjectsBase::OverloadToken<BaseTy>) {
260 callNumTrailingObjects(
const BaseTy *Obj,
261 TrailingObjectsBase::OverloadToken<BaseTy>) {
265 template <
typename T>
266 static size_t callNumTrailingObjects(
const BaseTy *Obj,
267 TrailingObjectsBase::OverloadToken<T>) {
268 return Obj->numTrailingObjects(TrailingObjectsBase::OverloadToken<T>());
274 using ParentType::OverloadToken;
278 template <
typename T>
279 using OverloadToken =
typename ParentType::template OverloadToken<T>;
286 verifyTrailingObjectsAssertions();
289 return this->getTrailingObjectsImpl(
290 static_cast<const BaseTy *
>(
this),
298 verifyTrailingObjectsAssertions();
301 return this->getTrailingObjectsImpl(
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...);
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...);
354 enum {
Size = totalSizeToAlloc<Tys...>(Counts...) };
366 assert(p &&
"FixedSizeStorageOwner owns null?");
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,...