summaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/DataLayout.cpp')
-rw-r--r--llvm/lib/IR/DataLayout.cpp53
1 files changed, 48 insertions, 5 deletions
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index dbd6d81ad2e2..ed629d4e5ea2 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -187,7 +187,6 @@ const char *DataLayout::getManglingComponent(const Triple &T) {
// Default primitive type specifications.
// NOTE: These arrays must be sorted by type bit width.
constexpr DataLayout::PrimitiveSpec DefaultIntSpecs[] = {
- {1, Align::Constant<1>(), Align::Constant<1>()}, // i1:8:8
{8, Align::Constant<1>(), Align::Constant<1>()}, // i8:8:8
{16, Align::Constant<2>(), Align::Constant<2>()}, // i16:16:16
{32, Align::Constant<4>(), Align::Constant<4>()}, // i32:32:32
@@ -694,7 +693,12 @@ void DataLayout::setPointerSpec(uint32_t AddrSpace, uint32_t BitWidth,
Align DataLayout::getIntegerAlignment(uint32_t BitWidth,
bool abi_or_pref) const {
- auto I = lower_bound(IntSpecs, BitWidth, LessPrimitiveBitWidth());
+ auto I = IntSpecs.begin();
+ for (; I != IntSpecs.end(); ++I) {
+ if (I->BitWidth >= BitWidth)
+ break;
+ }
+
// If we don't have an exact match, use alignment of next larger integer
// type. If there is none, use alignment of largest integer type by going
// back one element.
@@ -839,6 +843,44 @@ Align DataLayout::getAlignment(Type *Ty, bool abi_or_pref) const {
}
}
+TypeSize DataLayout::getTypeAllocSize(Type *Ty) const {
+ switch (Ty->getTypeID()) {
+ case Type::ArrayTyID: {
+ // The alignment of the array is the alignment of the element, so there
+ // is no need for further adjustment.
+ auto *ATy = cast<ArrayType>(Ty);
+ return ATy->getNumElements() * getTypeAllocSize(ATy->getElementType());
+ }
+ case Type::StructTyID: {
+ const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
+ TypeSize Size = Layout->getSizeInBytes();
+
+ if (cast<StructType>(Ty)->isPacked())
+ return Size;
+
+ Align A = std::max(StructABIAlignment, Layout->getAlignment());
+ return alignTo(Size, A.value());
+ }
+ case Type::IntegerTyID: {
+ unsigned BitWidth = Ty->getIntegerBitWidth();
+ TypeSize Size = TypeSize::getFixed(divideCeil(BitWidth, 8));
+ Align A = getIntegerAlignment(BitWidth, /*ABI=*/true);
+ return alignTo(Size, A.value());
+ }
+ case Type::PointerTyID: {
+ unsigned AS = Ty->getPointerAddressSpace();
+ TypeSize Size = TypeSize::getFixed(getPointerSize(AS));
+ return alignTo(Size, getPointerABIAlignment(AS).value());
+ }
+ case Type::TargetExtTyID: {
+ Type *LayoutTy = cast<TargetExtType>(Ty)->getLayoutType();
+ return getTypeAllocSize(LayoutTy);
+ }
+ default:
+ return alignTo(getTypeStoreSize(Ty), getABITypeAlign(Ty).value());
+ }
+}
+
Align DataLayout::getABITypeAlign(Type *Ty) const {
return getAlignment(Ty, true);
}
@@ -926,12 +968,13 @@ static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
return APInt::getZero(BitWidth);
}
- APInt Index = Offset.sdiv(ElemSize);
- Offset -= Index * ElemSize;
+ uint64_t FixedElemSize = ElemSize.getFixedValue();
+ APInt Index = Offset.sdiv(FixedElemSize);
+ Offset -= Index * FixedElemSize;
if (Offset.isNegative()) {
// Prefer a positive remaining offset to allow struct indexing.
--Index;
- Offset += ElemSize;
+ Offset += FixedElemSize;
assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
}
return Index;