10b57cec5SDimitry Andric //===- DataLayout.cpp - Data size & alignment routines ---------------------==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines layout properties related to datatype size/offset/alignment 100b57cec5SDimitry Andric // information. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric // This structure should be created once, filled in if the defaults are not 130b57cec5SDimitry Andric // correct and then passed around by const&. None of the members functions 140b57cec5SDimitry Andric // require modification to the object. 150b57cec5SDimitry Andric // 160b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 190b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 210b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 220b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 230b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h" 240b57cec5SDimitry Andric #include "llvm/IR/GlobalVariable.h" 250b57cec5SDimitry Andric #include "llvm/IR/Module.h" 260b57cec5SDimitry Andric #include "llvm/IR/Type.h" 270b57cec5SDimitry Andric #include "llvm/IR/Value.h" 280b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 29e8d8bef9SDimitry Andric #include "llvm/Support/Error.h" 300b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 310b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 321fd87a68SDimitry Andric #include "llvm/Support/MemAlloc.h" 338bcb0991SDimitry Andric #include "llvm/Support/TypeSize.h" 3406c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 350b57cec5SDimitry Andric #include <algorithm> 360b57cec5SDimitry Andric #include <cassert> 370b57cec5SDimitry Andric #include <cstdint> 380b57cec5SDimitry Andric #include <cstdlib> 391fd87a68SDimitry Andric #include <new> 400b57cec5SDimitry Andric #include <utility> 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric using namespace llvm; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 450b57cec5SDimitry Andric // Support for StructLayout 460b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 470b57cec5SDimitry Andric 4806c3fb27SDimitry Andric StructLayout::StructLayout(StructType *ST, const DataLayout &DL) 495f757f3fSDimitry Andric : StructSize(TypeSize::getFixed(0)) { 500b57cec5SDimitry Andric assert(!ST->isOpaque() && "Cannot get layout of opaque structs"); 510b57cec5SDimitry Andric IsPadded = false; 520b57cec5SDimitry Andric NumElements = ST->getNumElements(); 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric // Loop over each of the elements, placing them in memory. 550b57cec5SDimitry Andric for (unsigned i = 0, e = NumElements; i != e; ++i) { 560b57cec5SDimitry Andric Type *Ty = ST->getElementType(i); 5706c3fb27SDimitry Andric if (i == 0 && Ty->isScalableTy()) 585f757f3fSDimitry Andric StructSize = TypeSize::getScalable(0); 5906c3fb27SDimitry Andric 605ffd83dbSDimitry Andric const Align TyAlign = ST->isPacked() ? Align(1) : DL.getABITypeAlign(Ty); 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric // Add padding if necessary to align the data element properly. 6306c3fb27SDimitry Andric // Currently the only structure with scalable size will be the homogeneous 6406c3fb27SDimitry Andric // scalable vector types. Homogeneous scalable vector types have members of 6506c3fb27SDimitry Andric // the same data type so no alignment issue will happen. The condition here 6606c3fb27SDimitry Andric // assumes so and needs to be adjusted if this assumption changes (e.g. we 6706c3fb27SDimitry Andric // support structures with arbitrary scalable data type, or structure that 6806c3fb27SDimitry Andric // contains both fixed size and scalable size data type members). 6906c3fb27SDimitry Andric if (!StructSize.isScalable() && !isAligned(TyAlign, StructSize)) { 700b57cec5SDimitry Andric IsPadded = true; 715f757f3fSDimitry Andric StructSize = TypeSize::getFixed(alignTo(StructSize, TyAlign)); 720b57cec5SDimitry Andric } 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // Keep track of maximum alignment constraint. 750b57cec5SDimitry Andric StructAlignment = std::max(TyAlign, StructAlignment); 760b57cec5SDimitry Andric 77fe6060f1SDimitry Andric getMemberOffsets()[i] = StructSize; 78e8d8bef9SDimitry Andric // Consume space for this data item 7906c3fb27SDimitry Andric StructSize += DL.getTypeAllocSize(Ty); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric // Add padding to the end of the struct so that it could be put in an array 830b57cec5SDimitry Andric // and all array elements would be aligned correctly. 8406c3fb27SDimitry Andric if (!StructSize.isScalable() && !isAligned(StructAlignment, StructSize)) { 850b57cec5SDimitry Andric IsPadded = true; 865f757f3fSDimitry Andric StructSize = TypeSize::getFixed(alignTo(StructSize, StructAlignment)); 870b57cec5SDimitry Andric } 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// getElementContainingOffset - Given a valid offset into the structure, 910b57cec5SDimitry Andric /// return the structure index that contains it. 9206c3fb27SDimitry Andric unsigned StructLayout::getElementContainingOffset(uint64_t FixedOffset) const { 9306c3fb27SDimitry Andric assert(!StructSize.isScalable() && 9406c3fb27SDimitry Andric "Cannot get element at offset for structure containing scalable " 9506c3fb27SDimitry Andric "vector types"); 965f757f3fSDimitry Andric TypeSize Offset = TypeSize::getFixed(FixedOffset); 9706c3fb27SDimitry Andric ArrayRef<TypeSize> MemberOffsets = getMemberOffsets(); 9806c3fb27SDimitry Andric 9906c3fb27SDimitry Andric const auto *SI = 10006c3fb27SDimitry Andric std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), Offset, 10106c3fb27SDimitry Andric [](TypeSize LHS, TypeSize RHS) -> bool { 10206c3fb27SDimitry Andric return TypeSize::isKnownLT(LHS, RHS); 10306c3fb27SDimitry Andric }); 104fe6060f1SDimitry Andric assert(SI != MemberOffsets.begin() && "Offset not in structure type!"); 1050b57cec5SDimitry Andric --SI; 10606c3fb27SDimitry Andric assert(TypeSize::isKnownLE(*SI, Offset) && "upper_bound didn't work"); 10706c3fb27SDimitry Andric assert( 10806c3fb27SDimitry Andric (SI == MemberOffsets.begin() || TypeSize::isKnownLE(*(SI - 1), Offset)) && 10906c3fb27SDimitry Andric (SI + 1 == MemberOffsets.end() || 11006c3fb27SDimitry Andric TypeSize::isKnownGT(*(SI + 1), Offset)) && 1110b57cec5SDimitry Andric "Upper bound didn't work!"); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric // Multiple fields can have the same offset if any of them are zero sized. 1140b57cec5SDimitry Andric // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop 1150b57cec5SDimitry Andric // at the i32 element, because it is the last element at that offset. This is 1160b57cec5SDimitry Andric // the right one to return, because anything after it will have a higher 1170b57cec5SDimitry Andric // offset, implying that this element is non-empty. 118fe6060f1SDimitry Andric return SI - MemberOffsets.begin(); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1220b57cec5SDimitry Andric // LayoutAlignElem, LayoutAlign support 1230b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1240b57cec5SDimitry Andric 12506c3fb27SDimitry Andric LayoutAlignElem LayoutAlignElem::get(Align ABIAlign, Align PrefAlign, 12606c3fb27SDimitry Andric uint32_t BitWidth) { 12706c3fb27SDimitry Andric assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); 1280b57cec5SDimitry Andric LayoutAlignElem retval; 12906c3fb27SDimitry Andric retval.ABIAlign = ABIAlign; 13006c3fb27SDimitry Andric retval.PrefAlign = PrefAlign; 13106c3fb27SDimitry Andric retval.TypeBitWidth = BitWidth; 1320b57cec5SDimitry Andric return retval; 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 13506c3fb27SDimitry Andric bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const { 13606c3fb27SDimitry Andric return ABIAlign == rhs.ABIAlign && PrefAlign == rhs.PrefAlign && 13706c3fb27SDimitry Andric TypeBitWidth == rhs.TypeBitWidth; 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1410b57cec5SDimitry Andric // PointerAlignElem, PointerAlign support 1420b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1430b57cec5SDimitry Andric 1440eae32dcSDimitry Andric PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace, 1450eae32dcSDimitry Andric Align ABIAlign, Align PrefAlign, 1460eae32dcSDimitry Andric uint32_t TypeBitWidth, 1470eae32dcSDimitry Andric uint32_t IndexBitWidth) { 1480b57cec5SDimitry Andric assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!"); 1490b57cec5SDimitry Andric PointerAlignElem retval; 1500b57cec5SDimitry Andric retval.AddressSpace = AddressSpace; 1510b57cec5SDimitry Andric retval.ABIAlign = ABIAlign; 1520b57cec5SDimitry Andric retval.PrefAlign = PrefAlign; 1530eae32dcSDimitry Andric retval.TypeBitWidth = TypeBitWidth; 1540eae32dcSDimitry Andric retval.IndexBitWidth = IndexBitWidth; 1550b57cec5SDimitry Andric return retval; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric bool 1590b57cec5SDimitry Andric PointerAlignElem::operator==(const PointerAlignElem &rhs) const { 1600eae32dcSDimitry Andric return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace && 1610eae32dcSDimitry Andric PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth && 1620eae32dcSDimitry Andric IndexBitWidth == rhs.IndexBitWidth); 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1660b57cec5SDimitry Andric // DataLayout Class Implementation 1670b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1680b57cec5SDimitry Andric 1690b57cec5SDimitry Andric const char *DataLayout::getManglingComponent(const Triple &T) { 170349cc55cSDimitry Andric if (T.isOSBinFormatGOFF()) 171349cc55cSDimitry Andric return "-m:l"; 1720b57cec5SDimitry Andric if (T.isOSBinFormatMachO()) 1730b57cec5SDimitry Andric return "-m:o"; 1745f757f3fSDimitry Andric if ((T.isOSWindows() || T.isUEFI()) && T.isOSBinFormatCOFF()) 1750b57cec5SDimitry Andric return T.getArch() == Triple::x86 ? "-m:x" : "-m:w"; 1765ffd83dbSDimitry Andric if (T.isOSBinFormatXCOFF()) 1775ffd83dbSDimitry Andric return "-m:a"; 1780b57cec5SDimitry Andric return "-m:e"; 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 18106c3fb27SDimitry Andric static const std::pair<AlignTypeEnum, LayoutAlignElem> DefaultAlignments[] = { 18206c3fb27SDimitry Andric {INTEGER_ALIGN, {1, Align(1), Align(1)}}, // i1 18306c3fb27SDimitry Andric {INTEGER_ALIGN, {8, Align(1), Align(1)}}, // i8 18406c3fb27SDimitry Andric {INTEGER_ALIGN, {16, Align(2), Align(2)}}, // i16 18506c3fb27SDimitry Andric {INTEGER_ALIGN, {32, Align(4), Align(4)}}, // i32 18606c3fb27SDimitry Andric {INTEGER_ALIGN, {64, Align(4), Align(8)}}, // i64 18706c3fb27SDimitry Andric {FLOAT_ALIGN, {16, Align(2), Align(2)}}, // half, bfloat 18806c3fb27SDimitry Andric {FLOAT_ALIGN, {32, Align(4), Align(4)}}, // float 18906c3fb27SDimitry Andric {FLOAT_ALIGN, {64, Align(8), Align(8)}}, // double 19006c3fb27SDimitry Andric {FLOAT_ALIGN, {128, Align(16), Align(16)}}, // ppcf128, quad, ... 19106c3fb27SDimitry Andric {VECTOR_ALIGN, {64, Align(8), Align(8)}}, // v2i32, v1i64, ... 19206c3fb27SDimitry Andric {VECTOR_ALIGN, {128, Align(16), Align(16)}}, // v16i8, v8i16, v4i32, ... 1930b57cec5SDimitry Andric }; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric void DataLayout::reset(StringRef Desc) { 1960b57cec5SDimitry Andric clear(); 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric LayoutMap = nullptr; 1990b57cec5SDimitry Andric BigEndian = false; 2000b57cec5SDimitry Andric AllocaAddrSpace = 0; 2018bcb0991SDimitry Andric StackNaturalAlign.reset(); 2020b57cec5SDimitry Andric ProgramAddrSpace = 0; 203e8d8bef9SDimitry Andric DefaultGlobalsAddrSpace = 0; 2048bcb0991SDimitry Andric FunctionPtrAlign.reset(); 2050b57cec5SDimitry Andric TheFunctionPtrAlignType = FunctionPtrAlignType::Independent; 2060b57cec5SDimitry Andric ManglingMode = MM_None; 2070b57cec5SDimitry Andric NonIntegralAddressSpaces.clear(); 20806c3fb27SDimitry Andric StructAlignment = LayoutAlignElem::get(Align(1), Align(8), 0); 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric // Default alignments 21106c3fb27SDimitry Andric for (const auto &[Kind, Layout] : DefaultAlignments) { 21206c3fb27SDimitry Andric if (Error Err = setAlignment(Kind, Layout.ABIAlign, Layout.PrefAlign, 21306c3fb27SDimitry Andric Layout.TypeBitWidth)) 214e8d8bef9SDimitry Andric return report_fatal_error(std::move(Err)); 2150b57cec5SDimitry Andric } 2160eae32dcSDimitry Andric if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64)) 217e8d8bef9SDimitry Andric return report_fatal_error(std::move(Err)); 2180b57cec5SDimitry Andric 219e8d8bef9SDimitry Andric if (Error Err = parseSpecifier(Desc)) 220e8d8bef9SDimitry Andric return report_fatal_error(std::move(Err)); 221e8d8bef9SDimitry Andric } 222e8d8bef9SDimitry Andric 223e8d8bef9SDimitry Andric Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) { 224e8d8bef9SDimitry Andric DataLayout Layout(""); 225e8d8bef9SDimitry Andric if (Error Err = Layout.parseSpecifier(LayoutDescription)) 226e8d8bef9SDimitry Andric return std::move(Err); 227e8d8bef9SDimitry Andric return Layout; 228e8d8bef9SDimitry Andric } 229e8d8bef9SDimitry Andric 230e8d8bef9SDimitry Andric static Error reportError(const Twine &Message) { 231e8d8bef9SDimitry Andric return createStringError(inconvertibleErrorCode(), Message); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric /// Checked version of split, to ensure mandatory subparts. 235e8d8bef9SDimitry Andric static Error split(StringRef Str, char Separator, 236e8d8bef9SDimitry Andric std::pair<StringRef, StringRef> &Split) { 2370b57cec5SDimitry Andric assert(!Str.empty() && "parse error, string can't be empty here"); 238e8d8bef9SDimitry Andric Split = Str.split(Separator); 2390b57cec5SDimitry Andric if (Split.second.empty() && Split.first != Str) 240e8d8bef9SDimitry Andric return reportError("Trailing separator in datalayout string"); 2410b57cec5SDimitry Andric if (!Split.second.empty() && Split.first.empty()) 242e8d8bef9SDimitry Andric return reportError("Expected token before separator in datalayout string"); 243e8d8bef9SDimitry Andric return Error::success(); 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric /// Get an unsigned integer, including error checks. 247e8d8bef9SDimitry Andric template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) { 2480b57cec5SDimitry Andric bool error = R.getAsInteger(10, Result); (void)error; 2490b57cec5SDimitry Andric if (error) 250e8d8bef9SDimitry Andric return reportError("not a number, or does not fit in an unsigned int"); 251e8d8bef9SDimitry Andric return Error::success(); 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric 254e8d8bef9SDimitry Andric /// Get an unsigned integer representing the number of bits and convert it into 255e8d8bef9SDimitry Andric /// bytes. Error out of not a byte width multiple. 256e8d8bef9SDimitry Andric template <typename IntTy> 257e8d8bef9SDimitry Andric static Error getIntInBytes(StringRef R, IntTy &Result) { 258e8d8bef9SDimitry Andric if (Error Err = getInt<IntTy>(R, Result)) 259e8d8bef9SDimitry Andric return Err; 260e8d8bef9SDimitry Andric if (Result % 8) 261e8d8bef9SDimitry Andric return reportError("number of bits must be a byte width multiple"); 262e8d8bef9SDimitry Andric Result /= 8; 263e8d8bef9SDimitry Andric return Error::success(); 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric 266e8d8bef9SDimitry Andric static Error getAddrSpace(StringRef R, unsigned &AddrSpace) { 267e8d8bef9SDimitry Andric if (Error Err = getInt(R, AddrSpace)) 268e8d8bef9SDimitry Andric return Err; 2690b57cec5SDimitry Andric if (!isUInt<24>(AddrSpace)) 270e8d8bef9SDimitry Andric return reportError("Invalid address space, must be a 24-bit integer"); 271e8d8bef9SDimitry Andric return Error::success(); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 274e8d8bef9SDimitry Andric Error DataLayout::parseSpecifier(StringRef Desc) { 2755ffd83dbSDimitry Andric StringRepresentation = std::string(Desc); 2760b57cec5SDimitry Andric while (!Desc.empty()) { 2770b57cec5SDimitry Andric // Split at '-'. 278e8d8bef9SDimitry Andric std::pair<StringRef, StringRef> Split; 279349cc55cSDimitry Andric if (Error Err = ::split(Desc, '-', Split)) 280e8d8bef9SDimitry Andric return Err; 2810b57cec5SDimitry Andric Desc = Split.second; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric // Split at ':'. 284349cc55cSDimitry Andric if (Error Err = ::split(Split.first, ':', Split)) 285e8d8bef9SDimitry Andric return Err; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // Aliases used below. 2880b57cec5SDimitry Andric StringRef &Tok = Split.first; // Current token. 2890b57cec5SDimitry Andric StringRef &Rest = Split.second; // The rest of the string. 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric if (Tok == "ni") { 2920b57cec5SDimitry Andric do { 293349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 294e8d8bef9SDimitry Andric return Err; 2950b57cec5SDimitry Andric Rest = Split.second; 296e8d8bef9SDimitry Andric unsigned AS; 297e8d8bef9SDimitry Andric if (Error Err = getInt(Split.first, AS)) 298e8d8bef9SDimitry Andric return Err; 2990b57cec5SDimitry Andric if (AS == 0) 300e8d8bef9SDimitry Andric return reportError("Address space 0 can never be non-integral"); 3010b57cec5SDimitry Andric NonIntegralAddressSpaces.push_back(AS); 3020b57cec5SDimitry Andric } while (!Rest.empty()); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric continue; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric char Specifier = Tok.front(); 3080b57cec5SDimitry Andric Tok = Tok.substr(1); 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric switch (Specifier) { 3110b57cec5SDimitry Andric case 's': 3125ffd83dbSDimitry Andric // Deprecated, but ignoring here to preserve loading older textual llvm 3135ffd83dbSDimitry Andric // ASM file 3140b57cec5SDimitry Andric break; 3150b57cec5SDimitry Andric case 'E': 3160b57cec5SDimitry Andric BigEndian = true; 3170b57cec5SDimitry Andric break; 3180b57cec5SDimitry Andric case 'e': 3190b57cec5SDimitry Andric BigEndian = false; 3200b57cec5SDimitry Andric break; 3210b57cec5SDimitry Andric case 'p': { 3220b57cec5SDimitry Andric // Address space. 323e8d8bef9SDimitry Andric unsigned AddrSpace = 0; 324e8d8bef9SDimitry Andric if (!Tok.empty()) 325e8d8bef9SDimitry Andric if (Error Err = getInt(Tok, AddrSpace)) 326e8d8bef9SDimitry Andric return Err; 3270b57cec5SDimitry Andric if (!isUInt<24>(AddrSpace)) 32806c3fb27SDimitry Andric return reportError("Invalid address space, must be a 24-bit integer"); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric // Size. 3310b57cec5SDimitry Andric if (Rest.empty()) 332e8d8bef9SDimitry Andric return reportError( 3330b57cec5SDimitry Andric "Missing size specification for pointer in datalayout string"); 334349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 335e8d8bef9SDimitry Andric return Err; 336e8d8bef9SDimitry Andric unsigned PointerMemSize; 3370eae32dcSDimitry Andric if (Error Err = getInt(Tok, PointerMemSize)) 338e8d8bef9SDimitry Andric return Err; 3390b57cec5SDimitry Andric if (!PointerMemSize) 340e8d8bef9SDimitry Andric return reportError("Invalid pointer size of 0 bytes"); 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // ABI alignment. 3430b57cec5SDimitry Andric if (Rest.empty()) 344e8d8bef9SDimitry Andric return reportError( 3450b57cec5SDimitry Andric "Missing alignment specification for pointer in datalayout string"); 346349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 347e8d8bef9SDimitry Andric return Err; 348e8d8bef9SDimitry Andric unsigned PointerABIAlign; 349e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, PointerABIAlign)) 350e8d8bef9SDimitry Andric return Err; 3510b57cec5SDimitry Andric if (!isPowerOf2_64(PointerABIAlign)) 352e8d8bef9SDimitry Andric return reportError("Pointer ABI alignment must be a power of 2"); 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric // Size of index used in GEP for address calculation. 3550b57cec5SDimitry Andric // The parameter is optional. By default it is equal to size of pointer. 3560b57cec5SDimitry Andric unsigned IndexSize = PointerMemSize; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric // Preferred alignment. 3590b57cec5SDimitry Andric unsigned PointerPrefAlign = PointerABIAlign; 3600b57cec5SDimitry Andric if (!Rest.empty()) { 361349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 362e8d8bef9SDimitry Andric return Err; 363e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, PointerPrefAlign)) 364e8d8bef9SDimitry Andric return Err; 3650b57cec5SDimitry Andric if (!isPowerOf2_64(PointerPrefAlign)) 366e8d8bef9SDimitry Andric return reportError( 3670b57cec5SDimitry Andric "Pointer preferred alignment must be a power of 2"); 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric // Now read the index. It is the second optional parameter here. 3700b57cec5SDimitry Andric if (!Rest.empty()) { 371349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 372e8d8bef9SDimitry Andric return Err; 3730eae32dcSDimitry Andric if (Error Err = getInt(Tok, IndexSize)) 374e8d8bef9SDimitry Andric return Err; 3750b57cec5SDimitry Andric if (!IndexSize) 376e8d8bef9SDimitry Andric return reportError("Invalid index size of 0 bytes"); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric } 3790eae32dcSDimitry Andric if (Error Err = setPointerAlignmentInBits( 380e8d8bef9SDimitry Andric AddrSpace, assumeAligned(PointerABIAlign), 381e8d8bef9SDimitry Andric assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize)) 382e8d8bef9SDimitry Andric return Err; 3830b57cec5SDimitry Andric break; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric case 'i': 3860b57cec5SDimitry Andric case 'v': 3870b57cec5SDimitry Andric case 'f': 3880b57cec5SDimitry Andric case 'a': { 3890b57cec5SDimitry Andric AlignTypeEnum AlignType; 3900b57cec5SDimitry Andric switch (Specifier) { 3910b57cec5SDimitry Andric default: llvm_unreachable("Unexpected specifier!"); 3920b57cec5SDimitry Andric case 'i': AlignType = INTEGER_ALIGN; break; 3930b57cec5SDimitry Andric case 'v': AlignType = VECTOR_ALIGN; break; 3940b57cec5SDimitry Andric case 'f': AlignType = FLOAT_ALIGN; break; 3950b57cec5SDimitry Andric case 'a': AlignType = AGGREGATE_ALIGN; break; 3960b57cec5SDimitry Andric } 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric // Bit size. 399e8d8bef9SDimitry Andric unsigned Size = 0; 400e8d8bef9SDimitry Andric if (!Tok.empty()) 401e8d8bef9SDimitry Andric if (Error Err = getInt(Tok, Size)) 402e8d8bef9SDimitry Andric return Err; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric if (AlignType == AGGREGATE_ALIGN && Size != 0) 405e8d8bef9SDimitry Andric return reportError( 4060b57cec5SDimitry Andric "Sized aggregate specification in datalayout string"); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // ABI alignment. 4090b57cec5SDimitry Andric if (Rest.empty()) 410e8d8bef9SDimitry Andric return reportError( 4110b57cec5SDimitry Andric "Missing alignment specification in datalayout string"); 412349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 413e8d8bef9SDimitry Andric return Err; 414e8d8bef9SDimitry Andric unsigned ABIAlign; 415e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, ABIAlign)) 416e8d8bef9SDimitry Andric return Err; 4170b57cec5SDimitry Andric if (AlignType != AGGREGATE_ALIGN && !ABIAlign) 418e8d8bef9SDimitry Andric return reportError( 4190b57cec5SDimitry Andric "ABI alignment specification must be >0 for non-aggregate types"); 4200b57cec5SDimitry Andric 4218bcb0991SDimitry Andric if (!isUInt<16>(ABIAlign)) 422e8d8bef9SDimitry Andric return reportError("Invalid ABI alignment, must be a 16bit integer"); 4238bcb0991SDimitry Andric if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign)) 424e8d8bef9SDimitry Andric return reportError("Invalid ABI alignment, must be a power of 2"); 425bdd1243dSDimitry Andric if (AlignType == INTEGER_ALIGN && Size == 8 && ABIAlign != 1) 426bdd1243dSDimitry Andric return reportError( 427bdd1243dSDimitry Andric "Invalid ABI alignment, i8 must be naturally aligned"); 4288bcb0991SDimitry Andric 4290b57cec5SDimitry Andric // Preferred alignment. 4300b57cec5SDimitry Andric unsigned PrefAlign = ABIAlign; 4310b57cec5SDimitry Andric if (!Rest.empty()) { 432349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 433e8d8bef9SDimitry Andric return Err; 434e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, PrefAlign)) 435e8d8bef9SDimitry Andric return Err; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4388bcb0991SDimitry Andric if (!isUInt<16>(PrefAlign)) 439e8d8bef9SDimitry Andric return reportError( 4408bcb0991SDimitry Andric "Invalid preferred alignment, must be a 16bit integer"); 4418bcb0991SDimitry Andric if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign)) 442e8d8bef9SDimitry Andric return reportError("Invalid preferred alignment, must be a power of 2"); 4438bcb0991SDimitry Andric 444e8d8bef9SDimitry Andric if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign), 445e8d8bef9SDimitry Andric assumeAligned(PrefAlign), Size)) 446e8d8bef9SDimitry Andric return Err; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric break; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric case 'n': // Native integer types. 4510b57cec5SDimitry Andric while (true) { 452e8d8bef9SDimitry Andric unsigned Width; 453e8d8bef9SDimitry Andric if (Error Err = getInt(Tok, Width)) 454e8d8bef9SDimitry Andric return Err; 4550b57cec5SDimitry Andric if (Width == 0) 456e8d8bef9SDimitry Andric return reportError( 4570b57cec5SDimitry Andric "Zero width native integer type in datalayout string"); 4580b57cec5SDimitry Andric LegalIntWidths.push_back(Width); 4590b57cec5SDimitry Andric if (Rest.empty()) 4600b57cec5SDimitry Andric break; 461349cc55cSDimitry Andric if (Error Err = ::split(Rest, ':', Split)) 462e8d8bef9SDimitry Andric return Err; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric break; 4650b57cec5SDimitry Andric case 'S': { // Stack natural alignment. 466e8d8bef9SDimitry Andric uint64_t Alignment; 467e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, Alignment)) 468e8d8bef9SDimitry Andric return Err; 4698bcb0991SDimitry Andric if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment)) 470e8d8bef9SDimitry Andric return reportError("Alignment is neither 0 nor a power of 2"); 4718bcb0991SDimitry Andric StackNaturalAlign = MaybeAlign(Alignment); 4720b57cec5SDimitry Andric break; 4730b57cec5SDimitry Andric } 4740b57cec5SDimitry Andric case 'F': { 4750b57cec5SDimitry Andric switch (Tok.front()) { 4760b57cec5SDimitry Andric case 'i': 4770b57cec5SDimitry Andric TheFunctionPtrAlignType = FunctionPtrAlignType::Independent; 4780b57cec5SDimitry Andric break; 4790b57cec5SDimitry Andric case 'n': 4800b57cec5SDimitry Andric TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign; 4810b57cec5SDimitry Andric break; 4820b57cec5SDimitry Andric default: 483e8d8bef9SDimitry Andric return reportError("Unknown function pointer alignment type in " 4840b57cec5SDimitry Andric "datalayout string"); 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric Tok = Tok.substr(1); 487e8d8bef9SDimitry Andric uint64_t Alignment; 488e8d8bef9SDimitry Andric if (Error Err = getIntInBytes(Tok, Alignment)) 489e8d8bef9SDimitry Andric return Err; 4908bcb0991SDimitry Andric if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment)) 491e8d8bef9SDimitry Andric return reportError("Alignment is neither 0 nor a power of 2"); 4928bcb0991SDimitry Andric FunctionPtrAlign = MaybeAlign(Alignment); 4930b57cec5SDimitry Andric break; 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric case 'P': { // Function address space. 496e8d8bef9SDimitry Andric if (Error Err = getAddrSpace(Tok, ProgramAddrSpace)) 497e8d8bef9SDimitry Andric return Err; 4980b57cec5SDimitry Andric break; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric case 'A': { // Default stack/alloca address space. 501e8d8bef9SDimitry Andric if (Error Err = getAddrSpace(Tok, AllocaAddrSpace)) 502e8d8bef9SDimitry Andric return Err; 503e8d8bef9SDimitry Andric break; 504e8d8bef9SDimitry Andric } 505e8d8bef9SDimitry Andric case 'G': { // Default address space for global variables. 506e8d8bef9SDimitry Andric if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace)) 507e8d8bef9SDimitry Andric return Err; 5080b57cec5SDimitry Andric break; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric case 'm': 5110b57cec5SDimitry Andric if (!Tok.empty()) 512e8d8bef9SDimitry Andric return reportError("Unexpected trailing characters after mangling " 513e8d8bef9SDimitry Andric "specifier in datalayout string"); 5140b57cec5SDimitry Andric if (Rest.empty()) 515e8d8bef9SDimitry Andric return reportError("Expected mangling specifier in datalayout string"); 5160b57cec5SDimitry Andric if (Rest.size() > 1) 517e8d8bef9SDimitry Andric return reportError("Unknown mangling specifier in datalayout string"); 5180b57cec5SDimitry Andric switch(Rest[0]) { 5190b57cec5SDimitry Andric default: 520e8d8bef9SDimitry Andric return reportError("Unknown mangling in datalayout string"); 5210b57cec5SDimitry Andric case 'e': 5220b57cec5SDimitry Andric ManglingMode = MM_ELF; 5230b57cec5SDimitry Andric break; 524349cc55cSDimitry Andric case 'l': 525349cc55cSDimitry Andric ManglingMode = MM_GOFF; 526349cc55cSDimitry Andric break; 5270b57cec5SDimitry Andric case 'o': 5280b57cec5SDimitry Andric ManglingMode = MM_MachO; 5290b57cec5SDimitry Andric break; 5300b57cec5SDimitry Andric case 'm': 5310b57cec5SDimitry Andric ManglingMode = MM_Mips; 5320b57cec5SDimitry Andric break; 5330b57cec5SDimitry Andric case 'w': 5340b57cec5SDimitry Andric ManglingMode = MM_WinCOFF; 5350b57cec5SDimitry Andric break; 5360b57cec5SDimitry Andric case 'x': 5370b57cec5SDimitry Andric ManglingMode = MM_WinCOFFX86; 5380b57cec5SDimitry Andric break; 5395ffd83dbSDimitry Andric case 'a': 5405ffd83dbSDimitry Andric ManglingMode = MM_XCOFF; 5415ffd83dbSDimitry Andric break; 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric break; 5440b57cec5SDimitry Andric default: 545e8d8bef9SDimitry Andric return reportError("Unknown specifier in datalayout string"); 5460b57cec5SDimitry Andric break; 5470b57cec5SDimitry Andric } 5480b57cec5SDimitry Andric } 549e8d8bef9SDimitry Andric 550e8d8bef9SDimitry Andric return Error::success(); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric DataLayout::DataLayout(const Module *M) { 5540b57cec5SDimitry Andric init(M); 5550b57cec5SDimitry Andric } 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric void DataLayout::init(const Module *M) { *this = M->getDataLayout(); } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric bool DataLayout::operator==(const DataLayout &Other) const { 5600b57cec5SDimitry Andric bool Ret = BigEndian == Other.BigEndian && 5610b57cec5SDimitry Andric AllocaAddrSpace == Other.AllocaAddrSpace && 5620b57cec5SDimitry Andric StackNaturalAlign == Other.StackNaturalAlign && 5630b57cec5SDimitry Andric ProgramAddrSpace == Other.ProgramAddrSpace && 564e8d8bef9SDimitry Andric DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace && 5650b57cec5SDimitry Andric FunctionPtrAlign == Other.FunctionPtrAlign && 5660b57cec5SDimitry Andric TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType && 5670b57cec5SDimitry Andric ManglingMode == Other.ManglingMode && 5680b57cec5SDimitry Andric LegalIntWidths == Other.LegalIntWidths && 56906c3fb27SDimitry Andric IntAlignments == Other.IntAlignments && 57006c3fb27SDimitry Andric FloatAlignments == Other.FloatAlignments && 57106c3fb27SDimitry Andric VectorAlignments == Other.VectorAlignments && 57206c3fb27SDimitry Andric StructAlignment == Other.StructAlignment && 57306c3fb27SDimitry Andric Pointers == Other.Pointers; 5740b57cec5SDimitry Andric // Note: getStringRepresentation() might differs, it is not canonicalized 5750b57cec5SDimitry Andric return Ret; 5760b57cec5SDimitry Andric } 5770b57cec5SDimitry Andric 57806c3fb27SDimitry Andric static SmallVectorImpl<LayoutAlignElem>::const_iterator 57906c3fb27SDimitry Andric findAlignmentLowerBound(const SmallVectorImpl<LayoutAlignElem> &Alignments, 5800b57cec5SDimitry Andric uint32_t BitWidth) { 58106c3fb27SDimitry Andric return partition_point(Alignments, [BitWidth](const LayoutAlignElem &E) { 58206c3fb27SDimitry Andric return E.TypeBitWidth < BitWidth; 5830b57cec5SDimitry Andric }); 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric 58606c3fb27SDimitry Andric Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign, 58706c3fb27SDimitry Andric Align PrefAlign, uint32_t BitWidth) { 5888bcb0991SDimitry Andric // AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as 5898bcb0991SDimitry Andric // uint16_t, it is unclear if there are requirements for alignment to be less 5908bcb0991SDimitry Andric // than 2^16 other than storage. In the meantime we leave the restriction as 5918bcb0991SDimitry Andric // an assert. See D67400 for context. 59206c3fb27SDimitry Andric assert(Log2(ABIAlign) < 16 && Log2(PrefAlign) < 16 && "Alignment too big"); 59306c3fb27SDimitry Andric if (!isUInt<24>(BitWidth)) 59406c3fb27SDimitry Andric return reportError("Invalid bit width, must be a 24-bit integer"); 59506c3fb27SDimitry Andric if (PrefAlign < ABIAlign) 596e8d8bef9SDimitry Andric return reportError( 5970b57cec5SDimitry Andric "Preferred alignment cannot be less than the ABI alignment"); 5980b57cec5SDimitry Andric 59906c3fb27SDimitry Andric SmallVectorImpl<LayoutAlignElem> *Alignments; 60006c3fb27SDimitry Andric switch (AlignType) { 60106c3fb27SDimitry Andric case AGGREGATE_ALIGN: 60206c3fb27SDimitry Andric StructAlignment.ABIAlign = ABIAlign; 60306c3fb27SDimitry Andric StructAlignment.PrefAlign = PrefAlign; 60406c3fb27SDimitry Andric return Error::success(); 60506c3fb27SDimitry Andric case INTEGER_ALIGN: 60606c3fb27SDimitry Andric Alignments = &IntAlignments; 60706c3fb27SDimitry Andric break; 60806c3fb27SDimitry Andric case FLOAT_ALIGN: 60906c3fb27SDimitry Andric Alignments = &FloatAlignments; 61006c3fb27SDimitry Andric break; 61106c3fb27SDimitry Andric case VECTOR_ALIGN: 61206c3fb27SDimitry Andric Alignments = &VectorAlignments; 61306c3fb27SDimitry Andric break; 61406c3fb27SDimitry Andric } 61506c3fb27SDimitry Andric 61606c3fb27SDimitry Andric auto I = partition_point(*Alignments, [BitWidth](const LayoutAlignElem &E) { 61706c3fb27SDimitry Andric return E.TypeBitWidth < BitWidth; 61806c3fb27SDimitry Andric }); 61906c3fb27SDimitry Andric if (I != Alignments->end() && I->TypeBitWidth == BitWidth) { 6200b57cec5SDimitry Andric // Update the abi, preferred alignments. 62106c3fb27SDimitry Andric I->ABIAlign = ABIAlign; 62206c3fb27SDimitry Andric I->PrefAlign = PrefAlign; 6230b57cec5SDimitry Andric } else { 6240b57cec5SDimitry Andric // Insert before I to keep the vector sorted. 62506c3fb27SDimitry Andric Alignments->insert(I, LayoutAlignElem::get(ABIAlign, PrefAlign, BitWidth)); 6260b57cec5SDimitry Andric } 627e8d8bef9SDimitry Andric return Error::success(); 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 630e8d8bef9SDimitry Andric const PointerAlignElem & 631e8d8bef9SDimitry Andric DataLayout::getPointerAlignElem(uint32_t AddressSpace) const { 632e8d8bef9SDimitry Andric if (AddressSpace != 0) { 633e8d8bef9SDimitry Andric auto I = lower_bound(Pointers, AddressSpace, 6340b57cec5SDimitry Andric [](const PointerAlignElem &A, uint32_t AddressSpace) { 6350b57cec5SDimitry Andric return A.AddressSpace < AddressSpace; 6360b57cec5SDimitry Andric }); 637e8d8bef9SDimitry Andric if (I != Pointers.end() && I->AddressSpace == AddressSpace) 638e8d8bef9SDimitry Andric return *I; 6390b57cec5SDimitry Andric } 6400b57cec5SDimitry Andric 641e8d8bef9SDimitry Andric assert(Pointers[0].AddressSpace == 0); 642e8d8bef9SDimitry Andric return Pointers[0]; 643e8d8bef9SDimitry Andric } 644e8d8bef9SDimitry Andric 6450eae32dcSDimitry Andric Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign, 6460eae32dcSDimitry Andric Align PrefAlign, 6470eae32dcSDimitry Andric uint32_t TypeBitWidth, 6480eae32dcSDimitry Andric uint32_t IndexBitWidth) { 6490b57cec5SDimitry Andric if (PrefAlign < ABIAlign) 650e8d8bef9SDimitry Andric return reportError( 6510b57cec5SDimitry Andric "Preferred alignment cannot be less than the ABI alignment"); 6525f757f3fSDimitry Andric if (IndexBitWidth > TypeBitWidth) 6535f757f3fSDimitry Andric return reportError("Index width cannot be larger than pointer width"); 6540b57cec5SDimitry Andric 655e8d8bef9SDimitry Andric auto I = lower_bound(Pointers, AddrSpace, 656e8d8bef9SDimitry Andric [](const PointerAlignElem &A, uint32_t AddressSpace) { 657e8d8bef9SDimitry Andric return A.AddressSpace < AddressSpace; 658e8d8bef9SDimitry Andric }); 6590b57cec5SDimitry Andric if (I == Pointers.end() || I->AddressSpace != AddrSpace) { 6600eae32dcSDimitry Andric Pointers.insert(I, 6610eae32dcSDimitry Andric PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign, 6620eae32dcSDimitry Andric TypeBitWidth, IndexBitWidth)); 6630b57cec5SDimitry Andric } else { 6640b57cec5SDimitry Andric I->ABIAlign = ABIAlign; 6650b57cec5SDimitry Andric I->PrefAlign = PrefAlign; 6660eae32dcSDimitry Andric I->TypeBitWidth = TypeBitWidth; 6670eae32dcSDimitry Andric I->IndexBitWidth = IndexBitWidth; 6680b57cec5SDimitry Andric } 669e8d8bef9SDimitry Andric return Error::success(); 6700b57cec5SDimitry Andric } 6710b57cec5SDimitry Andric 672e8d8bef9SDimitry Andric Align DataLayout::getIntegerAlignment(uint32_t BitWidth, 673e8d8bef9SDimitry Andric bool abi_or_pref) const { 67406c3fb27SDimitry Andric auto I = findAlignmentLowerBound(IntAlignments, BitWidth); 675e8d8bef9SDimitry Andric // If we don't have an exact match, use alignment of next larger integer 676e8d8bef9SDimitry Andric // type. If there is none, use alignment of largest integer type by going 677e8d8bef9SDimitry Andric // back one element. 67806c3fb27SDimitry Andric if (I == IntAlignments.end()) 679e8d8bef9SDimitry Andric --I; 680e8d8bef9SDimitry Andric return abi_or_pref ? I->ABIAlign : I->PrefAlign; 6810b57cec5SDimitry Andric } 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric namespace { 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric class StructLayoutMap { 6860b57cec5SDimitry Andric using LayoutInfoTy = DenseMap<StructType*, StructLayout*>; 6870b57cec5SDimitry Andric LayoutInfoTy LayoutInfo; 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric public: 6900b57cec5SDimitry Andric ~StructLayoutMap() { 6910b57cec5SDimitry Andric // Remove any layouts. 6920b57cec5SDimitry Andric for (const auto &I : LayoutInfo) { 6930b57cec5SDimitry Andric StructLayout *Value = I.second; 6940b57cec5SDimitry Andric Value->~StructLayout(); 6950b57cec5SDimitry Andric free(Value); 6960b57cec5SDimitry Andric } 6970b57cec5SDimitry Andric } 6980b57cec5SDimitry Andric 6990b57cec5SDimitry Andric StructLayout *&operator[](StructType *STy) { 7000b57cec5SDimitry Andric return LayoutInfo[STy]; 7010b57cec5SDimitry Andric } 7020b57cec5SDimitry Andric }; 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric } // end anonymous namespace 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric void DataLayout::clear() { 7070b57cec5SDimitry Andric LegalIntWidths.clear(); 70806c3fb27SDimitry Andric IntAlignments.clear(); 70906c3fb27SDimitry Andric FloatAlignments.clear(); 71006c3fb27SDimitry Andric VectorAlignments.clear(); 7110b57cec5SDimitry Andric Pointers.clear(); 7120b57cec5SDimitry Andric delete static_cast<StructLayoutMap *>(LayoutMap); 7130b57cec5SDimitry Andric LayoutMap = nullptr; 7140b57cec5SDimitry Andric } 7150b57cec5SDimitry Andric 7160b57cec5SDimitry Andric DataLayout::~DataLayout() { 7170b57cec5SDimitry Andric clear(); 7180b57cec5SDimitry Andric } 7190b57cec5SDimitry Andric 7200b57cec5SDimitry Andric const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { 7210b57cec5SDimitry Andric if (!LayoutMap) 7220b57cec5SDimitry Andric LayoutMap = new StructLayoutMap(); 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap); 7250b57cec5SDimitry Andric StructLayout *&SL = (*STM)[Ty]; 7260b57cec5SDimitry Andric if (SL) return SL; 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric // Otherwise, create the struct layout. Because it is variable length, we 7290b57cec5SDimitry Andric // malloc it, then use placement new. 730fe6060f1SDimitry Andric StructLayout *L = (StructLayout *)safe_malloc( 73106c3fb27SDimitry Andric StructLayout::totalSizeToAlloc<TypeSize>(Ty->getNumElements())); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric // Set SL before calling StructLayout's ctor. The ctor could cause other 7340b57cec5SDimitry Andric // entries to be added to TheMap, invalidating our reference. 7350b57cec5SDimitry Andric SL = L; 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric new (L) StructLayout(Ty, *this); 7380b57cec5SDimitry Andric 7390b57cec5SDimitry Andric return L; 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric 7428bcb0991SDimitry Andric Align DataLayout::getPointerABIAlignment(unsigned AS) const { 743e8d8bef9SDimitry Andric return getPointerAlignElem(AS).ABIAlign; 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric 7468bcb0991SDimitry Andric Align DataLayout::getPointerPrefAlignment(unsigned AS) const { 747e8d8bef9SDimitry Andric return getPointerAlignElem(AS).PrefAlign; 7480b57cec5SDimitry Andric } 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric unsigned DataLayout::getPointerSize(unsigned AS) const { 7510eae32dcSDimitry Andric return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8); 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 754349cc55cSDimitry Andric unsigned DataLayout::getMaxIndexSize() const { 755349cc55cSDimitry Andric unsigned MaxIndexSize = 0; 7560b57cec5SDimitry Andric for (auto &P : Pointers) 7570eae32dcSDimitry Andric MaxIndexSize = 7580eae32dcSDimitry Andric std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8)); 7590b57cec5SDimitry Andric 760349cc55cSDimitry Andric return MaxIndexSize; 7610b57cec5SDimitry Andric } 7620b57cec5SDimitry Andric 7630b57cec5SDimitry Andric unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const { 7640b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && 7650b57cec5SDimitry Andric "This should only be called with a pointer or pointer vector type"); 7660b57cec5SDimitry Andric Ty = Ty->getScalarType(); 7670b57cec5SDimitry Andric return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); 7680b57cec5SDimitry Andric } 7690b57cec5SDimitry Andric 7700b57cec5SDimitry Andric unsigned DataLayout::getIndexSize(unsigned AS) const { 7710eae32dcSDimitry Andric return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 7740b57cec5SDimitry Andric unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const { 7750b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && 7760b57cec5SDimitry Andric "This should only be called with a pointer or pointer vector type"); 7770b57cec5SDimitry Andric Ty = Ty->getScalarType(); 7780b57cec5SDimitry Andric return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace()); 7790b57cec5SDimitry Andric } 7800b57cec5SDimitry Andric 7810b57cec5SDimitry Andric /*! 7820b57cec5SDimitry Andric \param abi_or_pref Flag that determines which alignment is returned. true 7830b57cec5SDimitry Andric returns the ABI alignment, false returns the preferred alignment. 7840b57cec5SDimitry Andric \param Ty The underlying type for which alignment is determined. 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref 7870b57cec5SDimitry Andric == false) for the requested type \a Ty. 7880b57cec5SDimitry Andric */ 7898bcb0991SDimitry Andric Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const { 7900b57cec5SDimitry Andric assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); 7910b57cec5SDimitry Andric switch (Ty->getTypeID()) { 7920b57cec5SDimitry Andric // Early escape for the non-numeric types. 7930b57cec5SDimitry Andric case Type::LabelTyID: 7948bcb0991SDimitry Andric return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0); 7950b57cec5SDimitry Andric case Type::PointerTyID: { 7960b57cec5SDimitry Andric unsigned AS = cast<PointerType>(Ty)->getAddressSpace(); 7978bcb0991SDimitry Andric return abi_or_pref ? getPointerABIAlignment(AS) 7988bcb0991SDimitry Andric : getPointerPrefAlignment(AS); 7990b57cec5SDimitry Andric } 8000b57cec5SDimitry Andric case Type::ArrayTyID: 8010b57cec5SDimitry Andric return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref); 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric case Type::StructTyID: { 8040b57cec5SDimitry Andric // Packed structure types always have an ABI alignment of one. 8050b57cec5SDimitry Andric if (cast<StructType>(Ty)->isPacked() && abi_or_pref) 8065ffd83dbSDimitry Andric return Align(1); 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric // Get the layout annotation... which is lazily created on demand. 8090b57cec5SDimitry Andric const StructLayout *Layout = getStructLayout(cast<StructType>(Ty)); 810e8d8bef9SDimitry Andric const Align Align = 81106c3fb27SDimitry Andric abi_or_pref ? StructAlignment.ABIAlign : StructAlignment.PrefAlign; 8120b57cec5SDimitry Andric return std::max(Align, Layout->getAlignment()); 8130b57cec5SDimitry Andric } 8140b57cec5SDimitry Andric case Type::IntegerTyID: 815e8d8bef9SDimitry Andric return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref); 8160b57cec5SDimitry Andric case Type::HalfTyID: 8175ffd83dbSDimitry Andric case Type::BFloatTyID: 8180b57cec5SDimitry Andric case Type::FloatTyID: 8190b57cec5SDimitry Andric case Type::DoubleTyID: 8200b57cec5SDimitry Andric // PPC_FP128TyID and FP128TyID have different data contents, but the 8210b57cec5SDimitry Andric // same size and alignment, so they look the same here. 8220b57cec5SDimitry Andric case Type::PPC_FP128TyID: 8230b57cec5SDimitry Andric case Type::FP128TyID: 824e8d8bef9SDimitry Andric case Type::X86_FP80TyID: { 825bdd1243dSDimitry Andric unsigned BitWidth = getTypeSizeInBits(Ty).getFixedValue(); 82606c3fb27SDimitry Andric auto I = findAlignmentLowerBound(FloatAlignments, BitWidth); 82706c3fb27SDimitry Andric if (I != FloatAlignments.end() && I->TypeBitWidth == BitWidth) 828e8d8bef9SDimitry Andric return abi_or_pref ? I->ABIAlign : I->PrefAlign; 829e8d8bef9SDimitry Andric 830e8d8bef9SDimitry Andric // If we still couldn't find a reasonable default alignment, fall back 831e8d8bef9SDimitry Andric // to a simple heuristic that the alignment is the first power of two 832e8d8bef9SDimitry Andric // greater-or-equal to the store size of the type. This is a reasonable 833e8d8bef9SDimitry Andric // approximation of reality, and if the user wanted something less 834e8d8bef9SDimitry Andric // less conservative, they should have specified it explicitly in the data 835e8d8bef9SDimitry Andric // layout. 836e8d8bef9SDimitry Andric return Align(PowerOf2Ceil(BitWidth / 8)); 837e8d8bef9SDimitry Andric } 8380b57cec5SDimitry Andric case Type::X86_MMXTyID: 8395ffd83dbSDimitry Andric case Type::FixedVectorTyID: 840e8d8bef9SDimitry Andric case Type::ScalableVectorTyID: { 841bdd1243dSDimitry Andric unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinValue(); 84206c3fb27SDimitry Andric auto I = findAlignmentLowerBound(VectorAlignments, BitWidth); 84306c3fb27SDimitry Andric if (I != VectorAlignments.end() && I->TypeBitWidth == BitWidth) 844e8d8bef9SDimitry Andric return abi_or_pref ? I->ABIAlign : I->PrefAlign; 845e8d8bef9SDimitry Andric 846e8d8bef9SDimitry Andric // By default, use natural alignment for vector types. This is consistent 847e8d8bef9SDimitry Andric // with what clang and llvm-gcc do. 848349cc55cSDimitry Andric // 849e8d8bef9SDimitry Andric // We're only calculating a natural alignment, so it doesn't have to be 850e8d8bef9SDimitry Andric // based on the full size for scalable vectors. Using the minimum element 851e8d8bef9SDimitry Andric // count should be enough here. 852bdd1243dSDimitry Andric return Align(PowerOf2Ceil(getTypeStoreSize(Ty).getKnownMinValue())); 853e8d8bef9SDimitry Andric } 854e8d8bef9SDimitry Andric case Type::X86_AMXTyID: 855e8d8bef9SDimitry Andric return Align(64); 856bdd1243dSDimitry Andric case Type::TargetExtTyID: { 857bdd1243dSDimitry Andric Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType(); 858bdd1243dSDimitry Andric return getAlignment(LayoutTy, abi_or_pref); 859bdd1243dSDimitry Andric } 8600b57cec5SDimitry Andric default: 8610b57cec5SDimitry Andric llvm_unreachable("Bad type for getAlignment!!!"); 8620b57cec5SDimitry Andric } 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric 8655ffd83dbSDimitry Andric Align DataLayout::getABITypeAlign(Type *Ty) const { 8665ffd83dbSDimitry Andric return getAlignment(Ty, true); 8670b57cec5SDimitry Andric } 8680b57cec5SDimitry Andric 8695ffd83dbSDimitry Andric /// TODO: Remove this function once the transition to Align is over. 870349cc55cSDimitry Andric uint64_t DataLayout::getPrefTypeAlignment(Type *Ty) const { 8715ffd83dbSDimitry Andric return getPrefTypeAlign(Ty).value(); 8725ffd83dbSDimitry Andric } 8735ffd83dbSDimitry Andric 8745ffd83dbSDimitry Andric Align DataLayout::getPrefTypeAlign(Type *Ty) const { 8755ffd83dbSDimitry Andric return getAlignment(Ty, false); 8760b57cec5SDimitry Andric } 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric IntegerType *DataLayout::getIntPtrType(LLVMContext &C, 8790b57cec5SDimitry Andric unsigned AddressSpace) const { 880480093f4SDimitry Andric return IntegerType::get(C, getPointerSizeInBits(AddressSpace)); 8810b57cec5SDimitry Andric } 8820b57cec5SDimitry Andric 8830b57cec5SDimitry Andric Type *DataLayout::getIntPtrType(Type *Ty) const { 8840b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && 8850b57cec5SDimitry Andric "Expected a pointer or pointer vector type."); 886480093f4SDimitry Andric unsigned NumBits = getPointerTypeSizeInBits(Ty); 8870b57cec5SDimitry Andric IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); 8880b57cec5SDimitry Andric if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) 8895ffd83dbSDimitry Andric return VectorType::get(IntTy, VecTy); 8900b57cec5SDimitry Andric return IntTy; 8910b57cec5SDimitry Andric } 8920b57cec5SDimitry Andric 8930b57cec5SDimitry Andric Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const { 8940b57cec5SDimitry Andric for (unsigned LegalIntWidth : LegalIntWidths) 8950b57cec5SDimitry Andric if (Width <= LegalIntWidth) 8960b57cec5SDimitry Andric return Type::getIntNTy(C, LegalIntWidth); 8970b57cec5SDimitry Andric return nullptr; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const { 901*0fca6ea1SDimitry Andric auto Max = llvm::max_element(LegalIntWidths); 9020b57cec5SDimitry Andric return Max != LegalIntWidths.end() ? *Max : 0; 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric 90506c3fb27SDimitry Andric IntegerType *DataLayout::getIndexType(LLVMContext &C, 90606c3fb27SDimitry Andric unsigned AddressSpace) const { 90706c3fb27SDimitry Andric return IntegerType::get(C, getIndexSizeInBits(AddressSpace)); 90806c3fb27SDimitry Andric } 90906c3fb27SDimitry Andric 9100b57cec5SDimitry Andric Type *DataLayout::getIndexType(Type *Ty) const { 9110b57cec5SDimitry Andric assert(Ty->isPtrOrPtrVectorTy() && 9120b57cec5SDimitry Andric "Expected a pointer or pointer vector type."); 9130b57cec5SDimitry Andric unsigned NumBits = getIndexTypeSizeInBits(Ty); 9140b57cec5SDimitry Andric IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits); 9150b57cec5SDimitry Andric if (VectorType *VecTy = dyn_cast<VectorType>(Ty)) 9165ffd83dbSDimitry Andric return VectorType::get(IntTy, VecTy); 9170b57cec5SDimitry Andric return IntTy; 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy, 9210b57cec5SDimitry Andric ArrayRef<Value *> Indices) const { 9220b57cec5SDimitry Andric int64_t Result = 0; 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric generic_gep_type_iterator<Value* const*> 9250b57cec5SDimitry Andric GTI = gep_type_begin(ElemTy, Indices), 9260b57cec5SDimitry Andric GTE = gep_type_end(ElemTy, Indices); 9270b57cec5SDimitry Andric for (; GTI != GTE; ++GTI) { 9280b57cec5SDimitry Andric Value *Idx = GTI.getOperand(); 9290b57cec5SDimitry Andric if (StructType *STy = GTI.getStructTypeOrNull()) { 9300b57cec5SDimitry Andric assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx"); 9310b57cec5SDimitry Andric unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue(); 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric // Get structure layout information... 9340b57cec5SDimitry Andric const StructLayout *Layout = getStructLayout(STy); 9350b57cec5SDimitry Andric 9360b57cec5SDimitry Andric // Add in the offset, as calculated by the structure layout info... 9370b57cec5SDimitry Andric Result += Layout->getElementOffset(FieldNo); 9380b57cec5SDimitry Andric } else { 9391db9f3b2SDimitry Andric if (int64_t ArrayIdx = cast<ConstantInt>(Idx)->getSExtValue()) 9401db9f3b2SDimitry Andric Result += ArrayIdx * GTI.getSequentialElementStride(*this); 9410b57cec5SDimitry Andric } 9420b57cec5SDimitry Andric } 9430b57cec5SDimitry Andric 9440b57cec5SDimitry Andric return Result; 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric 9470eae32dcSDimitry Andric static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) { 948349cc55cSDimitry Andric // Skip over scalable or zero size elements. Also skip element sizes larger 949349cc55cSDimitry Andric // than the positive index space, because the arithmetic below may not be 950349cc55cSDimitry Andric // correct in that case. 951349cc55cSDimitry Andric unsigned BitWidth = Offset.getBitWidth(); 952349cc55cSDimitry Andric if (ElemSize.isScalable() || ElemSize == 0 || 953349cc55cSDimitry Andric !isUIntN(BitWidth - 1, ElemSize)) { 9540eae32dcSDimitry Andric return APInt::getZero(BitWidth); 955349cc55cSDimitry Andric } 956349cc55cSDimitry Andric 957349cc55cSDimitry Andric APInt Index = Offset.sdiv(ElemSize); 958349cc55cSDimitry Andric Offset -= Index * ElemSize; 959349cc55cSDimitry Andric if (Offset.isNegative()) { 960349cc55cSDimitry Andric // Prefer a positive remaining offset to allow struct indexing. 961349cc55cSDimitry Andric --Index; 962349cc55cSDimitry Andric Offset += ElemSize; 963349cc55cSDimitry Andric assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative"); 964349cc55cSDimitry Andric } 9650eae32dcSDimitry Andric return Index; 966349cc55cSDimitry Andric } 967349cc55cSDimitry Andric 968bdd1243dSDimitry Andric std::optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy, 969349cc55cSDimitry Andric APInt &Offset) const { 970349cc55cSDimitry Andric if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) { 971349cc55cSDimitry Andric ElemTy = ArrTy->getElementType(); 9720eae32dcSDimitry Andric return getElementIndex(getTypeAllocSize(ElemTy), Offset); 973349cc55cSDimitry Andric } 974349cc55cSDimitry Andric 975bdd1243dSDimitry Andric if (isa<VectorType>(ElemTy)) { 976bdd1243dSDimitry Andric // Vector GEPs are partially broken (e.g. for overaligned element types), 977bdd1243dSDimitry Andric // and may be forbidden in the future, so avoid generating GEPs into 978bdd1243dSDimitry Andric // vectors. See https://discourse.llvm.org/t/67497 979bdd1243dSDimitry Andric return std::nullopt; 980349cc55cSDimitry Andric } 981349cc55cSDimitry Andric 982349cc55cSDimitry Andric if (auto *STy = dyn_cast<StructType>(ElemTy)) { 983349cc55cSDimitry Andric const StructLayout *SL = getStructLayout(STy); 984349cc55cSDimitry Andric uint64_t IntOffset = Offset.getZExtValue(); 985349cc55cSDimitry Andric if (IntOffset >= SL->getSizeInBytes()) 986bdd1243dSDimitry Andric return std::nullopt; 987349cc55cSDimitry Andric 988349cc55cSDimitry Andric unsigned Index = SL->getElementContainingOffset(IntOffset); 989349cc55cSDimitry Andric Offset -= SL->getElementOffset(Index); 990349cc55cSDimitry Andric ElemTy = STy->getElementType(Index); 9910eae32dcSDimitry Andric return APInt(32, Index); 992349cc55cSDimitry Andric } 993349cc55cSDimitry Andric 9940eae32dcSDimitry Andric // Non-aggregate type. 995bdd1243dSDimitry Andric return std::nullopt; 9960eae32dcSDimitry Andric } 9970eae32dcSDimitry Andric 9980eae32dcSDimitry Andric SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy, 9990eae32dcSDimitry Andric APInt &Offset) const { 10000eae32dcSDimitry Andric assert(ElemTy->isSized() && "Element type must be sized"); 10010eae32dcSDimitry Andric SmallVector<APInt> Indices; 10020eae32dcSDimitry Andric Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset)); 10030eae32dcSDimitry Andric while (Offset != 0) { 1004bdd1243dSDimitry Andric std::optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset); 10050eae32dcSDimitry Andric if (!Index) 1006349cc55cSDimitry Andric break; 10070eae32dcSDimitry Andric Indices.push_back(*Index); 1008349cc55cSDimitry Andric } 1009349cc55cSDimitry Andric 1010349cc55cSDimitry Andric return Indices; 1011349cc55cSDimitry Andric } 1012349cc55cSDimitry Andric 10135ffd83dbSDimitry Andric /// getPreferredAlign - Return the preferred alignment of the specified global. 10145ffd83dbSDimitry Andric /// This includes an explicitly requested alignment (if the global has one). 10155ffd83dbSDimitry Andric Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const { 10165ffd83dbSDimitry Andric MaybeAlign GVAlignment = GV->getAlign(); 10170b57cec5SDimitry Andric // If a section is specified, always precisely honor explicit alignment, 10180b57cec5SDimitry Andric // so we don't insert padding into a section we don't control. 10190b57cec5SDimitry Andric if (GVAlignment && GV->hasSection()) 10205ffd83dbSDimitry Andric return *GVAlignment; 10210b57cec5SDimitry Andric 10220b57cec5SDimitry Andric // If no explicit alignment is specified, compute the alignment based on 10230b57cec5SDimitry Andric // the IR type. If an alignment is specified, increase it to match the ABI 10240b57cec5SDimitry Andric // alignment of the IR type. 10250b57cec5SDimitry Andric // 10260b57cec5SDimitry Andric // FIXME: Not sure it makes sense to use the alignment of the type if 10270b57cec5SDimitry Andric // there's already an explicit alignment specification. 10280b57cec5SDimitry Andric Type *ElemType = GV->getValueType(); 10295ffd83dbSDimitry Andric Align Alignment = getPrefTypeAlign(ElemType); 10305ffd83dbSDimitry Andric if (GVAlignment) { 10315ffd83dbSDimitry Andric if (*GVAlignment >= Alignment) 10325ffd83dbSDimitry Andric Alignment = *GVAlignment; 10335ffd83dbSDimitry Andric else 10345ffd83dbSDimitry Andric Alignment = std::max(*GVAlignment, getABITypeAlign(ElemType)); 10350b57cec5SDimitry Andric } 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // If no explicit alignment is specified, and the global is large, increase 10380b57cec5SDimitry Andric // the alignment to 16. 10390b57cec5SDimitry Andric // FIXME: Why 16, specifically? 10405ffd83dbSDimitry Andric if (GV->hasInitializer() && !GVAlignment) { 10415ffd83dbSDimitry Andric if (Alignment < Align(16)) { 10420b57cec5SDimitry Andric // If the global is not external, see if it is large. If so, give it a 10430b57cec5SDimitry Andric // larger alignment. 10440b57cec5SDimitry Andric if (getTypeSizeInBits(ElemType) > 128) 10455ffd83dbSDimitry Andric Alignment = Align(16); // 16-byte alignment. 10460b57cec5SDimitry Andric } 10470b57cec5SDimitry Andric } 10480b57cec5SDimitry Andric return Alignment; 10490b57cec5SDimitry Andric } 1050