summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/IR/DataLayout.cpp')
-rw-r--r--contrib/llvm/lib/IR/DataLayout.cpp158
1 files changed, 74 insertions, 84 deletions
diff --git a/contrib/llvm/lib/IR/DataLayout.cpp b/contrib/llvm/lib/IR/DataLayout.cpp
index d15a34c..5de281a 100644
--- a/contrib/llvm/lib/IR/DataLayout.cpp
+++ b/contrib/llvm/lib/IR/DataLayout.cpp
@@ -1,4 +1,4 @@
-//===-- DataLayout.cpp - Data size & alignment routines --------------------==//
+//===- DataLayout.cpp - Data size & alignment routines ---------------------==//
//
// The LLVM Compiler Infrastructure
//
@@ -18,19 +18,25 @@
#include "llvm/IR/DataLayout.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstdint>
#include <cstdlib>
+#include <tuple>
+#include <utility>
+
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -73,7 +79,6 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
}
}
-
/// getElementContainingOffset - Given a valid offset into the structure,
/// return the structure index that contains it.
unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
@@ -118,9 +123,6 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
&& TypeBitWidth == rhs.TypeBitWidth);
}
-const LayoutAlignElem
-DataLayout::InvalidAlignmentElem = { INVALID_ALIGN, 0, 0, 0 };
-
//===----------------------------------------------------------------------===//
// PointerAlignElem, PointerAlign support
//===----------------------------------------------------------------------===//
@@ -145,9 +147,6 @@ PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
&& TypeByteWidth == rhs.TypeByteWidth);
}
-const PointerAlignElem
-DataLayout::InvalidPointerElem = { 0U, 0U, 0U, ~0U };
-
//===----------------------------------------------------------------------===//
// DataLayout Class Implementation
//===----------------------------------------------------------------------===//
@@ -180,6 +179,7 @@ void DataLayout::reset(StringRef Desc) {
LayoutMap = nullptr;
BigEndian = false;
+ AllocaAddrSpace = 0;
StackNaturalAlign = 0;
ManglingMode = MM_None;
NonIntegralAddressSpaces.clear();
@@ -307,7 +307,7 @@ void DataLayout::parseSpecifier(StringRef Desc) {
case 'a': {
AlignTypeEnum AlignType;
switch (Specifier) {
- default:
+ default: llvm_unreachable("Unexpected specifier!");
case 'i': AlignType = INTEGER_ALIGN; break;
case 'v': AlignType = VECTOR_ALIGN; break;
case 'f': AlignType = FLOAT_ALIGN; break;
@@ -343,7 +343,7 @@ void DataLayout::parseSpecifier(StringRef Desc) {
break;
}
case 'n': // Native integer types.
- for (;;) {
+ while (true) {
unsigned Width = getInt(Tok);
if (Width == 0)
report_fatal_error(
@@ -358,6 +358,12 @@ void DataLayout::parseSpecifier(StringRef Desc) {
StackNaturalAlign = inBytes(getInt(Tok));
break;
}
+ case 'A': { // Default stack/alloca address space.
+ AllocaAddrSpace = getInt(Tok);
+ if (!isUInt<24>(AllocaAddrSpace))
+ report_fatal_error("Invalid address space, must be a 24bit integer");
+ break;
+ }
case 'm':
if (!Tok.empty())
report_fatal_error("Unexpected trailing characters after mangling specifier in datalayout string");
@@ -392,7 +398,7 @@ void DataLayout::parseSpecifier(StringRef Desc) {
}
}
-DataLayout::DataLayout(const Module *M) : LayoutMap(nullptr) {
+DataLayout::DataLayout(const Module *M) {
init(M);
}
@@ -400,6 +406,7 @@ void DataLayout::init(const Module *M) { *this = M->getDataLayout(); }
bool DataLayout::operator==(const DataLayout &Other) const {
bool Ret = BigEndian == Other.BigEndian &&
+ AllocaAddrSpace == Other.AllocaAddrSpace &&
StackNaturalAlign == Other.StackNaturalAlign &&
ManglingMode == Other.ManglingMode &&
LegalIntWidths == Other.LegalIntWidths &&
@@ -408,6 +415,18 @@ bool DataLayout::operator==(const DataLayout &Other) const {
return Ret;
}
+DataLayout::AlignmentsTy::iterator
+DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
+ uint32_t BitWidth) {
+ auto Pair = std::make_pair((unsigned)AlignType, BitWidth);
+ return std::lower_bound(Alignments.begin(), Alignments.end(), Pair,
+ [](const LayoutAlignElem &LHS,
+ const std::pair<unsigned, uint32_t> &RHS) {
+ return std::tie(LHS.AlignType, LHS.TypeBitWidth) <
+ std::tie(RHS.first, RHS.second);
+ });
+}
+
void
DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width) {
@@ -426,18 +445,17 @@ DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
report_fatal_error(
"Preferred alignment cannot be less than the ABI alignment");
- for (LayoutAlignElem &Elem : Alignments) {
- if (Elem.AlignType == (unsigned)align_type &&
- Elem.TypeBitWidth == bit_width) {
- // Update the abi, preferred alignments.
- Elem.ABIAlign = abi_align;
- Elem.PrefAlign = pref_align;
- return;
- }
+ AlignmentsTy::iterator I = findAlignmentLowerBound(align_type, bit_width);
+ if (I != Alignments.end() &&
+ I->AlignType == (unsigned)align_type && I->TypeBitWidth == bit_width) {
+ // Update the abi, preferred alignments.
+ I->ABIAlign = abi_align;
+ I->PrefAlign = pref_align;
+ } else {
+ // Insert before I to keep the vector sorted.
+ Alignments.insert(I, LayoutAlignElem::get(align_type, abi_align,
+ pref_align, bit_width));
}
-
- Alignments.push_back(LayoutAlignElem::get(align_type, abi_align,
- pref_align, bit_width));
}
DataLayout::PointersTy::iterator
@@ -471,45 +489,29 @@ void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
uint32_t BitWidth, bool ABIInfo,
Type *Ty) const {
- // Check to see if we have an exact match and remember the best match we see.
- int BestMatchIdx = -1;
- int LargestInt = -1;
- for (unsigned i = 0, e = Alignments.size(); i != e; ++i) {
- if (Alignments[i].AlignType == (unsigned)AlignType &&
- Alignments[i].TypeBitWidth == BitWidth)
- return ABIInfo ? Alignments[i].ABIAlign : Alignments[i].PrefAlign;
-
- // The best match so far depends on what we're looking for.
- if (AlignType == INTEGER_ALIGN &&
- Alignments[i].AlignType == INTEGER_ALIGN) {
- // The "best match" for integers is the smallest size that is larger than
- // the BitWidth requested.
- if (Alignments[i].TypeBitWidth > BitWidth && (BestMatchIdx == -1 ||
- Alignments[i].TypeBitWidth < Alignments[BestMatchIdx].TypeBitWidth))
- BestMatchIdx = i;
- // However, if there isn't one that's larger, then we must use the
- // largest one we have (see below)
- if (LargestInt == -1 ||
- Alignments[i].TypeBitWidth > Alignments[LargestInt].TypeBitWidth)
- LargestInt = i;
+ 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;
}
- }
-
- // Okay, we didn't find an exact solution. Fall back here depending on what
- // is being looked for.
- if (BestMatchIdx == -1) {
- // If we didn't find an integer alignment, fall back on most conservative.
- if (AlignType == INTEGER_ALIGN) {
- BestMatchIdx = LargestInt;
- } 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());
- Align *= cast<VectorType>(Ty)->getNumElements();
- Align = PowerOf2Ceil(Align);
- return Align;
- }
- }
+ } 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());
+ Align *= cast<VectorType>(Ty)->getNumElements();
+ Align = PowerOf2Ceil(Align);
+ return Align;
+ }
// 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
@@ -517,21 +519,15 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
// 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);
- Align = PowerOf2Ceil(Align);
- return Align;
- }
-
- // Since we got a "best match" index, just return it.
- return ABIInfo ? Alignments[BestMatchIdx].ABIAlign
- : Alignments[BestMatchIdx].PrefAlign;
+ unsigned Align = getTypeStoreSize(Ty);
+ Align = PowerOf2Ceil(Align);
+ return Align;
}
namespace {
class StructLayoutMap {
- typedef DenseMap<StructType*, StructLayout*> LayoutInfoTy;
+ using LayoutInfoTy = DenseMap<StructType*, StructLayout*>;
LayoutInfoTy LayoutInfo;
public:
@@ -586,7 +582,6 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
return L;
}
-
unsigned DataLayout::getPointerABIAlignment(unsigned AS) const {
PointersTy::const_iterator I = findPointerLowerBound(AS);
if (I == Pointers.end() || I->AddressSpace != AS) {
@@ -617,11 +612,8 @@ unsigned DataLayout::getPointerSize(unsigned AS) const {
unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
assert(Ty->isPtrOrPtrVectorTy() &&
"This should only be called with a pointer or pointer vector type");
-
- if (Ty->isPointerTy())
- return getTypeSizeInBits(Ty);
-
- return getTypeSizeInBits(Ty->getScalarType());
+ Ty = Ty->getScalarType();
+ return getPointerSizeInBits(cast<PointerType>(Ty)->getAddressSpace());
}
/*!
@@ -633,7 +625,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
== false) for the requested type \a Ty.
*/
unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
- int AlignType = -1;
+ AlignTypeEnum AlignType;
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
switch (Ty->getTypeID()) {
@@ -682,8 +674,7 @@ unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
llvm_unreachable("Bad type for getAlignment!!!");
}
- return getAlignmentInfo((AlignTypeEnum)AlignType, getTypeSizeInBits(Ty),
- abi_or_pref, Ty);
+ return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty), abi_or_pref, Ty);
}
unsigned DataLayout::getABITypeAlignment(Type *Ty) const {
@@ -791,4 +782,3 @@ unsigned DataLayout::getPreferredAlignment(const GlobalVariable *GV) const {
unsigned DataLayout::getPreferredAlignmentLog(const GlobalVariable *GV) const {
return Log2_32(getPreferredAlignment(GV));
}
-
OpenPOWER on IntegriCloud