diff options
Diffstat (limited to 'lib/IR/DataLayout.cpp')
-rw-r--r-- | lib/IR/DataLayout.cpp | 134 |
1 files changed, 38 insertions, 96 deletions
diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp index 9c1dee0..4d867ef 100644 --- a/lib/IR/DataLayout.cpp +++ b/lib/IR/DataLayout.cpp @@ -33,11 +33,6 @@ #include <cstdlib> using namespace llvm; -// Handle the Pass registration stuff necessary to use DataLayout's. - -INITIALIZE_PASS(DataLayoutPass, "datalayout", "Data Layout", false, true) -char DataLayoutPass::ID = 0; - //===----------------------------------------------------------------------===// // Support for StructLayout //===----------------------------------------------------------------------===// @@ -155,8 +150,8 @@ DataLayout::InvalidPointerElem = { 0U, 0U, 0U, ~0U }; const char *DataLayout::getManglingComponent(const Triple &T) { if (T.isOSBinFormatMachO()) return "-m:o"; - if (T.isOSWindows() && T.getArch() == Triple::x86 && T.isOSBinFormatCOFF()) - return "-m:w"; + if (T.isOSWindows() && T.isOSBinFormatCOFF()) + return T.getArch() == Triple::x86 ? "-m:x" : "-m:w"; return "-m:e"; } @@ -221,6 +216,7 @@ static unsigned inBytes(unsigned Bits) { } void DataLayout::parseSpecifier(StringRef Desc) { + StringRepresentation = Desc; while (!Desc.empty()) { // Split at '-'. std::pair<StringRef, StringRef> Split = split(Desc, '-'); @@ -259,6 +255,8 @@ void DataLayout::parseSpecifier(StringRef Desc) { "Missing size specification for pointer in datalayout string"); Split = split(Rest, ':'); unsigned PointerMemSize = inBytes(getInt(Tok)); + if (!PointerMemSize) + report_fatal_error("Invalid pointer size of 0 bytes"); // ABI alignment. if (Rest.empty()) @@ -266,12 +264,18 @@ void DataLayout::parseSpecifier(StringRef Desc) { "Missing alignment specification for pointer in datalayout string"); Split = split(Rest, ':'); unsigned PointerABIAlign = inBytes(getInt(Tok)); + if (!isPowerOf2_64(PointerABIAlign)) + report_fatal_error( + "Pointer ABI alignment must be a power of 2"); // Preferred alignment. unsigned PointerPrefAlign = PointerABIAlign; if (!Rest.empty()) { Split = split(Rest, ':'); PointerPrefAlign = inBytes(getInt(Tok)); + if (!isPowerOf2_64(PointerPrefAlign)) + report_fatal_error( + "Pointer preferred alignment must be a power of 2"); } setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign, @@ -304,6 +308,9 @@ void DataLayout::parseSpecifier(StringRef Desc) { "Missing alignment specification in datalayout string"); Split = split(Rest, ':'); unsigned ABIAlign = inBytes(getInt(Tok)); + if (AlignType != AGGREGATE_ALIGN && !ABIAlign) + report_fatal_error( + "ABI alignment specification must be >0 for non-aggregate types"); // Preferred alignment. unsigned PrefAlign = ABIAlign; @@ -352,7 +359,10 @@ void DataLayout::parseSpecifier(StringRef Desc) { ManglingMode = MM_Mips; break; case 'w': - ManglingMode = MM_WINCOFF; + ManglingMode = MM_WinCOFF; + break; + case 'x': + ManglingMode = MM_WinCOFFX86; break; } break; @@ -367,13 +377,7 @@ DataLayout::DataLayout(const Module *M) : LayoutMap(nullptr) { init(M); } -void DataLayout::init(const Module *M) { - const DataLayout *Other = M->getDataLayout(); - if (Other) - *this = *Other; - else - reset(""); -} +void DataLayout::init(const Module *M) { *this = M->getDataLayout(); } bool DataLayout::operator==(const DataLayout &Other) const { bool Ret = BigEndian == Other.BigEndian && @@ -381,7 +385,7 @@ bool DataLayout::operator==(const DataLayout &Other) const { ManglingMode == Other.ManglingMode && LegalIntWidths == Other.LegalIntWidths && Alignments == Other.Alignments && Pointers == Other.Pointers; - assert(Ret == (getStringRepresentation() == Other.getStringRepresentation())); + // Note: getStringRepresentation() might differs, it is not canonicalized return Ret; } @@ -394,6 +398,10 @@ DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align, report_fatal_error("Invalid ABI alignment, must be a 16bit integer"); if (!isUInt<16>(pref_align)) report_fatal_error("Invalid preferred alignment, must be a 16bit integer"); + if (abi_align != 0 && !isPowerOf2_64(abi_align)) + report_fatal_error("Invalid ABI alignment, must be a power of 2"); + if (pref_align != 0 && !isPowerOf2_64(pref_align)) + report_fatal_error("Invalid preferred alignment, must be a power of 2"); if (pref_align < abi_align) report_fatal_error( @@ -474,9 +482,7 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType, // If we didn't find an integer alignment, fall back on most conservative. if (AlignType == INTEGER_ALIGN) { BestMatchIdx = LargestInt; - } else { - assert(AlignType == VECTOR_ALIGN && "Unknown alignment type!"); - + } else if (AlignType == VECTOR_ALIGN) { // By default, use natural alignment for vector types. This is consistent // with what clang and llvm-gcc do. unsigned Align = getTypeAllocSize(cast<VectorType>(Ty)->getElementType()); @@ -489,6 +495,19 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType, } } + // 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. + if (BestMatchIdx == -1) { + unsigned Align = getTypeStoreSize(Ty); + if (Align & (Align-1)) + Align = NextPowerOf2(Align); + return Align; + } + // Since we got a "best match" index, just return it. return ABIInfo ? Alignments[BestMatchIdx].ABIAlign : Alignments[BestMatchIdx].PrefAlign; @@ -552,68 +571,6 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const { return L; } -std::string DataLayout::getStringRepresentation() const { - std::string Result; - raw_string_ostream OS(Result); - - OS << (BigEndian ? "E" : "e"); - - switch (ManglingMode) { - case MM_None: - break; - case MM_ELF: - OS << "-m:e"; - break; - case MM_MachO: - OS << "-m:o"; - break; - case MM_WINCOFF: - OS << "-m:w"; - break; - case MM_Mips: - OS << "-m:m"; - break; - } - - for (const PointerAlignElem &PI : Pointers) { - // Skip default. - if (PI.AddressSpace == 0 && PI.ABIAlign == 8 && PI.PrefAlign == 8 && - PI.TypeByteWidth == 8) - continue; - - OS << "-p"; - if (PI.AddressSpace) { - OS << PI.AddressSpace; - } - OS << ":" << PI.TypeByteWidth*8 << ':' << PI.ABIAlign*8; - if (PI.PrefAlign != PI.ABIAlign) - OS << ':' << PI.PrefAlign*8; - } - - for (const LayoutAlignElem &AI : Alignments) { - if (std::find(std::begin(DefaultAlignments), std::end(DefaultAlignments), - AI) != std::end(DefaultAlignments)) - continue; - OS << '-' << (char)AI.AlignType; - if (AI.TypeBitWidth) - OS << AI.TypeBitWidth; - OS << ':' << AI.ABIAlign*8; - if (AI.ABIAlign != AI.PrefAlign) - OS << ':' << AI.PrefAlign*8; - } - - if (!LegalIntWidths.empty()) { - OS << "-n" << (unsigned)LegalIntWidths[0]; - - for (unsigned i = 1, e = LegalIntWidths.size(); i != e; ++i) - OS << ':' << (unsigned)LegalIntWidths[i]; - } - - if (StackNaturalAlign) - OS << "-S" << StackNaturalAlign*8; - - return OS.str(); -} unsigned DataLayout::getPointerABIAlignment(unsigned AS) const { PointersTy::const_iterator I = findPointerLowerBound(AS); @@ -829,18 +786,3 @@ unsigned DataLayout::getPreferredAlignmentLog(const GlobalVariable *GV) const { return Log2_32(getPreferredAlignment(GV)); } -DataLayoutPass::DataLayoutPass() : ImmutablePass(ID), DL("") { - initializeDataLayoutPassPass(*PassRegistry::getPassRegistry()); -} - -DataLayoutPass::~DataLayoutPass() {} - -bool DataLayoutPass::doInitialization(Module &M) { - DL.init(&M); - return false; -} - -bool DataLayoutPass::doFinalization(Module &M) { - DL.reset(""); - return false; -} |