aboutsummaryrefslogtreecommitdiffstats
path: root/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/DataLayout.cpp')
-rw-r--r--lib/IR/DataLayout.cpp134
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;
-}