xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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