Path: blob/main/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
35233 views
//===- DataLayout.cpp - Data size & alignment routines ---------------------==//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines layout properties related to datatype size/offset/alignment9// information.10//11// This structure should be created once, filled in if the defaults are not12// correct and then passed around by const&. None of the members functions13// require modification to the object.14//15//===----------------------------------------------------------------------===//1617#include "llvm/IR/DataLayout.h"18#include "llvm/ADT/DenseMap.h"19#include "llvm/ADT/StringRef.h"20#include "llvm/IR/Constants.h"21#include "llvm/IR/DerivedTypes.h"22#include "llvm/IR/GetElementPtrTypeIterator.h"23#include "llvm/IR/GlobalVariable.h"24#include "llvm/IR/Module.h"25#include "llvm/IR/Type.h"26#include "llvm/IR/Value.h"27#include "llvm/Support/Casting.h"28#include "llvm/Support/Error.h"29#include "llvm/Support/ErrorHandling.h"30#include "llvm/Support/MathExtras.h"31#include "llvm/Support/MemAlloc.h"32#include "llvm/Support/TypeSize.h"33#include "llvm/TargetParser/Triple.h"34#include <algorithm>35#include <cassert>36#include <cstdint>37#include <cstdlib>38#include <new>39#include <utility>4041using namespace llvm;4243//===----------------------------------------------------------------------===//44// Support for StructLayout45//===----------------------------------------------------------------------===//4647StructLayout::StructLayout(StructType *ST, const DataLayout &DL)48: StructSize(TypeSize::getFixed(0)) {49assert(!ST->isOpaque() && "Cannot get layout of opaque structs");50IsPadded = false;51NumElements = ST->getNumElements();5253// Loop over each of the elements, placing them in memory.54for (unsigned i = 0, e = NumElements; i != e; ++i) {55Type *Ty = ST->getElementType(i);56if (i == 0 && Ty->isScalableTy())57StructSize = TypeSize::getScalable(0);5859const Align TyAlign = ST->isPacked() ? Align(1) : DL.getABITypeAlign(Ty);6061// Add padding if necessary to align the data element properly.62// Currently the only structure with scalable size will be the homogeneous63// scalable vector types. Homogeneous scalable vector types have members of64// the same data type so no alignment issue will happen. The condition here65// assumes so and needs to be adjusted if this assumption changes (e.g. we66// support structures with arbitrary scalable data type, or structure that67// contains both fixed size and scalable size data type members).68if (!StructSize.isScalable() && !isAligned(TyAlign, StructSize)) {69IsPadded = true;70StructSize = TypeSize::getFixed(alignTo(StructSize, TyAlign));71}7273// Keep track of maximum alignment constraint.74StructAlignment = std::max(TyAlign, StructAlignment);7576getMemberOffsets()[i] = StructSize;77// Consume space for this data item78StructSize += DL.getTypeAllocSize(Ty);79}8081// Add padding to the end of the struct so that it could be put in an array82// and all array elements would be aligned correctly.83if (!StructSize.isScalable() && !isAligned(StructAlignment, StructSize)) {84IsPadded = true;85StructSize = TypeSize::getFixed(alignTo(StructSize, StructAlignment));86}87}8889/// getElementContainingOffset - Given a valid offset into the structure,90/// return the structure index that contains it.91unsigned StructLayout::getElementContainingOffset(uint64_t FixedOffset) const {92assert(!StructSize.isScalable() &&93"Cannot get element at offset for structure containing scalable "94"vector types");95TypeSize Offset = TypeSize::getFixed(FixedOffset);96ArrayRef<TypeSize> MemberOffsets = getMemberOffsets();9798const auto *SI =99std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), Offset,100[](TypeSize LHS, TypeSize RHS) -> bool {101return TypeSize::isKnownLT(LHS, RHS);102});103assert(SI != MemberOffsets.begin() && "Offset not in structure type!");104--SI;105assert(TypeSize::isKnownLE(*SI, Offset) && "upper_bound didn't work");106assert(107(SI == MemberOffsets.begin() || TypeSize::isKnownLE(*(SI - 1), Offset)) &&108(SI + 1 == MemberOffsets.end() ||109TypeSize::isKnownGT(*(SI + 1), Offset)) &&110"Upper bound didn't work!");111112// Multiple fields can have the same offset if any of them are zero sized.113// For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop114// at the i32 element, because it is the last element at that offset. This is115// the right one to return, because anything after it will have a higher116// offset, implying that this element is non-empty.117return SI - MemberOffsets.begin();118}119120//===----------------------------------------------------------------------===//121// LayoutAlignElem, LayoutAlign support122//===----------------------------------------------------------------------===//123124LayoutAlignElem LayoutAlignElem::get(Align ABIAlign, Align PrefAlign,125uint32_t BitWidth) {126assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");127LayoutAlignElem retval;128retval.ABIAlign = ABIAlign;129retval.PrefAlign = PrefAlign;130retval.TypeBitWidth = BitWidth;131return retval;132}133134bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {135return ABIAlign == rhs.ABIAlign && PrefAlign == rhs.PrefAlign &&136TypeBitWidth == rhs.TypeBitWidth;137}138139//===----------------------------------------------------------------------===//140// PointerAlignElem, PointerAlign support141//===----------------------------------------------------------------------===//142143PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace,144Align ABIAlign, Align PrefAlign,145uint32_t TypeBitWidth,146uint32_t IndexBitWidth) {147assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");148PointerAlignElem retval;149retval.AddressSpace = AddressSpace;150retval.ABIAlign = ABIAlign;151retval.PrefAlign = PrefAlign;152retval.TypeBitWidth = TypeBitWidth;153retval.IndexBitWidth = IndexBitWidth;154return retval;155}156157bool158PointerAlignElem::operator==(const PointerAlignElem &rhs) const {159return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&160PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth &&161IndexBitWidth == rhs.IndexBitWidth);162}163164//===----------------------------------------------------------------------===//165// DataLayout Class Implementation166//===----------------------------------------------------------------------===//167168const char *DataLayout::getManglingComponent(const Triple &T) {169if (T.isOSBinFormatGOFF())170return "-m:l";171if (T.isOSBinFormatMachO())172return "-m:o";173if ((T.isOSWindows() || T.isUEFI()) && T.isOSBinFormatCOFF())174return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";175if (T.isOSBinFormatXCOFF())176return "-m:a";177return "-m:e";178}179180static const std::pair<AlignTypeEnum, LayoutAlignElem> DefaultAlignments[] = {181{INTEGER_ALIGN, {1, Align(1), Align(1)}}, // i1182{INTEGER_ALIGN, {8, Align(1), Align(1)}}, // i8183{INTEGER_ALIGN, {16, Align(2), Align(2)}}, // i16184{INTEGER_ALIGN, {32, Align(4), Align(4)}}, // i32185{INTEGER_ALIGN, {64, Align(4), Align(8)}}, // i64186{FLOAT_ALIGN, {16, Align(2), Align(2)}}, // half, bfloat187{FLOAT_ALIGN, {32, Align(4), Align(4)}}, // float188{FLOAT_ALIGN, {64, Align(8), Align(8)}}, // double189{FLOAT_ALIGN, {128, Align(16), Align(16)}}, // ppcf128, quad, ...190{VECTOR_ALIGN, {64, Align(8), Align(8)}}, // v2i32, v1i64, ...191{VECTOR_ALIGN, {128, Align(16), Align(16)}}, // v16i8, v8i16, v4i32, ...192};193194void DataLayout::reset(StringRef Desc) {195clear();196197LayoutMap = nullptr;198BigEndian = false;199AllocaAddrSpace = 0;200StackNaturalAlign.reset();201ProgramAddrSpace = 0;202DefaultGlobalsAddrSpace = 0;203FunctionPtrAlign.reset();204TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;205ManglingMode = MM_None;206NonIntegralAddressSpaces.clear();207StructAlignment = LayoutAlignElem::get(Align(1), Align(8), 0);208209// Default alignments210for (const auto &[Kind, Layout] : DefaultAlignments) {211if (Error Err = setAlignment(Kind, Layout.ABIAlign, Layout.PrefAlign,212Layout.TypeBitWidth))213return report_fatal_error(std::move(Err));214}215if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))216return report_fatal_error(std::move(Err));217218if (Error Err = parseSpecifier(Desc))219return report_fatal_error(std::move(Err));220}221222Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {223DataLayout Layout("");224if (Error Err = Layout.parseSpecifier(LayoutDescription))225return std::move(Err);226return Layout;227}228229static Error reportError(const Twine &Message) {230return createStringError(inconvertibleErrorCode(), Message);231}232233/// Checked version of split, to ensure mandatory subparts.234static Error split(StringRef Str, char Separator,235std::pair<StringRef, StringRef> &Split) {236assert(!Str.empty() && "parse error, string can't be empty here");237Split = Str.split(Separator);238if (Split.second.empty() && Split.first != Str)239return reportError("Trailing separator in datalayout string");240if (!Split.second.empty() && Split.first.empty())241return reportError("Expected token before separator in datalayout string");242return Error::success();243}244245/// Get an unsigned integer, including error checks.246template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {247bool error = R.getAsInteger(10, Result); (void)error;248if (error)249return reportError("not a number, or does not fit in an unsigned int");250return Error::success();251}252253/// Get an unsigned integer representing the number of bits and convert it into254/// bytes. Error out of not a byte width multiple.255template <typename IntTy>256static Error getIntInBytes(StringRef R, IntTy &Result) {257if (Error Err = getInt<IntTy>(R, Result))258return Err;259if (Result % 8)260return reportError("number of bits must be a byte width multiple");261Result /= 8;262return Error::success();263}264265static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {266if (Error Err = getInt(R, AddrSpace))267return Err;268if (!isUInt<24>(AddrSpace))269return reportError("Invalid address space, must be a 24-bit integer");270return Error::success();271}272273Error DataLayout::parseSpecifier(StringRef Desc) {274StringRepresentation = std::string(Desc);275while (!Desc.empty()) {276// Split at '-'.277std::pair<StringRef, StringRef> Split;278if (Error Err = ::split(Desc, '-', Split))279return Err;280Desc = Split.second;281282// Split at ':'.283if (Error Err = ::split(Split.first, ':', Split))284return Err;285286// Aliases used below.287StringRef &Tok = Split.first; // Current token.288StringRef &Rest = Split.second; // The rest of the string.289290if (Tok == "ni") {291do {292if (Error Err = ::split(Rest, ':', Split))293return Err;294Rest = Split.second;295unsigned AS;296if (Error Err = getInt(Split.first, AS))297return Err;298if (AS == 0)299return reportError("Address space 0 can never be non-integral");300NonIntegralAddressSpaces.push_back(AS);301} while (!Rest.empty());302303continue;304}305306char Specifier = Tok.front();307Tok = Tok.substr(1);308309switch (Specifier) {310case 's':311// Deprecated, but ignoring here to preserve loading older textual llvm312// ASM file313break;314case 'E':315BigEndian = true;316break;317case 'e':318BigEndian = false;319break;320case 'p': {321// Address space.322unsigned AddrSpace = 0;323if (!Tok.empty())324if (Error Err = getInt(Tok, AddrSpace))325return Err;326if (!isUInt<24>(AddrSpace))327return reportError("Invalid address space, must be a 24-bit integer");328329// Size.330if (Rest.empty())331return reportError(332"Missing size specification for pointer in datalayout string");333if (Error Err = ::split(Rest, ':', Split))334return Err;335unsigned PointerMemSize;336if (Error Err = getInt(Tok, PointerMemSize))337return Err;338if (!PointerMemSize)339return reportError("Invalid pointer size of 0 bytes");340341// ABI alignment.342if (Rest.empty())343return reportError(344"Missing alignment specification for pointer in datalayout string");345if (Error Err = ::split(Rest, ':', Split))346return Err;347unsigned PointerABIAlign;348if (Error Err = getIntInBytes(Tok, PointerABIAlign))349return Err;350if (!isPowerOf2_64(PointerABIAlign))351return reportError("Pointer ABI alignment must be a power of 2");352353// Size of index used in GEP for address calculation.354// The parameter is optional. By default it is equal to size of pointer.355unsigned IndexSize = PointerMemSize;356357// Preferred alignment.358unsigned PointerPrefAlign = PointerABIAlign;359if (!Rest.empty()) {360if (Error Err = ::split(Rest, ':', Split))361return Err;362if (Error Err = getIntInBytes(Tok, PointerPrefAlign))363return Err;364if (!isPowerOf2_64(PointerPrefAlign))365return reportError(366"Pointer preferred alignment must be a power of 2");367368// Now read the index. It is the second optional parameter here.369if (!Rest.empty()) {370if (Error Err = ::split(Rest, ':', Split))371return Err;372if (Error Err = getInt(Tok, IndexSize))373return Err;374if (!IndexSize)375return reportError("Invalid index size of 0 bytes");376}377}378if (Error Err = setPointerAlignmentInBits(379AddrSpace, assumeAligned(PointerABIAlign),380assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))381return Err;382break;383}384case 'i':385case 'v':386case 'f':387case 'a': {388AlignTypeEnum AlignType;389switch (Specifier) {390default: llvm_unreachable("Unexpected specifier!");391case 'i': AlignType = INTEGER_ALIGN; break;392case 'v': AlignType = VECTOR_ALIGN; break;393case 'f': AlignType = FLOAT_ALIGN; break;394case 'a': AlignType = AGGREGATE_ALIGN; break;395}396397// Bit size.398unsigned Size = 0;399if (!Tok.empty())400if (Error Err = getInt(Tok, Size))401return Err;402403if (AlignType == AGGREGATE_ALIGN && Size != 0)404return reportError(405"Sized aggregate specification in datalayout string");406407// ABI alignment.408if (Rest.empty())409return reportError(410"Missing alignment specification in datalayout string");411if (Error Err = ::split(Rest, ':', Split))412return Err;413unsigned ABIAlign;414if (Error Err = getIntInBytes(Tok, ABIAlign))415return Err;416if (AlignType != AGGREGATE_ALIGN && !ABIAlign)417return reportError(418"ABI alignment specification must be >0 for non-aggregate types");419420if (!isUInt<16>(ABIAlign))421return reportError("Invalid ABI alignment, must be a 16bit integer");422if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))423return reportError("Invalid ABI alignment, must be a power of 2");424if (AlignType == INTEGER_ALIGN && Size == 8 && ABIAlign != 1)425return reportError(426"Invalid ABI alignment, i8 must be naturally aligned");427428// Preferred alignment.429unsigned PrefAlign = ABIAlign;430if (!Rest.empty()) {431if (Error Err = ::split(Rest, ':', Split))432return Err;433if (Error Err = getIntInBytes(Tok, PrefAlign))434return Err;435}436437if (!isUInt<16>(PrefAlign))438return reportError(439"Invalid preferred alignment, must be a 16bit integer");440if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))441return reportError("Invalid preferred alignment, must be a power of 2");442443if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),444assumeAligned(PrefAlign), Size))445return Err;446447break;448}449case 'n': // Native integer types.450while (true) {451unsigned Width;452if (Error Err = getInt(Tok, Width))453return Err;454if (Width == 0)455return reportError(456"Zero width native integer type in datalayout string");457LegalIntWidths.push_back(Width);458if (Rest.empty())459break;460if (Error Err = ::split(Rest, ':', Split))461return Err;462}463break;464case 'S': { // Stack natural alignment.465uint64_t Alignment;466if (Error Err = getIntInBytes(Tok, Alignment))467return Err;468if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))469return reportError("Alignment is neither 0 nor a power of 2");470StackNaturalAlign = MaybeAlign(Alignment);471break;472}473case 'F': {474switch (Tok.front()) {475case 'i':476TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;477break;478case 'n':479TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;480break;481default:482return reportError("Unknown function pointer alignment type in "483"datalayout string");484}485Tok = Tok.substr(1);486uint64_t Alignment;487if (Error Err = getIntInBytes(Tok, Alignment))488return Err;489if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))490return reportError("Alignment is neither 0 nor a power of 2");491FunctionPtrAlign = MaybeAlign(Alignment);492break;493}494case 'P': { // Function address space.495if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))496return Err;497break;498}499case 'A': { // Default stack/alloca address space.500if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))501return Err;502break;503}504case 'G': { // Default address space for global variables.505if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))506return Err;507break;508}509case 'm':510if (!Tok.empty())511return reportError("Unexpected trailing characters after mangling "512"specifier in datalayout string");513if (Rest.empty())514return reportError("Expected mangling specifier in datalayout string");515if (Rest.size() > 1)516return reportError("Unknown mangling specifier in datalayout string");517switch(Rest[0]) {518default:519return reportError("Unknown mangling in datalayout string");520case 'e':521ManglingMode = MM_ELF;522break;523case 'l':524ManglingMode = MM_GOFF;525break;526case 'o':527ManglingMode = MM_MachO;528break;529case 'm':530ManglingMode = MM_Mips;531break;532case 'w':533ManglingMode = MM_WinCOFF;534break;535case 'x':536ManglingMode = MM_WinCOFFX86;537break;538case 'a':539ManglingMode = MM_XCOFF;540break;541}542break;543default:544return reportError("Unknown specifier in datalayout string");545break;546}547}548549return Error::success();550}551552DataLayout::DataLayout(const Module *M) {553init(M);554}555556void DataLayout::init(const Module *M) { *this = M->getDataLayout(); }557558bool DataLayout::operator==(const DataLayout &Other) const {559bool Ret = BigEndian == Other.BigEndian &&560AllocaAddrSpace == Other.AllocaAddrSpace &&561StackNaturalAlign == Other.StackNaturalAlign &&562ProgramAddrSpace == Other.ProgramAddrSpace &&563DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&564FunctionPtrAlign == Other.FunctionPtrAlign &&565TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&566ManglingMode == Other.ManglingMode &&567LegalIntWidths == Other.LegalIntWidths &&568IntAlignments == Other.IntAlignments &&569FloatAlignments == Other.FloatAlignments &&570VectorAlignments == Other.VectorAlignments &&571StructAlignment == Other.StructAlignment &&572Pointers == Other.Pointers;573// Note: getStringRepresentation() might differs, it is not canonicalized574return Ret;575}576577static SmallVectorImpl<LayoutAlignElem>::const_iterator578findAlignmentLowerBound(const SmallVectorImpl<LayoutAlignElem> &Alignments,579uint32_t BitWidth) {580return partition_point(Alignments, [BitWidth](const LayoutAlignElem &E) {581return E.TypeBitWidth < BitWidth;582});583}584585Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign,586Align PrefAlign, uint32_t BitWidth) {587// AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as588// uint16_t, it is unclear if there are requirements for alignment to be less589// than 2^16 other than storage. In the meantime we leave the restriction as590// an assert. See D67400 for context.591assert(Log2(ABIAlign) < 16 && Log2(PrefAlign) < 16 && "Alignment too big");592if (!isUInt<24>(BitWidth))593return reportError("Invalid bit width, must be a 24-bit integer");594if (PrefAlign < ABIAlign)595return reportError(596"Preferred alignment cannot be less than the ABI alignment");597598SmallVectorImpl<LayoutAlignElem> *Alignments;599switch (AlignType) {600case AGGREGATE_ALIGN:601StructAlignment.ABIAlign = ABIAlign;602StructAlignment.PrefAlign = PrefAlign;603return Error::success();604case INTEGER_ALIGN:605Alignments = &IntAlignments;606break;607case FLOAT_ALIGN:608Alignments = &FloatAlignments;609break;610case VECTOR_ALIGN:611Alignments = &VectorAlignments;612break;613}614615auto I = partition_point(*Alignments, [BitWidth](const LayoutAlignElem &E) {616return E.TypeBitWidth < BitWidth;617});618if (I != Alignments->end() && I->TypeBitWidth == BitWidth) {619// Update the abi, preferred alignments.620I->ABIAlign = ABIAlign;621I->PrefAlign = PrefAlign;622} else {623// Insert before I to keep the vector sorted.624Alignments->insert(I, LayoutAlignElem::get(ABIAlign, PrefAlign, BitWidth));625}626return Error::success();627}628629const PointerAlignElem &630DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {631if (AddressSpace != 0) {632auto I = lower_bound(Pointers, AddressSpace,633[](const PointerAlignElem &A, uint32_t AddressSpace) {634return A.AddressSpace < AddressSpace;635});636if (I != Pointers.end() && I->AddressSpace == AddressSpace)637return *I;638}639640assert(Pointers[0].AddressSpace == 0);641return Pointers[0];642}643644Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,645Align PrefAlign,646uint32_t TypeBitWidth,647uint32_t IndexBitWidth) {648if (PrefAlign < ABIAlign)649return reportError(650"Preferred alignment cannot be less than the ABI alignment");651if (IndexBitWidth > TypeBitWidth)652return reportError("Index width cannot be larger than pointer width");653654auto I = lower_bound(Pointers, AddrSpace,655[](const PointerAlignElem &A, uint32_t AddressSpace) {656return A.AddressSpace < AddressSpace;657});658if (I == Pointers.end() || I->AddressSpace != AddrSpace) {659Pointers.insert(I,660PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign,661TypeBitWidth, IndexBitWidth));662} else {663I->ABIAlign = ABIAlign;664I->PrefAlign = PrefAlign;665I->TypeBitWidth = TypeBitWidth;666I->IndexBitWidth = IndexBitWidth;667}668return Error::success();669}670671Align DataLayout::getIntegerAlignment(uint32_t BitWidth,672bool abi_or_pref) const {673auto I = findAlignmentLowerBound(IntAlignments, BitWidth);674// If we don't have an exact match, use alignment of next larger integer675// type. If there is none, use alignment of largest integer type by going676// back one element.677if (I == IntAlignments.end())678--I;679return abi_or_pref ? I->ABIAlign : I->PrefAlign;680}681682namespace {683684class StructLayoutMap {685using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;686LayoutInfoTy LayoutInfo;687688public:689~StructLayoutMap() {690// Remove any layouts.691for (const auto &I : LayoutInfo) {692StructLayout *Value = I.second;693Value->~StructLayout();694free(Value);695}696}697698StructLayout *&operator[](StructType *STy) {699return LayoutInfo[STy];700}701};702703} // end anonymous namespace704705void DataLayout::clear() {706LegalIntWidths.clear();707IntAlignments.clear();708FloatAlignments.clear();709VectorAlignments.clear();710Pointers.clear();711delete static_cast<StructLayoutMap *>(LayoutMap);712LayoutMap = nullptr;713}714715DataLayout::~DataLayout() {716clear();717}718719const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {720if (!LayoutMap)721LayoutMap = new StructLayoutMap();722723StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);724StructLayout *&SL = (*STM)[Ty];725if (SL) return SL;726727// Otherwise, create the struct layout. Because it is variable length, we728// malloc it, then use placement new.729StructLayout *L = (StructLayout *)safe_malloc(730StructLayout::totalSizeToAlloc<TypeSize>(Ty->getNumElements()));731732// Set SL before calling StructLayout's ctor. The ctor could cause other733// entries to be added to TheMap, invalidating our reference.734SL = L;735736new (L) StructLayout(Ty, *this);737738return L;739}740741Align DataLayout::getPointerABIAlignment(unsigned AS) const {742return getPointerAlignElem(AS).ABIAlign;743}744745Align DataLayout::getPointerPrefAlignment(unsigned AS) const {746return getPointerAlignElem(AS).PrefAlign;747}748749unsigned DataLayout::getPointerSize(unsigned AS) const {750return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8);751}752753unsigned DataLayout::getMaxIndexSize() const {754unsigned MaxIndexSize = 0;755for (auto &P : Pointers)756MaxIndexSize =757std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8));758759return MaxIndexSize;760}761762unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {763assert(Ty->isPtrOrPtrVectorTy() &&764"This should only be called with a pointer or pointer vector type");765Ty = Ty->getScalarType();766return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());767}768769unsigned DataLayout::getIndexSize(unsigned AS) const {770return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8);771}772773unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {774assert(Ty->isPtrOrPtrVectorTy() &&775"This should only be called with a pointer or pointer vector type");776Ty = Ty->getScalarType();777return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace());778}779780/*!781\param abi_or_pref Flag that determines which alignment is returned. true782returns the ABI alignment, false returns the preferred alignment.783\param Ty The underlying type for which alignment is determined.784785Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref786== false) for the requested type \a Ty.787*/788Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {789assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");790switch (Ty->getTypeID()) {791// Early escape for the non-numeric types.792case Type::LabelTyID:793return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0);794case Type::PointerTyID: {795unsigned AS = cast<PointerType>(Ty)->getAddressSpace();796return abi_or_pref ? getPointerABIAlignment(AS)797: getPointerPrefAlignment(AS);798}799case Type::ArrayTyID:800return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);801802case Type::StructTyID: {803// Packed structure types always have an ABI alignment of one.804if (cast<StructType>(Ty)->isPacked() && abi_or_pref)805return Align(1);806807// Get the layout annotation... which is lazily created on demand.808const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));809const Align Align =810abi_or_pref ? StructAlignment.ABIAlign : StructAlignment.PrefAlign;811return std::max(Align, Layout->getAlignment());812}813case Type::IntegerTyID:814return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);815case Type::HalfTyID:816case Type::BFloatTyID:817case Type::FloatTyID:818case Type::DoubleTyID:819// PPC_FP128TyID and FP128TyID have different data contents, but the820// same size and alignment, so they look the same here.821case Type::PPC_FP128TyID:822case Type::FP128TyID:823case Type::X86_FP80TyID: {824unsigned BitWidth = getTypeSizeInBits(Ty).getFixedValue();825auto I = findAlignmentLowerBound(FloatAlignments, BitWidth);826if (I != FloatAlignments.end() && I->TypeBitWidth == BitWidth)827return abi_or_pref ? I->ABIAlign : I->PrefAlign;828829// If we still couldn't find a reasonable default alignment, fall back830// to a simple heuristic that the alignment is the first power of two831// greater-or-equal to the store size of the type. This is a reasonable832// approximation of reality, and if the user wanted something less833// less conservative, they should have specified it explicitly in the data834// layout.835return Align(PowerOf2Ceil(BitWidth / 8));836}837case Type::X86_MMXTyID:838case Type::FixedVectorTyID:839case Type::ScalableVectorTyID: {840unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinValue();841auto I = findAlignmentLowerBound(VectorAlignments, BitWidth);842if (I != VectorAlignments.end() && I->TypeBitWidth == BitWidth)843return abi_or_pref ? I->ABIAlign : I->PrefAlign;844845// By default, use natural alignment for vector types. This is consistent846// with what clang and llvm-gcc do.847//848// We're only calculating a natural alignment, so it doesn't have to be849// based on the full size for scalable vectors. Using the minimum element850// count should be enough here.851return Align(PowerOf2Ceil(getTypeStoreSize(Ty).getKnownMinValue()));852}853case Type::X86_AMXTyID:854return Align(64);855case Type::TargetExtTyID: {856Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();857return getAlignment(LayoutTy, abi_or_pref);858}859default:860llvm_unreachable("Bad type for getAlignment!!!");861}862}863864Align DataLayout::getABITypeAlign(Type *Ty) const {865return getAlignment(Ty, true);866}867868/// TODO: Remove this function once the transition to Align is over.869uint64_t DataLayout::getPrefTypeAlignment(Type *Ty) const {870return getPrefTypeAlign(Ty).value();871}872873Align DataLayout::getPrefTypeAlign(Type *Ty) const {874return getAlignment(Ty, false);875}876877IntegerType *DataLayout::getIntPtrType(LLVMContext &C,878unsigned AddressSpace) const {879return IntegerType::get(C, getPointerSizeInBits(AddressSpace));880}881882Type *DataLayout::getIntPtrType(Type *Ty) const {883assert(Ty->isPtrOrPtrVectorTy() &&884"Expected a pointer or pointer vector type.");885unsigned NumBits = getPointerTypeSizeInBits(Ty);886IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);887if (VectorType *VecTy = dyn_cast<VectorType>(Ty))888return VectorType::get(IntTy, VecTy);889return IntTy;890}891892Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {893for (unsigned LegalIntWidth : LegalIntWidths)894if (Width <= LegalIntWidth)895return Type::getIntNTy(C, LegalIntWidth);896return nullptr;897}898899unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const {900auto Max = llvm::max_element(LegalIntWidths);901return Max != LegalIntWidths.end() ? *Max : 0;902}903904IntegerType *DataLayout::getIndexType(LLVMContext &C,905unsigned AddressSpace) const {906return IntegerType::get(C, getIndexSizeInBits(AddressSpace));907}908909Type *DataLayout::getIndexType(Type *Ty) const {910assert(Ty->isPtrOrPtrVectorTy() &&911"Expected a pointer or pointer vector type.");912unsigned NumBits = getIndexTypeSizeInBits(Ty);913IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);914if (VectorType *VecTy = dyn_cast<VectorType>(Ty))915return VectorType::get(IntTy, VecTy);916return IntTy;917}918919int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,920ArrayRef<Value *> Indices) const {921int64_t Result = 0;922923generic_gep_type_iterator<Value* const*>924GTI = gep_type_begin(ElemTy, Indices),925GTE = gep_type_end(ElemTy, Indices);926for (; GTI != GTE; ++GTI) {927Value *Idx = GTI.getOperand();928if (StructType *STy = GTI.getStructTypeOrNull()) {929assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");930unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();931932// Get structure layout information...933const StructLayout *Layout = getStructLayout(STy);934935// Add in the offset, as calculated by the structure layout info...936Result += Layout->getElementOffset(FieldNo);937} else {938if (int64_t ArrayIdx = cast<ConstantInt>(Idx)->getSExtValue())939Result += ArrayIdx * GTI.getSequentialElementStride(*this);940}941}942943return Result;944}945946static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {947// Skip over scalable or zero size elements. Also skip element sizes larger948// than the positive index space, because the arithmetic below may not be949// correct in that case.950unsigned BitWidth = Offset.getBitWidth();951if (ElemSize.isScalable() || ElemSize == 0 ||952!isUIntN(BitWidth - 1, ElemSize)) {953return APInt::getZero(BitWidth);954}955956APInt Index = Offset.sdiv(ElemSize);957Offset -= Index * ElemSize;958if (Offset.isNegative()) {959// Prefer a positive remaining offset to allow struct indexing.960--Index;961Offset += ElemSize;962assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");963}964return Index;965}966967std::optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,968APInt &Offset) const {969if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {970ElemTy = ArrTy->getElementType();971return getElementIndex(getTypeAllocSize(ElemTy), Offset);972}973974if (isa<VectorType>(ElemTy)) {975// Vector GEPs are partially broken (e.g. for overaligned element types),976// and may be forbidden in the future, so avoid generating GEPs into977// vectors. See https://discourse.llvm.org/t/67497978return std::nullopt;979}980981if (auto *STy = dyn_cast<StructType>(ElemTy)) {982const StructLayout *SL = getStructLayout(STy);983uint64_t IntOffset = Offset.getZExtValue();984if (IntOffset >= SL->getSizeInBytes())985return std::nullopt;986987unsigned Index = SL->getElementContainingOffset(IntOffset);988Offset -= SL->getElementOffset(Index);989ElemTy = STy->getElementType(Index);990return APInt(32, Index);991}992993// Non-aggregate type.994return std::nullopt;995}996997SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,998APInt &Offset) const {999assert(ElemTy->isSized() && "Element type must be sized");1000SmallVector<APInt> Indices;1001Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));1002while (Offset != 0) {1003std::optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);1004if (!Index)1005break;1006Indices.push_back(*Index);1007}10081009return Indices;1010}10111012/// getPreferredAlign - Return the preferred alignment of the specified global.1013/// This includes an explicitly requested alignment (if the global has one).1014Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {1015MaybeAlign GVAlignment = GV->getAlign();1016// If a section is specified, always precisely honor explicit alignment,1017// so we don't insert padding into a section we don't control.1018if (GVAlignment && GV->hasSection())1019return *GVAlignment;10201021// If no explicit alignment is specified, compute the alignment based on1022// the IR type. If an alignment is specified, increase it to match the ABI1023// alignment of the IR type.1024//1025// FIXME: Not sure it makes sense to use the alignment of the type if1026// there's already an explicit alignment specification.1027Type *ElemType = GV->getValueType();1028Align Alignment = getPrefTypeAlign(ElemType);1029if (GVAlignment) {1030if (*GVAlignment >= Alignment)1031Alignment = *GVAlignment;1032else1033Alignment = std::max(*GVAlignment, getABITypeAlign(ElemType));1034}10351036// If no explicit alignment is specified, and the global is large, increase1037// the alignment to 16.1038// FIXME: Why 16, specifically?1039if (GV->hasInitializer() && !GVAlignment) {1040if (Alignment < Align(16)) {1041// If the global is not external, see if it is large. If so, give it a1042// larger alignment.1043if (getTypeSizeInBits(ElemType) > 128)1044Alignment = Align(16); // 16-byte alignment.1045}1046}1047return Alignment;1048}104910501051