diff options
author | Nikita Popov <npopov@redhat.com> | 2021-12-10 12:32:05 +0100 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2021-12-10 17:22:46 +0100 |
commit | 1d1e29ba6c80a78db488deb28670e779c48e1e06 (patch) | |
tree | f5f8243a5c4c1f37b53940110ec2c2f58cb35ebb /llvm/lib/IR/DataLayout.cpp | |
parent | 78ff12da1115abcaf4cbf50b605a197011505646 (diff) | |
download | llvm-1d1e29ba6c80a78db488deb28670e779c48e1e06.zip llvm-1d1e29ba6c80a78db488deb28670e779c48e1e06.tar.gz llvm-1d1e29ba6c80a78db488deb28670e779c48e1e06.tar.bz2 |
[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.
Diffstat (limited to 'llvm/lib/IR/DataLayout.cpp')
-rw-r--r-- | llvm/lib/IR/DataLayout.cpp | 79 |
1 files changed, 41 insertions, 38 deletions
diff --git a/llvm/lib/IR/DataLayout.cpp b/llvm/lib/IR/DataLayout.cpp index a0bd437..61b2b13 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; |