From af732203b8f7f006927528db5497f5cbc4c4742a Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 13 Jun 2021 21:31:46 +0200 Subject: 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) --- contrib/llvm-project/llvm/lib/IR/DataLayout.cpp | 414 +++++++++++++----------- 1 file changed, 232 insertions(+), 182 deletions(-) (limited to 'contrib/llvm-project/llvm/lib/IR/DataLayout.cpp') 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::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 split(StringRef Str, char Separator) { +static Error split(StringRef Str, char Separator, + std::pair &Split) { assert(!Str.empty() && "parse error, string can't be empty here"); - std::pair 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 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 +static Error getIntInBytes(StringRef R, IntTy &Result) { + if (Error Err = getInt(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 Split = split(Desc, '-'); + std::pair 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(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(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(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(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(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(); -- cgit v1.2.3