@@ -903,16 +903,14 @@ int64_t DataLayout::getIndexedOffsetInType(Type *ElemTy,
903
903
return Result;
904
904
}
905
905
906
- static void addElementIndex (SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
907
- APInt &Offset) {
906
+ static APInt getElementIndex (TypeSize ElemSize, APInt &Offset) {
908
907
// Skip over scalable or zero size elements. Also skip element sizes larger
909
908
// than the positive index space, because the arithmetic below may not be
910
909
// correct in that case.
911
910
unsigned BitWidth = Offset.getBitWidth ();
912
911
if (ElemSize.isScalable () || ElemSize == 0 ||
913
912
!isUIntN (BitWidth - 1 , ElemSize)) {
914
- Indices.push_back (APInt::getZero (BitWidth));
915
- return ;
913
+ return APInt::getZero (BitWidth);
916
914
}
917
915
918
916
APInt Index = Offset.sdiv (ElemSize);
@@ -923,47 +921,52 @@ static void addElementIndex(SmallVectorImpl<APInt> &Indices, TypeSize ElemSize,
923
921
Offset += ElemSize;
924
922
assert (Offset.isNonNegative () && " Remaining offset shouldn't be negative" );
925
923
}
926
- Indices. push_back ( Index) ;
924
+ return Index;
927
925
}
928
926
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
+ }
940
933
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 ;
947
940
948
- addElementIndex (Indices, TypeSize::Fixed (ElemSizeInBits / 8 ), Offset);
949
- continue ;
950
- }
941
+ return getElementIndex (TypeSize::Fixed (ElemSizeInBits / 8 ), Offset);
942
+ }
951
943
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 ;
957
949
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
+ }
964
959
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);
967
970
}
968
971
969
972
return Indices;
0 commit comments