aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/DataLayout.cpp')
-rw-r--r--lib/IR/DataLayout.cpp163
1 files changed, 83 insertions, 80 deletions
diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp
index 6e0ebbd4a730..5fe7a2e94b6a 100644
--- a/lib/IR/DataLayout.cpp
+++ b/lib/IR/DataLayout.cpp
@@ -29,6 +29,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/TypeSize.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -44,7 +45,6 @@ using namespace llvm;
StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
assert(!ST->isOpaque() && "Cannot get layout of opaque structs");
- StructAlignment = 0;
StructSize = 0;
IsPadded = false;
NumElements = ST->getNumElements();
@@ -52,10 +52,10 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
// Loop over each of the elements, placing them in memory.
for (unsigned i = 0, e = NumElements; i != e; ++i) {
Type *Ty = ST->getElementType(i);
- unsigned TyAlign = ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty);
+ const Align TyAlign(ST->isPacked() ? 1 : DL.getABITypeAlignment(Ty));
// Add padding if necessary to align the data element properly.
- if ((StructSize & (TyAlign-1)) != 0) {
+ if (!isAligned(TyAlign, StructSize)) {
IsPadded = true;
StructSize = alignTo(StructSize, TyAlign);
}
@@ -67,12 +67,9 @@ StructLayout::StructLayout(StructType *ST, const DataLayout &DL) {
StructSize += DL.getTypeAllocSize(Ty); // Consume space for this data item
}
- // Empty structures have alignment of 1 byte.
- if (StructAlignment == 0) StructAlignment = 1;
-
// Add padding to the end of the struct so that it could be put in an array
// and all array elements would be aligned correctly.
- if ((StructSize & (StructAlignment-1)) != 0) {
+ if (!isAligned(StructAlignment, StructSize)) {
IsPadded = true;
StructSize = alignTo(StructSize, StructAlignment);
}
@@ -102,9 +99,8 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
// LayoutAlignElem, LayoutAlign support
//===----------------------------------------------------------------------===//
-LayoutAlignElem
-LayoutAlignElem::get(AlignTypeEnum align_type, unsigned abi_align,
- unsigned pref_align, uint32_t bit_width) {
+LayoutAlignElem LayoutAlignElem::get(AlignTypeEnum align_type, Align abi_align,
+ Align pref_align, uint32_t bit_width) {
assert(abi_align <= pref_align && "Preferred alignment worse than ABI!");
LayoutAlignElem retval;
retval.AlignType = align_type;
@@ -126,10 +122,9 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
// PointerAlignElem, PointerAlign support
//===----------------------------------------------------------------------===//
-PointerAlignElem
-PointerAlignElem::get(uint32_t AddressSpace, unsigned ABIAlign,
- unsigned PrefAlign, uint32_t TypeByteWidth,
- uint32_t IndexWidth) {
+PointerAlignElem PointerAlignElem::get(uint32_t AddressSpace, Align ABIAlign,
+ Align PrefAlign, uint32_t TypeByteWidth,
+ uint32_t IndexWidth) {
assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
PointerAlignElem retval;
retval.AddressSpace = AddressSpace;
@@ -162,18 +157,18 @@ const char *DataLayout::getManglingComponent(const Triple &T) {
}
static const LayoutAlignElem DefaultAlignments[] = {
- { INTEGER_ALIGN, 1, 1, 1 }, // i1
- { INTEGER_ALIGN, 8, 1, 1 }, // i8
- { INTEGER_ALIGN, 16, 2, 2 }, // i16
- { INTEGER_ALIGN, 32, 4, 4 }, // i32
- { INTEGER_ALIGN, 64, 4, 8 }, // i64
- { FLOAT_ALIGN, 16, 2, 2 }, // half
- { FLOAT_ALIGN, 32, 4, 4 }, // float
- { FLOAT_ALIGN, 64, 8, 8 }, // double
- { FLOAT_ALIGN, 128, 16, 16 }, // ppcf128, quad, ...
- { VECTOR_ALIGN, 64, 8, 8 }, // v2i32, v1i64, ...
- { VECTOR_ALIGN, 128, 16, 16 }, // v16i8, v8i16, v4i32, ...
- { AGGREGATE_ALIGN, 0, 0, 8 } // struct
+ {INTEGER_ALIGN, 1, Align(1), Align(1)}, // i1
+ {INTEGER_ALIGN, 8, Align(1), Align(1)}, // i8
+ {INTEGER_ALIGN, 16, Align(2), Align(2)}, // i16
+ {INTEGER_ALIGN, 32, Align(4), Align(4)}, // i32
+ {INTEGER_ALIGN, 64, Align(4), Align(8)}, // i64
+ {FLOAT_ALIGN, 16, Align(2), Align(2)}, // half
+ {FLOAT_ALIGN, 32, Align(4), Align(4)}, // float
+ {FLOAT_ALIGN, 64, Align(8), Align(8)}, // double
+ {FLOAT_ALIGN, 128, Align(16), Align(16)}, // ppcf128, quad, ...
+ {VECTOR_ALIGN, 64, Align(8), Align(8)}, // v2i32, v1i64, ...
+ {VECTOR_ALIGN, 128, Align(16), Align(16)}, // v16i8, v8i16, v4i32, ...
+ {AGGREGATE_ALIGN, 0, Align(1), Align(8)} // struct
};
void DataLayout::reset(StringRef Desc) {
@@ -182,9 +177,9 @@ void DataLayout::reset(StringRef Desc) {
LayoutMap = nullptr;
BigEndian = false;
AllocaAddrSpace = 0;
- StackNaturalAlign = 0;
+ StackNaturalAlign.reset();
ProgramAddrSpace = 0;
- FunctionPtrAlign = 0;
+ FunctionPtrAlign.reset();
TheFunctionPtrAlignType = FunctionPtrAlignType::Independent;
ManglingMode = MM_None;
NonIntegralAddressSpaces.clear();
@@ -194,7 +189,7 @@ void DataLayout::reset(StringRef Desc) {
setAlignment((AlignTypeEnum)E.AlignType, E.ABIAlign, E.PrefAlign,
E.TypeBitWidth);
}
- setPointerAlignment(0, 8, 8, 8, 8);
+ setPointerAlignment(0, Align(8), Align(8), 8, 8);
parseSpecifier(Desc);
}
@@ -320,8 +315,9 @@ void DataLayout::parseSpecifier(StringRef Desc) {
report_fatal_error("Invalid index size of 0 bytes");
}
}
- setPointerAlignment(AddrSpace, PointerABIAlign, PointerPrefAlign,
- PointerMemSize, IndexSize);
+ setPointerAlignment(AddrSpace, assumeAligned(PointerABIAlign),
+ assumeAligned(PointerPrefAlign), PointerMemSize,
+ IndexSize);
break;
}
case 'i':
@@ -349,11 +345,16 @@ void DataLayout::parseSpecifier(StringRef Desc) {
report_fatal_error(
"Missing alignment specification in datalayout string");
Split = split(Rest, ':');
- unsigned ABIAlign = inBytes(getInt(Tok));
+ const unsigned ABIAlign = inBytes(getInt(Tok));
if (AlignType != AGGREGATE_ALIGN && !ABIAlign)
report_fatal_error(
"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");
+ if (ABIAlign != 0 && !isPowerOf2_64(ABIAlign))
+ report_fatal_error("Invalid ABI alignment, must be a power of 2");
+
// Preferred alignment.
unsigned PrefAlign = ABIAlign;
if (!Rest.empty()) {
@@ -361,7 +362,14 @@ void DataLayout::parseSpecifier(StringRef Desc) {
PrefAlign = inBytes(getInt(Tok));
}
- setAlignment(AlignType, ABIAlign, PrefAlign, Size);
+ if (!isUInt<16>(PrefAlign))
+ report_fatal_error(
+ "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");
+
+ setAlignment(AlignType, assumeAligned(ABIAlign), assumeAligned(PrefAlign),
+ Size);
break;
}
@@ -378,7 +386,10 @@ void DataLayout::parseSpecifier(StringRef Desc) {
}
break;
case 'S': { // Stack natural alignment.
- StackNaturalAlign = inBytes(getInt(Tok));
+ uint64_t Alignment = inBytes(getInt(Tok));
+ if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
+ report_fatal_error("Alignment is neither 0 nor a power of 2");
+ StackNaturalAlign = MaybeAlign(Alignment);
break;
}
case 'F': {
@@ -394,7 +405,10 @@ void DataLayout::parseSpecifier(StringRef Desc) {
"datalayout string");
}
Tok = Tok.substr(1);
- FunctionPtrAlign = inBytes(getInt(Tok));
+ uint64_t Alignment = inBytes(getInt(Tok));
+ if (Alignment != 0 && !llvm::isPowerOf2_64(Alignment))
+ report_fatal_error("Alignment is neither 0 nor a power of 2");
+ FunctionPtrAlign = MaybeAlign(Alignment);
break;
}
case 'P': { // Function address space.
@@ -468,20 +482,15 @@ DataLayout::findAlignmentLowerBound(AlignTypeEnum AlignType,
});
}
-void
-DataLayout::setAlignment(AlignTypeEnum align_type, unsigned abi_align,
- unsigned pref_align, uint32_t bit_width) {
+void 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");
- if (!isUInt<16>(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(
"Preferred alignment cannot be less than the ABI alignment");
@@ -507,8 +516,8 @@ DataLayout::findPointerLowerBound(uint32_t AddressSpace) {
});
}
-void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
- unsigned PrefAlign, uint32_t TypeByteWidth,
+void DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
+ Align PrefAlign, uint32_t TypeByteWidth,
uint32_t IndexWidth) {
if (PrefAlign < ABIAlign)
report_fatal_error(
@@ -528,9 +537,8 @@ void DataLayout::setPointerAlignment(uint32_t AddrSpace, unsigned ABIAlign,
/// getAlignmentInfo - Return the alignment (either ABI if ABIInfo = true or
/// preferred if ABIInfo = false) the layout wants for the specified datatype.
-unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
- uint32_t BitWidth, bool ABIInfo,
- Type *Ty) const {
+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
@@ -549,10 +557,11 @@ unsigned DataLayout::getAlignmentInfo(AlignTypeEnum AlignType,
} 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;
+ unsigned Alignment =
+ getTypeAllocSize(cast<VectorType>(Ty)->getElementType());
+ Alignment *= cast<VectorType>(Ty)->getNumElements();
+ Alignment = PowerOf2Ceil(Alignment);
+ return Align(Alignment);
}
// If we still couldn't find a reasonable default alignment, fall back
@@ -561,9 +570,9 @@ 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.
- unsigned Align = getTypeStoreSize(Ty);
- Align = PowerOf2Ceil(Align);
- return Align;
+ unsigned Alignment = getTypeStoreSize(Ty);
+ Alignment = PowerOf2Ceil(Alignment);
+ return Align(Alignment);
}
namespace {
@@ -624,7 +633,7 @@ const StructLayout *DataLayout::getStructLayout(StructType *Ty) const {
return L;
}
-unsigned DataLayout::getPointerABIAlignment(unsigned AS) const {
+Align DataLayout::getPointerABIAlignment(unsigned AS) const {
PointersTy::const_iterator I = findPointerLowerBound(AS);
if (I == Pointers.end() || I->AddressSpace != AS) {
I = findPointerLowerBound(0);
@@ -633,7 +642,7 @@ unsigned DataLayout::getPointerABIAlignment(unsigned AS) const {
return I->ABIAlign;
}
-unsigned DataLayout::getPointerPrefAlignment(unsigned AS) const {
+Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
PointersTy::const_iterator I = findPointerLowerBound(AS);
if (I == Pointers.end() || I->AddressSpace != AS) {
I = findPointerLowerBound(0);
@@ -690,21 +699,18 @@ unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
== false) for the requested type \a Ty.
*/
-unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
+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.
case Type::LabelTyID:
- return (abi_or_pref
- ? getPointerABIAlignment(0)
- : getPointerPrefAlignment(0));
+ return abi_or_pref ? getPointerABIAlignment(0) : getPointerPrefAlignment(0);
case Type::PointerTyID: {
unsigned AS = cast<PointerType>(Ty)->getAddressSpace();
- return (abi_or_pref
- ? getPointerABIAlignment(AS)
- : getPointerPrefAlignment(AS));
+ return abi_or_pref ? getPointerABIAlignment(AS)
+ : getPointerPrefAlignment(AS);
}
case Type::ArrayTyID:
return getAlignment(cast<ArrayType>(Ty)->getElementType(), abi_or_pref);
@@ -712,11 +718,11 @@ unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
case Type::StructTyID: {
// Packed structure types always have an ABI alignment of one.
if (cast<StructType>(Ty)->isPacked() && abi_or_pref)
- return 1;
+ return Align::None();
// Get the layout annotation... which is lazily created on demand.
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
- unsigned Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
+ const Align Align = getAlignmentInfo(AGGREGATE_ALIGN, 0, abi_or_pref, Ty);
return std::max(Align, Layout->getAlignment());
}
case Type::IntegerTyID:
@@ -740,27 +746,24 @@ unsigned DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
llvm_unreachable("Bad type for getAlignment!!!");
}
- return getAlignmentInfo(AlignType, getTypeSizeInBits(Ty), abi_or_pref, Ty);
+ // 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);
}
unsigned DataLayout::getABITypeAlignment(Type *Ty) const {
- return getAlignment(Ty, true);
+ return getAlignment(Ty, true).value();
}
/// getABIIntegerTypeAlignment - Return the minimum ABI-required alignment for
/// an integer type of the specified bitwidth.
-unsigned DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
+Align DataLayout::getABIIntegerTypeAlignment(unsigned BitWidth) const {
return getAlignmentInfo(INTEGER_ALIGN, BitWidth, true, nullptr);
}
unsigned DataLayout::getPrefTypeAlignment(Type *Ty) const {
- return getAlignment(Ty, false);
-}
-
-unsigned DataLayout::getPreferredTypeAlignmentShift(Type *Ty) const {
- unsigned Align = getPrefTypeAlignment(Ty);
- assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
- return Log2_32(Align);
+ return getAlignment(Ty, false).value();
}
IntegerType *DataLayout::getIntPtrType(LLVMContext &C,