10f5676f4SDimitry Andric //===- DataLayout.cpp - Data size & alignment routines ---------------------==//
2139f7f9bSDimitry Andric //
3139f7f9bSDimitry Andric //                     The LLVM Compiler Infrastructure
4139f7f9bSDimitry Andric //
5139f7f9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
6139f7f9bSDimitry Andric // License. See LICENSE.TXT for details.
7139f7f9bSDimitry Andric //
8139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
9139f7f9bSDimitry Andric //
10139f7f9bSDimitry Andric // This file defines layout properties related to datatype size/offset/alignment
11139f7f9bSDimitry Andric // information.
12139f7f9bSDimitry Andric //
13139f7f9bSDimitry Andric // This structure should be created once, filled in if the defaults are not
14139f7f9bSDimitry Andric // correct and then passed around by const&.  None of the members functions
15139f7f9bSDimitry Andric // require modification to the object.
16139f7f9bSDimitry Andric //
17139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
18139f7f9bSDimitry Andric 
19db17bf38SDimitry Andric #include "llvm/IR/DataLayout.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/DenseMap.h"
210f5676f4SDimitry Andric #include "llvm/ADT/StringRef.h"
2291bc56edSDimitry Andric #include "llvm/ADT/Triple.h"
23139f7f9bSDimitry Andric #include "llvm/IR/Constants.h"
24139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
2591bc56edSDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h"
260f5676f4SDimitry Andric #include "llvm/IR/GlobalVariable.h"
27139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
280f5676f4SDimitry Andric #include "llvm/IR/Type.h"
290f5676f4SDimitry Andric #include "llvm/IR/Value.h"
300f5676f4SDimitry Andric #include "llvm/Support/Casting.h"
31139f7f9bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
32139f7f9bSDimitry Andric #include "llvm/Support/MathExtras.h"
33139f7f9bSDimitry Andric #include <algorithm>
340f5676f4SDimitry Andric #include <cassert>
350f5676f4SDimitry Andric #include <cstdint>
36139f7f9bSDimitry Andric #include <cstdlib>
370f5676f4SDimitry Andric #include <tuple>
380f5676f4SDimitry Andric #include <utility>
390f5676f4SDimitry Andric 
40139f7f9bSDimitry Andric using namespace llvm;
41139f7f9bSDimitry Andric 
42139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
43139f7f9bSDimitry Andric // Support for StructLayout
44139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
45139f7f9bSDimitry Andric 
StructLayout(StructType * ST,const DataLayout & DL)46284c1978SDimitry Andric StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
47139f7f9bSDimitry Andric   assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
48139f7f9bSDimitry Andric   StructAlignment = 0;
49139f7f9bSDimitry Andric   StructSize = 0;
507d523365SDimitry Andric   IsPadded = false;
51139f7f9bSDimitry Andric   NumElements = ST->getNumElements();
52139f7f9bSDimitry Andric 
53139f7f9bSDimitry Andric   // Loop over each of the elements, placing them in memory.
54139f7f9bSDimitry Andric   for (unsigned i = 0, e = NumElements; i != e; ++i) {
55139f7f9bSDimitry Andric     Type *Ty = ST->getElementType(i);
56284c1978SDimitry Andric     unsigned TyAlign = ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty);
57139f7f9bSDimitry Andric 
58139f7f9bSDimitry Andric     // Add padding if necessary to align the data element properly.
597d523365SDimitry Andric     if ((StructSize & (TyAlign-1)) != 0) {
607d523365SDimitry Andric       IsPadded = true;
613ca95b02SDimitry Andric       StructSize = alignTo(StructSize, TyAlign);
627d523365SDimitry Andric     }
63139f7f9bSDimitry Andric 
64139f7f9bSDimitry Andric     // Keep track of maximum alignment constraint.
65139f7f9bSDimitry Andric     StructAlignment = std::max(TyAlign, StructAlignment);
66139f7f9bSDimitry Andric 
67139f7f9bSDimitry Andric     MemberOffsets[i] = StructSize;
68284c1978SDimitry Andric     StructSize += DL.getTypeAllocSize(Ty); // Consume space for this data item
69139f7f9bSDimitry Andric   }
70139f7f9bSDimitry Andric 
71139f7f9bSDimitry Andric   // Empty structures have alignment of 1 byte.
72139f7f9bSDimitry Andric   if (StructAlignment == 0) StructAlignment = 1;
73139f7f9bSDimitry Andric 
74139f7f9bSDimitry Andric   // Add padding to the end of the struct so that it could be put in an array
75139f7f9bSDimitry Andric   // and all array elements would be aligned correctly.
767d523365SDimitry Andric   if ((StructSize & (StructAlignment-1)) != 0) {
777d523365SDimitry Andric     IsPadded = true;
783ca95b02SDimitry Andric     StructSize = alignTo(StructSize, StructAlignment);
79139f7f9bSDimitry Andric   }
807d523365SDimitry Andric }
81139f7f9bSDimitry Andric 
82139f7f9bSDimitry Andric /// getElementContainingOffset - Given a valid offset into the structure,
83139f7f9bSDimitry Andric /// return the structure index that contains it.
getElementContainingOffset(uint64_t Offset) const84139f7f9bSDimitry Andric unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
85139f7f9bSDimitry Andric   const uint64_t *SI =
86139f7f9bSDimitry Andric     std::upper_bound(&MemberOffsets[0], &MemberOffsets[NumElements], Offset);
87139f7f9bSDimitry Andric   assert(SI != &MemberOffsets[0] && "Offset not in structure type!");
88139f7f9bSDimitry Andric   --SI;
89139f7f9bSDimitry Andric   assert(*SI <= Offset && "upper_bound didn't work");
90139f7f9bSDimitry Andric   assert((SI == &MemberOffsets[0] || *(SI-1) <= Offset) &&
91139f7f9bSDimitry Andric          (SI+1 == &MemberOffsets[NumElements] || *(SI+1) > Offset) &&
92139f7f9bSDimitry Andric          "Upper bound didn't work!");
93139f7f9bSDimitry Andric 
94139f7f9bSDimitry Andric   // Multiple fields can have the same offset if any of them are zero sized.
95139f7f9bSDimitry Andric   // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop
96139f7f9bSDimitry Andric   // at the i32 element, because it is the last element at that offset.  This is
97139f7f9bSDimitry Andric   // the right one to return, because anything after it will have a higher
98139f7f9bSDimitry Andric   // offset, implying that this element is non-empty.
99139f7f9bSDimitry Andric   return SI-&MemberOffsets[0];
100139f7f9bSDimitry Andric }
101139f7f9bSDimitry Andric 
102139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
103139f7f9bSDimitry Andric // LayoutAlignElem, LayoutAlign support
104139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
105139f7f9bSDimitry Andric 
106139f7f9bSDimitry Andric LayoutAlignElem
get(AlignTypeEnum align_type,unsigned abi_align,unsigned pref_align,uint32_t bit_width)107139f7f9bSDimitry Andric LayoutAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
108139f7f9bSDimitry Andric                      unsigned pref_align, uint32_t bit_width) {
109139f7f9bSDimitry Andric   assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
110139f7f9bSDimitry Andric   LayoutAlignElem retval;
111139f7f9bSDimitry Andric   retval.AlignType = align_type;
112139f7f9bSDimitry Andric   retval.ABIAlign = abi_align;
113139f7f9bSDimitry Andric   retval.PrefAlign = pref_align;
114139f7f9bSDimitry Andric   retval.TypeBitWidth = bit_width;
115139f7f9bSDimitry Andric   return retval;
116139f7f9bSDimitry Andric }
117139f7f9bSDimitry Andric 
118139f7f9bSDimitry Andric bool
operator ==(const LayoutAlignElem & rhs) const119139f7f9bSDimitry Andric LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
120139f7f9bSDimitry Andric   return (AlignType == rhs.AlignType
121139f7f9bSDimitry Andric           && ABIAlign == rhs.ABIAlign
122139f7f9bSDimitry Andric           && PrefAlign == rhs.PrefAlign
123139f7f9bSDimitry Andric           && TypeBitWidth == rhs.TypeBitWidth);
124139f7f9bSDimitry Andric }
125139f7f9bSDimitry Andric 
126139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
127139f7f9bSDimitry Andric // PointerAlignElem, PointerAlign support
128139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
129139f7f9bSDimitry Andric 
130139f7f9bSDimitry Andric PointerAlignElem
get(uint32_t AddressSpace,unsigned ABIAlign,unsigned PrefAlign,uint32_t TypeByteWidth,uint32_t IndexWidth)13191bc56edSDimitry Andric PointerAlignElem::get(uint32_t AddressSpace, unsigned ABIAlign,
1324ba319b5SDimitry Andric                       unsigned PrefAlign, uint32_t TypeByteWidth,
1334ba319b5SDimitry Andric                       uint32_t IndexWidth) {
13491bc56edSDimitry Andric   assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
135139f7f9bSDimitry Andric   PointerAlignElem retval;
13691bc56edSDimitry Andric   retval.AddressSpace = AddressSpace;
13791bc56edSDimitry Andric   retval.ABIAlign = ABIAlign;
13891bc56edSDimitry Andric   retval.PrefAlign = PrefAlign;
13991bc56edSDimitry Andric   retval.TypeByteWidth = TypeByteWidth;
1404ba319b5SDimitry Andric   retval.IndexWidth = IndexWidth;
141139f7f9bSDimitry Andric   return retval;
142139f7f9bSDimitry Andric }
143139f7f9bSDimitry Andric 
144139f7f9bSDimitry Andric bool
operator ==(const PointerAlignElem & rhs) const145139f7f9bSDimitry Andric PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
146139f7f9bSDimitry Andric   return (ABIAlign == rhs.ABIAlign
147139f7f9bSDimitry Andric           && AddressSpace == rhs.AddressSpace
148139f7f9bSDimitry Andric           && PrefAlign == rhs.PrefAlign
1494ba319b5SDimitry Andric           && TypeByteWidth == rhs.TypeByteWidth
1504ba319b5SDimitry Andric           && IndexWidth == rhs.IndexWidth);
151139f7f9bSDimitry Andric }
152139f7f9bSDimitry Andric 
153139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
154139f7f9bSDimitry Andric //                       DataLayout Class Implementation
155139f7f9bSDimitry Andric //===----------------------------------------------------------------------===//
156139f7f9bSDimitry Andric 
getManglingComponent(const Triple & T)15791bc56edSDimitry Andric const char *DataLayout::getManglingComponent(const Triple &T) {
15891bc56edSDimitry Andric   if (T.isOSBinFormatMachO())
15991bc56edSDimitry Andric     return "-m:o";
160ff0cc061SDimitry Andric   if (T.isOSWindows() && T.isOSBinFormatCOFF())
161ff0cc061SDimitry Andric     return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";
16291bc56edSDimitry Andric   return "-m:e";
16391bc56edSDimitry Andric }
164139f7f9bSDimitry Andric 
16591bc56edSDimitry Andric static const LayoutAlignElem DefaultAlignments[] = {
16691bc56edSDimitry Andric   { INTEGER_ALIGN, 1, 1, 1 },    // i1
16791bc56edSDimitry Andric   { INTEGER_ALIGN, 8, 1, 1 },    // i8
16891bc56edSDimitry Andric   { INTEGER_ALIGN, 16, 2, 2 },   // i16
16991bc56edSDimitry Andric   { INTEGER_ALIGN, 32, 4, 4 },   // i32
17091bc56edSDimitry Andric   { INTEGER_ALIGN, 64, 4, 8 },   // i64
17191bc56edSDimitry Andric   { FLOAT_ALIGN, 16, 2, 2 },     // half
17291bc56edSDimitry Andric   { FLOAT_ALIGN, 32, 4, 4 },     // float
17391bc56edSDimitry Andric   { FLOAT_ALIGN, 64, 8, 8 },     // double
17491bc56edSDimitry Andric   { FLOAT_ALIGN, 128, 16, 16 },  // ppcf128, quad, ...
17591bc56edSDimitry Andric   { VECTOR_ALIGN, 64, 8, 8 },    // v2i32, v1i64, ...
17691bc56edSDimitry Andric   { VECTOR_ALIGN, 128, 16, 16 }, // v16i8, v8i16, v4i32, ...
17791bc56edSDimitry Andric   { AGGREGATE_ALIGN, 0, 0, 8 }   // struct
17891bc56edSDimitry Andric };
17991bc56edSDimitry Andric 
reset(StringRef Desc)18091bc56edSDimitry Andric void DataLayout::reset(StringRef Desc) {
18191bc56edSDimitry Andric   clear();
18291bc56edSDimitry Andric 
18391bc56edSDimitry Andric   LayoutMap = nullptr;
18439d628a0SDimitry Andric   BigEndian = false;
1857a7e6055SDimitry Andric   AllocaAddrSpace = 0;
186139f7f9bSDimitry Andric   StackNaturalAlign = 0;
1874ba319b5SDimitry Andric   ProgramAddrSpace = 0;
18891bc56edSDimitry Andric   ManglingMode = MM_None;
189d88c1a5aSDimitry Andric   NonIntegralAddressSpaces.clear();
190139f7f9bSDimitry Andric 
191139f7f9bSDimitry Andric   // Default alignments
19291bc56edSDimitry Andric   for (const LayoutAlignElem &E : DefaultAlignments) {
19391bc56edSDimitry Andric     setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
19491bc56edSDimitry Andric                  E.TypeBitWidth);
19591bc56edSDimitry Andric   }
1964ba319b5SDimitry Andric   setPointerAlignment(0, 8, 8, 8, 8);
197139f7f9bSDimitry Andric 
198139f7f9bSDimitry Andric   parseSpecifier(Desc);
199139f7f9bSDimitry Andric }
200139f7f9bSDimitry Andric 
201139f7f9bSDimitry Andric /// Checked version of split, to ensure mandatory subparts.
split(StringRef Str,char Separator)202139f7f9bSDimitry Andric static std::pair<StringRef, StringRef> split(StringRef Str, char Separator) {
203139f7f9bSDimitry Andric   assert(!Str.empty() && "parse error, string can't be empty here");
204139f7f9bSDimitry Andric   std::pair<StringRef, StringRef> Split = Str.split(Separator);
20539d628a0SDimitry Andric   if (Split.second.empty() && Split.first != Str)
20639d628a0SDimitry Andric     report_fatal_error("Trailing separator in datalayout string");
20739d628a0SDimitry Andric   if (!Split.second.empty() && Split.first.empty())
20839d628a0SDimitry Andric     report_fatal_error("Expected token before separator in datalayout string");
209139f7f9bSDimitry Andric   return Split;
210139f7f9bSDimitry Andric }
211139f7f9bSDimitry Andric 
21291bc56edSDimitry Andric /// Get an unsigned integer, including error checks.
getInt(StringRef R)213139f7f9bSDimitry Andric static unsigned getInt(StringRef R) {
214139f7f9bSDimitry Andric   unsigned Result;
215139f7f9bSDimitry Andric   bool error = R.getAsInteger(10, Result); (void)error;
21691bc56edSDimitry Andric   if (error)
21791bc56edSDimitry Andric     report_fatal_error("not a number, or does not fit in an unsigned int");
218139f7f9bSDimitry Andric   return Result;
219139f7f9bSDimitry Andric }
220139f7f9bSDimitry Andric 
221139f7f9bSDimitry Andric /// Convert bits into bytes. Assert if not a byte width multiple.
inBytes(unsigned Bits)222139f7f9bSDimitry Andric static unsigned inBytes(unsigned Bits) {
22339d628a0SDimitry Andric   if (Bits % 8)
22439d628a0SDimitry Andric     report_fatal_error("number of bits must be a byte width multiple");
225139f7f9bSDimitry Andric   return Bits / 8;
226139f7f9bSDimitry Andric }
227139f7f9bSDimitry Andric 
getAddrSpace(StringRef R)2284ba319b5SDimitry Andric static unsigned getAddrSpace(StringRef R) {
2294ba319b5SDimitry Andric   unsigned AddrSpace = getInt(R);
2304ba319b5SDimitry Andric   if (!isUInt<24>(AddrSpace))
2314ba319b5SDimitry Andric     report_fatal_error("Invalid address space, must be a 24-bit integer");
2324ba319b5SDimitry Andric   return AddrSpace;
2334ba319b5SDimitry Andric }
2344ba319b5SDimitry Andric 
parseSpecifier(StringRef Desc)235139f7f9bSDimitry Andric void DataLayout::parseSpecifier(StringRef Desc) {
236ff0cc061SDimitry Andric   StringRepresentation = Desc;
237139f7f9bSDimitry Andric   while (!Desc.empty()) {
238139f7f9bSDimitry Andric     // Split at '-'.
239139f7f9bSDimitry Andric     std::pair<StringRef, StringRef> Split = split(Desc, '-');
240139f7f9bSDimitry Andric     Desc = Split.second;
241139f7f9bSDimitry Andric 
242139f7f9bSDimitry Andric     // Split at ':'.
243139f7f9bSDimitry Andric     Split = split(Split.first, ':');
244139f7f9bSDimitry Andric 
245139f7f9bSDimitry Andric     // Aliases used below.
246139f7f9bSDimitry Andric     StringRef &Tok  = Split.first;  // Current token.
247139f7f9bSDimitry Andric     StringRef &Rest = Split.second; // The rest of the string.
248139f7f9bSDimitry Andric 
249d88c1a5aSDimitry Andric     if (Tok == "ni") {
250d88c1a5aSDimitry Andric       do {
251d88c1a5aSDimitry Andric         Split = split(Rest, ':');
252d88c1a5aSDimitry Andric         Rest = Split.second;
253d88c1a5aSDimitry Andric         unsigned AS = getInt(Split.first);
254d88c1a5aSDimitry Andric         if (AS == 0)
255d88c1a5aSDimitry Andric           report_fatal_error("Address space 0 can never be non-integral");
256d88c1a5aSDimitry Andric         NonIntegralAddressSpaces.push_back(AS);
257d88c1a5aSDimitry Andric       } while (!Rest.empty());
258d88c1a5aSDimitry Andric 
259d88c1a5aSDimitry Andric       continue;
260d88c1a5aSDimitry Andric     }
261d88c1a5aSDimitry Andric 
262139f7f9bSDimitry Andric     char Specifier = Tok.front();
263139f7f9bSDimitry Andric     Tok = Tok.substr(1);
264139f7f9bSDimitry Andric 
265139f7f9bSDimitry Andric     switch (Specifier) {
26691bc56edSDimitry Andric     case 's':
26791bc56edSDimitry Andric       // Ignored for backward compatibility.
26891bc56edSDimitry Andric       // FIXME: remove this on LLVM 4.0.
26991bc56edSDimitry Andric       break;
270139f7f9bSDimitry Andric     case 'E':
27139d628a0SDimitry Andric       BigEndian = true;
272139f7f9bSDimitry Andric       break;
273139f7f9bSDimitry Andric     case 'e':
27439d628a0SDimitry Andric       BigEndian = false;
275139f7f9bSDimitry Andric       break;
276139f7f9bSDimitry Andric     case 'p': {
277139f7f9bSDimitry Andric       // Address space.
278139f7f9bSDimitry Andric       unsigned AddrSpace = Tok.empty() ? 0 : getInt(Tok);
27939d628a0SDimitry Andric       if (!isUInt<24>(AddrSpace))
28039d628a0SDimitry Andric         report_fatal_error("Invalid address space, must be a 24bit integer");
281139f7f9bSDimitry Andric 
282139f7f9bSDimitry Andric       // Size.
28339d628a0SDimitry Andric       if (Rest.empty())
28439d628a0SDimitry Andric         report_fatal_error(
28539d628a0SDimitry Andric             "Missing size specification for pointer in datalayout string");
286139f7f9bSDimitry Andric       Split = split(Rest, ':');
287139f7f9bSDimitry Andric       unsigned PointerMemSize = inBytes(getInt(Tok));
288ff0cc061SDimitry Andric       if (!PointerMemSize)
289ff0cc061SDimitry Andric         report_fatal_error("Invalid pointer size of 0 bytes");
290139f7f9bSDimitry Andric 
291139f7f9bSDimitry Andric       // ABI alignment.
29239d628a0SDimitry Andric       if (Rest.empty())
29339d628a0SDimitry Andric         report_fatal_error(
29439d628a0SDimitry Andric             "Missing alignment specification for pointer in datalayout string");
295139f7f9bSDimitry Andric       Split = split(Rest, ':');
296139f7f9bSDimitry Andric       unsigned PointerABIAlign = inBytes(getInt(Tok));
297ff0cc061SDimitry Andric       if (!isPowerOf2_64(PointerABIAlign))
298ff0cc061SDimitry Andric         report_fatal_error(
299ff0cc061SDimitry Andric             "Pointer ABI alignment must be a power of 2");
300139f7f9bSDimitry Andric 
3014ba319b5SDimitry Andric       // Size of index used in GEP for address calculation.
3024ba319b5SDimitry Andric       // The parameter is optional. By default it is equal to size of pointer.
3034ba319b5SDimitry Andric       unsigned IndexSize = PointerMemSize;
3044ba319b5SDimitry Andric 
305139f7f9bSDimitry Andric       // Preferred alignment.
306139f7f9bSDimitry Andric       unsigned PointerPrefAlign = PointerABIAlign;
307139f7f9bSDimitry Andric       if (!Rest.empty()) {
308139f7f9bSDimitry Andric         Split = split(Rest, ':');
309139f7f9bSDimitry Andric         PointerPrefAlign = inBytes(getInt(Tok));
310ff0cc061SDimitry Andric         if (!isPowerOf2_64(PointerPrefAlign))
311ff0cc061SDimitry Andric           report_fatal_error(
312ff0cc061SDimitry Andric             "Pointer preferred alignment must be a power of 2");
313139f7f9bSDimitry Andric 
3144ba319b5SDimitry Andric         // Now read the index. It is the second optional parameter here.
3154ba319b5SDimitry Andric         if (!Rest.empty()) {
3164ba319b5SDimitry Andric           Split = split(Rest, ':');
3174ba319b5SDimitry Andric           IndexSize = inBytes(getInt(Tok));
3184ba319b5SDimitry Andric           if (!IndexSize)
3194ba319b5SDimitry Andric             report_fatal_error("Invalid index size of 0 bytes");
3204ba319b5SDimitry Andric         }
3214ba319b5SDimitry Andric       }
322139f7f9bSDimitry Andric       setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign,
3234ba319b5SDimitry Andric                           PointerMemSize, IndexSize);
324139f7f9bSDimitry Andric       break;
325139f7f9bSDimitry Andric     }
326139f7f9bSDimitry Andric     case 'i':
327139f7f9bSDimitry Andric     case 'v':
328139f7f9bSDimitry Andric     case 'f':
32991bc56edSDimitry Andric     case 'a': {
330139f7f9bSDimitry Andric       AlignTypeEnum AlignType;
331139f7f9bSDimitry Andric       switch (Specifier) {
332d8866befSDimitry Andric       default: llvm_unreachable("Unexpected specifier!");
333139f7f9bSDimitry Andric       case 'i': AlignType = INTEGER_ALIGN; break;
334139f7f9bSDimitry Andric       case 'v': AlignType = VECTOR_ALIGN; break;
335139f7f9bSDimitry Andric       case 'f': AlignType = FLOAT_ALIGN; break;
336139f7f9bSDimitry Andric       case 'a': AlignType = AGGREGATE_ALIGN; break;
337139f7f9bSDimitry Andric       }
338139f7f9bSDimitry Andric 
339139f7f9bSDimitry Andric       // Bit size.
340139f7f9bSDimitry Andric       unsigned Size = Tok.empty() ? 0 : getInt(Tok);
341139f7f9bSDimitry Andric 
34239d628a0SDimitry Andric       if (AlignType == AGGREGATE_ALIGN && Size != 0)
34339d628a0SDimitry Andric         report_fatal_error(
34439d628a0SDimitry Andric             "Sized aggregate specification in datalayout string");
34591bc56edSDimitry Andric 
346139f7f9bSDimitry Andric       // ABI alignment.
34739d628a0SDimitry Andric       if (Rest.empty())
34839d628a0SDimitry Andric         report_fatal_error(
34939d628a0SDimitry Andric             "Missing alignment specification in datalayout string");
350139f7f9bSDimitry Andric       Split = split(Rest, ':');
351139f7f9bSDimitry Andric       unsigned ABIAlign = inBytes(getInt(Tok));
352ff0cc061SDimitry Andric       if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
353ff0cc061SDimitry Andric         report_fatal_error(
354ff0cc061SDimitry Andric             "ABI alignment specification must be >0 for non-aggregate types");
355139f7f9bSDimitry Andric 
356139f7f9bSDimitry Andric       // Preferred alignment.
357139f7f9bSDimitry Andric       unsigned PrefAlign = ABIAlign;
358139f7f9bSDimitry Andric       if (!Rest.empty()) {
359139f7f9bSDimitry Andric         Split = split(Rest, ':');
360139f7f9bSDimitry Andric         PrefAlign = inBytes(getInt(Tok));
361139f7f9bSDimitry Andric       }
362139f7f9bSDimitry Andric 
363139f7f9bSDimitry Andric       setAlignment(AlignType, ABIAlign, PrefAlign, Size);
364139f7f9bSDimitry Andric 
365139f7f9bSDimitry Andric       break;
366139f7f9bSDimitry Andric     }
367139f7f9bSDimitry Andric     case 'n':  // Native integer types.
3680f5676f4SDimitry Andric       while (true) {
369139f7f9bSDimitry Andric         unsigned Width = getInt(Tok);
37039d628a0SDimitry Andric         if (Width == 0)
37139d628a0SDimitry Andric           report_fatal_error(
37239d628a0SDimitry Andric               "Zero width native integer type in datalayout string");
373139f7f9bSDimitry Andric         LegalIntWidths.push_back(Width);
374139f7f9bSDimitry Andric         if (Rest.empty())
375139f7f9bSDimitry Andric           break;
376139f7f9bSDimitry Andric         Split = split(Rest, ':');
377139f7f9bSDimitry Andric       }
378139f7f9bSDimitry Andric       break;
379139f7f9bSDimitry Andric     case 'S': { // Stack natural alignment.
380139f7f9bSDimitry Andric       StackNaturalAlign = inBytes(getInt(Tok));
381139f7f9bSDimitry Andric       break;
382139f7f9bSDimitry Andric     }
3834ba319b5SDimitry Andric     case 'P': { // Function address space.
3844ba319b5SDimitry Andric       ProgramAddrSpace = getAddrSpace(Tok);
3854ba319b5SDimitry Andric       break;
3864ba319b5SDimitry Andric     }
3877a7e6055SDimitry Andric     case 'A': { // Default stack/alloca address space.
3884ba319b5SDimitry Andric       AllocaAddrSpace = getAddrSpace(Tok);
3897a7e6055SDimitry Andric       break;
3907a7e6055SDimitry Andric     }
39191bc56edSDimitry Andric     case 'm':
39239d628a0SDimitry Andric       if (!Tok.empty())
39339d628a0SDimitry Andric         report_fatal_error("Unexpected trailing characters after mangling specifier in datalayout string");
39439d628a0SDimitry Andric       if (Rest.empty())
39539d628a0SDimitry Andric         report_fatal_error("Expected mangling specifier in datalayout string");
39639d628a0SDimitry Andric       if (Rest.size() > 1)
39739d628a0SDimitry Andric         report_fatal_error("Unknown mangling specifier in datalayout string");
39891bc56edSDimitry Andric       switch(Rest[0]) {
39991bc56edSDimitry Andric       default:
40039d628a0SDimitry Andric         report_fatal_error("Unknown mangling in datalayout string");
40191bc56edSDimitry Andric       case 'e':
40291bc56edSDimitry Andric         ManglingMode = MM_ELF;
40391bc56edSDimitry Andric         break;
40491bc56edSDimitry Andric       case 'o':
40591bc56edSDimitry Andric         ManglingMode = MM_MachO;
40691bc56edSDimitry Andric         break;
40791bc56edSDimitry Andric       case 'm':
40891bc56edSDimitry Andric         ManglingMode = MM_Mips;
40991bc56edSDimitry Andric         break;
41091bc56edSDimitry Andric       case 'w':
411ff0cc061SDimitry Andric         ManglingMode = MM_WinCOFF;
412ff0cc061SDimitry Andric         break;
413ff0cc061SDimitry Andric       case 'x':
414ff0cc061SDimitry Andric         ManglingMode = MM_WinCOFFX86;
41591bc56edSDimitry Andric         break;
41691bc56edSDimitry Andric       }
41791bc56edSDimitry Andric       break;
418139f7f9bSDimitry Andric     default:
41939d628a0SDimitry Andric       report_fatal_error("Unknown specifier in datalayout string");
420139f7f9bSDimitry Andric       break;
421139f7f9bSDimitry Andric     }
422139f7f9bSDimitry Andric   }
423139f7f9bSDimitry Andric }
424139f7f9bSDimitry Andric 
DataLayout(const Module * M)4250f5676f4SDimitry Andric DataLayout::DataLayout(const Module *M) {
42639d628a0SDimitry Andric   init(M);
42739d628a0SDimitry Andric }
42839d628a0SDimitry Andric 
init(const Module * M)429ff0cc061SDimitry Andric void DataLayout::init(const Module *M) { *this = M->getDataLayout(); }
430139f7f9bSDimitry Andric 
operator ==(const DataLayout & Other) const43191bc56edSDimitry Andric bool DataLayout::operator==(const DataLayout &Other) const {
43239d628a0SDimitry Andric   bool Ret = BigEndian == Other.BigEndian &&
4337a7e6055SDimitry Andric              AllocaAddrSpace == Other.AllocaAddrSpace &&
43491bc56edSDimitry Andric              StackNaturalAlign == Other.StackNaturalAlign &&
4354ba319b5SDimitry Andric              ProgramAddrSpace == Other.ProgramAddrSpace &&
43691bc56edSDimitry Andric              ManglingMode == Other.ManglingMode &&
43791bc56edSDimitry Andric              LegalIntWidths == Other.LegalIntWidths &&
43891bc56edSDimitry Andric              Alignments == Other.Alignments && Pointers == Other.Pointers;
439ff0cc061SDimitry Andric   // Note: getStringRepresentation() might differs, it is not canonicalized
44091bc56edSDimitry Andric   return Ret;
441139f7f9bSDimitry Andric }
442139f7f9bSDimitry Andric 
4437a7e6055SDimitry Andric DataLayout::AlignmentsTy::iterator
findAlignmentLowerBound(AlignTypeEnum AlignType,uint32_t BitWidth)4447a7e6055SDimitry Andric DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
4457a7e6055SDimitry Andric                                     uint32_t BitWidth) {
4467a7e6055SDimitry Andric   auto Pair = std::make_pair((unsigned)AlignType, BitWidth);
4477a7e6055SDimitry Andric   return std::lower_bound(Alignments.begin(), Alignments.end(), Pair,
4487a7e6055SDimitry Andric                           [](const LayoutAlignElem &LHS,
4497a7e6055SDimitry Andric                              const std::pair<unsigned, uint32_t> &RHS) {
4507a7e6055SDimitry Andric                             return std::tie(LHS.AlignType, LHS.TypeBitWidth) <
4517a7e6055SDimitry Andric                                    std::tie(RHS.first, RHS.second);
4527a7e6055SDimitry Andric                           });
4537a7e6055SDimitry Andric }
4547a7e6055SDimitry Andric 
455139f7f9bSDimitry Andric void
setAlignment(AlignTypeEnum align_type,unsigned abi_align,unsigned pref_align,uint32_t bit_width)456139f7f9bSDimitry Andric DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
457139f7f9bSDimitry Andric                          unsigned pref_align, uint32_t bit_width) {
458ff0cc061SDimitry Andric   if (!isUInt<24>(bit_width))
459ff0cc061SDimitry Andric     report_fatal_error("Invalid bit width, must be a 24bit integer");
460ff0cc061SDimitry Andric   if (!isUInt<16>(abi_align))
461ff0cc061SDimitry Andric     report_fatal_error("Invalid ABI alignment, must be a 16bit integer");
462ff0cc061SDimitry Andric   if (!isUInt<16>(pref_align))
463ff0cc061SDimitry Andric     report_fatal_error("Invalid preferred alignment, must be a 16bit integer");
464ff0cc061SDimitry Andric   if (abi_align != 0 && !isPowerOf2_64(abi_align))
465ff0cc061SDimitry Andric     report_fatal_error("Invalid ABI alignment, must be a power of 2");
466ff0cc061SDimitry Andric   if (pref_align != 0 && !isPowerOf2_64(pref_align))
467ff0cc061SDimitry Andric     report_fatal_error("Invalid preferred alignment, must be a power of 2");
468ff0cc061SDimitry Andric 
469ff0cc061SDimitry Andric   if (pref_align < abi_align)
470ff0cc061SDimitry Andric     report_fatal_error(
471ff0cc061SDimitry Andric         "Preferred alignment cannot be less than the ABI alignment");
472ff0cc061SDimitry Andric 
4737a7e6055SDimitry Andric   AlignmentsTy::iterator I = findAlignmentLowerBound(align_type, bit_width);
4747a7e6055SDimitry Andric   if (I != Alignments.end() &&
4757a7e6055SDimitry Andric       I->AlignType == (unsigned)align_type && I->TypeBitWidth == bit_width) {
476139f7f9bSDimitry Andric     // Update the abi, preferred alignments.
4777a7e6055SDimitry Andric     I->ABIAlign = abi_align;
4787a7e6055SDimitry Andric     I->PrefAlign = pref_align;
4797a7e6055SDimitry Andric   } else {
4807a7e6055SDimitry Andric     // Insert before I to keep the vector sorted.
4817a7e6055SDimitry Andric     Alignments.insert(I, LayoutAlignElem::get(align_type, abi_align,
482139f7f9bSDimitry Andric                                               pref_align, bit_width));
483139f7f9bSDimitry Andric   }
4847a7e6055SDimitry Andric }
485139f7f9bSDimitry Andric 
48691bc56edSDimitry Andric DataLayout::PointersTy::iterator
findPointerLowerBound(uint32_t AddressSpace)48791bc56edSDimitry Andric DataLayout::findPointerLowerBound(uint32_t AddressSpace) {
48891bc56edSDimitry Andric   return std::lower_bound(Pointers.begin(), Pointers.end(), AddressSpace,
48991bc56edSDimitry Andric                           [](const PointerAlignElem &A, uint32_t AddressSpace) {
49091bc56edSDimitry Andric     return A.AddressSpace < AddressSpace;
49191bc56edSDimitry Andric   });
49291bc56edSDimitry Andric }
49391bc56edSDimitry Andric 
setPointerAlignment(uint32_t AddrSpace,unsigned ABIAlign,unsigned PrefAlign,uint32_t TypeByteWidth,uint32_t IndexWidth)49491bc56edSDimitry Andric void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
4954ba319b5SDimitry Andric                                      unsigned PrefAlign, uint32_t TypeByteWidth,
4964ba319b5SDimitry Andric                                      uint32_t IndexWidth) {
497ff0cc061SDimitry Andric   if (PrefAlign < ABIAlign)
498ff0cc061SDimitry Andric     report_fatal_error(
499ff0cc061SDimitry Andric         "Preferred alignment cannot be less than the ABI alignment");
500ff0cc061SDimitry Andric 
50191bc56edSDimitry Andric   PointersTy::iterator I = findPointerLowerBound(AddrSpace);
50291bc56edSDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
50391bc56edSDimitry Andric     Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign,
5044ba319b5SDimitry Andric                                              TypeByteWidth, IndexWidth));
505139f7f9bSDimitry Andric   } else {
50691bc56edSDimitry Andric     I->ABIAlign = ABIAlign;
50791bc56edSDimitry Andric     I->PrefAlign = PrefAlign;
50891bc56edSDimitry Andric     I->TypeByteWidth = TypeByteWidth;
5094ba319b5SDimitry Andric     I->IndexWidth = IndexWidth;
510139f7f9bSDimitry Andric   }
511139f7f9bSDimitry Andric }
512139f7f9bSDimitry Andric 
513139f7f9bSDimitry Andric /// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or
514139f7f9bSDimitry Andric /// preferred if ABIInfo = false) the layout wants for the specified datatype.
getAlignmentInfo(AlignTypeEnum AlignType,uint32_t BitWidth,bool ABIInfo,Type * Ty) const515139f7f9bSDimitry Andric unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
516139f7f9bSDimitry Andric                                       uint32_t BitWidth, bool ABIInfo,
517139f7f9bSDimitry Andric                                       Type *Ty) const {
5187a7e6055SDimitry Andric   AlignmentsTy::const_iterator I = findAlignmentLowerBound(AlignType, BitWidth);
5197a7e6055SDimitry Andric   // See if we found an exact match. Of if we are looking for an integer type,
5207a7e6055SDimitry Andric   // but don't have an exact match take the next largest integer. This is where
5217a7e6055SDimitry Andric   // the lower_bound will point to when it fails an exact match.
5227a7e6055SDimitry Andric   if (I != Alignments.end() && I->AlignType == (unsigned)AlignType &&
5237a7e6055SDimitry Andric       (I->TypeBitWidth == BitWidth || AlignType == INTEGER_ALIGN))
5247a7e6055SDimitry Andric     return ABIInfo ? I->ABIAlign : I->PrefAlign;
525139f7f9bSDimitry Andric 
526139f7f9bSDimitry Andric   if (AlignType == INTEGER_ALIGN) {
5277a7e6055SDimitry Andric     // If we didn't have a larger value try the largest value we have.
5287a7e6055SDimitry Andric     if (I != Alignments.begin()) {
5297a7e6055SDimitry Andric       --I; // Go to the previous entry and see if its an integer.
5307a7e6055SDimitry Andric       if (I->AlignType == INTEGER_ALIGN)
5317a7e6055SDimitry Andric         return ABIInfo ? I->ABIAlign : I->PrefAlign;
5327a7e6055SDimitry Andric     }
533ff0cc061SDimitry Andric   } else if (AlignType == VECTOR_ALIGN) {
534139f7f9bSDimitry Andric     // By default, use natural alignment for vector types. This is consistent
535139f7f9bSDimitry Andric     // with what clang and llvm-gcc do.
536139f7f9bSDimitry Andric     unsigned Align = getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
537139f7f9bSDimitry Andric     Align *= cast<VectorType>(Ty)->getNumElements();
538d88c1a5aSDimitry Andric     Align = PowerOf2Ceil(Align);
539139f7f9bSDimitry Andric     return Align;
540139f7f9bSDimitry Andric    }
541139f7f9bSDimitry Andric 
542ff0cc061SDimitry Andric   // If we still couldn't find a reasonable default alignment, fall back
543ff0cc061SDimitry Andric   // to a simple heuristic that the alignment is the first power of two
544ff0cc061SDimitry Andric   // greater-or-equal to the store size of the type.  This is a reasonable
545ff0cc061SDimitry Andric   // approximation of reality, and if the user wanted something less
546ff0cc061SDimitry Andric   // less conservative, they should have specified it explicitly in the data
547ff0cc061SDimitry Andric   // layout.
548ff0cc061SDimitry Andric   unsigned Align = getTypeStoreSize(Ty);
549d88c1a5aSDimitry Andric   Align = PowerOf2Ceil(Align);
550ff0cc061SDimitry Andric   return Align;
551ff0cc061SDimitry Andric }
552ff0cc061SDimitry Andric 
553139f7f9bSDimitry Andric namespace {
554139f7f9bSDimitry Andric 
555139f7f9bSDimitry Andric class StructLayoutMap {
5560f5676f4SDimitry Andric   using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;
557139f7f9bSDimitry Andric   LayoutInfoTy LayoutInfo;
558139f7f9bSDimitry Andric 
559139f7f9bSDimitry Andric public:
~StructLayoutMap()56091bc56edSDimitry Andric   ~StructLayoutMap() {
561139f7f9bSDimitry Andric     // Remove any layouts.
56291bc56edSDimitry Andric     for (const auto &I : LayoutInfo) {
56391bc56edSDimitry Andric       StructLayout *Value = I.second;
564139f7f9bSDimitry Andric       Value->~StructLayout();
565139f7f9bSDimitry Andric       free(Value);
566139f7f9bSDimitry Andric     }
567139f7f9bSDimitry Andric   }
568139f7f9bSDimitry Andric 
operator [](StructType * STy)569139f7f9bSDimitry Andric   StructLayout *&operator[](StructType *STy) {
570139f7f9bSDimitry Andric     return LayoutInfo[STy];
571139f7f9bSDimitry Andric   }
572139f7f9bSDimitry Andric };
573139f7f9bSDimitry Andric 
574139f7f9bSDimitry Andric } // end anonymous namespace
575139f7f9bSDimitry Andric 
clear()57691bc56edSDimitry Andric void DataLayout::clear() {
57791bc56edSDimitry Andric   LegalIntWidths.clear();
57891bc56edSDimitry Andric   Alignments.clear();
57991bc56edSDimitry Andric   Pointers.clear();
580139f7f9bSDimitry Andric   delete static_cast<StructLayoutMap *>(LayoutMap);
58191bc56edSDimitry Andric   LayoutMap = nullptr;
582139f7f9bSDimitry Andric }
583139f7f9bSDimitry Andric 
~DataLayout()58491bc56edSDimitry Andric DataLayout::~DataLayout() {
58591bc56edSDimitry Andric   clear();
586139f7f9bSDimitry Andric }
587139f7f9bSDimitry Andric 
getStructLayout(StructType * Ty) const588139f7f9bSDimitry Andric const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
589139f7f9bSDimitry Andric   if (!LayoutMap)
590139f7f9bSDimitry Andric     LayoutMap = new StructLayoutMap();
591139f7f9bSDimitry Andric 
592139f7f9bSDimitry Andric   StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
593139f7f9bSDimitry Andric   StructLayout *&SL = (*STM)[Ty];
594139f7f9bSDimitry Andric   if (SL) return SL;
595139f7f9bSDimitry Andric 
596139f7f9bSDimitry Andric   // Otherwise, create the struct layout.  Because it is variable length, we
597139f7f9bSDimitry Andric   // malloc it, then use placement new.
598139f7f9bSDimitry Andric   int NumElts = Ty->getNumElements();
5994ba319b5SDimitry Andric   StructLayout *L = (StructLayout *)
6004ba319b5SDimitry Andric       safe_malloc(sizeof(StructLayout)+(NumElts-1) * sizeof(uint64_t));
601139f7f9bSDimitry Andric 
602139f7f9bSDimitry Andric   // Set SL before calling StructLayout's ctor.  The ctor could cause other
603139f7f9bSDimitry Andric   // entries to be added to TheMap, invalidating our reference.
604139f7f9bSDimitry Andric   SL = L;
605139f7f9bSDimitry Andric 
606139f7f9bSDimitry Andric   new (L) StructLayout(Ty, *this);
607139f7f9bSDimitry Andric 
608139f7f9bSDimitry Andric   return L;
609139f7f9bSDimitry Andric }
610139f7f9bSDimitry Andric 
getPointerABIAlignment(unsigned AS) const61191bc56edSDimitry Andric unsigned DataLayout::getPointerABIAlignment(unsigned AS) const {
61291bc56edSDimitry Andric   PointersTy::const_iterator I = findPointerLowerBound(AS);
61391bc56edSDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AS) {
61491bc56edSDimitry Andric     I = findPointerLowerBound(0);
61591bc56edSDimitry Andric     assert(I->AddressSpace == 0);
61691bc56edSDimitry Andric   }
61791bc56edSDimitry Andric   return I->ABIAlign;
61891bc56edSDimitry Andric }
61991bc56edSDimitry Andric 
getPointerPrefAlignment(unsigned AS) const62091bc56edSDimitry Andric unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const {
62191bc56edSDimitry Andric   PointersTy::const_iterator I = findPointerLowerBound(AS);
62291bc56edSDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AS) {
62391bc56edSDimitry Andric     I = findPointerLowerBound(0);
62491bc56edSDimitry Andric     assert(I->AddressSpace == 0);
62591bc56edSDimitry Andric   }
62691bc56edSDimitry Andric   return I->PrefAlign;
62791bc56edSDimitry Andric }
62891bc56edSDimitry Andric 
getPointerSize(unsigned AS) const62991bc56edSDimitry Andric unsigned DataLayout::getPointerSize(unsigned AS) const {
63091bc56edSDimitry Andric   PointersTy::const_iterator I = findPointerLowerBound(AS);
63191bc56edSDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AS) {
63291bc56edSDimitry Andric     I = findPointerLowerBound(0);
63391bc56edSDimitry Andric     assert(I->AddressSpace == 0);
63491bc56edSDimitry Andric   }
63591bc56edSDimitry Andric   return I->TypeByteWidth;
63691bc56edSDimitry Andric }
63791bc56edSDimitry Andric 
getMaxPointerSize() const638*b5893f02SDimitry Andric unsigned DataLayout::getMaxPointerSize() const {
639*b5893f02SDimitry Andric   unsigned MaxPointerSize = 0;
640*b5893f02SDimitry Andric   for (auto &P : Pointers)
641*b5893f02SDimitry Andric     MaxPointerSize = std::max(MaxPointerSize, P.TypeByteWidth);
642*b5893f02SDimitry Andric 
643*b5893f02SDimitry Andric   return MaxPointerSize;
644*b5893f02SDimitry Andric }
645*b5893f02SDimitry Andric 
getPointerTypeSizeInBits(Type * Ty) const646f785676fSDimitry Andric unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
647f785676fSDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
648f785676fSDimitry Andric          "This should only be called with a pointer or pointer vector type");
6496bc11b14SDimitry Andric   Ty = Ty->getScalarType();
6506bc11b14SDimitry Andric   return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
651f785676fSDimitry Andric }
652139f7f9bSDimitry Andric 
getIndexSize(unsigned AS) const6534ba319b5SDimitry Andric unsigned DataLayout::getIndexSize(unsigned AS) const {
6544ba319b5SDimitry Andric   PointersTy::const_iterator I = findPointerLowerBound(AS);
6554ba319b5SDimitry Andric   if (I == Pointers.end() || I->AddressSpace != AS) {
6564ba319b5SDimitry Andric     I = findPointerLowerBound(0);
6574ba319b5SDimitry Andric     assert(I->AddressSpace == 0);
6584ba319b5SDimitry Andric   }
6594ba319b5SDimitry Andric   return I->IndexWidth;
6604ba319b5SDimitry Andric }
6614ba319b5SDimitry Andric 
getIndexTypeSizeInBits(Type * Ty) const6624ba319b5SDimitry Andric unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
6634ba319b5SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
6644ba319b5SDimitry Andric          "This should only be called with a pointer or pointer vector type");
6654ba319b5SDimitry Andric   Ty = Ty->getScalarType();
6664ba319b5SDimitry Andric   return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
6674ba319b5SDimitry Andric }
6684ba319b5SDimitry Andric 
669139f7f9bSDimitry Andric /*!
670139f7f9bSDimitry Andric   \param abi_or_pref Flag that determines which alignment is returned. true
671139f7f9bSDimitry Andric   returns the ABI alignment, false returns the preferred alignment.
672139f7f9bSDimitry Andric   \param Ty The underlying type for which alignment is determined.
673139f7f9bSDimitry Andric 
674139f7f9bSDimitry Andric   Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
675139f7f9bSDimitry Andric   == false) for the requested type \a Ty.
676139f7f9bSDimitry Andric  */
getAlignment(Type * Ty,bool abi_or_pref) const677139f7f9bSDimitry Andric unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
6786bc11b14SDimitry Andric   AlignTypeEnum AlignType;
679139f7f9bSDimitry Andric 
680139f7f9bSDimitry Andric   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
681139f7f9bSDimitry Andric   switch (Ty->getTypeID()) {
682139f7f9bSDimitry Andric   // Early escape for the non-numeric types.
683139f7f9bSDimitry Andric   case Type::LabelTyID:
684139f7f9bSDimitry Andric     return (abi_or_pref
685139f7f9bSDimitry Andric             ? getPointerABIAlignment(0)
686139f7f9bSDimitry Andric             : getPointerPrefAlignment(0));
687139f7f9bSDimitry Andric   case Type::PointerTyID: {
68839d628a0SDimitry Andric     unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
689139f7f9bSDimitry Andric     return (abi_or_pref
690139f7f9bSDimitry Andric             ? getPointerABIAlignment(AS)
691139f7f9bSDimitry Andric             : getPointerPrefAlignment(AS));
692139f7f9bSDimitry Andric     }
693139f7f9bSDimitry Andric   case Type::ArrayTyID:
694139f7f9bSDimitry Andric     return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
695139f7f9bSDimitry Andric 
696139f7f9bSDimitry Andric   case Type::StructTyID: {
697139f7f9bSDimitry Andric     // Packed structure types always have an ABI alignment of one.
698139f7f9bSDimitry Andric     if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
699139f7f9bSDimitry Andric       return 1;
700139f7f9bSDimitry Andric 
701139f7f9bSDimitry Andric     // Get the layout annotation... which is lazily created on demand.
702139f7f9bSDimitry Andric     const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
703139f7f9bSDimitry Andric     unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
704139f7f9bSDimitry Andric     return std::max(Align, Layout->getAlignment());
705139f7f9bSDimitry Andric   }
706139f7f9bSDimitry Andric   case Type::IntegerTyID:
707139f7f9bSDimitry Andric     AlignType = INTEGER_ALIGN;
708139f7f9bSDimitry Andric     break;
709139f7f9bSDimitry Andric   case Type::HalfTyID:
710139f7f9bSDimitry Andric   case Type::FloatTyID:
711139f7f9bSDimitry Andric   case Type::DoubleTyID:
712139f7f9bSDimitry Andric   // PPC_FP128TyID and FP128TyID have different data contents, but the
713139f7f9bSDimitry Andric   // same size and alignment, so they look the same here.
714139f7f9bSDimitry Andric   case Type::PPC_FP128TyID:
715139f7f9bSDimitry Andric   case Type::FP128TyID:
716139f7f9bSDimitry Andric   case Type::X86_FP80TyID:
717139f7f9bSDimitry Andric     AlignType = FLOAT_ALIGN;
718139f7f9bSDimitry Andric     break;
719139f7f9bSDimitry Andric   case Type::X86_MMXTyID:
720139f7f9bSDimitry Andric   case Type::VectorTyID:
721139f7f9bSDimitry Andric     AlignType = VECTOR_ALIGN;
722139f7f9bSDimitry Andric     break;
723139f7f9bSDimitry Andric   default:
724139f7f9bSDimitry Andric     llvm_unreachable("Bad type for getAlignment!!!");
725139f7f9bSDimitry Andric   }
726139f7f9bSDimitry Andric 
7276bc11b14SDimitry Andric   return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty), abi_or_pref, Ty);
728139f7f9bSDimitry Andric }
729139f7f9bSDimitry Andric 
getABITypeAlignment(Type * Ty) const730139f7f9bSDimitry Andric unsigned DataLayout::getABITypeAlignment(Type *Ty) const {
731139f7f9bSDimitry Andric   return getAlignment(Ty, true);
732139f7f9bSDimitry Andric }
733139f7f9bSDimitry Andric 
734139f7f9bSDimitry Andric /// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
735139f7f9bSDimitry Andric /// an integer type of the specified bitwidth.
getABIIntegerTypeAlignment(unsigned BitWidth) const736139f7f9bSDimitry Andric unsigned DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
73791bc56edSDimitry Andric   return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr);
738139f7f9bSDimitry Andric }
739139f7f9bSDimitry Andric 
getPrefTypeAlignment(Type * Ty) const740139f7f9bSDimitry Andric unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const {
741139f7f9bSDimitry Andric   return getAlignment(Ty, false);
742139f7f9bSDimitry Andric }
743139f7f9bSDimitry Andric 
getPreferredTypeAlignmentShift(Type * Ty) const744139f7f9bSDimitry Andric unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const {
745139f7f9bSDimitry Andric   unsigned Align = getPrefTypeAlignment(Ty);
746139f7f9bSDimitry Andric   assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
747139f7f9bSDimitry Andric   return Log2_32(Align);
748139f7f9bSDimitry Andric }
749139f7f9bSDimitry Andric 
getIntPtrType(LLVMContext & C,unsigned AddressSpace) const750139f7f9bSDimitry Andric IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
751139f7f9bSDimitry Andric                                        unsigned AddressSpace) const {
7524ba319b5SDimitry Andric   return IntegerType::get(C, getIndexSizeInBits(AddressSpace));
753139f7f9bSDimitry Andric }
754139f7f9bSDimitry Andric 
getIntPtrType(Type * Ty) const755139f7f9bSDimitry Andric Type *DataLayout::getIntPtrType(Type *Ty) const {
756139f7f9bSDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
757139f7f9bSDimitry Andric          "Expected a pointer or pointer vector type.");
7584ba319b5SDimitry Andric   unsigned NumBits = getIndexTypeSizeInBits(Ty);
759139f7f9bSDimitry Andric   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
760139f7f9bSDimitry Andric   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
761139f7f9bSDimitry Andric     return VectorType::get(IntTy, VecTy->getNumElements());
762139f7f9bSDimitry Andric   return IntTy;
763139f7f9bSDimitry Andric }
764139f7f9bSDimitry Andric 
getSmallestLegalIntType(LLVMContext & C,unsigned Width) const765139f7f9bSDimitry Andric Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
76691bc56edSDimitry Andric   for (unsigned LegalIntWidth : LegalIntWidths)
76791bc56edSDimitry Andric     if (Width <= LegalIntWidth)
76891bc56edSDimitry Andric       return Type::getIntNTy(C, LegalIntWidth);
76991bc56edSDimitry Andric   return nullptr;
770139f7f9bSDimitry Andric }
771139f7f9bSDimitry Andric 
getLargestLegalIntTypeSizeInBits() const7723ca95b02SDimitry Andric unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const {
77391bc56edSDimitry Andric   auto Max = std::max_element(LegalIntWidths.begin(), LegalIntWidths.end());
77491bc56edSDimitry Andric   return Max != LegalIntWidths.end() ? *Max : 0;
775f785676fSDimitry Andric }
776f785676fSDimitry Andric 
getIndexType(Type * Ty) const7774ba319b5SDimitry Andric Type *DataLayout::getIndexType(Type *Ty) const {
7784ba319b5SDimitry Andric   assert(Ty->isPtrOrPtrVectorTy() &&
7794ba319b5SDimitry Andric          "Expected a pointer or pointer vector type.");
7804ba319b5SDimitry Andric   unsigned NumBits = getIndexTypeSizeInBits(Ty);
7814ba319b5SDimitry Andric   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
7824ba319b5SDimitry Andric   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
7834ba319b5SDimitry Andric     return VectorType::get(IntTy, VecTy->getNumElements());
7844ba319b5SDimitry Andric   return IntTy;
7854ba319b5SDimitry Andric }
7864ba319b5SDimitry Andric 
getIndexedOffsetInType(Type * ElemTy,ArrayRef<Value * > Indices) const7873ca95b02SDimitry Andric int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
788139f7f9bSDimitry Andric                                            ArrayRef<Value *> Indices) const {
7893ca95b02SDimitry Andric   int64_t Result = 0;
790139f7f9bSDimitry Andric 
791139f7f9bSDimitry Andric   generic_gep_type_iterator<Value* const*>
792d88c1a5aSDimitry Andric     GTI = gep_type_begin(ElemTy, Indices),
793d88c1a5aSDimitry Andric     GTE = gep_type_end(ElemTy, Indices);
7943ca95b02SDimitry Andric   for (; GTI != GTE; ++GTI) {
7953ca95b02SDimitry Andric     Value *Idx = GTI.getOperand();
796d88c1a5aSDimitry Andric     if (StructType *STy = GTI.getStructTypeOrNull()) {
7973ca95b02SDimitry Andric       assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
7983ca95b02SDimitry Andric       unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();
799139f7f9bSDimitry Andric 
800139f7f9bSDimitry Andric       // Get structure layout information...
801139f7f9bSDimitry Andric       const StructLayout *Layout = getStructLayout(STy);
802139f7f9bSDimitry Andric 
803139f7f9bSDimitry Andric       // Add in the offset, as calculated by the structure layout info...
804139f7f9bSDimitry Andric       Result += Layout->getElementOffset(FieldNo);
805139f7f9bSDimitry Andric     } else {
806139f7f9bSDimitry Andric       // Get the array index and the size of each array element.
8073ca95b02SDimitry Andric       if (int64_t arrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
8083ca95b02SDimitry Andric         Result += arrayIdx * getTypeAllocSize(GTI.getIndexedType());
809139f7f9bSDimitry Andric     }
810139f7f9bSDimitry Andric   }
811139f7f9bSDimitry Andric 
812139f7f9bSDimitry Andric   return Result;
813139f7f9bSDimitry Andric }
814139f7f9bSDimitry Andric 
815139f7f9bSDimitry Andric /// getPreferredAlignment - Return the preferred alignment of the specified
816139f7f9bSDimitry Andric /// global.  This includes an explicitly requested alignment (if the global
817139f7f9bSDimitry Andric /// has one).
getPreferredAlignment(const GlobalVariable * GV) const818139f7f9bSDimitry Andric unsigned DataLayout::getPreferredAlignment(const GlobalVariable *GV) const {
819*b5893f02SDimitry Andric   unsigned GVAlignment = GV->getAlignment();
820*b5893f02SDimitry Andric   // If a section is specified, always precisely honor explicit alignment,
821*b5893f02SDimitry Andric   // so we don't insert padding into a section we don't control.
822*b5893f02SDimitry Andric   if (GVAlignment && GV->hasSection())
823*b5893f02SDimitry Andric     return GVAlignment;
824*b5893f02SDimitry Andric 
825*b5893f02SDimitry Andric   // If no explicit alignment is specified, compute the alignment based on
826*b5893f02SDimitry Andric   // the IR type. If an alignment is specified, increase it to match the ABI
827*b5893f02SDimitry Andric   // alignment of the IR type.
828*b5893f02SDimitry Andric   //
829*b5893f02SDimitry Andric   // FIXME: Not sure it makes sense to use the alignment of the type if
830*b5893f02SDimitry Andric   // there's already an explicit alignment specification.
8313ca95b02SDimitry Andric   Type *ElemType = GV->getValueType();
832139f7f9bSDimitry Andric   unsigned Alignment = getPrefTypeAlignment(ElemType);
833139f7f9bSDimitry Andric   if (GVAlignment >= Alignment) {
834139f7f9bSDimitry Andric     Alignment = GVAlignment;
835139f7f9bSDimitry Andric   } else if (GVAlignment != 0) {
836139f7f9bSDimitry Andric     Alignment = std::max(GVAlignment, getABITypeAlignment(ElemType));
837139f7f9bSDimitry Andric   }
838139f7f9bSDimitry Andric 
839*b5893f02SDimitry Andric   // If no explicit alignment is specified, and the global is large, increase
840*b5893f02SDimitry Andric   // the alignment to 16.
841*b5893f02SDimitry Andric   // FIXME: Why 16, specifically?
842139f7f9bSDimitry Andric   if (GV->hasInitializer() && GVAlignment == 0) {
843139f7f9bSDimitry Andric     if (Alignment < 16) {
844139f7f9bSDimitry Andric       // If the global is not external, see if it is large.  If so, give it a
845139f7f9bSDimitry Andric       // larger alignment.
846139f7f9bSDimitry Andric       if (getTypeSizeInBits(ElemType) > 128)
847139f7f9bSDimitry Andric         Alignment = 16;    // 16-byte alignment.
848139f7f9bSDimitry Andric     }
849139f7f9bSDimitry Andric   }
850139f7f9bSDimitry Andric   return Alignment;
851139f7f9bSDimitry Andric }
852139f7f9bSDimitry Andric 
853139f7f9bSDimitry Andric /// getPreferredAlignmentLog - Return the preferred alignment of the
854139f7f9bSDimitry Andric /// specified global, returned in log form.  This includes an explicitly
855139f7f9bSDimitry Andric /// requested alignment (if the global has one).
getPreferredAlignmentLog(const GlobalVariable * GV) const856139f7f9bSDimitry Andric unsigned DataLayout::getPreferredAlignmentLog(const GlobalVariable *GV) const {
857139f7f9bSDimitry Andric   return Log2_32(getPreferredAlignment(GV));
858139f7f9bSDimitry Andric }
859