File indexing completed on 2026-05-10 08:43:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef LLVM_IR_DATALAYOUT_H
0020 #define LLVM_IR_DATALAYOUT_H
0021
0022 #include "llvm/ADT/APInt.h"
0023 #include "llvm/ADT/ArrayRef.h"
0024 #include "llvm/ADT/STLExtras.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/IR/DerivedTypes.h"
0028 #include "llvm/IR/Type.h"
0029 #include "llvm/Support/Alignment.h"
0030 #include "llvm/Support/Casting.h"
0031 #include "llvm/Support/Compiler.h"
0032 #include "llvm/Support/ErrorHandling.h"
0033 #include "llvm/Support/MathExtras.h"
0034 #include "llvm/Support/TrailingObjects.h"
0035 #include "llvm/Support/TypeSize.h"
0036 #include <cassert>
0037 #include <cstdint>
0038 #include <string>
0039
0040
0041
0042 using LLVMTargetDataRef = struct LLVMOpaqueTargetData *;
0043
0044 namespace llvm {
0045
0046 class GlobalVariable;
0047 class LLVMContext;
0048 class StructLayout;
0049 class Triple;
0050 class Value;
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063 class DataLayout {
0064 public:
0065
0066 struct PrimitiveSpec {
0067 uint32_t BitWidth;
0068 Align ABIAlign;
0069 Align PrefAlign;
0070
0071 bool operator==(const PrimitiveSpec &Other) const;
0072 };
0073
0074
0075 struct PointerSpec {
0076 uint32_t AddrSpace;
0077 uint32_t BitWidth;
0078 Align ABIAlign;
0079 Align PrefAlign;
0080 uint32_t IndexBitWidth;
0081
0082
0083
0084
0085 bool IsNonIntegral;
0086 bool operator==(const PointerSpec &Other) const;
0087 };
0088
0089 enum class FunctionPtrAlignType {
0090
0091 Independent,
0092
0093 MultipleOfFunctionAlign,
0094 };
0095 private:
0096 bool BigEndian = false;
0097
0098 unsigned AllocaAddrSpace = 0;
0099 unsigned ProgramAddrSpace = 0;
0100 unsigned DefaultGlobalsAddrSpace = 0;
0101
0102 MaybeAlign StackNaturalAlign;
0103 MaybeAlign FunctionPtrAlign;
0104 FunctionPtrAlignType TheFunctionPtrAlignType =
0105 FunctionPtrAlignType::Independent;
0106
0107 enum ManglingModeT {
0108 MM_None,
0109 MM_ELF,
0110 MM_MachO,
0111 MM_WinCOFF,
0112 MM_WinCOFFX86,
0113 MM_GOFF,
0114 MM_Mips,
0115 MM_XCOFF
0116 };
0117 ManglingModeT ManglingMode = MM_None;
0118
0119
0120 SmallVector<unsigned char, 8> LegalIntWidths;
0121
0122
0123 SmallVector<PrimitiveSpec, 6> IntSpecs;
0124 SmallVector<PrimitiveSpec, 4> FloatSpecs;
0125 SmallVector<PrimitiveSpec, 10> VectorSpecs;
0126
0127
0128 SmallVector<PointerSpec, 8> PointerSpecs;
0129
0130
0131 std::string StringRepresentation;
0132
0133
0134 Align StructABIAlignment = Align::Constant<1>();
0135 Align StructPrefAlignment = Align::Constant<8>();
0136
0137
0138 mutable void *LayoutMap = nullptr;
0139
0140
0141 void setPrimitiveSpec(char Specifier, uint32_t BitWidth, Align ABIAlign,
0142 Align PrefAlign);
0143
0144
0145
0146 const PointerSpec &getPointerSpec(uint32_t AddrSpace) const;
0147
0148
0149 void setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth, Align ABIAlign,
0150 Align PrefAlign, uint32_t IndexBitWidth,
0151 bool IsNonIntegral);
0152
0153
0154 Align getIntegerAlignment(uint32_t BitWidth, bool abi_or_pref) const;
0155
0156
0157 Align getAlignment(Type *Ty, bool abi_or_pref) const;
0158
0159
0160 Error parsePrimitiveSpec(StringRef Spec);
0161
0162
0163 Error parseAggregateSpec(StringRef Spec);
0164
0165
0166 Error parsePointerSpec(StringRef Spec);
0167
0168
0169 Error parseSpecification(StringRef Spec,
0170 SmallVectorImpl<unsigned> &NonIntegralAddressSpaces);
0171
0172
0173 Error parseLayoutString(StringRef LayoutString);
0174
0175 public:
0176
0177 DataLayout();
0178
0179
0180
0181 explicit DataLayout(StringRef LayoutString);
0182
0183 DataLayout(const DataLayout &DL) { *this = DL; }
0184
0185 ~DataLayout();
0186
0187 DataLayout &operator=(const DataLayout &Other);
0188
0189 bool operator==(const DataLayout &Other) const;
0190 bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
0191
0192
0193
0194 static Expected<DataLayout> parse(StringRef LayoutString);
0195
0196
0197 bool isLittleEndian() const { return !BigEndian; }
0198 bool isBigEndian() const { return BigEndian; }
0199
0200
0201
0202
0203
0204
0205 const std::string &getStringRepresentation() const {
0206 return StringRepresentation;
0207 }
0208
0209
0210 bool isDefault() const { return StringRepresentation.empty(); }
0211
0212
0213
0214
0215
0216
0217
0218
0219 bool isLegalInteger(uint64_t Width) const {
0220 return llvm::is_contained(LegalIntWidths, Width);
0221 }
0222
0223 bool isIllegalInteger(uint64_t Width) const { return !isLegalInteger(Width); }
0224
0225
0226
0227 MaybeAlign getStackAlignment() const { return StackNaturalAlign; }
0228
0229 unsigned getAllocaAddrSpace() const { return AllocaAddrSpace; }
0230
0231 PointerType *getAllocaPtrType(LLVMContext &Ctx) const {
0232 return PointerType::get(Ctx, AllocaAddrSpace);
0233 }
0234
0235
0236
0237
0238 MaybeAlign getFunctionPtrAlign() const { return FunctionPtrAlign; }
0239
0240
0241
0242 FunctionPtrAlignType getFunctionPtrAlignType() const {
0243 return TheFunctionPtrAlignType;
0244 }
0245
0246 unsigned getProgramAddressSpace() const { return ProgramAddrSpace; }
0247 unsigned getDefaultGlobalsAddressSpace() const {
0248 return DefaultGlobalsAddrSpace;
0249 }
0250
0251 bool hasMicrosoftFastStdCallMangling() const {
0252 return ManglingMode == MM_WinCOFFX86;
0253 }
0254
0255
0256
0257 bool doNotMangleLeadingQuestionMark() const {
0258 return ManglingMode == MM_WinCOFF || ManglingMode == MM_WinCOFFX86;
0259 }
0260
0261 bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; }
0262
0263 StringRef getLinkerPrivateGlobalPrefix() const {
0264 if (ManglingMode == MM_MachO)
0265 return "l";
0266 return "";
0267 }
0268
0269 char getGlobalPrefix() const {
0270 switch (ManglingMode) {
0271 case MM_None:
0272 case MM_ELF:
0273 case MM_GOFF:
0274 case MM_Mips:
0275 case MM_WinCOFF:
0276 case MM_XCOFF:
0277 return '\0';
0278 case MM_MachO:
0279 case MM_WinCOFFX86:
0280 return '_';
0281 }
0282 llvm_unreachable("invalid mangling mode");
0283 }
0284
0285 StringRef getPrivateGlobalPrefix() const {
0286 switch (ManglingMode) {
0287 case MM_None:
0288 return "";
0289 case MM_ELF:
0290 case MM_WinCOFF:
0291 return ".L";
0292 case MM_GOFF:
0293 return "L#";
0294 case MM_Mips:
0295 return "$";
0296 case MM_MachO:
0297 case MM_WinCOFFX86:
0298 return "L";
0299 case MM_XCOFF:
0300 return "L..";
0301 }
0302 llvm_unreachable("invalid mangling mode");
0303 }
0304
0305 static const char *getManglingComponent(const Triple &T);
0306
0307
0308
0309
0310
0311
0312 bool fitsInLegalInteger(unsigned Width) const {
0313 for (unsigned LegalIntWidth : LegalIntWidths)
0314 if (Width <= LegalIntWidth)
0315 return true;
0316 return false;
0317 }
0318
0319
0320 Align getPointerABIAlignment(unsigned AS) const;
0321
0322
0323
0324
0325 Align getPointerPrefAlignment(unsigned AS = 0) const;
0326
0327
0328
0329
0330
0331 unsigned getPointerSize(unsigned AS = 0) const;
0332
0333
0334
0335 unsigned getIndexSize(unsigned AS) const;
0336
0337
0338
0339 SmallVector<unsigned, 8> getNonIntegralAddressSpaces() const {
0340 SmallVector<unsigned, 8> AddrSpaces;
0341 for (const PointerSpec &PS : PointerSpecs) {
0342 if (PS.IsNonIntegral)
0343 AddrSpaces.push_back(PS.AddrSpace);
0344 }
0345 return AddrSpaces;
0346 }
0347
0348 bool isNonIntegralAddressSpace(unsigned AddrSpace) const {
0349 return getPointerSpec(AddrSpace).IsNonIntegral;
0350 }
0351
0352 bool isNonIntegralPointerType(PointerType *PT) const {
0353 return isNonIntegralAddressSpace(PT->getAddressSpace());
0354 }
0355
0356 bool isNonIntegralPointerType(Type *Ty) const {
0357 auto *PTy = dyn_cast<PointerType>(Ty);
0358 return PTy && isNonIntegralPointerType(PTy);
0359 }
0360
0361
0362
0363
0364 unsigned getPointerSizeInBits(unsigned AS = 0) const {
0365 return getPointerSpec(AS).BitWidth;
0366 }
0367
0368
0369 unsigned getIndexSizeInBits(unsigned AS) const {
0370 return getPointerSpec(AS).IndexBitWidth;
0371 }
0372
0373
0374
0375
0376
0377
0378 unsigned getPointerTypeSizeInBits(Type *) const;
0379
0380
0381
0382 unsigned getIndexTypeSizeInBits(Type *Ty) const;
0383
0384 unsigned getPointerTypeSize(Type *Ty) const {
0385 return getPointerTypeSizeInBits(Ty) / 8;
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 TypeSize getTypeSizeInBits(Type *Ty) const;
0413
0414
0415
0416
0417
0418
0419
0420
0421 TypeSize getTypeStoreSize(Type *Ty) const {
0422 TypeSize StoreSizeInBits = getTypeStoreSizeInBits(Ty);
0423 return {StoreSizeInBits.getKnownMinValue() / 8,
0424 StoreSizeInBits.isScalable()};
0425 }
0426
0427
0428
0429
0430
0431
0432
0433
0434 TypeSize getTypeStoreSizeInBits(Type *Ty) const {
0435 TypeSize BaseSize = getTypeSizeInBits(Ty);
0436 uint64_t AlignedSizeInBits =
0437 alignToPowerOf2(BaseSize.getKnownMinValue(), 8);
0438 return {AlignedSizeInBits, BaseSize.isScalable()};
0439 }
0440
0441
0442
0443
0444
0445 bool typeSizeEqualsStoreSize(Type *Ty) const {
0446 return getTypeSizeInBits(Ty) == getTypeStoreSizeInBits(Ty);
0447 }
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 TypeSize getTypeAllocSize(Type *Ty) const {
0458
0459 return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value());
0460 }
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470 TypeSize getTypeAllocSizeInBits(Type *Ty) const {
0471 return 8 * getTypeAllocSize(Ty);
0472 }
0473
0474
0475 Align getABITypeAlign(Type *Ty) const;
0476
0477
0478
0479 inline Align getValueOrABITypeAlignment(MaybeAlign Alignment,
0480 Type *Ty) const {
0481 return Alignment ? *Alignment : getABITypeAlign(Ty);
0482 }
0483
0484
0485
0486 Align getABIIntegerTypeAlignment(unsigned BitWidth) const {
0487 return getIntegerAlignment(BitWidth, true);
0488 }
0489
0490
0491
0492
0493
0494 Align getPrefTypeAlign(Type *Ty) const;
0495
0496
0497
0498 IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
0499
0500
0501
0502 Type *getIntPtrType(Type *) const;
0503
0504
0505
0506 Type *getSmallestLegalIntType(LLVMContext &C, unsigned Width = 0) const;
0507
0508
0509 Type *getLargestLegalIntType(LLVMContext &C) const {
0510 unsigned LargestSize = getLargestLegalIntTypeSizeInBits();
0511 return (LargestSize == 0) ? nullptr : Type::getIntNTy(C, LargestSize);
0512 }
0513
0514
0515
0516 unsigned getLargestLegalIntTypeSizeInBits() const;
0517
0518
0519
0520
0521 IntegerType *getIndexType(LLVMContext &C, unsigned AddressSpace) const;
0522
0523
0524
0525
0526 Type *getIndexType(Type *PtrTy) const;
0527
0528
0529
0530
0531
0532
0533 int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef<Value *> Indices) const;
0534
0535
0536
0537 SmallVector<APInt> getGEPIndicesForOffset(Type *&ElemTy, APInt &Offset) const;
0538
0539
0540
0541
0542
0543 std::optional<APInt> getGEPIndexForOffset(Type *&ElemTy, APInt &Offset) const;
0544
0545
0546
0547
0548
0549 const StructLayout *getStructLayout(StructType *Ty) const;
0550
0551
0552
0553
0554 Align getPreferredAlign(const GlobalVariable *GV) const;
0555 };
0556
0557 inline DataLayout *unwrap(LLVMTargetDataRef P) {
0558 return reinterpret_cast<DataLayout *>(P);
0559 }
0560
0561 inline LLVMTargetDataRef wrap(const DataLayout *P) {
0562 return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P));
0563 }
0564
0565
0566
0567 class StructLayout final : public TrailingObjects<StructLayout, TypeSize> {
0568 TypeSize StructSize;
0569 Align StructAlignment;
0570 unsigned IsPadded : 1;
0571 unsigned NumElements : 31;
0572
0573 public:
0574 TypeSize getSizeInBytes() const { return StructSize; }
0575
0576 TypeSize getSizeInBits() const { return 8 * StructSize; }
0577
0578 Align getAlignment() const { return StructAlignment; }
0579
0580
0581
0582 bool hasPadding() const { return IsPadded; }
0583
0584
0585
0586 unsigned getElementContainingOffset(uint64_t FixedOffset) const;
0587
0588 MutableArrayRef<TypeSize> getMemberOffsets() {
0589 return llvm::MutableArrayRef(getTrailingObjects<TypeSize>(), NumElements);
0590 }
0591
0592 ArrayRef<TypeSize> getMemberOffsets() const {
0593 return llvm::ArrayRef(getTrailingObjects<TypeSize>(), NumElements);
0594 }
0595
0596 TypeSize getElementOffset(unsigned Idx) const {
0597 assert(Idx < NumElements && "Invalid element idx!");
0598 return getMemberOffsets()[Idx];
0599 }
0600
0601 TypeSize getElementOffsetInBits(unsigned Idx) const {
0602 return getElementOffset(Idx) * 8;
0603 }
0604
0605 private:
0606 friend class DataLayout;
0607
0608 StructLayout(StructType *ST, const DataLayout &DL);
0609
0610 size_t numTrailingObjects(OverloadToken<TypeSize>) const {
0611 return NumElements;
0612 }
0613 };
0614
0615
0616
0617 inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
0618 assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
0619 switch (Ty->getTypeID()) {
0620 case Type::LabelTyID:
0621 return TypeSize::getFixed(getPointerSizeInBits(0));
0622 case Type::PointerTyID:
0623 return TypeSize::getFixed(
0624 getPointerSizeInBits(Ty->getPointerAddressSpace()));
0625 case Type::ArrayTyID: {
0626 ArrayType *ATy = cast<ArrayType>(Ty);
0627 return ATy->getNumElements() *
0628 getTypeAllocSizeInBits(ATy->getElementType());
0629 }
0630 case Type::StructTyID:
0631
0632 return getStructLayout(cast<StructType>(Ty))->getSizeInBits();
0633 case Type::IntegerTyID:
0634 return TypeSize::getFixed(Ty->getIntegerBitWidth());
0635 case Type::HalfTyID:
0636 case Type::BFloatTyID:
0637 return TypeSize::getFixed(16);
0638 case Type::FloatTyID:
0639 return TypeSize::getFixed(32);
0640 case Type::DoubleTyID:
0641 return TypeSize::getFixed(64);
0642 case Type::PPC_FP128TyID:
0643 case Type::FP128TyID:
0644 return TypeSize::getFixed(128);
0645 case Type::X86_AMXTyID:
0646 return TypeSize::getFixed(8192);
0647
0648
0649 case Type::X86_FP80TyID:
0650 return TypeSize::getFixed(80);
0651 case Type::FixedVectorTyID:
0652 case Type::ScalableVectorTyID: {
0653 VectorType *VTy = cast<VectorType>(Ty);
0654 auto EltCnt = VTy->getElementCount();
0655 uint64_t MinBits = EltCnt.getKnownMinValue() *
0656 getTypeSizeInBits(VTy->getElementType()).getFixedValue();
0657 return TypeSize(MinBits, EltCnt.isScalable());
0658 }
0659 case Type::TargetExtTyID: {
0660 Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
0661 return getTypeSizeInBits(LayoutTy);
0662 }
0663 default:
0664 llvm_unreachable("DataLayout::getTypeSizeInBits(): Unsupported type");
0665 }
0666 }
0667
0668 }
0669
0670 #endif