aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-06-13 19:31:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-07-31 18:56:55 +0000
commitaf732203b8f7f006927528db5497f5cbc4c4742a (patch)
tree596f112de3b76118552871dbb6114bb7e3e17f40 /contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
parent83dea422ac8d4a8323e64203c2eadaa813768717 (diff)
downloadsrc-af732203b8f7f006927528db5497f5cbc4c4742a.tar.gz
src-af732203b8f7f006927528db5497f5cbc4c4742a.zip
Merge llvm-project 12.0.1 release and follow-up fixes
Merge llvm-project main llvmorg-12-init-17869-g8e464dd76bef This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12-init-17869-g8e464dd76bef, the last commit before the upstream release/12.x branch was created. PR: 255570 (cherry picked from commit e8d8bef961a50d4dc22501cde4fb9fb0be1b2532) Merge llvm-project 12.0.0 release This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.0-0-gd28af7c654d8, a.k.a. 12.0.0 release. PR: 255570 (cherry picked from commit d409305fa3838fb39b38c26fc085fb729b8766d5) Disable strict-fp for powerpcspe, as it does not work properly yet Merge commit 5c18d1136665 from llvm git (by Qiu Chaofan) [SPE] Disable strict-fp for SPE by default As discussed in PR50385, strict-fp on PowerPC SPE has not been handled well. This patch disables it by default for SPE. Reviewed By: nemanjai, vit9696, jhibbits Differential Revision: https://reviews.llvm.org/D103235 PR: 255570 (cherry picked from commit 715df83abc049b23d9acddc81f2480bd4c056d64) Apply upstream libc++ fix to allow building with devel/xxx-xtoolchain-gcc Merge commit 52e9d80d5db2 from llvm git (by Jason Liu): [libc++] add `inline` for __open's definition in ifstream and ofstream Summary: When building with gcc on AIX, it seems that gcc does not like the `always_inline` without the `inline` keyword. So adding the inline keywords in for __open in ifstream and ofstream. That will also make it consistent with __open in basic_filebuf (it seems we added `inline` there before for gcc build as well). Differential Revision: https://reviews.llvm.org/D99422 PR: 255570 (cherry picked from commit d099db25464b826c5724cf2fb5b22292bbe15f6e) Undefine HAVE_(DE)REGISTER_FRAME in llvm's config.h on arm Otherwise, the lli tool (enable by WITH_CLANG_EXTRAS) won't link on arm, stating that __register_frame is undefined. This function is normally provided by libunwind, but explicitly not for the ARM Exception ABI. Reported by: oh PR: 255570 (cherry picked from commit f336b45e943c7f9a90ffcea1a6c4c7039e54c73c) Merge llvm-project 12.0.1 rc2 This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.1-rc2-0-ge7dac564cd0e, a.k.a. 12.0.1 rc2. PR: 255570 (cherry picked from commit 23408297fbf3089f0388a8873b02fa75ab3f5bb9) Revert libunwind change to fix backtrace segfault on aarch64 Revert commit 22b615a96593 from llvm git (by Daniel Kiss): [libunwind] Support for leaf function unwinding. Unwinding leaf function is useful in cases when the backtrace finds a leaf function for example when it caused a signal. This patch also add the support for the DW_CFA_undefined because it marks the end of the frames. Ryan Prichard provided code for the tests. Reviewed By: #libunwind, mstorsjo Differential Revision: https://reviews.llvm.org/D83573 Reland with limit the test to the x86_64-linux target. Bisection has shown that this particular upstream commit causes programs using backtrace(3) on aarch64 to segfault. This affects the lang/rust port, for instance. Until we can upstream to fix this problem, revert the commit for now. Reported by: mikael PR: 256864 (cherry picked from commit 5866c369e4fd917c0d456f0f10b92ee354b82279) Merge llvm-project 12.0.1 release This updates llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp to llvmorg-12.0.1-0-gfed41342a82f, a.k.a. 12.0.1 release. PR: 255570 (cherry picked from commit 4652422eb477731f284b1345afeefef7f269da50) compilert-rt: build out-of-line LSE atomics helpers for aarch64 Both clang >= 12 and gcc >= 10.1 now default to -moutline-atomics for aarch64. This requires a bunch of helper functions in libcompiler_rt.a, to avoid link errors like "undefined symbol: __aarch64_ldadd8_acq_rel". (Note: of course you can use -mno-outline-atomics as a workaround too, but this would negate the potential performance benefit of the faster LSE instructions.) Bump __FreeBSD_version so ports maintainers can easily detect this. PR: 257392 (cherry picked from commit cc55ee8009a550810d38777fd6ace9abf3a2f6b4)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/DataLayout.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/IR/DataLayout.cpp414
1 files changed, 232 insertions, 182 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp b/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
index c44737c5bfc2..274ea0aa5fd1 100644
--- a/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
+++ b/contrib/llvm-project/llvm/lib/IR/DataLayout.cpp
@@ -27,6 +27,7 @@
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TypeSize.h"
@@ -64,7 +65,8 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
StructAlignment = std::max(TyAlign, StructAlignment);
MemberOffsets[i] = StructSize;
- StructSize += DL.getTypeAllocSize(Ty); // Consume space for this data item
+ // Consume space for this data item
+ StructSize += DL.getTypeAllocSize(Ty).getFixedValue();
}
// Add padding to the end of the struct so that it could be put in an array
@@ -181,6 +183,7 @@ void DataLayout::reset(StringRef Desc) {
AllocaAddrSpace = 0;
StackNaturalAlign.reset();
ProgramAddrSpace = 0;
+ DefaultGlobalsAddrSpace = 0;
FunctionPtrAlign.reset();
TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
ManglingMode = MM_None;
@@ -188,57 +191,80 @@ void DataLayout::reset(StringRef Desc) {
// Default alignments
for (const LayoutAlignElem &E : DefaultAlignments) {
- setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
- E.TypeBitWidth);
+ if (Error Err = setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign,
+ E.PrefAlign, E.TypeBitWidth))
+ return report_fatal_error(std::move(Err));
}
- setPointerAlignment(0, Align(8), Align(8), 8, 8);
+ if (Error Err = setPointerAlignment(0, Align(8), Align(8), 8, 8))
+ return report_fatal_error(std::move(Err));
- parseSpecifier(Desc);
+ if (Error Err = parseSpecifier(Desc))
+ return report_fatal_error(std::move(Err));
+}
+
+Expected<DataLayout> DataLayout::parse(StringRef LayoutDescription) {
+ DataLayout Layout("");
+ if (Error Err = Layout.parseSpecifier(LayoutDescription))
+ return std::move(Err);
+ return Layout;
+}
+
+static Error reportError(const Twine &Message) {
+ return createStringError(inconvertibleErrorCode(), Message);
}
/// Checked version of split, to ensure mandatory subparts.
-static std::pair<StringRef, StringRef> split(StringRef Str, char Separator) {
+static Error split(StringRef Str, char Separator,
+ std::pair<StringRef, StringRef> &Split) {
assert(!Str.empty() && "parse error, string can't be empty here");
- std::pair<StringRef, StringRef> Split = Str.split(Separator);
+ Split = Str.split(Separator);
if (Split.second.empty() && Split.first != Str)
- report_fatal_error("Trailing separator in datalayout string");
+ return reportError("Trailing separator in datalayout string");
if (!Split.second.empty() && Split.first.empty())
- report_fatal_error("Expected token before separator in datalayout string");
- return Split;
+ return reportError("Expected token before separator in datalayout string");
+ return Error::success();
}
/// Get an unsigned integer, including error checks.
-static unsigned getInt(StringRef R) {
- unsigned Result;
+template <typename IntTy> static Error getInt(StringRef R, IntTy &Result) {
bool error = R.getAsInteger(10, Result); (void)error;
if (error)
- report_fatal_error("not a number, or does not fit in an unsigned int");
- return Result;
+ return reportError("not a number, or does not fit in an unsigned int");
+ return Error::success();
}
-/// Convert bits into bytes. Assert if not a byte width multiple.
-static unsigned inBytes(unsigned Bits) {
- if (Bits % 8)
- report_fatal_error("number of bits must be a byte width multiple");
- return Bits / 8;
+/// Get an unsigned integer representing the number of bits and convert it into
+/// bytes. Error out of not a byte width multiple.
+template <typename IntTy>
+static Error getIntInBytes(StringRef R, IntTy &Result) {
+ if (Error Err = getInt<IntTy>(R, Result))
+ return Err;
+ if (Result % 8)
+ return reportError("number of bits must be a byte width multiple");
+ Result /= 8;
+ return Error::success();
}
-static unsigned getAddrSpace(StringRef R) {
- unsigned AddrSpace = getInt(R);
+static Error getAddrSpace(StringRef R, unsigned &AddrSpace) {
+ if (Error Err = getInt(R, AddrSpace))
+ return Err;
if (!isUInt<24>(AddrSpace))
- report_fatal_error("Invalid address space, must be a 24-bit integer");
- return AddrSpace;
+ return reportError("Invalid address space, must be a 24-bit integer");
+ return Error::success();
}
-void DataLayout::parseSpecifier(StringRef Desc) {
+Error DataLayout::parseSpecifier(StringRef Desc) {
StringRepresentation = std::string(Desc);
while (!Desc.empty()) {
// Split at '-'.
- std::pair<StringRef, StringRef> Split = split(Desc, '-');
+ std::pair<StringRef, StringRef> Split;
+ if (Error Err = split(Desc, '-', Split))
+ return Err;
Desc = Split.second;
// Split at ':'.
- Split = split(Split.first, ':');
+ if (Error Err = split(Split.first, ':', Split))
+ return Err;
// Aliases used below.
StringRef &Tok = Split.first; // Current token.
@@ -246,11 +272,14 @@ void DataLayout::parseSpecifier(StringRef Desc) {
if (Tok == "ni") {
do {
- Split = split(Rest, ':');
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
Rest = Split.second;
- unsigned AS = getInt(Split.first);
+ unsigned AS;
+ if (Error Err = getInt(Split.first, AS))
+ return Err;
if (AS == 0)
- report_fatal_error("Address space 0 can never be non-integral");
+ return reportError("Address space 0 can never be non-integral");
NonIntegralAddressSpaces.push_back(AS);
} while (!Rest.empty());
@@ -273,28 +302,36 @@ void DataLayout::parseSpecifier(StringRef Desc) {
break;
case 'p': {
// Address space.
- unsigned AddrSpace = Tok.empty() ? 0 : getInt(Tok);
+ unsigned AddrSpace = 0;
+ if (!Tok.empty())
+ if (Error Err = getInt(Tok, AddrSpace))
+ return Err;
if (!isUInt<24>(AddrSpace))
- report_fatal_error("Invalid address space, must be a 24bit integer");
+ return reportError("Invalid address space, must be a 24bit integer");
// Size.
if (Rest.empty())
- report_fatal_error(
+ return reportError(
"Missing size specification for pointer in datalayout string");
- Split = split(Rest, ':');
- unsigned PointerMemSize = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned PointerMemSize;
+ if (Error Err = getIntInBytes(Tok, PointerMemSize))
+ return Err;
if (!PointerMemSize)
- report_fatal_error("Invalid pointer size of 0 bytes");
+ return reportError("Invalid pointer size of 0 bytes");
// ABI alignment.
if (Rest.empty())
- report_fatal_error(
+ return reportError(
"Missing alignment specification for pointer in datalayout string");
- Split = split(Rest, ':');
- unsigned PointerABIAlign = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned PointerABIAlign;
+ if (Error Err = getIntInBytes(Tok, PointerABIAlign))
+ return Err;
if (!isPowerOf2_64(PointerABIAlign))
- report_fatal_error(
- "Pointer ABI alignment must be a power of 2");
+ return reportError("Pointer ABI alignment must be a power of 2");
// Size of index used in GEP for address calculation.
// The parameter is optional. By default it is equal to size of pointer.
@@ -303,23 +340,28 @@ void DataLayout::parseSpecifier(StringRef Desc) {
// Preferred alignment.
unsigned PointerPrefAlign = PointerABIAlign;
if (!Rest.empty()) {
- Split = split(Rest, ':');
- PointerPrefAlign = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, PointerPrefAlign))
+ return Err;
if (!isPowerOf2_64(PointerPrefAlign))
- report_fatal_error(
- "Pointer preferred alignment must be a power of 2");
+ return reportError(
+ "Pointer preferred alignment must be a power of 2");
// Now read the index. It is the second optional parameter here.
if (!Rest.empty()) {
- Split = split(Rest, ':');
- IndexSize = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, IndexSize))
+ return Err;
if (!IndexSize)
- report_fatal_error("Invalid index size of 0 bytes");
+ return reportError("Invalid index size of 0 bytes");
}
}
- setPointerAlignment(AddrSpace, assumeAligned(PointerABIAlign),
- assumeAligned(PointerPrefAlign), PointerMemSize,
- IndexSize);
+ if (Error Err = setPointerAlignment(
+ AddrSpace, assumeAligned(PointerABIAlign),
+ assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
+ return Err;
break;
}
case 'i':
@@ -336,61 +378,75 @@ void DataLayout::parseSpecifier(StringRef Desc) {
}
// Bit size.
- unsigned Size = Tok.empty() ? 0 : getInt(Tok);
+ unsigned Size = 0;
+ if (!Tok.empty())
+ if (Error Err = getInt(Tok, Size))
+ return Err;
if (AlignType == AGGREGATE_ALIGN && Size != 0)
- report_fatal_error(
+ return reportError(
"Sized aggregate specification in datalayout string");
// ABI alignment.
if (Rest.empty())
- report_fatal_error(
+ return reportError(
"Missing alignment specification in datalayout string");
- Split = split(Rest, ':');
- const unsigned ABIAlign = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ unsigned ABIAlign;
+ if (Error Err = getIntInBytes(Tok, ABIAlign))
+ return Err;
if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
- report_fatal_error(
+ return reportError(
"ABI alignment specification must be >0 for non-aggregate types");
if (!isUInt<16>(ABIAlign))
- report_fatal_error("Invalid ABI alignment, must be a 16bit integer");
+ return reportError("Invalid ABI alignment, must be a 16bit integer");
if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
- report_fatal_error("Invalid ABI alignment, must be a power of 2");
+ return reportError("Invalid ABI alignment, must be a power of 2");
// Preferred alignment.
unsigned PrefAlign = ABIAlign;
if (!Rest.empty()) {
- Split = split(Rest, ':');
- PrefAlign = inBytes(getInt(Tok));
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
+ if (Error Err = getIntInBytes(Tok, PrefAlign))
+ return Err;
}
if (!isUInt<16>(PrefAlign))
- report_fatal_error(
+ return reportError(
"Invalid preferred alignment, must be a 16bit integer");
if (PrefAlign != 0 && !isPowerOf2_64(PrefAlign))
- report_fatal_error("Invalid preferred alignment, must be a power of 2");
+ return reportError("Invalid preferred alignment, must be a power of 2");
- setAlignment(AlignType, assumeAligned(ABIAlign), assumeAligned(PrefAlign),
- Size);
+ if (Error Err = setAlignment(AlignType, assumeAligned(ABIAlign),
+ assumeAligned(PrefAlign), Size))
+ return Err;
break;
}
case 'n': // Native integer types.
while (true) {
- unsigned Width = getInt(Tok);
+ unsigned Width;
+ if (Error Err = getInt(Tok, Width))
+ return Err;
if (Width == 0)
- report_fatal_error(
+ return reportError(
"Zero width native integer type in datalayout string");
LegalIntWidths.push_back(Width);
if (Rest.empty())
break;
- Split = split(Rest, ':');
+ if (Error Err = split(Rest, ':', Split))
+ return Err;
}
break;
case 'S': { // Stack natural alignment.
- uint64_t Alignment = inBytes(getInt(Tok));
+ uint64_t Alignment;
+ if (Error Err = getIntInBytes(Tok, Alignment))
+ return Err;
if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
- report_fatal_error("Alignment is neither 0 nor a power of 2");
+ return reportError("Alignment is neither 0 nor a power of 2");
StackNaturalAlign = MaybeAlign(Alignment);
break;
}
@@ -403,34 +459,44 @@ void DataLayout::parseSpecifier(StringRef Desc) {
TheFunctionPtrAlignType = FunctionPtrAlignType::MultipleOfFunctionAlign;
break;
default:
- report_fatal_error("Unknown function pointer alignment type in "
+ return reportError("Unknown function pointer alignment type in "
"datalayout string");
}
Tok = Tok.substr(1);
- uint64_t Alignment = inBytes(getInt(Tok));
+ uint64_t Alignment;
+ if (Error Err = getIntInBytes(Tok, Alignment))
+ return Err;
if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
- report_fatal_error("Alignment is neither 0 nor a power of 2");
+ return reportError("Alignment is neither 0 nor a power of 2");
FunctionPtrAlign = MaybeAlign(Alignment);
break;
}
case 'P': { // Function address space.
- ProgramAddrSpace = getAddrSpace(Tok);
+ if (Error Err = getAddrSpace(Tok, ProgramAddrSpace))
+ return Err;
break;
}
case 'A': { // Default stack/alloca address space.
- AllocaAddrSpace = getAddrSpace(Tok);
+ if (Error Err = getAddrSpace(Tok, AllocaAddrSpace))
+ return Err;
+ break;
+ }
+ case 'G': { // Default address space for global variables.
+ if (Error Err = getAddrSpace(Tok, DefaultGlobalsAddrSpace))
+ return Err;
break;
}
case 'm':
if (!Tok.empty())
- report_fatal_error("Unexpected trailing characters after mangling specifier in datalayout string");
+ return reportError("Unexpected trailing characters after mangling "
+ "specifier in datalayout string");
if (Rest.empty())
- report_fatal_error("Expected mangling specifier in datalayout string");
+ return reportError("Expected mangling specifier in datalayout string");
if (Rest.size() > 1)
- report_fatal_error("Unknown mangling specifier in datalayout string");
+ return reportError("Unknown mangling specifier in datalayout string");
switch(Rest[0]) {
default:
- report_fatal_error("Unknown mangling in datalayout string");
+ return reportError("Unknown mangling in datalayout string");
case 'e':
ManglingMode = MM_ELF;
break;
@@ -452,10 +518,12 @@ void DataLayout::parseSpecifier(StringRef Desc) {
}
break;
default:
- report_fatal_error("Unknown specifier in datalayout string");
+ return reportError("Unknown specifier in datalayout string");
break;
}
}
+
+ return Error::success();
}
DataLayout::DataLayout(const Module *M) {
@@ -469,6 +537,7 @@ bool DataLayout::operator==(const DataLayout &Other) const {
AllocaAddrSpace == Other.AllocaAddrSpace &&
StackNaturalAlign == Other.StackNaturalAlign &&
ProgramAddrSpace == Other.ProgramAddrSpace &&
+ DefaultGlobalsAddrSpace == Other.DefaultGlobalsAddrSpace &&
FunctionPtrAlign == Other.FunctionPtrAlign &&
TheFunctionPtrAlignType == Other.TheFunctionPtrAlignType &&
ManglingMode == Other.ManglingMode &&
@@ -487,17 +556,17 @@ DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
});
}
-void DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
- Align pref_align, uint32_t bit_width) {
+Error DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
+ Align pref_align, uint32_t bit_width) {
// AlignmentsTy::ABIAlign and AlignmentsTy::PrefAlign were once stored as
// uint16_t, it is unclear if there are requirements for alignment to be less
// than 2^16 other than storage. In the meantime we leave the restriction as
// an assert. See D67400 for context.
assert(Log2(abi_align) < 16 && Log2(pref_align) < 16 && "Alignment too big");
if (!isUInt<24>(bit_width))
- report_fatal_error("Invalid bit width, must be a 24bit integer");
+ return reportError("Invalid bit width, must be a 24bit integer");
if (pref_align < abi_align)
- report_fatal_error(
+ return reportError(
"Preferred alignment cannot be less than the ABI alignment");
AlignmentsTy::iterator I = findAlignmentLowerBound(align_type, bit_width);
@@ -511,24 +580,35 @@ void DataLayout::setAlignment(AlignTypeEnum align_type, Align abi_align,
Alignments.insert(I, LayoutAlignElem::get(align_type, abi_align,
pref_align, bit_width));
}
-}
+ return Error::success();
+}
+
+const PointerAlignElem &
+DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
+ if (AddressSpace != 0) {
+ auto I = lower_bound(Pointers, AddressSpace,
+ [](const PointerAlignElem &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
+ if (I != Pointers.end() && I->AddressSpace == AddressSpace)
+ return *I;
+ }
-DataLayout::PointersTy::iterator
-DataLayout::findPointerLowerBound(uint32_t AddressSpace) {
- return std::lower_bound(Pointers.begin(), Pointers.end(), AddressSpace,
- [](const PointerAlignElem &A, uint32_t AddressSpace) {
- return A.AddressSpace < AddressSpace;
- });
+ assert(Pointers[0].AddressSpace == 0);
+ return Pointers[0];
}
-void DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeByteWidth,
- uint32_t IndexWidth) {
+Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
+ Align PrefAlign, uint32_t TypeByteWidth,
+ uint32_t IndexWidth) {
if (PrefAlign < ABIAlign)
- report_fatal_error(
+ return reportError(
"Preferred alignment cannot be less than the ABI alignment");
- PointersTy::iterator I = findPointerLowerBound(AddrSpace);
+ auto I = lower_bound(Pointers, AddrSpace,
+ [](const PointerAlignElem &A, uint32_t AddressSpace) {
+ return A.AddressSpace < AddressSpace;
+ });
if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign,
TypeByteWidth, IndexWidth));
@@ -538,49 +618,19 @@ void DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
I->TypeByteWidth = TypeByteWidth;
I->IndexWidth = IndexWidth;
}
+ return Error::success();
}
-/// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or
-/// preferred if ABIInfo = false) the layout wants for the specified datatype.
-Align DataLayout::getAlignmentInfo(AlignTypeEnum AlignType, uint32_t BitWidth,
- bool ABIInfo, Type *Ty) const {
- AlignmentsTy::const_iterator I = findAlignmentLowerBound(AlignType, BitWidth);
- // See if we found an exact match. Of if we are looking for an integer type,
- // but don't have an exact match take the next largest integer. This is where
- // the lower_bound will point to when it fails an exact match.
- if (I != Alignments.end() && I->AlignType == (unsigned)AlignType &&
- (I->TypeBitWidth == BitWidth || AlignType == INTEGER_ALIGN))
- return ABIInfo ? I->ABIAlign : I->PrefAlign;
-
- if (AlignType == INTEGER_ALIGN) {
- // If we didn't have a larger value try the largest value we have.
- if (I != Alignments.begin()) {
- --I; // Go to the previous entry and see if its an integer.
- if (I->AlignType == INTEGER_ALIGN)
- return ABIInfo ? I->ABIAlign : I->PrefAlign;
- }
- } else if (AlignType == VECTOR_ALIGN) {
- // By default, use natural alignment for vector types. This is consistent
- // with what clang and llvm-gcc do.
- unsigned Alignment =
- getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
- // We're only calculating a natural alignment, so it doesn't have to be
- // based on the full size for scalable vectors. Using the minimum element
- // count should be enough here.
- Alignment *= cast<VectorType>(Ty)->getElementCount().Min;
- Alignment = PowerOf2Ceil(Alignment);
- return Align(Alignment);
- }
-
- // If we still couldn't find a reasonable default alignment, fall back
- // to a simple heuristic that the alignment is the first power of two
- // greater-or-equal to the store size of the type. This is a reasonable
- // approximation of reality, and if the user wanted something less
- // less conservative, they should have specified it explicitly in the data
- // layout.
- unsigned Alignment = getTypeStoreSize(Ty);
- Alignment = PowerOf2Ceil(Alignment);
- return Align(Alignment);
+Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
+ bool abi_or_pref) const {
+ auto I = findAlignmentLowerBound(INTEGER_ALIGN, BitWidth);
+ // If we don't have an exact match, use alignment of next larger integer
+ // type. If there is none, use alignment of largest integer type by going
+ // back one element.
+ if (I == Alignments.end() || I->AlignType != INTEGER_ALIGN)
+ --I;
+ assert(I->AlignType == INTEGER_ALIGN && "Must be integer alignment");
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
}
namespace {
@@ -642,30 +692,15 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
}
Align DataLayout::getPointerABIAlignment(unsigned AS) const {
- PointersTy::const_iterator I = findPointerLowerBound(AS);
- if (I == Pointers.end() || I->AddressSpace != AS) {
- I = findPointerLowerBound(0);
- assert(I->AddressSpace == 0);
- }
- return I->ABIAlign;
+ return getPointerAlignElem(AS).ABIAlign;
}
Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
- PointersTy::const_iterator I = findPointerLowerBound(AS);
- if (I == Pointers.end() || I->AddressSpace != AS) {
- I = findPointerLowerBound(0);
- assert(I->AddressSpace == 0);
- }
- return I->PrefAlign;
+ return getPointerAlignElem(AS).PrefAlign;
}
unsigned DataLayout::getPointerSize(unsigned AS) const {
- PointersTy::const_iterator I = findPointerLowerBound(AS);
- if (I == Pointers.end() || I->AddressSpace != AS) {
- I = findPointerLowerBound(0);
- assert(I->AddressSpace == 0);
- }
- return I->TypeByteWidth;
+ return getPointerAlignElem(AS).TypeByteWidth;
}
unsigned DataLayout::getMaxPointerSize() const {
@@ -684,12 +719,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
}
unsigned DataLayout::getIndexSize(unsigned AS) const {
- PointersTy::const_iterator I = findPointerLowerBound(AS);
- if (I == Pointers.end() || I->AddressSpace != AS) {
- I = findPointerLowerBound(0);
- assert(I->AddressSpace == 0);
- }
- return I->IndexWidth;
+ return getPointerAlignElem(AS).IndexWidth;
}
unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
@@ -708,8 +738,6 @@ unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
== false) for the requested type \a Ty.
*/
Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
- AlignTypeEnum AlignType;
-
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
switch (Ty->getTypeID()) {
// Early escape for the non-numeric types.
@@ -730,12 +758,15 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
// Get the layout annotation... which is lazily created on demand.
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
- const Align Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
+ const LayoutAlignElem &AggregateAlign = Alignments[0];
+ assert(AggregateAlign.AlignType == AGGREGATE_ALIGN &&
+ "Aggregate alignment must be first alignment entry");
+ const Align Align =
+ abi_or_pref ? AggregateAlign.ABIAlign : AggregateAlign.PrefAlign;
return std::max(Align, Layout->getAlignment());
}
case Type::IntegerTyID:
- AlignType = INTEGER_ALIGN;
- break;
+ return getIntegerAlignment(Ty->getIntegerBitWidth(), abi_or_pref);
case Type::HalfTyID:
case Type::BFloatTyID:
case Type::FloatTyID:
@@ -744,22 +775,47 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
// same size and alignment, so they look the same here.
case Type::PPC_FP128TyID:
case Type::FP128TyID:
- case Type::X86_FP80TyID:
- AlignType = FLOAT_ALIGN;
- break;
+ case Type::X86_FP80TyID: {
+ unsigned BitWidth = getTypeSizeInBits(Ty).getFixedSize();
+ auto I = findAlignmentLowerBound(FLOAT_ALIGN, BitWidth);
+ if (I != Alignments.end() && I->AlignType == FLOAT_ALIGN &&
+ I->TypeBitWidth == BitWidth)
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+
+ // If we still couldn't find a reasonable default alignment, fall back
+ // to a simple heuristic that the alignment is the first power of two
+ // greater-or-equal to the store size of the type. This is a reasonable
+ // approximation of reality, and if the user wanted something less
+ // less conservative, they should have specified it explicitly in the data
+ // layout.
+ return Align(PowerOf2Ceil(BitWidth / 8));
+ }
case Type::X86_MMXTyID:
case Type::FixedVectorTyID:
- case Type::ScalableVectorTyID:
- AlignType = VECTOR_ALIGN;
- break;
+ case Type::ScalableVectorTyID: {
+ unsigned BitWidth = getTypeSizeInBits(Ty).getKnownMinSize();
+ auto I = findAlignmentLowerBound(VECTOR_ALIGN, BitWidth);
+ if (I != Alignments.end() && I->AlignType == VECTOR_ALIGN &&
+ I->TypeBitWidth == BitWidth)
+ return abi_or_pref ? I->ABIAlign : I->PrefAlign;
+
+ // By default, use natural alignment for vector types. This is consistent
+ // with what clang and llvm-gcc do.
+ // TODO: This should probably not be using the alloc size.
+ unsigned Alignment =
+ getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
+ // We're only calculating a natural alignment, so it doesn't have to be
+ // based on the full size for scalable vectors. Using the minimum element
+ // count should be enough here.
+ Alignment *= cast<VectorType>(Ty)->getElementCount().getKnownMinValue();
+ Alignment = PowerOf2Ceil(Alignment);
+ return Align(Alignment);
+ }
+ case Type::X86_AMXTyID:
+ return Align(64);
default:
llvm_unreachable("Bad type for getAlignment!!!");
}
-
- // If we're dealing with a scalable vector, we just need the known minimum
- // size for determining alignment. If not, we'll get the exact size.
- return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty).getKnownMinSize(),
- abi_or_pref, Ty);
}
/// TODO: Remove this function once the transition to Align is over.
@@ -771,12 +827,6 @@ Align DataLayout::getABITypeAlign(Type *Ty) const {
return getAlignment(Ty, true);
}
-/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
-/// an integer type of the specified bitwidth.
-Align DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
- return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr);
-}
-
/// TODO: Remove this function once the transition to Align is over.
unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const {
return getPrefTypeAlign(Ty).value();