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