xref: /src/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1c46e6a59SDimitry Andric //===- DataLayout.cpp - Data size & alignment routines ---------------------==//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9522600a2SDimitry Andric // This file defines layout properties related to datatype size/offset/alignment
10009b1c42SEd Schouten // information.
11009b1c42SEd Schouten //
12009b1c42SEd Schouten // This structure should be created once, filled in if the defaults are not
13009b1c42SEd Schouten // correct and then passed around by const&.  None of the members functions
14009b1c42SEd Schouten // require modification to the object.
15009b1c42SEd Schouten //
16009b1c42SEd Schouten //===----------------------------------------------------------------------===//
17009b1c42SEd Schouten 
187ab83427SDimitry Andric #include "llvm/IR/DataLayout.h"
19009b1c42SEd Schouten #include "llvm/ADT/DenseMap.h"
20c46e6a59SDimitry Andric #include "llvm/ADT/StringRef.h"
214a16efa3SDimitry Andric #include "llvm/IR/Constants.h"
224a16efa3SDimitry Andric #include "llvm/IR/DerivedTypes.h"
235ca98fd9SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
24c46e6a59SDimitry Andric #include "llvm/IR/GlobalVariable.h"
254a16efa3SDimitry Andric #include "llvm/IR/Module.h"
26c46e6a59SDimitry Andric #include "llvm/IR/Type.h"
27c46e6a59SDimitry Andric #include "llvm/IR/Value.h"
28c46e6a59SDimitry Andric #include "llvm/Support/Casting.h"
29b60736ecSDimitry Andric #include "llvm/Support/Error.h"
304a16efa3SDimitry Andric #include "llvm/Support/ErrorHandling.h"
314a16efa3SDimitry Andric #include "llvm/Support/MathExtras.h"
32ecbca9f5SDimitry Andric #include "llvm/Support/MemAlloc.h"
331d5ae102SDimitry Andric #include "llvm/Support/TypeSize.h"
347fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
35009b1c42SEd Schouten #include <algorithm>
36c46e6a59SDimitry Andric #include <cassert>
37c46e6a59SDimitry Andric #include <cstdint>
38009b1c42SEd Schouten #include <cstdlib>
39ecbca9f5SDimitry Andric #include <new>
40c46e6a59SDimitry Andric #include <utility>
41c46e6a59SDimitry Andric 
42009b1c42SEd Schouten using namespace llvm;
43009b1c42SEd Schouten 
44009b1c42SEd Schouten //===----------------------------------------------------------------------===//
45009b1c42SEd Schouten // Support for StructLayout
46009b1c42SEd Schouten //===----------------------------------------------------------------------===//
47009b1c42SEd Schouten 
StructLayout(StructType * ST,const DataLayout & DL)487fa27ce4SDimitry Andric StructLayout::StructLayout(StructType *ST, const DataLayout &DL)
49b1c73532SDimitry Andric     : StructSize(TypeSize::getFixed(0)) {
50411bd29eSDimitry Andric   assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
51dd58ef01SDimitry Andric   IsPadded = false;
52009b1c42SEd Schouten   NumElements = ST->getNumElements();
53009b1c42SEd Schouten 
54009b1c42SEd Schouten   // Loop over each of the elements, placing them in memory.
55009b1c42SEd Schouten   for (unsigned i = 0, e = NumElements; i != e; ++i) {
5630815c53SDimitry Andric     Type *Ty = ST->getElementType(i);
577fa27ce4SDimitry Andric     if (i == 0 && Ty->isScalableTy())
58b1c73532SDimitry Andric       StructSize = TypeSize::getScalable(0);
597fa27ce4SDimitry Andric 
60cfca06d7SDimitry Andric     const Align TyAlign = ST->isPacked() ? Align(1) : DL.getABITypeAlign(Ty);
61009b1c42SEd Schouten 
62009b1c42SEd Schouten     // Add padding if necessary to align the data element properly.
637fa27ce4SDimitry Andric     // Currently the only structure with scalable size will be the homogeneous
647fa27ce4SDimitry Andric     // scalable vector types. Homogeneous scalable vector types have members of
657fa27ce4SDimitry Andric     // the same data type so no alignment issue will happen. The condition here
667fa27ce4SDimitry Andric     // assumes so and needs to be adjusted if this assumption changes (e.g. we
677fa27ce4SDimitry Andric     // support structures with arbitrary scalable data type, or structure that
687fa27ce4SDimitry Andric     // contains both fixed size and scalable size data type members).
697fa27ce4SDimitry Andric     if (!StructSize.isScalable() && !isAligned(TyAlign, StructSize)) {
70dd58ef01SDimitry Andric       IsPadded = true;
71b1c73532SDimitry Andric       StructSize = TypeSize::getFixed(alignTo(StructSize, TyAlign));
72dd58ef01SDimitry Andric     }
73009b1c42SEd Schouten 
74009b1c42SEd Schouten     // Keep track of maximum alignment constraint.
75009b1c42SEd Schouten     StructAlignment = std::max(TyAlign, StructAlignment);
76009b1c42SEd Schouten 
77344a3780SDimitry Andric     getMemberOffsets()[i] = StructSize;
78b60736ecSDimitry Andric     // Consume space for this data item
797fa27ce4SDimitry Andric     StructSize += DL.getTypeAllocSize(Ty);
80009b1c42SEd Schouten   }
81009b1c42SEd Schouten 
82009b1c42SEd Schouten   // Add padding to the end of the struct so that it could be put in an array
83009b1c42SEd Schouten   // and all array elements would be aligned correctly.
847fa27ce4SDimitry Andric   if (!StructSize.isScalable() && !isAligned(StructAlignment, StructSize)) {
85dd58ef01SDimitry Andric     IsPadded = true;
86b1c73532SDimitry Andric     StructSize = TypeSize::getFixed(alignTo(StructSize, StructAlignment));
87009b1c42SEd Schouten   }
88dd58ef01SDimitry Andric }
89009b1c42SEd Schouten 
90009b1c42SEd Schouten /// getElementContainingOffset - Given a valid offset into the structure,
91009b1c42SEd Schouten /// return the structure index that contains it.
getElementContainingOffset(uint64_t FixedOffset) const927fa27ce4SDimitry Andric unsigned StructLayout::getElementContainingOffset(uint64_t FixedOffset) const {
937fa27ce4SDimitry Andric   assert(!StructSize.isScalable() &&
947fa27ce4SDimitry Andric          "Cannot get element at offset for structure containing scalable "
957fa27ce4SDimitry Andric          "vector types");
96b1c73532SDimitry Andric   TypeSize Offset = TypeSize::getFixed(FixedOffset);
977fa27ce4SDimitry Andric   ArrayRef<TypeSize> MemberOffsets = getMemberOffsets();
987fa27ce4SDimitry Andric 
997fa27ce4SDimitry Andric   const auto *SI =
1007fa27ce4SDimitry Andric       std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), Offset,
1017fa27ce4SDimitry Andric                        [](TypeSize LHS, TypeSize RHS) -> bool {
1027fa27ce4SDimitry Andric                          return TypeSize::isKnownLT(LHS, RHS);
1037fa27ce4SDimitry Andric                        });
104344a3780SDimitry Andric   assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
105009b1c42SEd Schouten   --SI;
1067fa27ce4SDimitry Andric   assert(TypeSize::isKnownLE(*SI, Offset) && "upper_bound didn't work");
1077fa27ce4SDimitry Andric   assert(
1087fa27ce4SDimitry Andric       (SI == MemberOffsets.begin() || TypeSize::isKnownLE(*(SI - 1), Offset)) &&
1097fa27ce4SDimitry Andric       (SI + 1 == MemberOffsets.end() ||
1107fa27ce4SDimitry Andric        TypeSize::isKnownGT(*(SI + 1), Offset)) &&
111009b1c42SEd Schouten       "Upper bound didn't work!");
112009b1c42SEd Schouten 
113009b1c42SEd Schouten   // Multiple fields can have the same offset if any of them are zero sized.
114009b1c42SEd Schouten   // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop
115009b1c42SEd Schouten   // at the i32 element, because it is the last element at that offset.  This is
116009b1c42SEd Schouten   // the right one to return, because anything after it will have a higher
117009b1c42SEd Schouten   // offset, implying that this element is non-empty.
118344a3780SDimitry Andric   return SI - MemberOffsets.begin();
119009b1c42SEd Schouten }
120009b1c42SEd Schouten 
121009b1c42SEd Schouten //===----------------------------------------------------------------------===//
122522600a2SDimitry Andric // LayoutAlignElem, LayoutAlign support
123009b1c42SEd Schouten //===----------------------------------------------------------------------===//
124009b1c42SEd Schouten 
get(Align ABIAlign,Align PrefAlign,uint32_t BitWidth)1257fa27ce4SDimitry Andric LayoutAlignElem LayoutAlignElem::get(Align ABIAlign, Align PrefAlign,
1267fa27ce4SDimitry Andric                                      uint32_t BitWidth) {
1277fa27ce4SDimitry Andric   assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
128522600a2SDimitry Andric   LayoutAlignElem retval;
1297fa27ce4SDimitry Andric   retval.ABIAlign = ABIAlign;
1307fa27ce4SDimitry Andric   retval.PrefAlign = PrefAlign;
1317fa27ce4SDimitry Andric   retval.TypeBitWidth = BitWidth;
132009b1c42SEd Schouten   return retval;
133009b1c42SEd Schouten }
134009b1c42SEd Schouten 
operator ==(const LayoutAlignElem & rhs) const1357fa27ce4SDimitry Andric bool LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
1367fa27ce4SDimitry Andric   return ABIAlign == rhs.ABIAlign && PrefAlign == rhs.PrefAlign &&
1377fa27ce4SDimitry Andric          TypeBitWidth == rhs.TypeBitWidth;
138009b1c42SEd Schouten }
139009b1c42SEd Schouten 
140009b1c42SEd Schouten //===----------------------------------------------------------------------===//
141522600a2SDimitry Andric // PointerAlignElem, PointerAlign support
142522600a2SDimitry Andric //===----------------------------------------------------------------------===//
143522600a2SDimitry Andric 
getInBits(uint32_t AddressSpace,Align ABIAlign,Align PrefAlign,uint32_t TypeBitWidth,uint32_t IndexBitWidth)14477fc4c14SDimitry Andric PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace,
14577fc4c14SDimitry Andric                                              Align ABIAlign, Align PrefAlign,
14677fc4c14SDimitry Andric                                              uint32_t TypeBitWidth,
14777fc4c14SDimitry Andric                                              uint32_t IndexBitWidth) {
1485ca98fd9SDimitry Andric   assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
149522600a2SDimitry Andric   PointerAlignElem retval;
1505ca98fd9SDimitry Andric   retval.AddressSpace = AddressSpace;
1515ca98fd9SDimitry Andric   retval.ABIAlign = ABIAlign;
1525ca98fd9SDimitry Andric   retval.PrefAlign = PrefAlign;
15377fc4c14SDimitry Andric   retval.TypeBitWidth = TypeBitWidth;
15477fc4c14SDimitry Andric   retval.IndexBitWidth = IndexBitWidth;
155522600a2SDimitry Andric   return retval;
156522600a2SDimitry Andric }
157522600a2SDimitry Andric 
158522600a2SDimitry Andric bool
operator ==(const PointerAlignElem & rhs) const159522600a2SDimitry Andric PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
16077fc4c14SDimitry Andric   return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&
16177fc4c14SDimitry Andric           PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth &&
16277fc4c14SDimitry Andric           IndexBitWidth == rhs.IndexBitWidth);
163522600a2SDimitry Andric }
164522600a2SDimitry Andric 
165522600a2SDimitry Andric //===----------------------------------------------------------------------===//
166522600a2SDimitry Andric //                       DataLayout Class Implementation
167009b1c42SEd Schouten //===----------------------------------------------------------------------===//
168009b1c42SEd Schouten 
getManglingComponent(const Triple & T)1695ca98fd9SDimitry Andric const char *DataLayout::getManglingComponent(const Triple &T) {
170c0981da4SDimitry Andric   if (T.isOSBinFormatGOFF())
171c0981da4SDimitry Andric     return "-m:l";
1725ca98fd9SDimitry Andric   if (T.isOSBinFormatMachO())
1735ca98fd9SDimitry Andric     return "-m:o";
174b1c73532SDimitry Andric   if ((T.isOSWindows() || T.isUEFI()) && T.isOSBinFormatCOFF())
1755a5ac124SDimitry Andric     return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";
176cfca06d7SDimitry Andric   if (T.isOSBinFormatXCOFF())
177cfca06d7SDimitry Andric     return "-m:a";
1785ca98fd9SDimitry Andric   return "-m:e";
1795ca98fd9SDimitry Andric }
180cf099d11SDimitry Andric 
1817fa27ce4SDimitry Andric static const std::pair<AlignTypeEnum, LayoutAlignElem> DefaultAlignments[] = {
1827fa27ce4SDimitry Andric     {INTEGER_ALIGN, {1, Align(1), Align(1)}},    // i1
1837fa27ce4SDimitry Andric     {INTEGER_ALIGN, {8, Align(1), Align(1)}},    // i8
1847fa27ce4SDimitry Andric     {INTEGER_ALIGN, {16, Align(2), Align(2)}},   // i16
1857fa27ce4SDimitry Andric     {INTEGER_ALIGN, {32, Align(4), Align(4)}},   // i32
1867fa27ce4SDimitry Andric     {INTEGER_ALIGN, {64, Align(4), Align(8)}},   // i64
1877fa27ce4SDimitry Andric     {FLOAT_ALIGN, {16, Align(2), Align(2)}},     // half, bfloat
1887fa27ce4SDimitry Andric     {FLOAT_ALIGN, {32, Align(4), Align(4)}},     // float
1897fa27ce4SDimitry Andric     {FLOAT_ALIGN, {64, Align(8), Align(8)}},     // double
1907fa27ce4SDimitry Andric     {FLOAT_ALIGN, {128, Align(16), Align(16)}},  // ppcf128, quad, ...
1917fa27ce4SDimitry Andric     {VECTOR_ALIGN, {64, Align(8), Align(8)}},    // v2i32, v1i64, ...
1927fa27ce4SDimitry Andric     {VECTOR_ALIGN, {128, Align(16), Align(16)}}, // v16i8, v8i16, v4i32, ...
1935ca98fd9SDimitry Andric };
1945ca98fd9SDimitry Andric 
reset(StringRef Desc)1955ca98fd9SDimitry Andric void DataLayout::reset(StringRef Desc) {
1965ca98fd9SDimitry Andric   clear();
1975ca98fd9SDimitry Andric 
1985ca98fd9SDimitry Andric   LayoutMap = nullptr;
19967c32a98SDimitry Andric   BigEndian = false;
20071d5a254SDimitry Andric   AllocaAddrSpace = 0;
2011d5ae102SDimitry Andric   StackNaturalAlign.reset();
202eb11fae6SDimitry Andric   ProgramAddrSpace = 0;
203b60736ecSDimitry Andric   DefaultGlobalsAddrSpace = 0;
2041d5ae102SDimitry Andric   FunctionPtrAlign.reset();
205e6d15924SDimitry Andric   TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
2065ca98fd9SDimitry Andric   ManglingMode = MM_None;
207b915e9e0SDimitry Andric   NonIntegralAddressSpaces.clear();
2087fa27ce4SDimitry Andric   StructAlignment = LayoutAlignElem::get(Align(1), Align(8), 0);
209009b1c42SEd Schouten 
210009b1c42SEd Schouten   // Default alignments
2117fa27ce4SDimitry Andric   for (const auto &[Kind, Layout] : DefaultAlignments) {
2127fa27ce4SDimitry Andric     if (Error Err = setAlignment(Kind, Layout.ABIAlign, Layout.PrefAlign,
2137fa27ce4SDimitry Andric                                  Layout.TypeBitWidth))
214b60736ecSDimitry Andric       return report_fatal_error(std::move(Err));
2155ca98fd9SDimitry Andric   }
21677fc4c14SDimitry Andric   if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
217b60736ecSDimitry Andric     return report_fatal_error(std::move(Err));
2184a16efa3SDimitry Andric 
219b60736ecSDimitry Andric   if (Error Err = parseSpecifier(Desc))
220b60736ecSDimitry Andric     return report_fatal_error(std::move(Err));
221b60736ecSDimitry Andric }
222b60736ecSDimitry Andric 
parse(StringRef LayoutDescription)223b60736ecSDimitry Andric Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
224b60736ecSDimitry Andric   DataLayout Layout("");
225b60736ecSDimitry Andric   if (Error Err = Layout.parseSpecifier(LayoutDescription))
226b60736ecSDimitry Andric     return std::move(Err);
227b60736ecSDimitry Andric   return Layout;
228b60736ecSDimitry Andric }
229b60736ecSDimitry Andric 
reportError(const Twine & Message)230b60736ecSDimitry Andric static Error reportError(const Twine &Message) {
231b60736ecSDimitry Andric   return createStringError(inconvertibleErrorCode(), Message);
23263faed5bSDimitry Andric }
23363faed5bSDimitry Andric 
2344a16efa3SDimitry Andric /// Checked version of split, to ensure mandatory subparts.
split(StringRef Str,char Separator,std::pair<StringRef,StringRef> & Split)235b60736ecSDimitry Andric static Error split(StringRef Str, char Separator,
236b60736ecSDimitry Andric                    std::pair<StringRef, StringRef> &Split) {
2374a16efa3SDimitry Andric   assert(!Str.empty() && "parse error, string can't be empty here");
238b60736ecSDimitry Andric   Split = Str.split(Separator);
23967c32a98SDimitry Andric   if (Split.second.empty() && Split.first != Str)
240b60736ecSDimitry Andric     return reportError("Trailing separator in datalayout string");
24167c32a98SDimitry Andric   if (!Split.second.empty() && Split.first.empty())
242b60736ecSDimitry Andric     return reportError("Expected token before separator in datalayout string");
243b60736ecSDimitry Andric   return Error::success();
2444a16efa3SDimitry Andric }
24563faed5bSDimitry Andric 
2465ca98fd9SDimitry Andric /// Get an unsigned integer, including error checks.
getInt(StringRef R,IntTy & Result)247b60736ecSDimitry Andric template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
2484a16efa3SDimitry Andric   bool error = R.getAsInteger(10, Result); (void)error;
2495ca98fd9SDimitry Andric   if (error)
250b60736ecSDimitry Andric     return reportError("not a number, or does not fit in an unsigned int");
251b60736ecSDimitry Andric   return Error::success();
2524a16efa3SDimitry Andric }
2534a16efa3SDimitry Andric 
254b60736ecSDimitry Andric /// Get an unsigned integer representing the number of bits and convert it into
255b60736ecSDimitry Andric /// bytes. Error out of not a byte width multiple.
256b60736ecSDimitry Andric template <typename IntTy>
getIntInBytes(StringRef R,IntTy & Result)257b60736ecSDimitry Andric static Error getIntInBytes(StringRef R, IntTy &Result) {
258b60736ecSDimitry Andric   if (Error Err = getInt<IntTy>(R, Result))
259b60736ecSDimitry Andric     return Err;
260b60736ecSDimitry Andric   if (Result % 8)
261b60736ecSDimitry Andric     return reportError("number of bits must be a byte width multiple");
262b60736ecSDimitry Andric   Result /= 8;
263b60736ecSDimitry Andric   return Error::success();
2644a16efa3SDimitry Andric }
2654a16efa3SDimitry Andric 
getAddrSpace(StringRef R,unsigned & AddrSpace)266b60736ecSDimitry Andric static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {
267b60736ecSDimitry Andric   if (Error Err = getInt(R, AddrSpace))
268b60736ecSDimitry Andric     return Err;
269eb11fae6SDimitry Andric   if (!isUInt<24>(AddrSpace))
270b60736ecSDimitry Andric     return reportError("Invalid address space, must be a 24-bit integer");
271b60736ecSDimitry Andric   return Error::success();
272eb11fae6SDimitry Andric }
273eb11fae6SDimitry Andric 
parseSpecifier(StringRef Desc)274b60736ecSDimitry Andric Error DataLayout::parseSpecifier(StringRef Desc) {
275cfca06d7SDimitry Andric   StringRepresentation = std::string(Desc);
276907da171SRoman Divacky   while (!Desc.empty()) {
2774a16efa3SDimitry Andric     // Split at '-'.
278b60736ecSDimitry Andric     std::pair<StringRef, StringRef> Split;
279c0981da4SDimitry Andric     if (Error Err = ::split(Desc, '-', Split))
280b60736ecSDimitry Andric       return Err;
281907da171SRoman Divacky     Desc = Split.second;
282907da171SRoman Divacky 
2834a16efa3SDimitry Andric     // Split at ':'.
284c0981da4SDimitry Andric     if (Error Err = ::split(Split.first, ':', Split))
285b60736ecSDimitry Andric       return Err;
286907da171SRoman Divacky 
2874a16efa3SDimitry Andric     // Aliases used below.
2884a16efa3SDimitry Andric     StringRef &Tok  = Split.first;  // Current token.
2894a16efa3SDimitry Andric     StringRef &Rest = Split.second; // The rest of the string.
290907da171SRoman Divacky 
291b915e9e0SDimitry Andric     if (Tok == "ni") {
292b915e9e0SDimitry Andric       do {
293c0981da4SDimitry Andric         if (Error Err = ::split(Rest, ':', Split))
294b60736ecSDimitry Andric           return Err;
295b915e9e0SDimitry Andric         Rest = Split.second;
296b60736ecSDimitry Andric         unsigned AS;
297b60736ecSDimitry Andric         if (Error Err = getInt(Split.first, AS))
298b60736ecSDimitry Andric           return Err;
299b915e9e0SDimitry Andric         if (AS == 0)
300b60736ecSDimitry Andric           return reportError("Address space 0 can never be non-integral");
301b915e9e0SDimitry Andric         NonIntegralAddressSpaces.push_back(AS);
302b915e9e0SDimitry Andric       } while (!Rest.empty());
303b915e9e0SDimitry Andric 
304b915e9e0SDimitry Andric       continue;
305b915e9e0SDimitry Andric     }
306b915e9e0SDimitry Andric 
3074a16efa3SDimitry Andric     char Specifier = Tok.front();
3084a16efa3SDimitry Andric     Tok = Tok.substr(1);
309907da171SRoman Divacky 
3104a16efa3SDimitry Andric     switch (Specifier) {
3115ca98fd9SDimitry Andric     case 's':
312cfca06d7SDimitry Andric       // Deprecated, but ignoring here to preserve loading older textual llvm
313cfca06d7SDimitry Andric       // ASM file
3145ca98fd9SDimitry Andric       break;
315009b1c42SEd Schouten     case 'E':
31667c32a98SDimitry Andric       BigEndian = true;
317009b1c42SEd Schouten       break;
318009b1c42SEd Schouten     case 'e':
31967c32a98SDimitry Andric       BigEndian = false;
320009b1c42SEd Schouten       break;
32163faed5bSDimitry Andric     case 'p': {
3224a16efa3SDimitry Andric       // Address space.
323b60736ecSDimitry Andric       unsigned AddrSpace = 0;
324b60736ecSDimitry Andric       if (!Tok.empty())
325b60736ecSDimitry Andric         if (Error Err = getInt(Tok, AddrSpace))
326b60736ecSDimitry Andric           return Err;
32767c32a98SDimitry Andric       if (!isUInt<24>(AddrSpace))
3287fa27ce4SDimitry Andric         return reportError("Invalid address space, must be a 24-bit integer");
32963faed5bSDimitry Andric 
3304a16efa3SDimitry Andric       // Size.
33167c32a98SDimitry Andric       if (Rest.empty())
332b60736ecSDimitry Andric         return reportError(
33367c32a98SDimitry Andric             "Missing size specification for pointer in datalayout string");
334c0981da4SDimitry Andric       if (Error Err = ::split(Rest, ':', Split))
335b60736ecSDimitry Andric         return Err;
336b60736ecSDimitry Andric       unsigned PointerMemSize;
33777fc4c14SDimitry Andric       if (Error Err = getInt(Tok, PointerMemSize))
338b60736ecSDimitry Andric         return Err;
3395a5ac124SDimitry Andric       if (!PointerMemSize)
340b60736ecSDimitry Andric         return reportError("Invalid pointer size of 0 bytes");
3414a16efa3SDimitry Andric 
3424a16efa3SDimitry Andric       // ABI alignment.
34367c32a98SDimitry Andric       if (Rest.empty())
344b60736ecSDimitry Andric         return reportError(
34567c32a98SDimitry Andric             "Missing alignment specification for pointer in datalayout string");
346c0981da4SDimitry Andric       if (Error Err = ::split(Rest, ':', Split))
347b60736ecSDimitry Andric         return Err;
348b60736ecSDimitry Andric       unsigned PointerABIAlign;
349b60736ecSDimitry Andric       if (Error Err = getIntInBytes(Tok, PointerABIAlign))
350b60736ecSDimitry Andric         return Err;
3515a5ac124SDimitry Andric       if (!isPowerOf2_64(PointerABIAlign))
352b60736ecSDimitry Andric         return reportError("Pointer ABI alignment must be a power of 2");
3534a16efa3SDimitry Andric 
354eb11fae6SDimitry Andric       // Size of index used in GEP for address calculation.
355eb11fae6SDimitry Andric       // The parameter is optional. By default it is equal to size of pointer.
356eb11fae6SDimitry Andric       unsigned IndexSize = PointerMemSize;
357eb11fae6SDimitry Andric 
3584a16efa3SDimitry Andric       // Preferred alignment.
3594a16efa3SDimitry Andric       unsigned PointerPrefAlign = PointerABIAlign;
3604a16efa3SDimitry Andric       if (!Rest.empty()) {
361c0981da4SDimitry Andric         if (Error Err = ::split(Rest, ':', Split))
362b60736ecSDimitry Andric           return Err;
363b60736ecSDimitry Andric         if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
364b60736ecSDimitry Andric           return Err;
3655a5ac124SDimitry Andric         if (!isPowerOf2_64(PointerPrefAlign))
366b60736ecSDimitry Andric           return reportError(
3675a5ac124SDimitry Andric               "Pointer preferred alignment must be a power of 2");
36863faed5bSDimitry Andric 
369eb11fae6SDimitry Andric         // Now read the index. It is the second optional parameter here.
370eb11fae6SDimitry Andric         if (!Rest.empty()) {
371c0981da4SDimitry Andric           if (Error Err = ::split(Rest, ':', Split))
372b60736ecSDimitry Andric             return Err;
37377fc4c14SDimitry Andric           if (Error Err = getInt(Tok, IndexSize))
374b60736ecSDimitry Andric             return Err;
375eb11fae6SDimitry Andric           if (!IndexSize)
376b60736ecSDimitry Andric             return reportError("Invalid index size of 0 bytes");
377eb11fae6SDimitry Andric         }
378eb11fae6SDimitry Andric       }
37977fc4c14SDimitry Andric       if (Error Err = setPointerAlignmentInBits(
380b60736ecSDimitry Andric               AddrSpace, assumeAligned(PointerABIAlign),
381b60736ecSDimitry Andric               assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
382b60736ecSDimitry Andric         return Err;
383009b1c42SEd Schouten       break;
38463faed5bSDimitry Andric     }
385009b1c42SEd Schouten     case 'i':
386009b1c42SEd Schouten     case 'v':
387009b1c42SEd Schouten     case 'f':
3885ca98fd9SDimitry Andric     case 'a': {
389907da171SRoman Divacky       AlignTypeEnum AlignType;
3904a16efa3SDimitry Andric       switch (Specifier) {
391b5630dbaSDimitry Andric       default: llvm_unreachable("Unexpected specifier!");
392907da171SRoman Divacky       case 'i': AlignType = INTEGER_ALIGN; break;
393907da171SRoman Divacky       case 'v': AlignType = VECTOR_ALIGN; break;
394907da171SRoman Divacky       case 'f': AlignType = FLOAT_ALIGN; break;
395907da171SRoman Divacky       case 'a': AlignType = AGGREGATE_ALIGN; break;
396009b1c42SEd Schouten       }
3974a16efa3SDimitry Andric 
3984a16efa3SDimitry Andric       // Bit size.
399b60736ecSDimitry Andric       unsigned Size = 0;
400b60736ecSDimitry Andric       if (!Tok.empty())
401b60736ecSDimitry Andric         if (Error Err = getInt(Tok, Size))
402b60736ecSDimitry Andric           return Err;
4034a16efa3SDimitry Andric 
40467c32a98SDimitry Andric       if (AlignType == AGGREGATE_ALIGN && Size != 0)
405b60736ecSDimitry Andric         return reportError(
40667c32a98SDimitry Andric             "Sized aggregate specification in datalayout string");
4075ca98fd9SDimitry Andric 
4084a16efa3SDimitry Andric       // ABI alignment.
40967c32a98SDimitry Andric       if (Rest.empty())
410b60736ecSDimitry Andric         return reportError(
41167c32a98SDimitry Andric             "Missing alignment specification in datalayout string");
412c0981da4SDimitry Andric       if (Error Err = ::split(Rest, ':', Split))
413b60736ecSDimitry Andric         return Err;
414b60736ecSDimitry Andric       unsigned ABIAlign;
415b60736ecSDimitry Andric       if (Error Err = getIntInBytes(Tok, ABIAlign))
416b60736ecSDimitry Andric         return Err;
4175a5ac124SDimitry Andric       if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
418b60736ecSDimitry Andric         return reportError(
4195a5ac124SDimitry Andric             "ABI alignment specification must be >0 for non-aggregate types");
4204a16efa3SDimitry Andric 
4211d5ae102SDimitry Andric       if (!isUInt<16>(ABIAlign))
422b60736ecSDimitry Andric         return reportError("Invalid ABI alignment, must be a 16bit integer");
4231d5ae102SDimitry Andric       if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
424b60736ecSDimitry Andric         return reportError("Invalid ABI alignment, must be a power of 2");
425e3b55780SDimitry Andric       if (AlignType == INTEGER_ALIGN && Size == 8 && ABIAlign != 1)
426e3b55780SDimitry Andric         return reportError(
427e3b55780SDimitry Andric             "Invalid ABI alignment, i8 must be naturally aligned");
4281d5ae102SDimitry Andric 
4294a16efa3SDimitry Andric       // Preferred alignment.
4304a16efa3SDimitry Andric       unsigned PrefAlign = ABIAlign;
4314a16efa3SDimitry Andric       if (!Rest.empty()) {
432c0981da4SDimitry Andric         if (Error Err = ::split(Rest, ':', Split))
433b60736ecSDimitry Andric           return Err;
434b60736ecSDimitry Andric         if (Error Err = getIntInBytes(Tok, PrefAlign))
435b60736ecSDimitry Andric           return Err;
43663faed5bSDimitry Andric       }
43763faed5bSDimitry Andric 
4381d5ae102SDimitry Andric       if (!isUInt<16>(PrefAlign))
439b60736ecSDimitry Andric         return reportError(
4401d5ae102SDimitry Andric             "Invalid preferred alignment, must be a 16bit integer");
4411d5ae102SDimitry Andric       if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
442b60736ecSDimitry Andric         return reportError("Invalid preferred alignment, must be a power of 2");
4431d5ae102SDimitry Andric 
444b60736ecSDimitry Andric       if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
445b60736ecSDimitry Andric                                    assumeAligned(PrefAlign), Size))
446b60736ecSDimitry Andric         return Err;
447907da171SRoman Divacky 
448009b1c42SEd Schouten       break;
449009b1c42SEd Schouten     }
450907da171SRoman Divacky     case 'n':  // Native integer types.
451c46e6a59SDimitry Andric       while (true) {
452b60736ecSDimitry Andric         unsigned Width;
453b60736ecSDimitry Andric         if (Error Err = getInt(Tok, Width))
454b60736ecSDimitry Andric           return Err;
45567c32a98SDimitry Andric         if (Width == 0)
456b60736ecSDimitry Andric           return reportError(
45767c32a98SDimitry Andric               "Zero width native integer type in datalayout string");
4584a16efa3SDimitry Andric         LegalIntWidths.push_back(Width);
4594a16efa3SDimitry Andric         if (Rest.empty())
4604a16efa3SDimitry Andric           break;
461c0981da4SDimitry Andric         if (Error Err = ::split(Rest, ':', Split))
462b60736ecSDimitry Andric           return Err;
46363faed5bSDimitry Andric       }
464907da171SRoman Divacky       break;
46563faed5bSDimitry Andric     case 'S': { // Stack natural alignment.
466b60736ecSDimitry Andric       uint64_t Alignment;
467b60736ecSDimitry Andric       if (Error Err = getIntInBytes(Tok, Alignment))
468b60736ecSDimitry Andric         return Err;
4691d5ae102SDimitry Andric       if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
470b60736ecSDimitry Andric         return reportError("Alignment is neither 0 nor a power of 2");
4711d5ae102SDimitry Andric       StackNaturalAlign = MaybeAlign(Alignment);
47230815c53SDimitry Andric       break;
47363faed5bSDimitry Andric     }
474e6d15924SDimitry Andric     case 'F': {
475e6d15924SDimitry Andric       switch (Tok.front()) {
476e6d15924SDimitry Andric       case 'i':
477e6d15924SDimitry Andric         TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
478e6d15924SDimitry Andric         break;
479e6d15924SDimitry Andric       case 'n':
480e6d15924SDimitry Andric         TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;
481e6d15924SDimitry Andric         break;
482e6d15924SDimitry Andric       default:
483b60736ecSDimitry Andric         return reportError("Unknown function pointer alignment type in "
484e6d15924SDimitry Andric                            "datalayout string");
485e6d15924SDimitry Andric       }
486e6d15924SDimitry Andric       Tok = Tok.substr(1);
487b60736ecSDimitry Andric       uint64_t Alignment;
488b60736ecSDimitry Andric       if (Error Err = getIntInBytes(Tok, Alignment))
489b60736ecSDimitry Andric         return Err;
4901d5ae102SDimitry Andric       if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
491b60736ecSDimitry Andric         return reportError("Alignment is neither 0 nor a power of 2");
4921d5ae102SDimitry Andric       FunctionPtrAlign = MaybeAlign(Alignment);
493e6d15924SDimitry Andric       break;
494e6d15924SDimitry Andric     }
495eb11fae6SDimitry Andric     case 'P': { // Function address space.
496b60736ecSDimitry Andric       if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))
497b60736ecSDimitry Andric         return Err;
498eb11fae6SDimitry Andric       break;
499eb11fae6SDimitry Andric     }
50071d5a254SDimitry Andric     case 'A': { // Default stack/alloca address space.
501b60736ecSDimitry Andric       if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
502b60736ecSDimitry Andric         return Err;
503b60736ecSDimitry Andric       break;
504b60736ecSDimitry Andric     }
505b60736ecSDimitry Andric     case 'G': { // Default address space for global variables.
506b60736ecSDimitry Andric       if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
507b60736ecSDimitry Andric         return Err;
50871d5a254SDimitry Andric       break;
50971d5a254SDimitry Andric     }
5105ca98fd9SDimitry Andric     case 'm':
51167c32a98SDimitry Andric       if (!Tok.empty())
512b60736ecSDimitry Andric         return reportError("Unexpected trailing characters after mangling "
513b60736ecSDimitry Andric                            "specifier in datalayout string");
51467c32a98SDimitry Andric       if (Rest.empty())
515b60736ecSDimitry Andric         return reportError("Expected mangling specifier in datalayout string");
51667c32a98SDimitry Andric       if (Rest.size() > 1)
517b60736ecSDimitry Andric         return reportError("Unknown mangling specifier in datalayout string");
5185ca98fd9SDimitry Andric       switch(Rest[0]) {
5195ca98fd9SDimitry Andric       default:
520b60736ecSDimitry Andric         return reportError("Unknown mangling in datalayout string");
5215ca98fd9SDimitry Andric       case 'e':
5225ca98fd9SDimitry Andric         ManglingMode = MM_ELF;
5235ca98fd9SDimitry Andric         break;
524c0981da4SDimitry Andric       case 'l':
525c0981da4SDimitry Andric         ManglingMode = MM_GOFF;
526c0981da4SDimitry Andric         break;
5275ca98fd9SDimitry Andric       case 'o':
5285ca98fd9SDimitry Andric         ManglingMode = MM_MachO;
5295ca98fd9SDimitry Andric         break;
5305ca98fd9SDimitry Andric       case 'm':
5315ca98fd9SDimitry Andric         ManglingMode = MM_Mips;
5325ca98fd9SDimitry Andric         break;
5335ca98fd9SDimitry Andric       case 'w':
5345a5ac124SDimitry Andric         ManglingMode = MM_WinCOFF;
5355a5ac124SDimitry Andric         break;
5365a5ac124SDimitry Andric       case 'x':
5375a5ac124SDimitry Andric         ManglingMode = MM_WinCOFFX86;
5385ca98fd9SDimitry Andric         break;
539cfca06d7SDimitry Andric       case 'a':
540cfca06d7SDimitry Andric         ManglingMode = MM_XCOFF;
541cfca06d7SDimitry Andric         break;
5425ca98fd9SDimitry Andric       }
5435ca98fd9SDimitry Andric       break;
544009b1c42SEd Schouten     default:
545b60736ecSDimitry Andric       return reportError("Unknown specifier in datalayout string");
546009b1c42SEd Schouten       break;
547009b1c42SEd Schouten     }
548009b1c42SEd Schouten   }
549b60736ecSDimitry Andric 
550b60736ecSDimitry Andric   return Error::success();
551009b1c42SEd Schouten }
552009b1c42SEd Schouten 
DataLayout(const Module * M)553c46e6a59SDimitry Andric DataLayout::DataLayout(const Module *M) {
55467c32a98SDimitry Andric   init(M);
55567c32a98SDimitry Andric }
55667c32a98SDimitry Andric 
init(const Module * M)5575a5ac124SDimitry Andric void DataLayout::init(const Module *M) { *this = M->getDataLayout(); }
558907da171SRoman Divacky 
operator ==(const DataLayout & Other) const5595ca98fd9SDimitry Andric bool DataLayout::operator==(const DataLayout &Other) const {
56067c32a98SDimitry Andric   bool Ret = BigEndian == Other.BigEndian &&
56171d5a254SDimitry Andric              AllocaAddrSpace == Other.AllocaAddrSpace &&
5625ca98fd9SDimitry Andric              StackNaturalAlign == Other.StackNaturalAlign &&
563eb11fae6SDimitry Andric              ProgramAddrSpace == Other.ProgramAddrSpace &&
564b60736ecSDimitry Andric              DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
565e6d15924SDimitry Andric              FunctionPtrAlign == Other.FunctionPtrAlign &&
566e6d15924SDimitry Andric              TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
5675ca98fd9SDimitry Andric              ManglingMode == Other.ManglingMode &&
5685ca98fd9SDimitry Andric              LegalIntWidths == Other.LegalIntWidths &&
5697fa27ce4SDimitry Andric              IntAlignments == Other.IntAlignments &&
5707fa27ce4SDimitry Andric              FloatAlignments == Other.FloatAlignments &&
5717fa27ce4SDimitry Andric              VectorAlignments == Other.VectorAlignments &&
5727fa27ce4SDimitry Andric              StructAlignment == Other.StructAlignment &&
5737fa27ce4SDimitry Andric              Pointers == Other.Pointers;
5745a5ac124SDimitry Andric   // Note: getStringRepresentation() might differs, it is not canonicalized
5755ca98fd9SDimitry Andric   return Ret;
576009b1c42SEd Schouten }
577009b1c42SEd Schouten 
5787fa27ce4SDimitry Andric static SmallVectorImpl<LayoutAlignElem>::const_iterator
findAlignmentLowerBound(const SmallVectorImpl<LayoutAlignElem> & Alignments,uint32_t BitWidth)5797fa27ce4SDimitry Andric findAlignmentLowerBound(const SmallVectorImpl<LayoutAlignElem> &Alignments,
58071d5a254SDimitry Andric                         uint32_t BitWidth) {
5817fa27ce4SDimitry Andric   return partition_point(Alignments, [BitWidth](const LayoutAlignElem &E) {
5827fa27ce4SDimitry Andric     return E.TypeBitWidth < BitWidth;
58371d5a254SDimitry Andric   });
58471d5a254SDimitry Andric }
58571d5a254SDimitry Andric 
setAlignment(AlignTypeEnum AlignType,Align ABIAlign,Align PrefAlign,uint32_t BitWidth)5867fa27ce4SDimitry Andric Error DataLayout::setAlignment(AlignTypeEnum AlignType, Align ABIAlign,
5877fa27ce4SDimitry Andric                                Align PrefAlign, uint32_t BitWidth) {
5881d5ae102SDimitry Andric   // AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as
5891d5ae102SDimitry Andric   // uint16_t, it is unclear if there are requirements for alignment to be less
5901d5ae102SDimitry Andric   // than 2^16 other than storage. In the meantime we leave the restriction as
5911d5ae102SDimitry Andric   // an assert. See D67400 for context.
5927fa27ce4SDimitry Andric   assert(Log2(ABIAlign) < 16 && Log2(PrefAlign) < 16 && "Alignment too big");
5937fa27ce4SDimitry Andric   if (!isUInt<24>(BitWidth))
5947fa27ce4SDimitry Andric     return reportError("Invalid bit width, must be a 24-bit integer");
5957fa27ce4SDimitry Andric   if (PrefAlign < ABIAlign)
596b60736ecSDimitry Andric     return reportError(
5975a5ac124SDimitry Andric         "Preferred alignment cannot be less than the ABI alignment");
5985a5ac124SDimitry Andric 
5997fa27ce4SDimitry Andric   SmallVectorImpl<LayoutAlignElem> *Alignments;
6007fa27ce4SDimitry Andric   switch (AlignType) {
6017fa27ce4SDimitry Andric   case AGGREGATE_ALIGN:
6027fa27ce4SDimitry Andric     StructAlignment.ABIAlign = ABIAlign;
6037fa27ce4SDimitry Andric     StructAlignment.PrefAlign = PrefAlign;
6047fa27ce4SDimitry Andric     return Error::success();
6057fa27ce4SDimitry Andric   case INTEGER_ALIGN:
6067fa27ce4SDimitry Andric     Alignments = &IntAlignments;
6077fa27ce4SDimitry Andric     break;
6087fa27ce4SDimitry Andric   case FLOAT_ALIGN:
6097fa27ce4SDimitry Andric     Alignments = &FloatAlignments;
6107fa27ce4SDimitry Andric     break;
6117fa27ce4SDimitry Andric   case VECTOR_ALIGN:
6127fa27ce4SDimitry Andric     Alignments = &VectorAlignments;
6137fa27ce4SDimitry Andric     break;
6147fa27ce4SDimitry Andric   }
6157fa27ce4SDimitry Andric 
6167fa27ce4SDimitry Andric   auto I = partition_point(*Alignments, [BitWidth](const LayoutAlignElem &E) {
6177fa27ce4SDimitry Andric     return E.TypeBitWidth < BitWidth;
6187fa27ce4SDimitry Andric   });
6197fa27ce4SDimitry Andric   if (I != Alignments->end() && I->TypeBitWidth == BitWidth) {
620009b1c42SEd Schouten     // Update the abi, preferred alignments.
6217fa27ce4SDimitry Andric     I->ABIAlign = ABIAlign;
6227fa27ce4SDimitry Andric     I->PrefAlign = PrefAlign;
62371d5a254SDimitry Andric   } else {
62471d5a254SDimitry Andric     // Insert before I to keep the vector sorted.
6257fa27ce4SDimitry Andric     Alignments->insert(I, LayoutAlignElem::get(ABIAlign, PrefAlign, BitWidth));
626009b1c42SEd Schouten   }
627b60736ecSDimitry Andric   return Error::success();
62871d5a254SDimitry Andric }
629009b1c42SEd Schouten 
630b60736ecSDimitry Andric const PointerAlignElem &
getPointerAlignElem(uint32_t AddressSpace) const631b60736ecSDimitry Andric DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
632b60736ecSDimitry Andric   if (AddressSpace != 0) {
633b60736ecSDimitry Andric     auto I = lower_bound(Pointers, AddressSpace,
6345ca98fd9SDimitry Andric                          [](const PointerAlignElem &A, uint32_t AddressSpace) {
6355ca98fd9SDimitry Andric       return A.AddressSpace < AddressSpace;
6365ca98fd9SDimitry Andric     });
637b60736ecSDimitry Andric     if (I != Pointers.end() && I->AddressSpace == AddressSpace)
638b60736ecSDimitry Andric       return *I;
6395ca98fd9SDimitry Andric   }
6405ca98fd9SDimitry Andric 
641b60736ecSDimitry Andric   assert(Pointers[0].AddressSpace == 0);
642b60736ecSDimitry Andric   return Pointers[0];
643b60736ecSDimitry Andric }
644b60736ecSDimitry Andric 
setPointerAlignmentInBits(uint32_t AddrSpace,Align ABIAlign,Align PrefAlign,uint32_t TypeBitWidth,uint32_t IndexBitWidth)64577fc4c14SDimitry Andric Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
64677fc4c14SDimitry Andric                                             Align PrefAlign,
64777fc4c14SDimitry Andric                                             uint32_t TypeBitWidth,
64877fc4c14SDimitry Andric                                             uint32_t IndexBitWidth) {
6495a5ac124SDimitry Andric   if (PrefAlign < ABIAlign)
650b60736ecSDimitry Andric     return reportError(
6515a5ac124SDimitry Andric         "Preferred alignment cannot be less than the ABI alignment");
652b1c73532SDimitry Andric   if (IndexBitWidth > TypeBitWidth)
653b1c73532SDimitry Andric     return reportError("Index width cannot be larger than pointer width");
6545a5ac124SDimitry Andric 
655b60736ecSDimitry Andric   auto I = lower_bound(Pointers, AddrSpace,
656b60736ecSDimitry Andric                        [](const PointerAlignElem &A, uint32_t AddressSpace) {
657b60736ecSDimitry Andric     return A.AddressSpace < AddressSpace;
658b60736ecSDimitry Andric   });
6595ca98fd9SDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
66077fc4c14SDimitry Andric     Pointers.insert(I,
66177fc4c14SDimitry Andric                     PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign,
66277fc4c14SDimitry Andric                                                 TypeBitWidth, IndexBitWidth));
663522600a2SDimitry Andric   } else {
6645ca98fd9SDimitry Andric     I->ABIAlign = ABIAlign;
6655ca98fd9SDimitry Andric     I->PrefAlign = PrefAlign;
66677fc4c14SDimitry Andric     I->TypeBitWidth = TypeBitWidth;
66777fc4c14SDimitry Andric     I->IndexBitWidth = IndexBitWidth;
668522600a2SDimitry Andric   }
669b60736ecSDimitry Andric   return Error::success();
670522600a2SDimitry Andric }
671522600a2SDimitry Andric 
getIntegerAlignment(uint32_t BitWidth,bool abi_or_pref) const672b60736ecSDimitry Andric Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
673b60736ecSDimitry Andric                                       bool abi_or_pref) const {
6747fa27ce4SDimitry Andric   auto I = findAlignmentLowerBound(IntAlignments, BitWidth);
675b60736ecSDimitry Andric   // If we don't have an exact match, use alignment of next larger integer
676b60736ecSDimitry Andric   // type. If there is none, use alignment of largest integer type by going
677b60736ecSDimitry Andric   // back one element.
6787fa27ce4SDimitry Andric   if (I == IntAlignments.end())
679b60736ecSDimitry Andric     --I;
680b60736ecSDimitry Andric   return abi_or_pref ? I->ABIAlign : I->PrefAlign;
6815a5ac124SDimitry Andric }
6825a5ac124SDimitry Andric 
683571945e6SRoman Divacky namespace {
684009b1c42SEd Schouten 
685411bd29eSDimitry Andric class StructLayoutMap {
686c46e6a59SDimitry Andric   using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;
687907da171SRoman Divacky   LayoutInfoTy LayoutInfo;
688907da171SRoman Divacky 
689907da171SRoman Divacky public:
~StructLayoutMap()6905ca98fd9SDimitry Andric   ~StructLayoutMap() {
691907da171SRoman Divacky     // Remove any layouts.
6925ca98fd9SDimitry Andric     for (const auto &I : LayoutInfo) {
6935ca98fd9SDimitry Andric       StructLayout *Value = I.second;
694571945e6SRoman Divacky       Value->~StructLayout();
695571945e6SRoman Divacky       free(Value);
696907da171SRoman Divacky     }
697907da171SRoman Divacky   }
698907da171SRoman Divacky 
operator [](StructType * STy)69930815c53SDimitry Andric   StructLayout *&operator[](StructType *STy) {
700907da171SRoman Divacky     return LayoutInfo[STy];
701907da171SRoman Divacky   }
702907da171SRoman Divacky };
703907da171SRoman Divacky 
704571945e6SRoman Divacky } // end anonymous namespace
705907da171SRoman Divacky 
clear()7065ca98fd9SDimitry Andric void DataLayout::clear() {
7075ca98fd9SDimitry Andric   LegalIntWidths.clear();
7087fa27ce4SDimitry Andric   IntAlignments.clear();
7097fa27ce4SDimitry Andric   FloatAlignments.clear();
7107fa27ce4SDimitry Andric   VectorAlignments.clear();
7115ca98fd9SDimitry Andric   Pointers.clear();
712571945e6SRoman Divacky   delete static_cast<StructLayoutMap *>(LayoutMap);
7135ca98fd9SDimitry Andric   LayoutMap = nullptr;
714009b1c42SEd Schouten }
715009b1c42SEd Schouten 
~DataLayout()7165ca98fd9SDimitry Andric DataLayout::~DataLayout() {
7175ca98fd9SDimitry Andric   clear();
7184a16efa3SDimitry Andric }
7194a16efa3SDimitry Andric 
getStructLayout(StructType * Ty) const720522600a2SDimitry Andric const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
72159850d08SRoman Divacky   if (!LayoutMap)
722907da171SRoman Divacky     LayoutMap = new StructLayoutMap();
723009b1c42SEd Schouten 
724571945e6SRoman Divacky   StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
725571945e6SRoman Divacky   StructLayout *&SL = (*STM)[Ty];
726009b1c42SEd Schouten   if (SL) return SL;
727009b1c42SEd Schouten 
728009b1c42SEd Schouten   // Otherwise, create the struct layout.  Because it is variable length, we
729009b1c42SEd Schouten   // malloc it, then use placement new.
730344a3780SDimitry Andric   StructLayout *L = (StructLayout *)safe_malloc(
7317fa27ce4SDimitry Andric       StructLayout::totalSizeToAlloc<TypeSize>(Ty->getNumElements()));
732009b1c42SEd Schouten 
733009b1c42SEd Schouten   // Set SL before calling StructLayout's ctor.  The ctor could cause other
734009b1c42SEd Schouten   // entries to be added to TheMap, invalidating our reference.
735009b1c42SEd Schouten   SL = L;
736009b1c42SEd Schouten 
737009b1c42SEd Schouten   new (L) StructLayout(Ty, *this);
738571945e6SRoman Divacky 
739009b1c42SEd Schouten   return L;
740009b1c42SEd Schouten }
741009b1c42SEd Schouten 
getPointerABIAlignment(unsigned AS) const7421d5ae102SDimitry Andric Align DataLayout::getPointerABIAlignment(unsigned AS) const {
743b60736ecSDimitry Andric   return getPointerAlignElem(AS).ABIAlign;
7445ca98fd9SDimitry Andric }
7455ca98fd9SDimitry Andric 
getPointerPrefAlignment(unsigned AS) const7461d5ae102SDimitry Andric Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
747b60736ecSDimitry Andric   return getPointerAlignElem(AS).PrefAlign;
7485ca98fd9SDimitry Andric }
7495ca98fd9SDimitry Andric 
getPointerSize(unsigned AS) const7505ca98fd9SDimitry Andric unsigned DataLayout::getPointerSize(unsigned AS) const {
75177fc4c14SDimitry Andric   return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8);
7525ca98fd9SDimitry Andric }
7535ca98fd9SDimitry Andric 
getMaxIndexSize() const754c0981da4SDimitry Andric unsigned DataLayout::getMaxIndexSize() const {
755c0981da4SDimitry Andric   unsigned MaxIndexSize = 0;
756d8e91e46SDimitry Andric   for (auto &P : Pointers)
75777fc4c14SDimitry Andric     MaxIndexSize =
75877fc4c14SDimitry Andric         std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8));
759d8e91e46SDimitry Andric 
760c0981da4SDimitry Andric   return MaxIndexSize;
761d8e91e46SDimitry Andric }
762d8e91e46SDimitry Andric 
getPointerTypeSizeInBits(Type * Ty) const763f8af5cf6SDimitry Andric unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
764f8af5cf6SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
765f8af5cf6SDimitry Andric          "This should only be called with a pointer or pointer vector type");
766d99dafe2SDimitry Andric   Ty = Ty->getScalarType();
767d99dafe2SDimitry Andric   return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
768f8af5cf6SDimitry Andric }
769009b1c42SEd Schouten 
getIndexSize(unsigned AS) const770eb11fae6SDimitry Andric unsigned DataLayout::getIndexSize(unsigned AS) const {
77177fc4c14SDimitry Andric   return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8);
772eb11fae6SDimitry Andric }
773eb11fae6SDimitry Andric 
getIndexTypeSizeInBits(Type * Ty) const774eb11fae6SDimitry Andric unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
775eb11fae6SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
776eb11fae6SDimitry Andric          "This should only be called with a pointer or pointer vector type");
777eb11fae6SDimitry Andric   Ty = Ty->getScalarType();
778eb11fae6SDimitry Andric   return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
779eb11fae6SDimitry Andric }
780eb11fae6SDimitry Andric 
781009b1c42SEd Schouten /*!
782009b1c42SEd Schouten   \param abi_or_pref Flag that determines which alignment is returned. true
783009b1c42SEd Schouten   returns the ABI alignment, false returns the preferred alignment.
784009b1c42SEd Schouten   \param Ty The underlying type for which alignment is determined.
785009b1c42SEd Schouten 
786009b1c42SEd Schouten   Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
787009b1c42SEd Schouten   == false) for the requested type \a Ty.
788009b1c42SEd Schouten  */
getAlignment(Type * Ty,bool abi_or_pref) const7891d5ae102SDimitry Andric Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
790009b1c42SEd Schouten   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
791009b1c42SEd Schouten   switch (Ty->getTypeID()) {
792009b1c42SEd Schouten   // Early escape for the non-numeric types.
793009b1c42SEd Schouten   case Type::LabelTyID:
7941d5ae102SDimitry Andric     return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0);
795522600a2SDimitry Andric   case Type::PointerTyID: {
79667c32a98SDimitry Andric     unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
7971d5ae102SDimitry Andric     return abi_or_pref ? getPointerABIAlignment(AS)
7981d5ae102SDimitry Andric                        : getPointerPrefAlignment(AS);
799522600a2SDimitry Andric     }
800009b1c42SEd Schouten   case Type::ArrayTyID:
801009b1c42SEd Schouten     return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
802009b1c42SEd Schouten 
803009b1c42SEd Schouten   case Type::StructTyID: {
804009b1c42SEd Schouten     // Packed structure types always have an ABI alignment of one.
805009b1c42SEd Schouten     if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
806cfca06d7SDimitry Andric       return Align(1);
807009b1c42SEd Schouten 
808009b1c42SEd Schouten     // Get the layout annotation... which is lazily created on demand.
809009b1c42SEd Schouten     const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
810b60736ecSDimitry Andric     const Align Align =
8117fa27ce4SDimitry Andric         abi_or_pref ? StructAlignment.ABIAlign : StructAlignment.PrefAlign;
812d39c594dSDimitry Andric     return std::max(Align, Layout->getAlignment());
8132f12f10aSRoman Divacky   }
814009b1c42SEd Schouten   case Type::IntegerTyID:
815b60736ecSDimitry Andric     return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
81663faed5bSDimitry Andric   case Type::HalfTyID:
817cfca06d7SDimitry Andric   case Type::BFloatTyID:
818009b1c42SEd Schouten   case Type::FloatTyID:
819009b1c42SEd Schouten   case Type::DoubleTyID:
820009b1c42SEd Schouten   // PPC_FP128TyID and FP128TyID have different data contents, but the
821009b1c42SEd Schouten   // same size and alignment, so they look the same here.
822009b1c42SEd Schouten   case Type::PPC_FP128TyID:
823009b1c42SEd Schouten   case Type::FP128TyID:
824b60736ecSDimitry Andric   case Type::X86_FP80TyID: {
825e3b55780SDimitry Andric     unsigned BitWidth = getTypeSizeInBits(Ty).getFixedValue();
8267fa27ce4SDimitry Andric     auto I = findAlignmentLowerBound(FloatAlignments, BitWidth);
8277fa27ce4SDimitry Andric     if (I != FloatAlignments.end() && I->TypeBitWidth == BitWidth)
828b60736ecSDimitry Andric       return abi_or_pref ? I->ABIAlign : I->PrefAlign;
829b60736ecSDimitry Andric 
830b60736ecSDimitry Andric     // If we still couldn't find a reasonable default alignment, fall back
831b60736ecSDimitry Andric     // to a simple heuristic that the alignment is the first power of two
832b60736ecSDimitry Andric     // greater-or-equal to the store size of the type.  This is a reasonable
833b60736ecSDimitry Andric     // approximation of reality, and if the user wanted something less
834b60736ecSDimitry Andric     // less conservative, they should have specified it explicitly in the data
835b60736ecSDimitry Andric     // layout.
836b60736ecSDimitry Andric     return Align(PowerOf2Ceil(BitWidth / 8));
837b60736ecSDimitry Andric   }
838cf099d11SDimitry Andric   case Type::X86_MMXTyID:
839cfca06d7SDimitry Andric   case Type::FixedVectorTyID:
840b60736ecSDimitry Andric   case Type::ScalableVectorTyID: {
841e3b55780SDimitry Andric     unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinValue();
8427fa27ce4SDimitry Andric     auto I = findAlignmentLowerBound(VectorAlignments, BitWidth);
8437fa27ce4SDimitry Andric     if (I != VectorAlignments.end() && I->TypeBitWidth == BitWidth)
844b60736ecSDimitry Andric       return abi_or_pref ? I->ABIAlign : I->PrefAlign;
845b60736ecSDimitry Andric 
846b60736ecSDimitry Andric     // By default, use natural alignment for vector types. This is consistent
847b60736ecSDimitry Andric     // with what clang and llvm-gcc do.
848c0981da4SDimitry Andric     //
849b60736ecSDimitry Andric     // We're only calculating a natural alignment, so it doesn't have to be
850b60736ecSDimitry Andric     // based on the full size for scalable vectors. Using the minimum element
851b60736ecSDimitry Andric     // count should be enough here.
852e3b55780SDimitry Andric     return Align(PowerOf2Ceil(getTypeStoreSize(Ty).getKnownMinValue()));
853b60736ecSDimitry Andric   }
854b60736ecSDimitry Andric   case Type::X86_AMXTyID:
855b60736ecSDimitry Andric     return Align(64);
856e3b55780SDimitry Andric   case Type::TargetExtTyID: {
857e3b55780SDimitry Andric     Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
858e3b55780SDimitry Andric     return getAlignment(LayoutTy, abi_or_pref);
859e3b55780SDimitry Andric   }
860009b1c42SEd Schouten   default:
86159850d08SRoman Divacky     llvm_unreachable("Bad type for getAlignment!!!");
862009b1c42SEd Schouten   }
863009b1c42SEd Schouten }
864009b1c42SEd Schouten 
getABITypeAlign(Type * Ty) const865cfca06d7SDimitry Andric Align DataLayout::getABITypeAlign(Type *Ty) const {
866cfca06d7SDimitry Andric   return getAlignment(Ty, true);
867009b1c42SEd Schouten }
868009b1c42SEd Schouten 
869cfca06d7SDimitry Andric /// TODO: Remove this function once the transition to Align is over.
getPrefTypeAlignment(Type * Ty) const870c0981da4SDimitry Andric uint64_t DataLayout::getPrefTypeAlignment(Type *Ty) const {
871cfca06d7SDimitry Andric   return getPrefTypeAlign(Ty).value();
872cfca06d7SDimitry Andric }
873cfca06d7SDimitry Andric 
getPrefTypeAlign(Type * Ty) const874cfca06d7SDimitry Andric Align DataLayout::getPrefTypeAlign(Type *Ty) const {
875cfca06d7SDimitry Andric   return getAlignment(Ty, false);
876009b1c42SEd Schouten }
877009b1c42SEd Schouten 
getIntPtrType(LLVMContext & C,unsigned AddressSpace) const878522600a2SDimitry Andric IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
879522600a2SDimitry Andric                                        unsigned AddressSpace) const {
880706b4fc4SDimitry Andric   return IntegerType::get(C, getPointerSizeInBits(AddressSpace));
881009b1c42SEd Schouten }
882009b1c42SEd Schouten 
getIntPtrType(Type * Ty) const883522600a2SDimitry Andric Type *DataLayout::getIntPtrType(Type *Ty) const {
884522600a2SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
885522600a2SDimitry Andric          "Expected a pointer or pointer vector type.");
886706b4fc4SDimitry Andric   unsigned NumBits = getPointerTypeSizeInBits(Ty);
887522600a2SDimitry Andric   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
888522600a2SDimitry Andric   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
889cfca06d7SDimitry Andric     return VectorType::get(IntTy, VecTy);
890522600a2SDimitry Andric   return IntTy;
891522600a2SDimitry Andric }
892009b1c42SEd Schouten 
getSmallestLegalIntType(LLVMContext & C,unsigned Width) const8934a16efa3SDimitry Andric Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
8945ca98fd9SDimitry Andric   for (unsigned LegalIntWidth : LegalIntWidths)
8955ca98fd9SDimitry Andric     if (Width <= LegalIntWidth)
8965ca98fd9SDimitry Andric       return Type::getIntNTy(C, LegalIntWidth);
8975ca98fd9SDimitry Andric   return nullptr;
8984a16efa3SDimitry Andric }
8994a16efa3SDimitry Andric 
getLargestLegalIntTypeSizeInBits() const90001095a5dSDimitry Andric unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const {
901ac9a064cSDimitry Andric   auto Max = llvm::max_element(LegalIntWidths);
9025ca98fd9SDimitry Andric   return Max != LegalIntWidths.end() ? *Max : 0;
903f8af5cf6SDimitry Andric }
904f8af5cf6SDimitry Andric 
getIndexType(LLVMContext & C,unsigned AddressSpace) const9057fa27ce4SDimitry Andric IntegerType *DataLayout::getIndexType(LLVMContext &C,
9067fa27ce4SDimitry Andric                                       unsigned AddressSpace) const {
9077fa27ce4SDimitry Andric   return IntegerType::get(C, getIndexSizeInBits(AddressSpace));
9087fa27ce4SDimitry Andric }
9097fa27ce4SDimitry Andric 
getIndexType(Type * Ty) const910eb11fae6SDimitry Andric Type *DataLayout::getIndexType(Type *Ty) const {
911eb11fae6SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
912eb11fae6SDimitry Andric          "Expected a pointer or pointer vector type.");
913eb11fae6SDimitry Andric   unsigned NumBits = getIndexTypeSizeInBits(Ty);
914eb11fae6SDimitry Andric   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
915eb11fae6SDimitry Andric   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
916cfca06d7SDimitry Andric     return VectorType::get(IntTy, VecTy);
917eb11fae6SDimitry Andric   return IntTy;
918eb11fae6SDimitry Andric }
919eb11fae6SDimitry Andric 
getIndexedOffsetInType(Type * ElemTy,ArrayRef<Value * > Indices) const92001095a5dSDimitry Andric int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
92130815c53SDimitry Andric                                            ArrayRef<Value *> Indices) const {
92201095a5dSDimitry Andric   int64_t Result = 0;
923009b1c42SEd Schouten 
924009b1c42SEd Schouten   generic_gep_type_iterator<Value* const*>
925b915e9e0SDimitry Andric     GTI = gep_type_begin(ElemTy, Indices),
926b915e9e0SDimitry Andric     GTE = gep_type_end(ElemTy, Indices);
92701095a5dSDimitry Andric   for (; GTI != GTE; ++GTI) {
92801095a5dSDimitry Andric     Value *Idx = GTI.getOperand();
929b915e9e0SDimitry Andric     if (StructType *STy = GTI.getStructTypeOrNull()) {
93001095a5dSDimitry Andric       assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
93101095a5dSDimitry Andric       unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();
932009b1c42SEd Schouten 
933009b1c42SEd Schouten       // Get structure layout information...
934009b1c42SEd Schouten       const StructLayout *Layout = getStructLayout(STy);
935009b1c42SEd Schouten 
936009b1c42SEd Schouten       // Add in the offset, as calculated by the structure layout info...
937009b1c42SEd Schouten       Result += Layout->getElementOffset(FieldNo);
938009b1c42SEd Schouten     } else {
939aca2e42cSDimitry Andric       if (int64_t ArrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
940aca2e42cSDimitry Andric         Result += ArrayIdx * GTI.getSequentialElementStride(*this);
941009b1c42SEd Schouten     }
942009b1c42SEd Schouten   }
943009b1c42SEd Schouten 
944009b1c42SEd Schouten   return Result;
945009b1c42SEd Schouten }
946009b1c42SEd Schouten 
getElementIndex(TypeSize ElemSize,APInt & Offset)94777fc4c14SDimitry Andric static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
948c0981da4SDimitry Andric   // Skip over scalable or zero size elements. Also skip element sizes larger
949c0981da4SDimitry Andric   // than the positive index space, because the arithmetic below may not be
950c0981da4SDimitry Andric   // correct in that case.
951c0981da4SDimitry Andric   unsigned BitWidth = Offset.getBitWidth();
952c0981da4SDimitry Andric   if (ElemSize.isScalable() || ElemSize == 0 ||
953c0981da4SDimitry Andric       !isUIntN(BitWidth - 1, ElemSize)) {
95477fc4c14SDimitry Andric     return APInt::getZero(BitWidth);
955c0981da4SDimitry Andric   }
956c0981da4SDimitry Andric 
957c0981da4SDimitry Andric   APInt Index = Offset.sdiv(ElemSize);
958c0981da4SDimitry Andric   Offset -= Index * ElemSize;
959c0981da4SDimitry Andric   if (Offset.isNegative()) {
960c0981da4SDimitry Andric     // Prefer a positive remaining offset to allow struct indexing.
961c0981da4SDimitry Andric     --Index;
962c0981da4SDimitry Andric     Offset += ElemSize;
963c0981da4SDimitry Andric     assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
964c0981da4SDimitry Andric   }
96577fc4c14SDimitry Andric   return Index;
966c0981da4SDimitry Andric }
967c0981da4SDimitry Andric 
getGEPIndexForOffset(Type * & ElemTy,APInt & Offset) const968e3b55780SDimitry Andric std::optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,
969c0981da4SDimitry Andric                                                       APInt &Offset) const {
970c0981da4SDimitry Andric   if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
971c0981da4SDimitry Andric     ElemTy = ArrTy->getElementType();
97277fc4c14SDimitry Andric     return getElementIndex(getTypeAllocSize(ElemTy), Offset);
973c0981da4SDimitry Andric   }
974c0981da4SDimitry Andric 
975e3b55780SDimitry Andric   if (isa<VectorType>(ElemTy)) {
976e3b55780SDimitry Andric     // Vector GEPs are partially broken (e.g. for overaligned element types),
977e3b55780SDimitry Andric     // and may be forbidden in the future, so avoid generating GEPs into
978e3b55780SDimitry Andric     // vectors. See https://discourse.llvm.org/t/67497
979e3b55780SDimitry Andric     return std::nullopt;
980c0981da4SDimitry Andric   }
981c0981da4SDimitry Andric 
982c0981da4SDimitry Andric   if (auto *STy = dyn_cast<StructType>(ElemTy)) {
983c0981da4SDimitry Andric     const StructLayout *SL = getStructLayout(STy);
984c0981da4SDimitry Andric     uint64_t IntOffset = Offset.getZExtValue();
985c0981da4SDimitry Andric     if (IntOffset >= SL->getSizeInBytes())
986e3b55780SDimitry Andric       return std::nullopt;
987c0981da4SDimitry Andric 
988c0981da4SDimitry Andric     unsigned Index = SL->getElementContainingOffset(IntOffset);
989c0981da4SDimitry Andric     Offset -= SL->getElementOffset(Index);
990c0981da4SDimitry Andric     ElemTy = STy->getElementType(Index);
99177fc4c14SDimitry Andric     return APInt(32, Index);
992c0981da4SDimitry Andric   }
993c0981da4SDimitry Andric 
99477fc4c14SDimitry Andric   // Non-aggregate type.
995e3b55780SDimitry Andric   return std::nullopt;
99677fc4c14SDimitry Andric }
99777fc4c14SDimitry Andric 
getGEPIndicesForOffset(Type * & ElemTy,APInt & Offset) const99877fc4c14SDimitry Andric SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
99977fc4c14SDimitry Andric                                                       APInt &Offset) const {
100077fc4c14SDimitry Andric   assert(ElemTy->isSized() && "Element type must be sized");
100177fc4c14SDimitry Andric   SmallVector<APInt> Indices;
100277fc4c14SDimitry Andric   Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));
100377fc4c14SDimitry Andric   while (Offset != 0) {
1004e3b55780SDimitry Andric     std::optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);
100577fc4c14SDimitry Andric     if (!Index)
1006c0981da4SDimitry Andric       break;
100777fc4c14SDimitry Andric     Indices.push_back(*Index);
1008c0981da4SDimitry Andric   }
1009c0981da4SDimitry Andric 
1010c0981da4SDimitry Andric   return Indices;
1011c0981da4SDimitry Andric }
1012c0981da4SDimitry Andric 
1013cfca06d7SDimitry Andric /// getPreferredAlign - Return the preferred alignment of the specified global.
1014cfca06d7SDimitry Andric /// This includes an explicitly requested alignment (if the global has one).
getPreferredAlign(const GlobalVariable * GV) const1015cfca06d7SDimitry Andric Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
1016cfca06d7SDimitry Andric   MaybeAlign GVAlignment = GV->getAlign();
1017d8e91e46SDimitry Andric   // If a section is specified, always precisely honor explicit alignment,
1018d8e91e46SDimitry Andric   // so we don't insert padding into a section we don't control.
1019d8e91e46SDimitry Andric   if (GVAlignment && GV->hasSection())
1020cfca06d7SDimitry Andric     return *GVAlignment;
1021d8e91e46SDimitry Andric 
1022d8e91e46SDimitry Andric   // If no explicit alignment is specified, compute the alignment based on
1023d8e91e46SDimitry Andric   // the IR type. If an alignment is specified, increase it to match the ABI
1024d8e91e46SDimitry Andric   // alignment of the IR type.
1025d8e91e46SDimitry Andric   //
1026d8e91e46SDimitry Andric   // FIXME: Not sure it makes sense to use the alignment of the type if
1027d8e91e46SDimitry Andric   // there's already an explicit alignment specification.
102801095a5dSDimitry Andric   Type *ElemType = GV->getValueType();
1029cfca06d7SDimitry Andric   Align Alignment = getPrefTypeAlign(ElemType);
1030cfca06d7SDimitry Andric   if (GVAlignment) {
1031cfca06d7SDimitry Andric     if (*GVAlignment >= Alignment)
1032cfca06d7SDimitry Andric       Alignment = *GVAlignment;
1033cfca06d7SDimitry Andric     else
1034cfca06d7SDimitry Andric       Alignment = std::max(*GVAlignment, getABITypeAlign(ElemType));
10356b943ff3SDimitry Andric   }
1036009b1c42SEd Schouten 
1037d8e91e46SDimitry Andric   // If no explicit alignment is specified, and the global is large, increase
1038d8e91e46SDimitry Andric   // the alignment to 16.
1039d8e91e46SDimitry Andric   // FIXME: Why 16, specifically?
1040cfca06d7SDimitry Andric   if (GV->hasInitializer() && !GVAlignment) {
1041cfca06d7SDimitry Andric     if (Alignment < Align(16)) {
1042009b1c42SEd Schouten       // If the global is not external, see if it is large.  If so, give it a
1043009b1c42SEd Schouten       // larger alignment.
1044009b1c42SEd Schouten       if (getTypeSizeInBits(ElemType) > 128)
1045cfca06d7SDimitry Andric         Alignment = Align(16); // 16-byte alignment.
1046009b1c42SEd Schouten     }
1047009b1c42SEd Schouten   }
1048009b1c42SEd Schouten   return Alignment;
1049009b1c42SEd Schouten }
1050