[llvm] 1d1e29b - [IR] Extract method to get single GEP index from offset (NFC)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 10 08:22:55 PST 2021
Author: Nikita Popov
Date: 2021-12-10T17:22:46+01:00
New Revision: 1d1e29ba6c80a78db488deb28670e779c48e1e06
URL: https://github.com/llvm/llvm-project/commit/1d1e29ba6c80a78db488deb28670e779c48e1e06
DIFF: https://github.com/llvm/llvm-project/commit/1d1e29ba6c80a78db488deb28670e779c48e1e06.diff
LOG: [IR] Extract method to get single GEP index from offset (NFC)
This exposes the core logic of getGEPIndicesForOffset() as a
getGEPIndexForOffset() method that only returns a single offset,
instead of following the whole chain.
Added:
Modified:
llvm/include/llvm/IR/DataLayout.h
llvm/lib/IR/DataLayout.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/DataLayout.h b/llvm/include/llvm/IR/DataLayout.h
index 5a18dcd1e3460..36438fc4f4e0e 100644
--- a/llvm/include/llvm/IR/DataLayout.h
+++ b/llvm/include/llvm/IR/DataLayout.h
@@ -591,6 +591,12 @@ class DataLayout {
/// the result element type and Offset to be the residual offset.
SmallVector<APInt> getGEPIndicesForOffset(Type *&ElemTy, APInt &Offset) const;
+ /// Get single GEP index to access Offset inside ElemTy. Returns None if
+ /// index cannot be computed, e.g. because the type is not an aggregate.
+ /// ElemTy is updated to be the result element type and Offset to be the
+ /// residual offset.
+ Optional<APInt> getGEPIndexForOffset(Type *&ElemTy, APInt &Offset) const;
+
/// Returns a StructLayout object, indicating the alignment of the
/// struct, its size, and the offsets of its fields.
///
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp
index a0bd437d78c58..61b2b13bfd034 100644
--- a/llvm/lib/IR/DataLayout.cpp
+++ b/llvm/lib/IR/DataLayout.cpp
@@ -903,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);
@@ -923,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;
More information about the llvm-commits
mailing list