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