1f53a7b45SEugene Zelenko //===- DataLayout.cpp - Data size & alignment routines ---------------------==//
2ef860a24SChandler Carruth //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ef860a24SChandler Carruth //
7ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
8ef860a24SChandler Carruth //
9ef860a24SChandler Carruth // This file defines layout properties related to datatype size/offset/alignment
10ef860a24SChandler Carruth // information.
11ef860a24SChandler Carruth //
12ef860a24SChandler Carruth // This structure should be created once, filled in if the defaults are not
13ef860a24SChandler Carruth // correct and then passed around by const&.  None of the members functions
14ef860a24SChandler Carruth // require modification to the object.
15ef860a24SChandler Carruth //
16ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
17ef860a24SChandler Carruth 
186bda14b3SChandler Carruth #include "llvm/IR/DataLayout.h"
19ef860a24SChandler Carruth #include "llvm/ADT/DenseMap.h"
20f53a7b45SEugene Zelenko #include "llvm/ADT/StringRef.h"
2158873566SRafael Espindola #include "llvm/ADT/Triple.h"
229fb823bbSChandler Carruth #include "llvm/IR/Constants.h"
239fb823bbSChandler Carruth #include "llvm/IR/DerivedTypes.h"
2403eb0de9SChandler Carruth #include "llvm/IR/GetElementPtrTypeIterator.h"
25f53a7b45SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
269fb823bbSChandler Carruth #include "llvm/IR/Module.h"
27f53a7b45SEugene Zelenko #include "llvm/IR/Type.h"
28f53a7b45SEugene Zelenko #include "llvm/IR/Value.h"
29f53a7b45SEugene Zelenko #include "llvm/Support/Casting.h"
30874aef87SAlex Zinenko #include "llvm/Support/Error.h"
31ef860a24SChandler Carruth #include "llvm/Support/ErrorHandling.h"
32ef860a24SChandler Carruth #include "llvm/Support/MathExtras.h"
33*e188aae4Sserge-sans-paille #include "llvm/Support/MemAlloc.h"
34b302561bSGraham Hunter #include "llvm/Support/TypeSize.h"
35ef860a24SChandler Carruth #include <algorithm>
36f53a7b45SEugene Zelenko #include <cassert>
37f53a7b45SEugene Zelenko #include <cstdint>
38ef860a24SChandler Carruth #include <cstdlib>
39*e188aae4Sserge-sans-paille #include <new>
40f53a7b45SEugene Zelenko #include <utility>
41f53a7b45SEugene Zelenko 
42ef860a24SChandler Carruth using namespace llvm;
43ef860a24SChandler Carruth 
44ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
45ef860a24SChandler Carruth // Support for StructLayout
46ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
47ef860a24SChandler Carruth 
StructLayout(StructType * ST,const DataLayout & DL)480ae73930SPete Cooper StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
49ef860a24SChandler Carruth   assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
50ef860a24SChandler Carruth   StructSize = 0;
511c131b37SMehdi Amini   IsPadded = false;
52ef860a24SChandler Carruth   NumElements = ST->getNumElements();
53ef860a24SChandler Carruth 
54ef860a24SChandler Carruth   // Loop over each of the elements, placing them in memory.
55ef860a24SChandler Carruth   for (unsigned i = 0, e = NumElements; i != e; ++i) {
56ef860a24SChandler Carruth     Type *Ty = ST->getElementType(i);
57d3085c25SGuillaume Chatelet     const Align TyAlign = ST->isPacked() ? Align(1) : DL.getABITypeAlign(Ty);
58ef860a24SChandler Carruth 
59ef860a24SChandler Carruth     // Add padding if necessary to align the data element properly.
606c127cdbSGuillaume Chatelet     if (!isAligned(TyAlign, StructSize)) {
611c131b37SMehdi Amini       IsPadded = true;
62da00f2fdSRui Ueyama       StructSize = alignTo(StructSize, TyAlign);
631c131b37SMehdi Amini     }
64ef860a24SChandler Carruth 
65ef860a24SChandler Carruth     // Keep track of maximum alignment constraint.
66ef860a24SChandler Carruth     StructAlignment = std::max(TyAlign, StructAlignment);
67ef860a24SChandler Carruth 
68f59ba084SCraig Topper     getMemberOffsets()[i] = StructSize;
69cfec6cd5SCraig Topper     // Consume space for this data item
70cfec6cd5SCraig Topper     StructSize += DL.getTypeAllocSize(Ty).getFixedValue();
71ef860a24SChandler Carruth   }
72ef860a24SChandler Carruth 
73ef860a24SChandler Carruth   // Add padding to the end of the struct so that it could be put in an array
74ef860a24SChandler Carruth   // and all array elements would be aligned correctly.
756c127cdbSGuillaume Chatelet   if (!isAligned(StructAlignment, StructSize)) {
761c131b37SMehdi Amini     IsPadded = true;
77da00f2fdSRui Ueyama     StructSize = alignTo(StructSize, StructAlignment);
78ef860a24SChandler Carruth   }
791c131b37SMehdi Amini }
80ef860a24SChandler Carruth 
81ef860a24SChandler Carruth /// getElementContainingOffset - Given a valid offset into the structure,
82ef860a24SChandler Carruth /// return the structure index that contains it.
getElementContainingOffset(uint64_t Offset) const83ef860a24SChandler Carruth unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
84f59ba084SCraig Topper   ArrayRef<uint64_t> MemberOffsets = getMemberOffsets();
85f59ba084SCraig Topper   auto SI = llvm::upper_bound(MemberOffsets, Offset);
86f59ba084SCraig Topper   assert(SI != MemberOffsets.begin() && "Offset not in structure type!");
87ef860a24SChandler Carruth   --SI;
88ef860a24SChandler Carruth   assert(*SI <= Offset && "upper_bound didn't work");
89f59ba084SCraig Topper   assert((SI == MemberOffsets.begin() || *(SI - 1) <= Offset) &&
90f59ba084SCraig Topper          (SI + 1 == MemberOffsets.end() || *(SI + 1) > Offset) &&
91ef860a24SChandler Carruth          "Upper bound didn't work!");
92ef860a24SChandler Carruth 
93ef860a24SChandler Carruth   // Multiple fields can have the same offset if any of them are zero sized.
94ef860a24SChandler Carruth   // For example, in { i32, [0 x i32], i32 }, searching for offset 4 will stop
95ef860a24SChandler Carruth   // at the i32 element, because it is the last element at that offset.  This is
96ef860a24SChandler Carruth   // the right one to return, because anything after it will have a higher
97ef860a24SChandler Carruth   // offset, implying that this element is non-empty.
98f59ba084SCraig Topper   return SI - MemberOffsets.begin();
99ef860a24SChandler Carruth }
100ef860a24SChandler Carruth 
101ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
102ef860a24SChandler Carruth // LayoutAlignElem, LayoutAlign support
103ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
104ef860a24SChandler Carruth 
get(AlignTypeEnum align_type,Align abi_align,Align pref_align,uint32_t bit_width)10518f805a7SGuillaume Chatelet LayoutAlignElem LayoutAlignElem::get(AlignTypeEnum align_type, Align abi_align,
10618f805a7SGuillaume Chatelet                                      Align pref_align, uint32_t bit_width) {
107ef860a24SChandler Carruth   assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
108ef860a24SChandler Carruth   LayoutAlignElem retval;
109ef860a24SChandler Carruth   retval.AlignType = align_type;
110ef860a24SChandler Carruth   retval.ABIAlign = abi_align;
111ef860a24SChandler Carruth   retval.PrefAlign = pref_align;
112ef860a24SChandler Carruth   retval.TypeBitWidth = bit_width;
113ef860a24SChandler Carruth   return retval;
114ef860a24SChandler Carruth }
115ef860a24SChandler Carruth 
116ef860a24SChandler Carruth bool
operator ==(const LayoutAlignElem & rhs) const117ef860a24SChandler Carruth LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
118ef860a24SChandler Carruth   return (AlignType == rhs.AlignType
119ef860a24SChandler Carruth           && ABIAlign == rhs.ABIAlign
120ef860a24SChandler Carruth           && PrefAlign == rhs.PrefAlign
121ef860a24SChandler Carruth           && TypeBitWidth == rhs.TypeBitWidth);
122ef860a24SChandler Carruth }
123ef860a24SChandler Carruth 
124ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
125ef860a24SChandler Carruth // PointerAlignElem, PointerAlign support
126ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
127ef860a24SChandler Carruth 
getInBits(uint32_t AddressSpace,Align ABIAlign,Align PrefAlign,uint32_t TypeBitWidth,uint32_t IndexBitWidth)1280fcb16eeSStephen Neuendorffer PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace,
1290fcb16eeSStephen Neuendorffer                                              Align ABIAlign, Align PrefAlign,
1300fcb16eeSStephen Neuendorffer                                              uint32_t TypeBitWidth,
1310fcb16eeSStephen Neuendorffer                                              uint32_t IndexBitWidth) {
132f39136c3SRafael Espindola   assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
133ef860a24SChandler Carruth   PointerAlignElem retval;
134f39136c3SRafael Espindola   retval.AddressSpace = AddressSpace;
135f39136c3SRafael Espindola   retval.ABIAlign = ABIAlign;
136f39136c3SRafael Espindola   retval.PrefAlign = PrefAlign;
1370fcb16eeSStephen Neuendorffer   retval.TypeBitWidth = TypeBitWidth;
1380fcb16eeSStephen Neuendorffer   retval.IndexBitWidth = IndexBitWidth;
139ef860a24SChandler Carruth   return retval;
140ef860a24SChandler Carruth }
141ef860a24SChandler Carruth 
142ef860a24SChandler Carruth bool
operator ==(const PointerAlignElem & rhs) const143ef860a24SChandler Carruth PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
1440fcb16eeSStephen Neuendorffer   return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&
1450fcb16eeSStephen Neuendorffer           PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth &&
1460fcb16eeSStephen Neuendorffer           IndexBitWidth == rhs.IndexBitWidth);
147ef860a24SChandler Carruth }
148ef860a24SChandler Carruth 
149ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
150ef860a24SChandler Carruth //                       DataLayout Class Implementation
151ef860a24SChandler Carruth //===----------------------------------------------------------------------===//
152ef860a24SChandler Carruth 
getManglingComponent(const Triple & T)15358873566SRafael Espindola const char *DataLayout::getManglingComponent(const Triple &T) {
154e09a1dc4SAnirudh Prasad   if (T.isOSBinFormatGOFF())
155e09a1dc4SAnirudh Prasad     return "-m:l";
15658873566SRafael Espindola   if (T.isOSBinFormatMachO())
15758873566SRafael Espindola     return "-m:o";
1587db449a6SDavid Majnemer   if (T.isOSWindows() && T.isOSBinFormatCOFF())
1597db449a6SDavid Majnemer     return T.getArch() == Triple::x86 ? "-m:x" : "-m:w";
160572dde55Sjasonliu   if (T.isOSBinFormatXCOFF())
161572dde55Sjasonliu     return "-m:a";
162cd130829SSaleem Abdulrasool   return "-m:e";
16358873566SRafael Espindola }
16458873566SRafael Espindola 
165e23b8774SRafael Espindola static const LayoutAlignElem DefaultAlignments[] = {
16618f805a7SGuillaume Chatelet     {INTEGER_ALIGN, 1, Align(1), Align(1)},    // i1
16718f805a7SGuillaume Chatelet     {INTEGER_ALIGN, 8, Align(1), Align(1)},    // i8
16818f805a7SGuillaume Chatelet     {INTEGER_ALIGN, 16, Align(2), Align(2)},   // i16
16918f805a7SGuillaume Chatelet     {INTEGER_ALIGN, 32, Align(4), Align(4)},   // i32
17018f805a7SGuillaume Chatelet     {INTEGER_ALIGN, 64, Align(4), Align(8)},   // i64
1718c24f331STies Stuij     {FLOAT_ALIGN, 16, Align(2), Align(2)},     // half, bfloat
17218f805a7SGuillaume Chatelet     {FLOAT_ALIGN, 32, Align(4), Align(4)},     // float
17318f805a7SGuillaume Chatelet     {FLOAT_ALIGN, 64, Align(8), Align(8)},     // double
17418f805a7SGuillaume Chatelet     {FLOAT_ALIGN, 128, Align(16), Align(16)},  // ppcf128, quad, ...
17518f805a7SGuillaume Chatelet     {VECTOR_ALIGN, 64, Align(8), Align(8)},    // v2i32, v1i64, ...
17618f805a7SGuillaume Chatelet     {VECTOR_ALIGN, 128, Align(16), Align(16)}, // v16i8, v8i16, v4i32, ...
17718f805a7SGuillaume Chatelet     {AGGREGATE_ALIGN, 0, Align(1), Align(8)}   // struct
178458a4851SRafael Espindola };
179458a4851SRafael Espindola 
reset(StringRef Desc)180248ac139SRafael Espindola void DataLayout::reset(StringRef Desc) {
181248ac139SRafael Espindola   clear();
182248ac139SRafael Espindola 
183c620761cSCraig Topper   LayoutMap = nullptr;
184f67321cbSChandler Carruth   BigEndian = false;
1853c1fc768SMatt Arsenault   AllocaAddrSpace = 0;
18665e4b47aSGuillaume Chatelet   StackNaturalAlign.reset();
187ced2fe68SDylan McKay   ProgramAddrSpace = 0;
1883bc41575SAlex Richardson   DefaultGlobalsAddrSpace = 0;
18965e4b47aSGuillaume Chatelet   FunctionPtrAlign.reset();
190308e82ecSMichael Platings   TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
19158873566SRafael Espindola   ManglingMode = MM_None;
192c6af5eadSSanjoy Das   NonIntegralAddressSpaces.clear();
193ef860a24SChandler Carruth 
194ef860a24SChandler Carruth   // Default alignments
1953ad5c962SBenjamin Kramer   for (const LayoutAlignElem &E : DefaultAlignments) {
196874aef87SAlex Zinenko     if (Error Err = setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign,
197874aef87SAlex Zinenko                                  E.PrefAlign, E.TypeBitWidth))
198874aef87SAlex Zinenko       return report_fatal_error(std::move(Err));
199458a4851SRafael Espindola   }
2000fcb16eeSStephen Neuendorffer   if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
201874aef87SAlex Zinenko     return report_fatal_error(std::move(Err));
202ef860a24SChandler Carruth 
203874aef87SAlex Zinenko   if (Error Err = parseSpecifier(Desc))
204874aef87SAlex Zinenko     return report_fatal_error(std::move(Err));
205874aef87SAlex Zinenko }
206874aef87SAlex Zinenko 
parse(StringRef LayoutDescription)207874aef87SAlex Zinenko Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
208874aef87SAlex Zinenko   DataLayout Layout("");
209874aef87SAlex Zinenko   if (Error Err = Layout.parseSpecifier(LayoutDescription))
210874aef87SAlex Zinenko     return std::move(Err);
211874aef87SAlex Zinenko   return Layout;
212874aef87SAlex Zinenko }
213874aef87SAlex Zinenko 
reportError(const Twine & Message)214874aef87SAlex Zinenko static Error reportError(const Twine &Message) {
215874aef87SAlex Zinenko   return createStringError(inconvertibleErrorCode(), Message);
216ef860a24SChandler Carruth }
217ef860a24SChandler Carruth 
218ef860a24SChandler Carruth /// Checked version of split, to ensure mandatory subparts.
split(StringRef Str,char Separator,std::pair<StringRef,StringRef> & Split)219874aef87SAlex Zinenko static Error split(StringRef Str, char Separator,
220874aef87SAlex Zinenko                    std::pair<StringRef, StringRef> &Split) {
221ef860a24SChandler Carruth   assert(!Str.empty() && "parse error, string can't be empty here");
222874aef87SAlex Zinenko   Split = Str.split(Separator);
2232dc1b0f5SDavid Majnemer   if (Split.second.empty() && Split.first != Str)
224874aef87SAlex Zinenko     return reportError("Trailing separator in datalayout string");
225612f3128SDavid Majnemer   if (!Split.second.empty() && Split.first.empty())
226874aef87SAlex Zinenko     return reportError("Expected token before separator in datalayout string");
227874aef87SAlex Zinenko   return Error::success();
228ef860a24SChandler Carruth }
229ef860a24SChandler Carruth 
2308af9eac3SCameron McInally /// Get an unsigned integer, including error checks.
getInt(StringRef R,IntTy & Result)231874aef87SAlex Zinenko template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
232ef860a24SChandler Carruth   bool error = R.getAsInteger(10, Result); (void)error;
233f0379fa4SCameron McInally   if (error)
234874aef87SAlex Zinenko     return reportError("not a number, or does not fit in an unsigned int");
235874aef87SAlex Zinenko   return Error::success();
236ef860a24SChandler Carruth }
237ef860a24SChandler Carruth 
238874aef87SAlex Zinenko /// Get an unsigned integer representing the number of bits and convert it into
239874aef87SAlex Zinenko /// bytes. Error out of not a byte width multiple.
240874aef87SAlex Zinenko template <typename IntTy>
getIntInBytes(StringRef R,IntTy & Result)241874aef87SAlex Zinenko static Error getIntInBytes(StringRef R, IntTy &Result) {
242874aef87SAlex Zinenko   if (Error Err = getInt<IntTy>(R, Result))
243874aef87SAlex Zinenko     return Err;
244874aef87SAlex Zinenko   if (Result % 8)
245874aef87SAlex Zinenko     return reportError("number of bits must be a byte width multiple");
246874aef87SAlex Zinenko   Result /= 8;
247874aef87SAlex Zinenko   return Error::success();
248ef860a24SChandler Carruth }
249ef860a24SChandler Carruth 
getAddrSpace(StringRef R,unsigned & AddrSpace)250874aef87SAlex Zinenko static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {
251874aef87SAlex Zinenko   if (Error Err = getInt(R, AddrSpace))
252874aef87SAlex Zinenko     return Err;
253ced2fe68SDylan McKay   if (!isUInt<24>(AddrSpace))
254874aef87SAlex Zinenko     return reportError("Invalid address space, must be a 24-bit integer");
255874aef87SAlex Zinenko   return Error::success();
256ced2fe68SDylan McKay }
257ced2fe68SDylan McKay 
parseSpecifier(StringRef Desc)258874aef87SAlex Zinenko Error DataLayout::parseSpecifier(StringRef Desc) {
259adcd0268SBenjamin Kramer   StringRepresentation = std::string(Desc);
260ef860a24SChandler Carruth   while (!Desc.empty()) {
261ef860a24SChandler Carruth     // Split at '-'.
262874aef87SAlex Zinenko     std::pair<StringRef, StringRef> Split;
26366e06cc8SMichał Górny     if (Error Err = ::split(Desc, '-', Split))
264874aef87SAlex Zinenko       return Err;
265ef860a24SChandler Carruth     Desc = Split.second;
266ef860a24SChandler Carruth 
267ef860a24SChandler Carruth     // Split at ':'.
26866e06cc8SMichał Górny     if (Error Err = ::split(Split.first, ':', Split))
269874aef87SAlex Zinenko       return Err;
270ef860a24SChandler Carruth 
271ef860a24SChandler Carruth     // Aliases used below.
272ef860a24SChandler Carruth     StringRef &Tok  = Split.first;  // Current token.
273ef860a24SChandler Carruth     StringRef &Rest = Split.second; // The rest of the string.
274ef860a24SChandler Carruth 
275c6af5eadSSanjoy Das     if (Tok == "ni") {
276c6af5eadSSanjoy Das       do {
27766e06cc8SMichał Górny         if (Error Err = ::split(Rest, ':', Split))
278874aef87SAlex Zinenko           return Err;
279c6af5eadSSanjoy Das         Rest = Split.second;
280874aef87SAlex Zinenko         unsigned AS;
281874aef87SAlex Zinenko         if (Error Err = getInt(Split.first, AS))
282874aef87SAlex Zinenko           return Err;
283c6af5eadSSanjoy Das         if (AS == 0)
284874aef87SAlex Zinenko           return reportError("Address space 0 can never be non-integral");
285c6af5eadSSanjoy Das         NonIntegralAddressSpaces.push_back(AS);
286c6af5eadSSanjoy Das       } while (!Rest.empty());
287c6af5eadSSanjoy Das 
288c6af5eadSSanjoy Das       continue;
289c6af5eadSSanjoy Das     }
290c6af5eadSSanjoy Das 
291ef860a24SChandler Carruth     char Specifier = Tok.front();
292ef860a24SChandler Carruth     Tok = Tok.substr(1);
293ef860a24SChandler Carruth 
294ef860a24SChandler Carruth     switch (Specifier) {
2956994fdf3SRafael Espindola     case 's':
2964abf0243SMehdi Amini       // Deprecated, but ignoring here to preserve loading older textual llvm
2974abf0243SMehdi Amini       // ASM file
2986994fdf3SRafael Espindola       break;
299ef860a24SChandler Carruth     case 'E':
300f67321cbSChandler Carruth       BigEndian = true;
301ef860a24SChandler Carruth       break;
302ef860a24SChandler Carruth     case 'e':
303f67321cbSChandler Carruth       BigEndian = false;
304ef860a24SChandler Carruth       break;
305ef860a24SChandler Carruth     case 'p': {
306ef860a24SChandler Carruth       // Address space.
307874aef87SAlex Zinenko       unsigned AddrSpace = 0;
308874aef87SAlex Zinenko       if (!Tok.empty())
309874aef87SAlex Zinenko         if (Error Err = getInt(Tok, AddrSpace))
310874aef87SAlex Zinenko           return Err;
3115330c69bSDavid Majnemer       if (!isUInt<24>(AddrSpace))
312874aef87SAlex Zinenko         return reportError("Invalid address space, must be a 24bit integer");
313ef860a24SChandler Carruth 
314ef860a24SChandler Carruth       // Size.
3152dc1b0f5SDavid Majnemer       if (Rest.empty())
316874aef87SAlex Zinenko         return reportError(
3172dc1b0f5SDavid Majnemer             "Missing size specification for pointer in datalayout string");
31866e06cc8SMichał Górny       if (Error Err = ::split(Rest, ':', Split))
319874aef87SAlex Zinenko         return Err;
320874aef87SAlex Zinenko       unsigned PointerMemSize;
3210fcb16eeSStephen Neuendorffer       if (Error Err = getInt(Tok, PointerMemSize))
322874aef87SAlex Zinenko         return Err;
3235bc2bbe6SOwen Anderson       if (!PointerMemSize)
324874aef87SAlex Zinenko         return reportError("Invalid pointer size of 0 bytes");
325ef860a24SChandler Carruth 
326ef860a24SChandler Carruth       // ABI alignment.
3272dc1b0f5SDavid Majnemer       if (Rest.empty())
328874aef87SAlex Zinenko         return reportError(
3292dc1b0f5SDavid Majnemer             "Missing alignment specification for pointer in datalayout string");
33066e06cc8SMichał Górny       if (Error Err = ::split(Rest, ':', Split))
331874aef87SAlex Zinenko         return Err;
332874aef87SAlex Zinenko       unsigned PointerABIAlign;
333874aef87SAlex Zinenko       if (Error Err = getIntInBytes(Tok, PointerABIAlign))
334874aef87SAlex Zinenko         return Err;
335040f2f89SOwen Anderson       if (!isPowerOf2_64(PointerABIAlign))
336874aef87SAlex Zinenko         return reportError("Pointer ABI alignment must be a power of 2");
337ef860a24SChandler Carruth 
338945b7e5aSElena Demikhovsky       // Size of index used in GEP for address calculation.
339945b7e5aSElena Demikhovsky       // The parameter is optional. By default it is equal to size of pointer.
340945b7e5aSElena Demikhovsky       unsigned IndexSize = PointerMemSize;
341945b7e5aSElena Demikhovsky 
342ef860a24SChandler Carruth       // Preferred alignment.
343ef860a24SChandler Carruth       unsigned PointerPrefAlign = PointerABIAlign;
344ef860a24SChandler Carruth       if (!Rest.empty()) {
34566e06cc8SMichał Górny         if (Error Err = ::split(Rest, ':', Split))
346874aef87SAlex Zinenko           return Err;
347874aef87SAlex Zinenko         if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
348874aef87SAlex Zinenko           return Err;
349040f2f89SOwen Anderson         if (!isPowerOf2_64(PointerPrefAlign))
350874aef87SAlex Zinenko           return reportError(
351040f2f89SOwen Anderson               "Pointer preferred alignment must be a power of 2");
352ef860a24SChandler Carruth 
353945b7e5aSElena Demikhovsky         // Now read the index. It is the second optional parameter here.
354945b7e5aSElena Demikhovsky         if (!Rest.empty()) {
35566e06cc8SMichał Górny           if (Error Err = ::split(Rest, ':', Split))
356874aef87SAlex Zinenko             return Err;
3570fcb16eeSStephen Neuendorffer           if (Error Err = getInt(Tok, IndexSize))
358874aef87SAlex Zinenko             return Err;
359945b7e5aSElena Demikhovsky           if (!IndexSize)
360874aef87SAlex Zinenko             return reportError("Invalid index size of 0 bytes");
361945b7e5aSElena Demikhovsky         }
362945b7e5aSElena Demikhovsky       }
3630fcb16eeSStephen Neuendorffer       if (Error Err = setPointerAlignmentInBits(
364874aef87SAlex Zinenko               AddrSpace, assumeAligned(PointerABIAlign),
365874aef87SAlex Zinenko               assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
366874aef87SAlex Zinenko         return Err;
367ef860a24SChandler Carruth       break;
368ef860a24SChandler Carruth     }
369ef860a24SChandler Carruth     case 'i':
370ef860a24SChandler Carruth     case 'v':
371ef860a24SChandler Carruth     case 'f':
3726994fdf3SRafael Espindola     case 'a': {
373ef860a24SChandler Carruth       AlignTypeEnum AlignType;
374ef860a24SChandler Carruth       switch (Specifier) {
37564a65ec4SCraig Topper       default: llvm_unreachable("Unexpected specifier!");
376ef860a24SChandler Carruth       case 'i': AlignType = INTEGER_ALIGN; break;
377ef860a24SChandler Carruth       case 'v': AlignType = VECTOR_ALIGN; break;
378ef860a24SChandler Carruth       case 'f': AlignType = FLOAT_ALIGN; break;
379ef860a24SChandler Carruth       case 'a': AlignType = AGGREGATE_ALIGN; break;
380ef860a24SChandler Carruth       }
381ef860a24SChandler Carruth 
382ef860a24SChandler Carruth       // Bit size.
383874aef87SAlex Zinenko       unsigned Size = 0;
384874aef87SAlex Zinenko       if (!Tok.empty())
385874aef87SAlex Zinenko         if (Error Err = getInt(Tok, Size))
386874aef87SAlex Zinenko           return Err;
387ef860a24SChandler Carruth 
3885330c69bSDavid Majnemer       if (AlignType == AGGREGATE_ALIGN && Size != 0)
389874aef87SAlex Zinenko         return reportError(
3905330c69bSDavid Majnemer             "Sized aggregate specification in datalayout string");
391abdd726cSRafael Espindola 
392ef860a24SChandler Carruth       // ABI alignment.
393612f3128SDavid Majnemer       if (Rest.empty())
394874aef87SAlex Zinenko         return reportError(
395612f3128SDavid Majnemer             "Missing alignment specification in datalayout string");
39666e06cc8SMichał Górny       if (Error Err = ::split(Rest, ':', Split))
397874aef87SAlex Zinenko         return Err;
398874aef87SAlex Zinenko       unsigned ABIAlign;
399874aef87SAlex Zinenko       if (Error Err = getIntInBytes(Tok, ABIAlign))
400874aef87SAlex Zinenko         return Err;
401ab1c7a77SOwen Anderson       if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
402874aef87SAlex Zinenko         return reportError(
403ab1c7a77SOwen Anderson             "ABI alignment specification must be >0 for non-aggregate types");
404ef860a24SChandler Carruth 
4056c127cdbSGuillaume Chatelet       if (!isUInt<16>(ABIAlign))
406874aef87SAlex Zinenko         return reportError("Invalid ABI alignment, must be a 16bit integer");
4076c127cdbSGuillaume Chatelet       if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
408874aef87SAlex Zinenko         return reportError("Invalid ABI alignment, must be a power of 2");
4096c127cdbSGuillaume Chatelet 
410ef860a24SChandler Carruth       // Preferred alignment.
411ef860a24SChandler Carruth       unsigned PrefAlign = ABIAlign;
412ef860a24SChandler Carruth       if (!Rest.empty()) {
41366e06cc8SMichał Górny         if (Error Err = ::split(Rest, ':', Split))
414874aef87SAlex Zinenko           return Err;
415874aef87SAlex Zinenko         if (Error Err = getIntInBytes(Tok, PrefAlign))
416874aef87SAlex Zinenko           return Err;
417ef860a24SChandler Carruth       }
418ef860a24SChandler Carruth 
4196c127cdbSGuillaume Chatelet       if (!isUInt<16>(PrefAlign))
420874aef87SAlex Zinenko         return reportError(
4216c127cdbSGuillaume Chatelet             "Invalid preferred alignment, must be a 16bit integer");
4226c127cdbSGuillaume Chatelet       if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
423874aef87SAlex Zinenko         return reportError("Invalid preferred alignment, must be a power of 2");
4246c127cdbSGuillaume Chatelet 
425874aef87SAlex Zinenko       if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
426874aef87SAlex Zinenko                                    assumeAligned(PrefAlign), Size))
427874aef87SAlex Zinenko         return Err;
428ef860a24SChandler Carruth 
429ef860a24SChandler Carruth       break;
430ef860a24SChandler Carruth     }
431ef860a24SChandler Carruth     case 'n':  // Native integer types.
432f53a7b45SEugene Zelenko       while (true) {
433874aef87SAlex Zinenko         unsigned Width;
434874aef87SAlex Zinenko         if (Error Err = getInt(Tok, Width))
435874aef87SAlex Zinenko           return Err;
4365330c69bSDavid Majnemer         if (Width == 0)
437874aef87SAlex Zinenko           return reportError(
4385330c69bSDavid Majnemer               "Zero width native integer type in datalayout string");
439ef860a24SChandler Carruth         LegalIntWidths.push_back(Width);
440ef860a24SChandler Carruth         if (Rest.empty())
441ef860a24SChandler Carruth           break;
44266e06cc8SMichał Górny         if (Error Err = ::split(Rest, ':', Split))
443874aef87SAlex Zinenko           return Err;
444ef860a24SChandler Carruth       }
445ef860a24SChandler Carruth       break;
446ef860a24SChandler Carruth     case 'S': { // Stack natural alignment.
447874aef87SAlex Zinenko       uint64_t Alignment;
448874aef87SAlex Zinenko       if (Error Err = getIntInBytes(Tok, Alignment))
449874aef87SAlex Zinenko         return Err;
450d8c3c173SFlorian Hahn       if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
451874aef87SAlex Zinenko         return reportError("Alignment is neither 0 nor a power of 2");
452d8c3c173SFlorian Hahn       StackNaturalAlign = MaybeAlign(Alignment);
453ef860a24SChandler Carruth       break;
454ef860a24SChandler Carruth     }
455308e82ecSMichael Platings     case 'F': {
456308e82ecSMichael Platings       switch (Tok.front()) {
457308e82ecSMichael Platings       case 'i':
458308e82ecSMichael Platings         TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
459308e82ecSMichael Platings         break;
460308e82ecSMichael Platings       case 'n':
461308e82ecSMichael Platings         TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;
462308e82ecSMichael Platings         break;
463308e82ecSMichael Platings       default:
464874aef87SAlex Zinenko         return reportError("Unknown function pointer alignment type in "
465308e82ecSMichael Platings                            "datalayout string");
466308e82ecSMichael Platings       }
467308e82ecSMichael Platings       Tok = Tok.substr(1);
468874aef87SAlex Zinenko       uint64_t Alignment;
469874aef87SAlex Zinenko       if (Error Err = getIntInBytes(Tok, Alignment))
470874aef87SAlex Zinenko         return Err;
471d8c3c173SFlorian Hahn       if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
472874aef87SAlex Zinenko         return reportError("Alignment is neither 0 nor a power of 2");
473d8c3c173SFlorian Hahn       FunctionPtrAlign = MaybeAlign(Alignment);
474308e82ecSMichael Platings       break;
475308e82ecSMichael Platings     }
476ced2fe68SDylan McKay     case 'P': { // Function address space.
477874aef87SAlex Zinenko       if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))
478874aef87SAlex Zinenko         return Err;
479ced2fe68SDylan McKay       break;
480ced2fe68SDylan McKay     }
4813c1fc768SMatt Arsenault     case 'A': { // Default stack/alloca address space.
482874aef87SAlex Zinenko       if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
483874aef87SAlex Zinenko         return Err;
4843c1fc768SMatt Arsenault       break;
4853c1fc768SMatt Arsenault     }
4863bc41575SAlex Richardson     case 'G': { // Default address space for global variables.
4873bc41575SAlex Richardson       if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
4883bc41575SAlex Richardson         return Err;
4893bc41575SAlex Richardson       break;
4903bc41575SAlex Richardson     }
49158873566SRafael Espindola     case 'm':
492612f3128SDavid Majnemer       if (!Tok.empty())
493874aef87SAlex Zinenko         return reportError("Unexpected trailing characters after mangling "
494874aef87SAlex Zinenko                            "specifier in datalayout string");
495612f3128SDavid Majnemer       if (Rest.empty())
496874aef87SAlex Zinenko         return reportError("Expected mangling specifier in datalayout string");
497612f3128SDavid Majnemer       if (Rest.size() > 1)
498874aef87SAlex Zinenko         return reportError("Unknown mangling specifier in datalayout string");
49958873566SRafael Espindola       switch(Rest[0]) {
50058873566SRafael Espindola       default:
501874aef87SAlex Zinenko         return reportError("Unknown mangling in datalayout string");
50258873566SRafael Espindola       case 'e':
50358873566SRafael Espindola         ManglingMode = MM_ELF;
50458873566SRafael Espindola         break;
505e09a1dc4SAnirudh Prasad       case 'l':
506e09a1dc4SAnirudh Prasad         ManglingMode = MM_GOFF;
507e09a1dc4SAnirudh Prasad         break;
50858873566SRafael Espindola       case 'o':
50958873566SRafael Espindola         ManglingMode = MM_MachO;
51058873566SRafael Espindola         break;
51158873566SRafael Espindola       case 'm':
51258873566SRafael Espindola         ManglingMode = MM_Mips;
51358873566SRafael Espindola         break;
514af77e120SRafael Espindola       case 'w':
5157db449a6SDavid Majnemer         ManglingMode = MM_WinCOFF;
5167db449a6SDavid Majnemer         break;
5177db449a6SDavid Majnemer       case 'x':
5187db449a6SDavid Majnemer         ManglingMode = MM_WinCOFFX86;
51958873566SRafael Espindola         break;
520572dde55Sjasonliu       case 'a':
521572dde55Sjasonliu         ManglingMode = MM_XCOFF;
522572dde55Sjasonliu         break;
52358873566SRafael Espindola       }
52458873566SRafael Espindola       break;
525ef860a24SChandler Carruth     default:
526874aef87SAlex Zinenko       return reportError("Unknown specifier in datalayout string");
527ef860a24SChandler Carruth       break;
528ef860a24SChandler Carruth     }
529ef860a24SChandler Carruth   }
530874aef87SAlex Zinenko 
531874aef87SAlex Zinenko   return Error::success();
532ef860a24SChandler Carruth }
533ef860a24SChandler Carruth 
DataLayout(const Module * M)534f53a7b45SEugene Zelenko DataLayout::DataLayout(const Module *M) {
535c435adcdSRafael Espindola   init(M);
536c435adcdSRafael Espindola }
537c435adcdSRafael Espindola 
init(const Module * M)53846a43556SMehdi Amini void DataLayout::init(const Module *M) { *this = M->getDataLayout(); }
539ef860a24SChandler Carruth 
operator ==(const DataLayout & Other) const540ae593f15SRafael Espindola bool DataLayout::operator==(const DataLayout &Other) const {
541f67321cbSChandler Carruth   bool Ret = BigEndian == Other.BigEndian &&
5423c1fc768SMatt Arsenault              AllocaAddrSpace == Other.AllocaAddrSpace &&
543ae593f15SRafael Espindola              StackNaturalAlign == Other.StackNaturalAlign &&
544ced2fe68SDylan McKay              ProgramAddrSpace == Other.ProgramAddrSpace &&
5453bc41575SAlex Richardson              DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
546308e82ecSMichael Platings              FunctionPtrAlign == Other.FunctionPtrAlign &&
547308e82ecSMichael Platings              TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
548ae593f15SRafael Espindola              ManglingMode == Other.ManglingMode &&
549ae593f15SRafael Espindola              LegalIntWidths == Other.LegalIntWidths &&
55089992b0dSRafael Espindola              Alignments == Other.Alignments && Pointers == Other.Pointers;
55146a43556SMehdi Amini   // Note: getStringRepresentation() might differs, it is not canonicalized
552ae593f15SRafael Espindola   return Ret;
553ae593f15SRafael Espindola }
554ae593f15SRafael Espindola 
555490889c4SCraig Topper DataLayout::AlignmentsTy::iterator
findAlignmentLowerBound(AlignTypeEnum AlignType,uint32_t BitWidth)556490889c4SCraig Topper DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
557490889c4SCraig Topper                                     uint32_t BitWidth) {
558490889c4SCraig Topper   auto Pair = std::make_pair((unsigned)AlignType, BitWidth);
55978ee2fbfSFangrui Song   return partition_point(Alignments, [=](const LayoutAlignElem &E) {
56078ee2fbfSFangrui Song     return std::make_pair(E.AlignType, E.TypeBitWidth) < Pair;
561490889c4SCraig Topper   });
562490889c4SCraig Topper }
563490889c4SCraig Topper 
setAlignment(AlignTypeEnum align_type,Align abi_align,Align pref_align,uint32_t bit_width)564874aef87SAlex Zinenko Error DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
56518f805a7SGuillaume Chatelet                                Align pref_align, uint32_t bit_width) {
5666c127cdbSGuillaume Chatelet   // AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as
5676c127cdbSGuillaume Chatelet   // uint16_t, it is unclear if there are requirements for alignment to be less
5686c127cdbSGuillaume Chatelet   // than 2^16 other than storage. In the meantime we leave the restriction as
5696c127cdbSGuillaume Chatelet   // an assert. See D67400 for context.
5706c127cdbSGuillaume Chatelet   assert(Log2(abi_align) < 16 && Log2(pref_align) < 16 && "Alignment too big");
5711b9fc3a1SDavid Majnemer   if (!isUInt<24>(bit_width))
572874aef87SAlex Zinenko     return reportError("Invalid bit width, must be a 24bit integer");
5731b9fc3a1SDavid Majnemer   if (pref_align < abi_align)
574874aef87SAlex Zinenko     return reportError(
5751b9fc3a1SDavid Majnemer         "Preferred alignment cannot be less than the ABI alignment");
5761b9fc3a1SDavid Majnemer 
577490889c4SCraig Topper   AlignmentsTy::iterator I = findAlignmentLowerBound(align_type, bit_width);
578490889c4SCraig Topper   if (I != Alignments.end() &&
579490889c4SCraig Topper       I->AlignType == (unsigned)align_type && I->TypeBitWidth == bit_width) {
580ef860a24SChandler Carruth     // Update the abi, preferred alignments.
581490889c4SCraig Topper     I->ABIAlign = abi_align;
582490889c4SCraig Topper     I->PrefAlign = pref_align;
583490889c4SCraig Topper   } else {
584490889c4SCraig Topper     // Insert before I to keep the vector sorted.
585490889c4SCraig Topper     Alignments.insert(I, LayoutAlignElem::get(align_type, abi_align,
586ef860a24SChandler Carruth                                               pref_align, bit_width));
587ef860a24SChandler Carruth   }
588874aef87SAlex Zinenko   return Error::success();
589490889c4SCraig Topper }
590ef860a24SChandler Carruth 
591891170e8SNikita Popov const PointerAlignElem &
getPointerAlignElem(uint32_t AddressSpace) const592891170e8SNikita Popov DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
593891170e8SNikita Popov   if (AddressSpace != 0) {
594891170e8SNikita Popov     auto I = lower_bound(Pointers, AddressSpace,
5953ad5c962SBenjamin Kramer                          [](const PointerAlignElem &A, uint32_t AddressSpace) {
5963ad5c962SBenjamin Kramer       return A.AddressSpace < AddressSpace;
5973ad5c962SBenjamin Kramer     });
598891170e8SNikita Popov     if (I != Pointers.end() && I->AddressSpace == AddressSpace)
599891170e8SNikita Popov       return *I;
600891170e8SNikita Popov   }
601891170e8SNikita Popov 
602891170e8SNikita Popov   assert(Pointers[0].AddressSpace == 0);
603891170e8SNikita Popov   return Pointers[0];
604667fcb83SRafael Espindola }
605667fcb83SRafael Espindola 
setPointerAlignmentInBits(uint32_t AddrSpace,Align ABIAlign,Align PrefAlign,uint32_t TypeBitWidth,uint32_t IndexBitWidth)6060fcb16eeSStephen Neuendorffer Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
6070fcb16eeSStephen Neuendorffer                                             Align PrefAlign,
6080fcb16eeSStephen Neuendorffer                                             uint32_t TypeBitWidth,
6090fcb16eeSStephen Neuendorffer                                             uint32_t IndexBitWidth) {
6104b042926SDavid Majnemer   if (PrefAlign < ABIAlign)
611874aef87SAlex Zinenko     return reportError(
6124b042926SDavid Majnemer         "Preferred alignment cannot be less than the ABI alignment");
6134b042926SDavid Majnemer 
614891170e8SNikita Popov   auto I = lower_bound(Pointers, AddrSpace,
615891170e8SNikita Popov                        [](const PointerAlignElem &A, uint32_t AddressSpace) {
616891170e8SNikita Popov     return A.AddressSpace < AddressSpace;
617891170e8SNikita Popov   });
618667fcb83SRafael Espindola   if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
6190fcb16eeSStephen Neuendorffer     Pointers.insert(I,
6200fcb16eeSStephen Neuendorffer                     PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign,
6210fcb16eeSStephen Neuendorffer                                                 TypeBitWidth, IndexBitWidth));
622ef860a24SChandler Carruth   } else {
623667fcb83SRafael Espindola     I->ABIAlign = ABIAlign;
624667fcb83SRafael Espindola     I->PrefAlign = PrefAlign;
6250fcb16eeSStephen Neuendorffer     I->TypeBitWidth = TypeBitWidth;
6260fcb16eeSStephen Neuendorffer     I->IndexBitWidth = IndexBitWidth;
627ef860a24SChandler Carruth   }
628874aef87SAlex Zinenko   return Error::success();
629ef860a24SChandler Carruth }
630ef860a24SChandler Carruth 
getIntegerAlignment(uint32_t BitWidth,bool abi_or_pref) const631b5f23189SNikita Popov Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
632b5f23189SNikita Popov                                       bool abi_or_pref) const {
633b5f23189SNikita Popov   auto I = findAlignmentLowerBound(INTEGER_ALIGN, BitWidth);
634b5f23189SNikita Popov   // If we don't have an exact match, use alignment of next larger integer
635b5f23189SNikita Popov   // type. If there is none, use alignment of largest integer type by going
636b5f23189SNikita Popov   // back one element.
637b5f23189SNikita Popov   if (I == Alignments.end() || I->AlignType != INTEGER_ALIGN)
638b5f23189SNikita Popov     --I;
639b5f23189SNikita Popov   assert(I->AlignType == INTEGER_ALIGN && "Must be integer alignment");
640b5f23189SNikita Popov   return abi_or_pref ? I->ABIAlign : I->PrefAlign;
6417e621e9dSOwen Anderson }
6427e621e9dSOwen Anderson 
643ef860a24SChandler Carruth namespace {
644ef860a24SChandler Carruth 
645ef860a24SChandler Carruth class StructLayoutMap {
646f53a7b45SEugene Zelenko   using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;
647ef860a24SChandler Carruth   LayoutInfoTy LayoutInfo;
648ef860a24SChandler Carruth 
649ef860a24SChandler Carruth public:
~StructLayoutMap()6503ad5c962SBenjamin Kramer   ~StructLayoutMap() {
651ef860a24SChandler Carruth     // Remove any layouts.
6523ad5c962SBenjamin Kramer     for (const auto &I : LayoutInfo) {
6533ad5c962SBenjamin Kramer       StructLayout *Value = I.second;
654ef860a24SChandler Carruth       Value->~StructLayout();
655ef860a24SChandler Carruth       free(Value);
656ef860a24SChandler Carruth     }
657ef860a24SChandler Carruth   }
658ef860a24SChandler Carruth 
operator [](StructType * STy)6590ae73930SPete Cooper   StructLayout *&operator[](StructType *STy) {
660ef860a24SChandler Carruth     return LayoutInfo[STy];
661ef860a24SChandler Carruth   }
662ef860a24SChandler Carruth };
663ef860a24SChandler Carruth 
664ef860a24SChandler Carruth } // end anonymous namespace
665ef860a24SChandler Carruth 
clear()666248ac139SRafael Espindola void DataLayout::clear() {
667248ac139SRafael Espindola   LegalIntWidths.clear();
668248ac139SRafael Espindola   Alignments.clear();
669248ac139SRafael Espindola   Pointers.clear();
670ef860a24SChandler Carruth   delete static_cast<StructLayoutMap *>(LayoutMap);
671c620761cSCraig Topper   LayoutMap = nullptr;
672248ac139SRafael Espindola }
673248ac139SRafael Espindola 
~DataLayout()674248ac139SRafael Espindola DataLayout::~DataLayout() {
675248ac139SRafael Espindola   clear();
676ef860a24SChandler Carruth }
677ef860a24SChandler Carruth 
getStructLayout(StructType * Ty) const6780ae73930SPete Cooper const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
679ef860a24SChandler Carruth   if (!LayoutMap)
680ef860a24SChandler Carruth     LayoutMap = new StructLayoutMap();
681ef860a24SChandler Carruth 
682ef860a24SChandler Carruth   StructLayoutMap *STM = static_cast<StructLayoutMap*>(LayoutMap);
683ef860a24SChandler Carruth   StructLayout *&SL = (*STM)[Ty];
684ef860a24SChandler Carruth   if (SL) return SL;
685ef860a24SChandler Carruth 
686ef860a24SChandler Carruth   // Otherwise, create the struct layout.  Because it is variable length, we
687ef860a24SChandler Carruth   // malloc it, then use placement new.
688f59ba084SCraig Topper   StructLayout *L = (StructLayout *)safe_malloc(
689f59ba084SCraig Topper       StructLayout::totalSizeToAlloc<uint64_t>(Ty->getNumElements()));
690ef860a24SChandler Carruth 
691ef860a24SChandler Carruth   // Set SL before calling StructLayout's ctor.  The ctor could cause other
692ef860a24SChandler Carruth   // entries to be added to TheMap, invalidating our reference.
693ef860a24SChandler Carruth   SL = L;
694ef860a24SChandler Carruth 
695ef860a24SChandler Carruth   new (L) StructLayout(Ty, *this);
696ef860a24SChandler Carruth 
697ef860a24SChandler Carruth   return L;
698ef860a24SChandler Carruth }
699ef860a24SChandler Carruth 
getPointerABIAlignment(unsigned AS) const70018f805a7SGuillaume Chatelet Align DataLayout::getPointerABIAlignment(unsigned AS) const {
701891170e8SNikita Popov   return getPointerAlignElem(AS).ABIAlign;
7025109fcc0SRafael Espindola }
7035109fcc0SRafael Espindola 
getPointerPrefAlignment(unsigned AS) const70418f805a7SGuillaume Chatelet Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
705891170e8SNikita Popov   return getPointerAlignElem(AS).PrefAlign;
7065109fcc0SRafael Espindola }
7075109fcc0SRafael Espindola 
getPointerSize(unsigned AS) const7085109fcc0SRafael Espindola unsigned DataLayout::getPointerSize(unsigned AS) const {
7090fcb16eeSStephen Neuendorffer   return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8);
7105109fcc0SRafael Espindola }
7115109fcc0SRafael Espindola 
getMaxIndexSize() const712a8c318b5SNikita Popov unsigned DataLayout::getMaxIndexSize() const {
713a8c318b5SNikita Popov   unsigned MaxIndexSize = 0;
7144f238144SHal Finkel   for (auto &P : Pointers)
7150fcb16eeSStephen Neuendorffer     MaxIndexSize =
7160fcb16eeSStephen Neuendorffer         std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8));
7174f238144SHal Finkel 
718a8c318b5SNikita Popov   return MaxIndexSize;
7194f238144SHal Finkel }
7204f238144SHal Finkel 
getPointerTypeSizeInBits(Type * Ty) const7210ae73930SPete Cooper unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
7226f4be905SMatt Arsenault   assert(Ty->isPtrOrPtrVectorTy() &&
7236f4be905SMatt Arsenault          "This should only be called with a pointer or pointer vector type");
7245b4f5b08SCraig Topper   Ty = Ty->getScalarType();
7255b4f5b08SCraig Topper   return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
7266f4be905SMatt Arsenault }
727ef860a24SChandler Carruth 
getIndexSize(unsigned AS) const728945b7e5aSElena Demikhovsky unsigned DataLayout::getIndexSize(unsigned AS) const {
7290fcb16eeSStephen Neuendorffer   return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8);
730945b7e5aSElena Demikhovsky }
731945b7e5aSElena Demikhovsky 
getIndexTypeSizeInBits(Type * Ty) const732945b7e5aSElena Demikhovsky unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
733945b7e5aSElena Demikhovsky   assert(Ty->isPtrOrPtrVectorTy() &&
734945b7e5aSElena Demikhovsky          "This should only be called with a pointer or pointer vector type");
735945b7e5aSElena Demikhovsky   Ty = Ty->getScalarType();
736945b7e5aSElena Demikhovsky   return getIndexSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
737945b7e5aSElena Demikhovsky }
738945b7e5aSElena Demikhovsky 
739ef860a24SChandler Carruth /*!
740ef860a24SChandler Carruth   \param abi_or_pref Flag that determines which alignment is returned. true
741ef860a24SChandler Carruth   returns the ABI alignment, false returns the preferred alignment.
742ef860a24SChandler Carruth   \param Ty The underlying type for which alignment is determined.
743ef860a24SChandler Carruth 
744ef860a24SChandler Carruth   Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
745ef860a24SChandler Carruth   == false) for the requested type \a Ty.
746ef860a24SChandler Carruth  */
getAlignment(Type * Ty,bool abi_or_pref) const74718f805a7SGuillaume Chatelet Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
748ef860a24SChandler Carruth   assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
749ef860a24SChandler Carruth   switch (Ty->getTypeID()) {
750ef860a24SChandler Carruth   // Early escape for the non-numeric types.
751ef860a24SChandler Carruth   case Type::LabelTyID:
7521ae7905fSGuillaume Chatelet     return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0);
753ef860a24SChandler Carruth   case Type::PointerTyID: {
754c1728972SMatt Arsenault     unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
7551ae7905fSGuillaume Chatelet     return abi_or_pref ? getPointerABIAlignment(AS)
7561ae7905fSGuillaume Chatelet                        : getPointerPrefAlignment(AS);
757ef860a24SChandler Carruth     }
758ef860a24SChandler Carruth   case Type::ArrayTyID:
759ef860a24SChandler Carruth     return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
760ef860a24SChandler Carruth 
761ef860a24SChandler Carruth   case Type::StructTyID: {
762ef860a24SChandler Carruth     // Packed structure types always have an ABI alignment of one.
763ef860a24SChandler Carruth     if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
764805c157eSGuillaume Chatelet       return Align(1);
765ef860a24SChandler Carruth 
766ef860a24SChandler Carruth     // Get the layout annotation... which is lazily created on demand.
767ef860a24SChandler Carruth     const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
768b5f23189SNikita Popov     const LayoutAlignElem &AggregateAlign = Alignments[0];
769b5f23189SNikita Popov     assert(AggregateAlign.AlignType == AGGREGATE_ALIGN &&
770b5f23189SNikita Popov            "Aggregate alignment must be first alignment entry");
771b5f23189SNikita Popov     const Align Align =
772b5f23189SNikita Popov         abi_or_pref ? AggregateAlign.ABIAlign : AggregateAlign.PrefAlign;
773ef860a24SChandler Carruth     return std::max(Align, Layout->getAlignment());
774ef860a24SChandler Carruth   }
775ef860a24SChandler Carruth   case Type::IntegerTyID:
776b5f23189SNikita Popov     return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
777ef860a24SChandler Carruth   case Type::HalfTyID:
7788c24f331STies Stuij   case Type::BFloatTyID:
779ef860a24SChandler Carruth   case Type::FloatTyID:
780ef860a24SChandler Carruth   case Type::DoubleTyID:
781ef860a24SChandler Carruth   // PPC_FP128TyID and FP128TyID have different data contents, but the
782ef860a24SChandler Carruth   // same size and alignment, so they look the same here.
783ef860a24SChandler Carruth   case Type::PPC_FP128TyID:
784ef860a24SChandler Carruth   case Type::FP128TyID:
785b5f23189SNikita Popov   case Type::X86_FP80TyID: {
786b5f23189SNikita Popov     unsigned BitWidth = getTypeSizeInBits(Ty).getFixedSize();
787b5f23189SNikita Popov     auto I = findAlignmentLowerBound(FLOAT_ALIGN, BitWidth);
788b5f23189SNikita Popov     if (I != Alignments.end() && I->AlignType == FLOAT_ALIGN &&
789b5f23189SNikita Popov         I->TypeBitWidth == BitWidth)
790b5f23189SNikita Popov       return abi_or_pref ? I->ABIAlign : I->PrefAlign;
791b5f23189SNikita Popov 
792b5f23189SNikita Popov     // If we still couldn't find a reasonable default alignment, fall back
793b5f23189SNikita Popov     // to a simple heuristic that the alignment is the first power of two
794b5f23189SNikita Popov     // greater-or-equal to the store size of the type.  This is a reasonable
795b5f23189SNikita Popov     // approximation of reality, and if the user wanted something less
796b5f23189SNikita Popov     // less conservative, they should have specified it explicitly in the data
797b5f23189SNikita Popov     // layout.
798b5f23189SNikita Popov     return Align(PowerOf2Ceil(BitWidth / 8));
799b5f23189SNikita Popov   }
800ef860a24SChandler Carruth   case Type::X86_MMXTyID:
8012dea3f12SChristopher Tetreault   case Type::FixedVectorTyID:
802b5f23189SNikita Popov   case Type::ScalableVectorTyID: {
803b5f23189SNikita Popov     unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinSize();
804b5f23189SNikita Popov     auto I = findAlignmentLowerBound(VECTOR_ALIGN, BitWidth);
805b5f23189SNikita Popov     if (I != Alignments.end() && I->AlignType == VECTOR_ALIGN &&
806b5f23189SNikita Popov         I->TypeBitWidth == BitWidth)
807b5f23189SNikita Popov       return abi_or_pref ? I->ABIAlign : I->PrefAlign;
808b5f23189SNikita Popov 
809b5f23189SNikita Popov     // By default, use natural alignment for vector types. This is consistent
810b5f23189SNikita Popov     // with what clang and llvm-gcc do.
811bdd55b2fSEli Friedman     //
812b5f23189SNikita Popov     // We're only calculating a natural alignment, so it doesn't have to be
813b5f23189SNikita Popov     // based on the full size for scalable vectors. Using the minimum element
814b5f23189SNikita Popov     // count should be enough here.
815bdd55b2fSEli Friedman     return Align(PowerOf2Ceil(getTypeStoreSize(Ty).getKnownMinSize()));
816b5f23189SNikita Popov   }
817981a0bd8SLuo, Yuanke   case Type::X86_AMXTyID:
818981a0bd8SLuo, Yuanke     return Align(64);
819ef860a24SChandler Carruth   default:
820ef860a24SChandler Carruth     llvm_unreachable("Bad type for getAlignment!!!");
821ef860a24SChandler Carruth   }
822ef860a24SChandler Carruth }
823ef860a24SChandler Carruth 
82459f95222SGuillaume Chatelet /// TODO: Remove this function once the transition to Align is over.
getABITypeAlignment(Type * Ty) const82505392466SArthur Eubanks uint64_t DataLayout::getABITypeAlignment(Type *Ty) const {
82659f95222SGuillaume Chatelet   return getABITypeAlign(Ty).value();
82759f95222SGuillaume Chatelet }
82859f95222SGuillaume Chatelet 
getABITypeAlign(Type * Ty) const82959f95222SGuillaume Chatelet Align DataLayout::getABITypeAlign(Type *Ty) const {
83059f95222SGuillaume Chatelet   return getAlignment(Ty, true);
831ef860a24SChandler Carruth }
832ef860a24SChandler Carruth 
83359f95222SGuillaume Chatelet /// TODO: Remove this function once the transition to Align is over.
getPrefTypeAlignment(Type * Ty) const83405392466SArthur Eubanks uint64_t DataLayout::getPrefTypeAlignment(Type *Ty) const {
83559f95222SGuillaume Chatelet   return getPrefTypeAlign(Ty).value();
83659f95222SGuillaume Chatelet }
83759f95222SGuillaume Chatelet 
getPrefTypeAlign(Type * Ty) const83859f95222SGuillaume Chatelet Align DataLayout::getPrefTypeAlign(Type *Ty) const {
83959f95222SGuillaume Chatelet   return getAlignment(Ty, false);
840ef860a24SChandler Carruth }
841ef860a24SChandler Carruth 
getIntPtrType(LLVMContext & C,unsigned AddressSpace) const842ef860a24SChandler Carruth IntegerType *DataLayout::getIntPtrType(LLVMContext &C,
843ef860a24SChandler Carruth                                        unsigned AddressSpace) const {
84497572775SNicola Zaghen   return IntegerType::get(C, getPointerSizeInBits(AddressSpace));
845ef860a24SChandler Carruth }
846ef860a24SChandler Carruth 
getIntPtrType(Type * Ty) const8470ae73930SPete Cooper Type *DataLayout::getIntPtrType(Type *Ty) const {
848ef860a24SChandler Carruth   assert(Ty->isPtrOrPtrVectorTy() &&
849ef860a24SChandler Carruth          "Expected a pointer or pointer vector type.");
85097572775SNicola Zaghen   unsigned NumBits = getPointerTypeSizeInBits(Ty);
851ef860a24SChandler Carruth   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
8520ae73930SPete Cooper   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
8537a834a0aSDavid Sherwood     return VectorType::get(IntTy, VecTy);
854ef860a24SChandler Carruth   return IntTy;
855ef860a24SChandler Carruth }
856ef860a24SChandler Carruth 
getSmallestLegalIntType(LLVMContext & C,unsigned Width) const857f364bc63SArnaud A. de Grandmaison Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
8583ad5c962SBenjamin Kramer   for (unsigned LegalIntWidth : LegalIntWidths)
8593ad5c962SBenjamin Kramer     if (Width <= LegalIntWidth)
8603ad5c962SBenjamin Kramer       return Type::getIntNTy(C, LegalIntWidth);
861c620761cSCraig Topper   return nullptr;
862f364bc63SArnaud A. de Grandmaison }
863f364bc63SArnaud A. de Grandmaison 
getLargestLegalIntTypeSizeInBits() const864be11bdc4SJun Bum Lim unsigned DataLayout::getLargestLegalIntTypeSizeInBits() const {
8653ad5c962SBenjamin Kramer   auto Max = std::max_element(LegalIntWidths.begin(), LegalIntWidths.end());
8663ad5c962SBenjamin Kramer   return Max != LegalIntWidths.end() ? *Max : 0;
867899f7d2bSMatt Arsenault }
868899f7d2bSMatt Arsenault 
getIndexType(Type * Ty) const869945b7e5aSElena Demikhovsky Type *DataLayout::getIndexType(Type *Ty) const {
870945b7e5aSElena Demikhovsky   assert(Ty->isPtrOrPtrVectorTy() &&
871945b7e5aSElena Demikhovsky          "Expected a pointer or pointer vector type.");
872945b7e5aSElena Demikhovsky   unsigned NumBits = getIndexTypeSizeInBits(Ty);
873945b7e5aSElena Demikhovsky   IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
874945b7e5aSElena Demikhovsky   if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
87590ad7869SEli Friedman     return VectorType::get(IntTy, VecTy);
876945b7e5aSElena Demikhovsky   return IntTy;
877945b7e5aSElena Demikhovsky }
878945b7e5aSElena Demikhovsky 
getIndexedOffsetInType(Type * ElemTy,ArrayRef<Value * > Indices) const87917bdf445SDavid Majnemer int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
880ef860a24SChandler Carruth                                            ArrayRef<Value *> Indices) const {
88117bdf445SDavid Majnemer   int64_t Result = 0;
882ef860a24SChandler Carruth 
883ef860a24SChandler Carruth   generic_gep_type_iterator<Value* const*>
884ab85225bSPeter Collingbourne     GTI = gep_type_begin(ElemTy, Indices),
885ab85225bSPeter Collingbourne     GTE = gep_type_end(ElemTy, Indices);
88668e7f49fSEduard Burtescu   for (; GTI != GTE; ++GTI) {
88768e7f49fSEduard Burtescu     Value *Idx = GTI.getOperand();
888ab85225bSPeter Collingbourne     if (StructType *STy = GTI.getStructTypeOrNull()) {
889cc13c2cfSManuel Jacob       assert(Idx->getType()->isIntegerTy(32) && "Illegal struct idx");
89068e7f49fSEduard Burtescu       unsigned FieldNo = cast<ConstantInt>(Idx)->getZExtValue();
891ef860a24SChandler Carruth 
892ef860a24SChandler Carruth       // Get structure layout information...
893ef860a24SChandler Carruth       const StructLayout *Layout = getStructLayout(STy);
894ef860a24SChandler Carruth 
895ef860a24SChandler Carruth       // Add in the offset, as calculated by the structure layout info...
896ef860a24SChandler Carruth       Result += Layout->getElementOffset(FieldNo);
897ef860a24SChandler Carruth     } else {
898ef860a24SChandler Carruth       // Get the array index and the size of each array element.
89968e7f49fSEduard Burtescu       if (int64_t arrayIdx = cast<ConstantInt>(Idx)->getSExtValue())
90017bdf445SDavid Majnemer         Result += arrayIdx * getTypeAllocSize(GTI.getIndexedType());
901ef860a24SChandler Carruth     }
902ef860a24SChandler Carruth   }
903ef860a24SChandler Carruth 
904ef860a24SChandler Carruth   return Result;
905ef860a24SChandler Carruth }
906ef860a24SChandler Carruth 
getElementIndex(TypeSize ElemSize,APInt & Offset)9071d1e29baSNikita Popov static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
9085969e574SNikita Popov   // Skip over scalable or zero size elements. Also skip element sizes larger
9095969e574SNikita Popov   // than the positive index space, because the arithmetic below may not be
9105969e574SNikita Popov   // correct in that case.
9115969e574SNikita Popov   unsigned BitWidth = Offset.getBitWidth();
9125969e574SNikita Popov   if (ElemSize.isScalable() || ElemSize == 0 ||
9135969e574SNikita Popov       !isUIntN(BitWidth - 1, ElemSize)) {
9141d1e29baSNikita Popov     return APInt::getZero(BitWidth);
915dd022656SNikita Popov   }
916dd022656SNikita Popov 
917dd022656SNikita Popov   APInt Index = Offset.sdiv(ElemSize);
918dd022656SNikita Popov   Offset -= Index * ElemSize;
919dd022656SNikita Popov   if (Offset.isNegative()) {
920dd022656SNikita Popov     // Prefer a positive remaining offset to allow struct indexing.
921dd022656SNikita Popov     --Index;
922dd022656SNikita Popov     Offset += ElemSize;
923dd022656SNikita Popov     assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
924dd022656SNikita Popov   }
9251d1e29baSNikita Popov   return Index;
926dd022656SNikita Popov }
927dd022656SNikita Popov 
getGEPIndexForOffset(Type * & ElemTy,APInt & Offset) const9281d1e29baSNikita Popov Optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,
929dd022656SNikita Popov                                                  APInt &Offset) const {
930dd022656SNikita Popov   if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
931dd022656SNikita Popov     ElemTy = ArrTy->getElementType();
9321d1e29baSNikita Popov     return getElementIndex(getTypeAllocSize(ElemTy), Offset);
933dd022656SNikita Popov   }
934dd022656SNikita Popov 
935dd022656SNikita Popov   if (auto *VecTy = dyn_cast<VectorType>(ElemTy)) {
936dd022656SNikita Popov     ElemTy = VecTy->getElementType();
937dd022656SNikita Popov     unsigned ElemSizeInBits = getTypeSizeInBits(ElemTy).getFixedSize();
938dd022656SNikita Popov     // GEPs over non-multiple of 8 size vector elements are invalid.
939dd022656SNikita Popov     if (ElemSizeInBits % 8 != 0)
9401d1e29baSNikita Popov       return None;
941dd022656SNikita Popov 
9421d1e29baSNikita Popov     return getElementIndex(TypeSize::Fixed(ElemSizeInBits / 8), Offset);
943dd022656SNikita Popov   }
944dd022656SNikita Popov 
945dd022656SNikita Popov   if (auto *STy = dyn_cast<StructType>(ElemTy)) {
946dd022656SNikita Popov     const StructLayout *SL = getStructLayout(STy);
947dd022656SNikita Popov     uint64_t IntOffset = Offset.getZExtValue();
948dd022656SNikita Popov     if (IntOffset >= SL->getSizeInBytes())
9491d1e29baSNikita Popov       return None;
950dd022656SNikita Popov 
951dd022656SNikita Popov     unsigned Index = SL->getElementContainingOffset(IntOffset);
952dd022656SNikita Popov     Offset -= SL->getElementOffset(Index);
953dd022656SNikita Popov     ElemTy = STy->getElementType(Index);
9541d1e29baSNikita Popov     return APInt(32, Index);
955dd022656SNikita Popov   }
956dd022656SNikita Popov 
9571d1e29baSNikita Popov   // Non-aggregate type.
9581d1e29baSNikita Popov   return None;
9591d1e29baSNikita Popov }
9601d1e29baSNikita Popov 
getGEPIndicesForOffset(Type * & ElemTy,APInt & Offset) const9611d1e29baSNikita Popov SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
9621d1e29baSNikita Popov                                                       APInt &Offset) const {
9631d1e29baSNikita Popov   assert(ElemTy->isSized() && "Element type must be sized");
9641d1e29baSNikita Popov   SmallVector<APInt> Indices;
9651d1e29baSNikita Popov   Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));
9661d1e29baSNikita Popov   while (Offset != 0) {
9671d1e29baSNikita Popov     Optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);
9681d1e29baSNikita Popov     if (!Index)
969dd022656SNikita Popov       break;
9701d1e29baSNikita Popov     Indices.push_back(*Index);
971dd022656SNikita Popov   }
972dd022656SNikita Popov 
973dd022656SNikita Popov   return Indices;
974dd022656SNikita Popov }
975dd022656SNikita Popov 
976368a5e3aSGuillaume Chatelet /// getPreferredAlign - Return the preferred alignment of the specified global.
977368a5e3aSGuillaume Chatelet /// This includes an explicitly requested alignment (if the global has one).
getPreferredAlign(const GlobalVariable * GV) const978368a5e3aSGuillaume Chatelet Align DataLayout::getPreferredAlign(const GlobalVariable *GV) const {
979368a5e3aSGuillaume Chatelet   MaybeAlign GVAlignment = GV->getAlign();
98037696393SEli Friedman   // If a section is specified, always precisely honor explicit alignment,
98137696393SEli Friedman   // so we don't insert padding into a section we don't control.
98237696393SEli Friedman   if (GVAlignment && GV->hasSection())
983368a5e3aSGuillaume Chatelet     return *GVAlignment;
98437696393SEli Friedman 
98537696393SEli Friedman   // If no explicit alignment is specified, compute the alignment based on
98637696393SEli Friedman   // the IR type. If an alignment is specified, increase it to match the ABI
98737696393SEli Friedman   // alignment of the IR type.
98837696393SEli Friedman   //
98937696393SEli Friedman   // FIXME: Not sure it makes sense to use the alignment of the type if
99037696393SEli Friedman   // there's already an explicit alignment specification.
9915f6eaac6SManuel Jacob   Type *ElemType = GV->getValueType();
992368a5e3aSGuillaume Chatelet   Align Alignment = getPrefTypeAlign(ElemType);
993368a5e3aSGuillaume Chatelet   if (GVAlignment) {
994368a5e3aSGuillaume Chatelet     if (*GVAlignment >= Alignment)
995368a5e3aSGuillaume Chatelet       Alignment = *GVAlignment;
996368a5e3aSGuillaume Chatelet     else
997368a5e3aSGuillaume Chatelet       Alignment = std::max(*GVAlignment, getABITypeAlign(ElemType));
998ef860a24SChandler Carruth   }
999ef860a24SChandler Carruth 
100037696393SEli Friedman   // If no explicit alignment is specified, and the global is large, increase
100137696393SEli Friedman   // the alignment to 16.
100237696393SEli Friedman   // FIXME: Why 16, specifically?
1003368a5e3aSGuillaume Chatelet   if (GV->hasInitializer() && !GVAlignment) {
1004368a5e3aSGuillaume Chatelet     if (Alignment < Align(16)) {
1005ef860a24SChandler Carruth       // If the global is not external, see if it is large.  If so, give it a
1006ef860a24SChandler Carruth       // larger alignment.
1007ef860a24SChandler Carruth       if (getTypeSizeInBits(ElemType) > 128)
1008368a5e3aSGuillaume Chatelet         Alignment = Align(16); // 16-byte alignment.
1009ef860a24SChandler Carruth     }
1010ef860a24SChandler Carruth   }
1011ef860a24SChandler Carruth   return Alignment;
1012ef860a24SChandler Carruth }
1013