aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DataLayout.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-12-25 22:30:44 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-25 22:30:44 +0000
commit77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (patch)
tree5c0eb39553003b9c75a901af6bc4ddabd6f2f28c /llvm/lib/IR/DataLayout.cpp
parentf65dcba83ce5035ab88a85fe17628b447eb56e1b (diff)
Vendor import of llvm-project main llvmorg-14-init-13186-g0c553cc1af2e.vendor/llvm-project/llvmorg-14-init-13186-g0c553cc1af2e
Diffstat (limited to 'llvm/lib/IR/DataLayout.cpp')
-rw-r--r--llvm/lib/IR/DataLayout.cpp129
1 files changed, 67 insertions, 62 deletions
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index 2ace18048262..61b2b13bfd03 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -124,26 +124,25 @@ LayoutAlignElem::operator==(const LayoutAlignElem &rhs) const {
// PointerAlignElem, PointerAlign support
//===----------------------------------------------------------------------===//
-PointerAlignElem PointerAlignElem::get(uint32_t AddressSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeByteWidth,
- uint32_t IndexWidth) {
+PointerAlignElem PointerAlignElem::getInBits(uint32_t AddressSpace,
+ Align ABIAlign, Align PrefAlign,
+ uint32_t TypeBitWidth,
+ uint32_t IndexBitWidth) {
assert(ABIAlign <= PrefAlign && "Preferred alignment worse than ABI!");
PointerAlignElem retval;
retval.AddressSpace = AddressSpace;
retval.ABIAlign = ABIAlign;
retval.PrefAlign = PrefAlign;
- retval.TypeByteWidth = TypeByteWidth;
- retval.IndexWidth = IndexWidth;
+ retval.TypeBitWidth = TypeBitWidth;
+ retval.IndexBitWidth = IndexBitWidth;
return retval;
}
bool
PointerAlignElem::operator==(const PointerAlignElem &rhs) const {
- return (ABIAlign == rhs.ABIAlign
- && AddressSpace == rhs.AddressSpace
- && PrefAlign == rhs.PrefAlign
- && TypeByteWidth == rhs.TypeByteWidth
- && IndexWidth == rhs.IndexWidth);
+ return (ABIAlign == rhs.ABIAlign && AddressSpace == rhs.AddressSpace &&
+ PrefAlign == rhs.PrefAlign && TypeBitWidth == rhs.TypeBitWidth &&
+ IndexBitWidth == rhs.IndexBitWidth);
}
//===----------------------------------------------------------------------===//
@@ -197,7 +196,7 @@ void DataLayout::reset(StringRef Desc) {
E.PrefAlign, E.TypeBitWidth))
return report_fatal_error(std::move(Err));
}
- if (Error Err = setPointerAlignment(0, Align(8), Align(8), 8, 8))
+ if (Error Err = setPointerAlignmentInBits(0, Align(8), Align(8), 64, 64))
return report_fatal_error(std::move(Err));
if (Error Err = parseSpecifier(Desc))
@@ -318,7 +317,7 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
if (Error Err = ::split(Rest, ':', Split))
return Err;
unsigned PointerMemSize;
- if (Error Err = getIntInBytes(Tok, PointerMemSize))
+ if (Error Err = getInt(Tok, PointerMemSize))
return Err;
if (!PointerMemSize)
return reportError("Invalid pointer size of 0 bytes");
@@ -354,13 +353,13 @@ Error DataLayout::parseSpecifier(StringRef Desc) {
if (!Rest.empty()) {
if (Error Err = ::split(Rest, ':', Split))
return Err;
- if (Error Err = getIntInBytes(Tok, IndexSize))
+ if (Error Err = getInt(Tok, IndexSize))
return Err;
if (!IndexSize)
return reportError("Invalid index size of 0 bytes");
}
}
- if (Error Err = setPointerAlignment(
+ if (Error Err = setPointerAlignmentInBits(
AddrSpace, assumeAligned(PointerABIAlign),
assumeAligned(PointerPrefAlign), PointerMemSize, IndexSize))
return Err;
@@ -603,9 +602,10 @@ DataLayout::getPointerAlignElem(uint32_t AddressSpace) const {
return Pointers[0];
}
-Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
- Align PrefAlign, uint32_t TypeByteWidth,
- uint32_t IndexWidth) {
+Error DataLayout::setPointerAlignmentInBits(uint32_t AddrSpace, Align ABIAlign,
+ Align PrefAlign,
+ uint32_t TypeBitWidth,
+ uint32_t IndexBitWidth) {
if (PrefAlign < ABIAlign)
return reportError(
"Preferred alignment cannot be less than the ABI alignment");
@@ -615,13 +615,14 @@ Error DataLayout::setPointerAlignment(uint32_t AddrSpace, Align ABIAlign,
return A.AddressSpace < AddressSpace;
});
if (I == Pointers.end() || I->AddressSpace != AddrSpace) {
- Pointers.insert(I, PointerAlignElem::get(AddrSpace, ABIAlign, PrefAlign,
- TypeByteWidth, IndexWidth));
+ Pointers.insert(I,
+ PointerAlignElem::getInBits(AddrSpace, ABIAlign, PrefAlign,
+ TypeBitWidth, IndexBitWidth));
} else {
I->ABIAlign = ABIAlign;
I->PrefAlign = PrefAlign;
- I->TypeByteWidth = TypeByteWidth;
- I->IndexWidth = IndexWidth;
+ I->TypeBitWidth = TypeBitWidth;
+ I->IndexBitWidth = IndexBitWidth;
}
return Error::success();
}
@@ -704,13 +705,14 @@ Align DataLayout::getPointerPrefAlignment(unsigned AS) const {
}
unsigned DataLayout::getPointerSize(unsigned AS) const {
- return getPointerAlignElem(AS).TypeByteWidth;
+ return divideCeil(getPointerAlignElem(AS).TypeBitWidth, 8);
}
unsigned DataLayout::getMaxIndexSize() const {
unsigned MaxIndexSize = 0;
for (auto &P : Pointers)
- MaxIndexSize = std::max(MaxIndexSize, P.IndexWidth);
+ MaxIndexSize =
+ std::max(MaxIndexSize, (unsigned)divideCeil(P.TypeBitWidth, 8));
return MaxIndexSize;
}
@@ -723,7 +725,7 @@ unsigned DataLayout::getPointerTypeSizeInBits(Type *Ty) const {
}
unsigned DataLayout::getIndexSize(unsigned AS) const {
- return getPointerAlignElem(AS).IndexWidth;
+ return divideCeil(getPointerAlignElem(AS).IndexBitWidth, 8);
}
unsigned DataLayout::getIndexTypeSizeInBits(Type *Ty) const {
@@ -901,16 +903,14 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
return Result;
}
-static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
- APInt &Offset) {
+static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
// Skip over scalable or zero size elements. Also skip element sizes larger
// than the positive index space, because the arithmetic below may not be
// correct in that case.
unsigned BitWidth = Offset.getBitWidth();
if (ElemSize.isScalable() || ElemSize == 0 ||
!isUIntN(BitWidth - 1, ElemSize)) {
- Indices.push_back(APInt::getZero(BitWidth));
- return;
+ return APInt::getZero(BitWidth);
}
APInt Index = Offset.sdiv(ElemSize);
@@ -921,47 +921,52 @@ static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
Offset += ElemSize;
assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
}
- Indices.push_back(Index);
+ return Index;
}
-SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
- APInt &Offset) const {
- assert(ElemTy->isSized() && "Element type must be sized");
- SmallVector<APInt> Indices;
- addElementIndex(Indices, getTypeAllocSize(ElemTy), Offset);
- while (Offset != 0) {
- if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
- ElemTy = ArrTy->getElementType();
- addElementIndex(Indices, getTypeAllocSize(ElemTy), Offset);
- continue;
- }
+Optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,
+ APInt &Offset) const {
+ if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
+ ElemTy = ArrTy->getElementType();
+ return getElementIndex(getTypeAllocSize(ElemTy), Offset);
+ }
- if (auto *VecTy = dyn_cast<VectorType>(ElemTy)) {
- ElemTy = VecTy->getElementType();
- unsigned ElemSizeInBits = getTypeSizeInBits(ElemTy).getFixedSize();
- // GEPs over non-multiple of 8 size vector elements are invalid.
- if (ElemSizeInBits % 8 != 0)
- break;
+ if (auto *VecTy = dyn_cast<VectorType>(ElemTy)) {
+ ElemTy = VecTy->getElementType();
+ unsigned ElemSizeInBits = getTypeSizeInBits(ElemTy).getFixedSize();
+ // GEPs over non-multiple of 8 size vector elements are invalid.
+ if (ElemSizeInBits % 8 != 0)
+ return None;
- addElementIndex(Indices, TypeSize::Fixed(ElemSizeInBits / 8), Offset);
- continue;
- }
+ return getElementIndex(TypeSize::Fixed(ElemSizeInBits / 8), Offset);
+ }
- if (auto *STy = dyn_cast<StructType>(ElemTy)) {
- const StructLayout *SL = getStructLayout(STy);
- uint64_t IntOffset = Offset.getZExtValue();
- if (IntOffset >= SL->getSizeInBytes())
- break;
+ if (auto *STy = dyn_cast<StructType>(ElemTy)) {
+ const StructLayout *SL = getStructLayout(STy);
+ uint64_t IntOffset = Offset.getZExtValue();
+ if (IntOffset >= SL->getSizeInBytes())
+ return None;
- unsigned Index = SL->getElementContainingOffset(IntOffset);
- Offset -= SL->getElementOffset(Index);
- ElemTy = STy->getElementType(Index);
- Indices.push_back(APInt(32, Index));
- continue;
- }
+ unsigned Index = SL->getElementContainingOffset(IntOffset);
+ Offset -= SL->getElementOffset(Index);
+ ElemTy = STy->getElementType(Index);
+ return APInt(32, Index);
+ }
+
+ // Non-aggregate type.
+ return None;
+}
- // Can't index into non-aggregate type.
- break;
+SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
+ APInt &Offset) const {
+ assert(ElemTy->isSized() && "Element type must be sized");
+ SmallVector<APInt> Indices;
+ Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));
+ while (Offset != 0) {
+ Optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);
+ if (!Index)
+ break;
+ Indices.push_back(*Index);
}
return Indices;