Skip to content

Commit 1d1e29b

Browse files
committed
[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.
1 parent 78ff12d commit 1d1e29b

File tree

2 files changed

+47
-38
lines changed

2 files changed

+47
-38
lines changed

llvm/include/llvm/IR/DataLayout.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,12 @@ class DataLayout {
591591
/// the result element type and Offset to be the residual offset.
592592
SmallVector<APInt> getGEPIndicesForOffset(Type *&ElemTy, APInt &Offset) const;
593593

594+
/// Get single GEP index to access Offset inside ElemTy. Returns None if
595+
/// index cannot be computed, e.g. because the type is not an aggregate.
596+
/// ElemTy is updated to be the result element type and Offset to be the
597+
/// residual offset.
598+
Optional<APInt> getGEPIndexForOffset(Type *&ElemTy, APInt &Offset) const;
599+
594600
/// Returns a StructLayout object, indicating the alignment of the
595601
/// struct, its size, and the offsets of its fields.
596602
///

llvm/lib/IR/DataLayout.cpp

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -903,16 +903,14 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
903903
return Result;
904904
}
905905

906-
static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
907-
APInt &Offset) {
906+
static APInt getElementIndex(TypeSize ElemSize, APInt &Offset) {
908907
// Skip over scalable or zero size elements. Also skip element sizes larger
909908
// than the positive index space, because the arithmetic below may not be
910909
// correct in that case.
911910
unsigned BitWidth = Offset.getBitWidth();
912911
if (ElemSize.isScalable() || ElemSize == 0 ||
913912
!isUIntN(BitWidth - 1, ElemSize)) {
914-
Indices.push_back(APInt::getZero(BitWidth));
915-
return;
913+
return APInt::getZero(BitWidth);
916914
}
917915

918916
APInt Index = Offset.sdiv(ElemSize);
@@ -923,47 +921,52 @@ static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
923921
Offset += ElemSize;
924922
assert(Offset.isNonNegative() && "Remaining offset shouldn't be negative");
925923
}
926-
Indices.push_back(Index);
924+
return Index;
927925
}
928926

929-
SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
930-
APInt &Offset) const {
931-
assert(ElemTy->isSized() && "Element type must be sized");
932-
SmallVector<APInt> Indices;
933-
addElementIndex(Indices, getTypeAllocSize(ElemTy), Offset);
934-
while (Offset != 0) {
935-
if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
936-
ElemTy = ArrTy->getElementType();
937-
addElementIndex(Indices, getTypeAllocSize(ElemTy), Offset);
938-
continue;
939-
}
927+
Optional<APInt> DataLayout::getGEPIndexForOffset(Type *&ElemTy,
928+
APInt &Offset) const {
929+
if (auto *ArrTy = dyn_cast<ArrayType>(ElemTy)) {
930+
ElemTy = ArrTy->getElementType();
931+
return getElementIndex(getTypeAllocSize(ElemTy), Offset);
932+
}
940933

941-
if (auto *VecTy = dyn_cast<VectorType>(ElemTy)) {
942-
ElemTy = VecTy->getElementType();
943-
unsigned ElemSizeInBits = getTypeSizeInBits(ElemTy).getFixedSize();
944-
// GEPs over non-multiple of 8 size vector elements are invalid.
945-
if (ElemSizeInBits % 8 != 0)
946-
break;
934+
if (auto *VecTy = dyn_cast<VectorType>(ElemTy)) {
935+
ElemTy = VecTy->getElementType();
936+
unsigned ElemSizeInBits = getTypeSizeInBits(ElemTy).getFixedSize();
937+
// GEPs over non-multiple of 8 size vector elements are invalid.
938+
if (ElemSizeInBits % 8 != 0)
939+
return None;
947940

948-
addElementIndex(Indices, TypeSize::Fixed(ElemSizeInBits / 8), Offset);
949-
continue;
950-
}
941+
return getElementIndex(TypeSize::Fixed(ElemSizeInBits / 8), Offset);
942+
}
951943

952-
if (auto *STy = dyn_cast<StructType>(ElemTy)) {
953-
const StructLayout *SL = getStructLayout(STy);
954-
uint64_t IntOffset = Offset.getZExtValue();
955-
if (IntOffset >= SL->getSizeInBytes())
956-
break;
944+
if (auto *STy = dyn_cast<StructType>(ElemTy)) {
945+
const StructLayout *SL = getStructLayout(STy);
946+
uint64_t IntOffset = Offset.getZExtValue();
947+
if (IntOffset >= SL->getSizeInBytes())
948+
return None;
957949

958-
unsigned Index = SL->getElementContainingOffset(IntOffset);
959-
Offset -= SL->getElementOffset(Index);
960-
ElemTy = STy->getElementType(Index);
961-
Indices.push_back(APInt(32, Index));
962-
continue;
963-
}
950+
unsigned Index = SL->getElementContainingOffset(IntOffset);
951+
Offset -= SL->getElementOffset(Index);
952+
ElemTy = STy->getElementType(Index);
953+
return APInt(32, Index);
954+
}
955+
956+
// Non-aggregate type.
957+
return None;
958+
}
964959

965-
// Can't index into non-aggregate type.
966-
break;
960+
SmallVector<APInt> DataLayout::getGEPIndicesForOffset(Type *&ElemTy,
961+
APInt &Offset) const {
962+
assert(ElemTy->isSized() && "Element type must be sized");
963+
SmallVector<APInt> Indices;
964+
Indices.push_back(getElementIndex(getTypeAllocSize(ElemTy), Offset));
965+
while (Offset != 0) {
966+
Optional<APInt> Index = getGEPIndexForOffset(ElemTy, Offset);
967+
if (!Index)
968+
break;
969+
Indices.push_back(*Index);
967970
}
968971

969972
return Indices;

0 commit comments

Comments
 (0)