#include "llvm/ADT/Triple.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Mutex.h"
const char *DataLayout::getManglingComponent(const Triple &T) {
if (T.isOSBinFormatMachO())
return "-m:o";
- if (T.isOSBinFormatELF() || T.isArch64Bit())
- return "-m:e";
- assert(T.isOSBinFormatCOFF());
- return "-m:w";
+ if (T.isOSWindows() && T.getArch() == Triple::x86 && T.isOSBinFormatCOFF())
+ return "-m:w";
+ return "-m:e";
}
static const LayoutAlignElem DefaultAlignments[] = {
{ AGGREGATE_ALIGN, 0, 0, 8 } // struct
};
-void DataLayout::init(StringRef Desc) {
- LayoutMap = 0;
+void DataLayout::reset(StringRef Desc) {
+ clear();
+
+ LayoutMap = nullptr;
LittleEndian = false;
StackNaturalAlign = 0;
ManglingMode = MM_None;
// Default alignments
- for (int I = 0, N = array_lengthof(DefaultAlignments); I < N; ++I) {
- const LayoutAlignElem &E = DefaultAlignments[I];
+ for (const LayoutAlignElem &E : DefaultAlignments) {
setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
E.TypeBitWidth);
}
}
}
-DataLayout::DataLayout(const Module *M) {
+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
- init("");
+ reset("");
+}
+
+bool DataLayout::operator==(const DataLayout &Other) const {
+ bool Ret = LittleEndian == Other.LittleEndian &&
+ StackNaturalAlign == Other.StackNaturalAlign &&
+ ManglingMode == Other.ManglingMode &&
+ LegalIntWidths == Other.LegalIntWidths &&
+ Alignments == Other.Alignments && Pointers == Other.Pointers;
+ assert(Ret == (getStringRepresentation() == Other.getStringRepresentation()));
+ return Ret;
}
void
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
assert(pref_align < (1 << 16) && "Alignment doesn't fit in bitfield");
assert(bit_width < (1 << 24) && "Bit width doesn't fit in bitfield");
- for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- if (Alignments[i].AlignType == (unsigned)align_type &&
- Alignments[i].TypeBitWidth == bit_width) {
+ for (LayoutAlignElem &Elem : Alignments) {
+ if (Elem.AlignType == (unsigned)align_type &&
+ Elem.TypeBitWidth == bit_width) {
// Update the abi, preferred alignments.
- Alignments[i].ABIAlign = abi_align;
- Alignments[i].PrefAlign = pref_align;
+ Elem.ABIAlign = abi_align;
+ Elem.PrefAlign = pref_align;
return;
}
}
pref_align, bit_width));
}
+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;
+ });
+}
+
void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
unsigned PrefAlign,
uint32_t TypeByteWidth) {
assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
- DenseMap<unsigned,PointerAlignElem>::iterator val = Pointers.find(AddrSpace);
- if (val == Pointers.end()) {
- Pointers[AddrSpace] =
- PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign, TypeByteWidth);
+ PointersTy::iterator I = findPointerLowerBound(AddrSpace);
+ if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
+ Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign,
+ TypeByteWidth));
} else {
- val->second.ABIAlign = ABIAlign;
- val->second.PrefAlign = PrefAlign;
- val->second.TypeByteWidth = TypeByteWidth;
+ I->ABIAlign = ABIAlign;
+ I->PrefAlign = PrefAlign;
+ I->TypeByteWidth = TypeByteWidth;
}
}
LayoutInfoTy LayoutInfo;
public:
- virtual ~StructLayoutMap() {
+ ~StructLayoutMap() {
// Remove any layouts.
- for (LayoutInfoTy::iterator I = LayoutInfo.begin(), E = LayoutInfo.end();
- I != E; ++I) {
- StructLayout *Value = I->second;
+ for (const auto &I : LayoutInfo) {
+ StructLayout *Value = I.second;
Value->~StructLayout();
free(Value);
}
StructLayout *&operator[](StructType *STy) {
return LayoutInfo[STy];
}
-
- // for debugging...
- virtual void dump() const {}
};
} // end anonymous namespace
+void DataLayout::clear() {
+ LegalIntWidths.clear();
+ Alignments.clear();
+ Pointers.clear();
+ delete static_cast<StructLayoutMap *>(LayoutMap);
+ LayoutMap = nullptr;
+}
+
DataLayout::~DataLayout() {
- delete static_cast<StructLayoutMap*>(LayoutMap);
+ clear();
}
const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
break;
}
- SmallVector<unsigned, 8> addrSpaces;
- // Lets get all of the known address spaces and sort them
- // into increasing order so that we can emit the string
- // in a cleaner format.
- for (DenseMap<unsigned, PointerAlignElem>::const_iterator
- pib = Pointers.begin(), pie = Pointers.end();
- pib != pie; ++pib) {
- addrSpaces.push_back(pib->first);
- }
- std::sort(addrSpaces.begin(), addrSpaces.end());
- for (SmallVectorImpl<unsigned>::iterator asb = addrSpaces.begin(),
- ase = addrSpaces.end(); asb != ase; ++asb) {
- const PointerAlignElem &PI = Pointers.find(*asb)->second;
-
+ for (const PointerAlignElem &PI : Pointers) {
// Skip default.
if (PI.AddressSpace == 0 && PI.ABIAlign == 8 && PI.PrefAlign == 8 &&
PI.TypeByteWidth == 8)
OS << ':' << PI.PrefAlign*8;
}
- const LayoutAlignElem *DefaultStart = DefaultAlignments;
- const LayoutAlignElem *DefaultEnd =
- DefaultStart + array_lengthof(DefaultAlignments);
- for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- const LayoutAlignElem &AI = Alignments[i];
- if (std::find(DefaultStart, DefaultEnd, AI) != DefaultEnd)
+ 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)
return OS.str();
}
+unsigned 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;
+}
+
+unsigned 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;
+}
+
+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;
+}
+
unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
assert(Ty->isPtrOrPtrVectorTy() &&
"This should only be called with a pointer or pointer vector type");
? getPointerABIAlignment(0)
: getPointerPrefAlignment(0));
case Type::PointerTyID: {
- unsigned AS = dyn_cast<PointerType>(Ty)->getAddressSpace();
+ unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
return (abi_or_pref
? getPointerABIAlignment(AS)
: getPointerPrefAlignment(AS));
/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
/// an integer type of the specified bitwidth.
unsigned DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
- return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, 0);
+ return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr);
}
unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const {
Type *DataLayout::getIntPtrType(Type *Ty) const {
assert(Ty->isPtrOrPtrVectorTy() &&
"Expected a pointer or pointer vector type.");
- unsigned NumBits = getTypeSizeInBits(Ty->getScalarType());
+ unsigned NumBits = getPointerTypeSizeInBits(Ty);
IntegerType *IntTy = IntegerType::get(Ty->getContext(), NumBits);
if (VectorType *VecTy = dyn_cast<VectorType>(Ty))
return VectorType::get(IntTy, VecTy->getNumElements());
}
Type *DataLayout::getSmallestLegalIntType(LLVMContext &C, unsigned Width) const {
- for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
- if (Width <= LegalIntWidths[i])
- return Type::getIntNTy(C, LegalIntWidths[i]);
- return 0;
+ for (unsigned LegalIntWidth : LegalIntWidths)
+ if (Width <= LegalIntWidth)
+ return Type::getIntNTy(C, LegalIntWidth);
+ return nullptr;
}
unsigned DataLayout::getLargestLegalIntTypeSize() const {
- unsigned MaxWidth = 0;
- for (unsigned i = 0, e = (unsigned)LegalIntWidths.size(); i != e; ++i)
- MaxWidth = std::max<unsigned>(MaxWidth, LegalIntWidths[i]);
- return MaxWidth;
+ auto Max = std::max_element(LegalIntWidths.begin(), LegalIntWidths.end());
+ return Max != LegalIntWidths.end() ? *Max : 0;
}
uint64_t DataLayout::getIndexedOffset(Type *ptrTy,
}
DataLayoutPass::DataLayoutPass() : ImmutablePass(ID), DL("") {
- report_fatal_error("Bad DataLayoutPass ctor used. Tool did not specify a "
- "DataLayout to use?");
+ initializeDataLayoutPassPass(*PassRegistry::getPassRegistry());
}
DataLayoutPass::~DataLayoutPass() {}
-DataLayoutPass::DataLayoutPass(const DataLayout &DL)
- : ImmutablePass(ID), DL(DL) {
- initializeDataLayoutPassPass(*PassRegistry::getPassRegistry());
+bool DataLayoutPass::doInitialization(Module &M) {
+ DL.init(&M);
+ return false;
}
-DataLayoutPass::DataLayoutPass(StringRef Str) : ImmutablePass(ID), DL(Str) {
- initializeDataLayoutPassPass(*PassRegistry::getPassRegistry());
-}
-
-DataLayoutPass::DataLayoutPass(const Module *M) : ImmutablePass(ID), DL(M) {
- initializeDataLayoutPassPass(*PassRegistry::getPassRegistry());
+bool DataLayoutPass::doFinalization(Module &M) {
+ DL.reset("");
+ return false;
}