49 : StructSize(
TypeSize::getFixed(0)) {
50 assert(!
ST->isOpaque() &&
"Cannot get layout of opaque structs");
52 NumElements =
ST->getNumElements();
55 for (
unsigned i = 0, e = NumElements; i !=
e; ++i) {
56 Type *Ty =
ST->getElementType(i);
60 const Align TyAlign =
ST->isPacked() ?
Align(1) :
DL.getABITypeAlign(Ty);
69 if (!StructSize.isScalable() && !
isAligned(TyAlign, StructSize)) {
75 StructAlignment = std::max(TyAlign, StructAlignment);
77 getMemberOffsets()[i] = StructSize;
79 StructSize +=
DL.getTypeAllocSize(Ty);
84 if (!StructSize.isScalable() && !
isAligned(StructAlignment, StructSize)) {
94 "Cannot get element at offset for structure containing scalable "
100 std::upper_bound(MemberOffsets.
begin(), MemberOffsets.
end(),
Offset,
102 return TypeSize::isKnownLT(LHS, RHS);
104 assert(SI != MemberOffsets.
begin() &&
"Offset not in structure type!");
109 (SI + 1 == MemberOffsets.
end() ||
111 "Upper bound didn't work!");
118 return SI - MemberOffsets.
begin();
123class StructLayoutMap {
125 LayoutInfoTy LayoutInfo;
130 for (
const auto &
I : LayoutInfo) {
132 Value->~StructLayout();
153 ABIAlign ==
Other.ABIAlign && PrefAlign ==
Other.PrefAlign &&
154 IndexBitWidth ==
Other.IndexBitWidth;
159struct LessPrimitiveBitWidth {
161 unsigned RHSBitWidth)
const {
162 return LHS.BitWidth < RHSBitWidth;
167struct LessPointerAddrSpace {
169 unsigned RHSAddrSpace)
const {
170 return LHS.AddrSpace < RHSAddrSpace;
176 if (
T.isOSBinFormatGOFF())
178 if (
T.isOSBinFormatMachO())
180 if ((
T.isOSWindows() ||
T.isUEFI()) &&
T.isOSBinFormatCOFF())
182 if (
T.isOSBinFormatXCOFF())
190 {1, Align::Constant<1>(), Align::Constant<1>()},
191 {8, Align::Constant<1>(), Align::Constant<1>()},
192 {16, Align::Constant<2>(), Align::Constant<2>()},
193 {32, Align::Constant<4>(), Align::Constant<4>()},
194 {64, Align::Constant<4>(), Align::Constant<8>()},
197 {16, Align::Constant<2>(), Align::Constant<2>()},
198 {32, Align::Constant<4>(), Align::Constant<4>()},
199 {64, Align::Constant<8>(), Align::Constant<8>()},
200 {128, Align::Constant<16>(), Align::Constant<16>()},
203 {64, Align::Constant<8>(), Align::Constant<8>()},
204 {128, Align::Constant<16>(), Align::Constant<16>()},
209 {0, 64, Align::Constant<8>(), Align::Constant<8>(), 64}
219 if (
Error Err = parseLayoutString(LayoutString))
224 delete static_cast<StructLayoutMap *
>(LayoutMap);
226 StringRepresentation =
Other.StringRepresentation;
227 BigEndian =
Other.BigEndian;
228 AllocaAddrSpace =
Other.AllocaAddrSpace;
229 ProgramAddrSpace =
Other.ProgramAddrSpace;
230 DefaultGlobalsAddrSpace =
Other.DefaultGlobalsAddrSpace;
231 StackNaturalAlign =
Other.StackNaturalAlign;
232 FunctionPtrAlign =
Other.FunctionPtrAlign;
233 TheFunctionPtrAlignType =
Other.TheFunctionPtrAlignType;
234 ManglingMode =
Other.ManglingMode;
235 LegalIntWidths =
Other.LegalIntWidths;
236 IntSpecs =
Other.IntSpecs;
237 FloatSpecs =
Other.FloatSpecs;
238 VectorSpecs =
Other.VectorSpecs;
239 PointerSpecs =
Other.PointerSpecs;
240 StructABIAlignment =
Other.StructABIAlignment;
241 StructPrefAlignment =
Other.StructPrefAlignment;
242 NonIntegralAddressSpaces =
Other.NonIntegralAddressSpaces;
249 return BigEndian ==
Other.BigEndian &&
250 AllocaAddrSpace ==
Other.AllocaAddrSpace &&
251 ProgramAddrSpace ==
Other.ProgramAddrSpace &&
252 DefaultGlobalsAddrSpace ==
Other.DefaultGlobalsAddrSpace &&
253 StackNaturalAlign ==
Other.StackNaturalAlign &&
254 FunctionPtrAlign ==
Other.FunctionPtrAlign &&
255 TheFunctionPtrAlignType ==
Other.TheFunctionPtrAlignType &&
256 ManglingMode ==
Other.ManglingMode &&
257 LegalIntWidths ==
Other.LegalIntWidths && IntSpecs ==
Other.IntSpecs &&
258 FloatSpecs ==
Other.FloatSpecs && VectorSpecs ==
Other.VectorSpecs &&
259 PointerSpecs ==
Other.PointerSpecs &&
260 StructABIAlignment ==
Other.StructABIAlignment &&
261 StructPrefAlignment ==
Other.StructPrefAlignment;
266 if (
Error Err = Layout.parseLayoutString(LayoutString))
267 return std::move(Err);
281 if (!to_integer(Str, AddrSpace, 10) || !isUInt<24>(AddrSpace))
311 bool AllowZero =
false) {
316 if (!to_integer(Str,
Value, 10) || !isUInt<16>(
Value))
322 Alignment =
Align(1);
326 constexpr unsigned ByteWidth = 8;
329 Name +
" alignment must be a power of two times the byte width");
338 char Specifier =
Spec.front();
339 assert(Specifier ==
'i' || Specifier ==
'f' || Specifier ==
'v');
340 Spec.drop_front().split(Components,
':');
342 if (Components.
size() < 2 || Components.
size() > 3)
355 if (Specifier ==
'i' &&
BitWidth == 8 && ABIAlign != 1)
359 Align PrefAlign = ABIAlign;
360 if (Components.
size() > 2)
364 if (PrefAlign < ABIAlign)
366 "preferred alignment cannot be less than the ABI alignment");
368 setPrimitiveSpec(Specifier,
BitWidth, ABIAlign, PrefAlign);
376 Spec.drop_front().split(Components,
':');
378 if (Components.
size() < 2 || Components.
size() > 3)
384 if (!Components[0].empty()) {
397 Align PrefAlign = ABIAlign;
398 if (Components.
size() > 2)
402 if (PrefAlign < ABIAlign)
404 "preferred alignment cannot be less than the ABI alignment");
406 StructABIAlignment = ABIAlign;
407 StructPrefAlignment = PrefAlign;
415 Spec.drop_front().split(Components,
':');
417 if (Components.
size() < 3 || Components.
size() > 5)
421 unsigned AddrSpace = 0;
422 if (!Components[0].empty())
438 Align PrefAlign = ABIAlign;
439 if (Components.
size() > 3)
443 if (PrefAlign < ABIAlign)
445 "preferred alignment cannot be less than the ABI alignment");
449 if (Components.
size() > 4)
450 if (
Error Err =
parseSize(Components[4], IndexBitWidth,
"index size"))
455 "index size cannot be larger than the pointer size");
457 setPointerSpec(AddrSpace,
BitWidth, ABIAlign, PrefAlign, IndexBitWidth);
463 if (
Spec.starts_with(
"ni")) {
477 NonIntegralAddressSpaces.
push_back(AddrSpace);
483 assert(!
Spec.empty() &&
"Empty specification is handled by the caller");
484 char Specifier =
Spec.front();
486 if (Specifier ==
'i' || Specifier ==
'f' || Specifier ==
'v')
487 return parsePrimitiveSpec(
Spec);
489 if (Specifier ==
'a')
490 return parseAggregateSpec(
Spec);
492 if (Specifier ==
'p')
493 return parsePointerSpec(
Spec);
505 "malformed specification, must be just 'e' or 'E'");
506 BigEndian = Specifier ==
'E';
524 StackNaturalAlign = Alignment;
547 FunctionPtrAlign = Alignment;
580 ManglingMode = MM_ELF;
583 ManglingMode = MM_GOFF;
586 ManglingMode = MM_MachO;
589 ManglingMode = MM_Mips;
592 ManglingMode = MM_WinCOFF;
595 ManglingMode = MM_WinCOFFX86;
598 ManglingMode = MM_XCOFF;
610 StringRepresentation = std::string(LayoutString);
612 if (LayoutString.
empty())
620 if (
Error Err = parseSpecification(
Spec))
640 Specs = &VectorSpecs;
647 I->ABIAlign = ABIAlign;
648 I->PrefAlign = PrefAlign;
656DataLayout::getPointerSpec(
uint32_t AddrSpace)
const {
657 if (AddrSpace != 0) {
658 auto I =
lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
659 if (
I != PointerSpecs.end() &&
I->AddrSpace == AddrSpace)
663 assert(PointerSpecs[0].AddrSpace == 0);
664 return PointerSpecs[0];
670 auto I =
lower_bound(PointerSpecs, AddrSpace, LessPointerAddrSpace());
671 if (
I == PointerSpecs.end() ||
I->AddrSpace != AddrSpace) {
672 PointerSpecs.insert(
I, PointerSpec{AddrSpace,
BitWidth, ABIAlign, PrefAlign,
676 I->ABIAlign = ABIAlign;
677 I->PrefAlign = PrefAlign;
678 I->IndexBitWidth = IndexBitWidth;
683 bool abi_or_pref)
const {
688 if (
I == IntSpecs.end())
690 return abi_or_pref ?
I->ABIAlign :
I->PrefAlign;
697 LayoutMap =
new StructLayoutMap();
699 StructLayoutMap *STM =
static_cast<StructLayoutMap*
>(LayoutMap);
730 unsigned MaxIndexSize = 0;
740 "This should only be called with a pointer or pointer vector type");
746 return divideCeil(getPointerSpec(AS).IndexBitWidth, 8);
751 "This should only be called with a pointer or pointer vector type");
764Align DataLayout::getAlignment(
Type *Ty,
bool abi_or_pref)
const {
765 assert(Ty->
isSized() &&
"Cannot getTypeInfo() on a type that is unsized!");
771 unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
776 return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
780 if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
785 const Align Align = abi_or_pref ? StructABIAlignment : StructPrefAlignment;
801 if (
I != FloatSpecs.end() &&
I->BitWidth ==
BitWidth)
802 return abi_or_pref ?
I->ABIAlign :
I->PrefAlign;
816 if (
I != VectorSpecs.end() &&
I->BitWidth ==
BitWidth)
817 return abi_or_pref ?
I->ABIAlign :
I->PrefAlign;
830 Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
831 return getAlignment(LayoutTy, abi_or_pref);
839 return getAlignment(Ty,
true);
843 return getAlignment(Ty,
false);
853 "Expected a pointer or pointer vector type.");
856 if (
VectorType *VecTy = dyn_cast<VectorType>(Ty))
862 for (
unsigned LegalIntWidth : LegalIntWidths)
863 if (Width <= LegalIntWidth)
870 return Max != LegalIntWidths.
end() ? *Max : 0;
880 "Expected a pointer or pointer vector type.");
883 if (
VectorType *VecTy = dyn_cast<VectorType>(Ty))
895 for (; GTI != GTE; ++GTI) {
898 assert(
Idx->getType()->isIntegerTy(32) &&
"Illegal struct idx");
899 unsigned FieldNo = cast<ConstantInt>(
Idx)->getZExtValue();
907 if (int64_t ArrayIdx = cast<ConstantInt>(
Idx)->getSExtValue())
927 if (
Offset.isNegative()) {
931 assert(
Offset.isNonNegative() &&
"Remaining offset shouldn't be negative");
938 if (
auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
939 ElemTy = ArrTy->getElementType();
943 if (isa<VectorType>(ElemTy)) {
950 if (
auto *STy = dyn_cast<StructType>(ElemTy)) {
958 ElemTy = STy->getElementType(
Index);
999 if (*GVAlignment >= Alignment)
1000 Alignment = *GVAlignment;
1009 if (Alignment <
Align(16)) {
1013 Alignment =
Align(16);
static MachineBasicBlock * split(MachineBasicBlock::iterator I)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Error parseSize(StringRef Str, unsigned &BitWidth, StringRef Name="size")
Attempts to parse a size component of a specification.
static APInt getElementIndex(TypeSize ElemSize, APInt &Offset)
static Error parseAddrSpace(StringRef Str, unsigned &AddrSpace)
Attempts to parse an address space component of a specification.
static Error createSpecFormatError(Twine Format)
static Error parseAlignment(StringRef Str, Align &Alignment, StringRef Name, bool AllowZero=false)
Attempts to parse an alignment component of a specification.
constexpr DataLayout::PrimitiveSpec DefaultFloatSpecs[]
constexpr DataLayout::PrimitiveSpec DefaultVectorSpecs[]
constexpr DataLayout::PointerSpec DefaultPointerSpecs[]
constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[]
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines counterparts of C library allocation functions defined in the namespace 'std'.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A parsed version of the target data layout string in and methods for querying it.
static const char * getManglingComponent(const Triple &T)
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
unsigned getMaxIndexSize() const
Returns the maximum index size over all address spaces.
@ MultipleOfFunctionAlign
The function pointer alignment is a multiple of the function alignment.
@ Independent
The function pointer alignment is independent of the function alignment.
SmallVector< APInt > getGEPIndicesForOffset(Type *&ElemTy, APInt &Offset) const
Get GEP indices to access Offset inside ElemTy.
unsigned getLargestLegalIntTypeSizeInBits() const
Returns the size of largest legal integer type size, or 0 if none are set.
unsigned getIndexSize(unsigned AS) const
rounded up to a whole number of bytes.
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
DataLayout()
Constructs a DataLayout with default values.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
Align getABITypeAlign(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
unsigned getIndexTypeSizeInBits(Type *Ty) const
Layout size of the index used in GEP calculation.
unsigned getPointerTypeSizeInBits(Type *) const
Layout pointer size, in bits, based on the type.
DataLayout & operator=(const DataLayout &Other)
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
std::optional< APInt > getGEPIndexForOffset(Type *&ElemTy, APInt &Offset) const
Get single GEP index to access Offset inside ElemTy.
Type * getSmallestLegalIntType(LLVMContext &C, unsigned Width=0) const
Returns the smallest integer type with size at least as big as Width bits.
Align getPreferredAlign(const GlobalVariable *GV) const
Returns the preferred alignment of the specified global.
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size in bytes, rounded up to a whole number of bytes.
Align getPointerPrefAlignment(unsigned AS=0) const
Return target's alignment for stack-based pointers FIXME: The defaults need to be removed once all of...
unsigned getIndexSizeInBits(unsigned AS) const
Size in bits of index used for address calculation in getelementptr.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
TypeSize getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type.
bool operator==(const DataLayout &Other) const
int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef< Value * > Indices) const
Returns the offset from the beginning of the type for the specified indices.
Align getPointerABIAlignment(unsigned AS) const
Layout pointer alignment.
Align getPrefTypeAlign(Type *Ty) const
Returns the preferred stack/global alignment for the specified type.
static Expected< DataLayout > parse(StringRef LayoutString)
Parse a data layout string and return the layout.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasSection() const
Check if this global has a custom object file section.
Type * getValueType() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
Class to represent integer types.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
TypeSize getSizeInBytes() const
MutableArrayRef< TypeSize > getMemberOffsets()
unsigned getElementContainingOffset(uint64_t FixedOffset) const
Given a valid byte offset into the structure, returns the structure index that contains it.
TypeSize getElementOffset(unsigned Idx) const
Align getAlignment() const
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
The instances of the Type class are immutable: once they are created, they are never changed.
unsigned getIntegerBitWidth() const
@ X86_AMXTyID
AMX vectors (8192 bits, X86 specific)
@ HalfTyID
16-bit floating point type
@ TargetExtTyID
Target extension type.
@ ScalableVectorTyID
Scalable SIMD vector type.
@ FloatTyID
32-bit floating point type
@ IntegerTyID
Arbitrary bit width integers.
@ FixedVectorTyID
Fixed width SIMD vector type.
@ BFloatTyID
16-bit floating point type (7-bit significand)
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
TypeID getTypeID() const
Return the type id for the type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
LLVM Value Representation.
Base class of all SIMD vector types.
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
StructType * getStructTypeOrNull() const
TypeSize getSequentialElementStride(const DataLayout &DL) const
Value * getOperand() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
gep_type_iterator gep_type_end(const User *GEP)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * safe_malloc(size_t Sz)
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
constexpr unsigned BitWidth
gep_type_iterator gep_type_begin(const User *GEP)
This struct is a compact representation of a valid (non-zero power of two) alignment.
Pointer type specification.
bool operator==(const PointerSpec &Other) const
Primitive type specification.
bool operator==(const PrimitiveSpec &Other) const
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.