diff options
author | Chris Lattner <sabre@nondot.org> | 2002-03-21 06:27:20 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-03-21 06:27:20 +0000 |
commit | 9e77f7e08b4241b810a3cccafb3d56dc256e0d1b (patch) | |
tree | 550c6ad6045d8da34d440a703feab2915f27fd03 /lib/Transforms/TransformInternals.cpp | |
parent | 8e86542fb698258a7feaa5703a1cf3918a7198fb (diff) |
Make ConvertableToGEP handle cases where the user is indexing into the
first element of a structure type. Before this would not be handled because
getStructOffset would either stop immediately (because StopEarly was true
and Offset = 0), or blast past the level we wanted.
Now ConvertableToGEP steps down through the type one level at a time, checking
the Offset and Scale conditions at each step
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1931 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/TransformInternals.cpp')
-rw-r--r-- | lib/Transforms/TransformInternals.cpp | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/lib/Transforms/TransformInternals.cpp b/lib/Transforms/TransformInternals.cpp index 9ea053e040..796cdc7cb4 100644 --- a/lib/Transforms/TransformInternals.cpp +++ b/lib/Transforms/TransformInternals.cpp @@ -83,6 +83,27 @@ BasicBlock::iterator InsertInstBeforeInst(Instruction *NewInst, +static const Type *getStructOffsetStep(const StructType *STy, unsigned &Offset, + std::vector<Value*> &Indices) { + assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!"); + const StructLayout *SL = TD.getStructLayout(STy); + + // This loop terminates always on a 0 <= i < MemberOffsets.size() + unsigned i; + for (i = 0; i < SL->MemberOffsets.size()-1; ++i) + if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) + break; + + assert(Offset >= SL->MemberOffsets[i] && + (i == SL->MemberOffsets.size()-1 || Offset < SL->MemberOffsets[i+1])); + + // Make sure to save the current index... + Indices.push_back(ConstantUInt::get(Type::UByteTy, i)); + Offset = SL->MemberOffsets[i]; + return STy->getContainedType(i); +} + + // getStructOffsetType - Return a vector of offsets that are to be used to index // into the specified struct type to get as close as possible to index as we // can. Note that it is possible that we cannot get exactly to Offset, in which @@ -95,36 +116,22 @@ BasicBlock::iterator InsertInstBeforeInst(Instruction *NewInst, // false if you want a leaf // const Type *getStructOffsetType(const Type *Ty, unsigned &Offset, - std::vector<Value*> &Offsets, + std::vector<Value*> &Indices, bool StopEarly = true) { - if (Offset == 0 && StopEarly && !Offsets.empty()) + if (Offset == 0 && StopEarly && !Indices.empty()) return Ty; // Return the leaf type unsigned ThisOffset; const Type *NextType; if (const StructType *STy = dyn_cast<StructType>(Ty)) { - assert(Offset < TD.getTypeSize(STy) && "Offset not in composite!"); - const StructLayout *SL = TD.getStructLayout(STy); - - // This loop terminates always on a 0 <= i < MemberOffsets.size() - unsigned i; - for (i = 0; i < SL->MemberOffsets.size()-1; ++i) - if (Offset >= SL->MemberOffsets[i] && Offset < SL->MemberOffsets[i+1]) - break; - - assert(Offset >= SL->MemberOffsets[i] && - (i == SL->MemberOffsets.size()-1 || Offset <SL->MemberOffsets[i+1])); - - // Make sure to save the current index... - Offsets.push_back(ConstantUInt::get(Type::UByteTy, i)); - ThisOffset = SL->MemberOffsets[i]; - NextType = STy->getElementTypes()[i]; + ThisOffset = Offset; + NextType = getStructOffsetStep(STy, ThisOffset, Indices); } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { assert(Offset < TD.getTypeSize(ATy) && "Offset not in composite!"); NextType = ATy->getElementType(); unsigned ChildSize = TD.getTypeSize(NextType); - Offsets.push_back(ConstantUInt::get(Type::UIntTy, Offset/ChildSize)); + Indices.push_back(ConstantUInt::get(Type::UIntTy, Offset/ChildSize)); ThisOffset = (Offset/ChildSize)*ChildSize; } else { Offset = 0; // Return the offset that we were able to acheive @@ -133,7 +140,7 @@ const Type *getStructOffsetType(const Type *Ty, unsigned &Offset, unsigned SubOffs = Offset - ThisOffset; const Type *LeafTy = getStructOffsetType(NextType, SubOffs, - Offsets, StopEarly); + Indices, StopEarly); Offset = ThisOffset + SubOffs; return LeafTy; } @@ -183,10 +190,9 @@ const Type *ConvertableToGEP(const Type *Ty, Value *OffsetVal, CompTy = cast<CompositeType>(NextTy); if (const StructType *StructTy = dyn_cast<StructType>(CompTy)) { + // Step into the appropriate element of the structure... unsigned ActualOffset = Offset; - NextTy = getStructOffsetType(StructTy, ActualOffset, Indices); - if (StructTy == NextTy && ActualOffset == 0) - return 0; // No progress. :( + NextTy = getStructOffsetStep(StructTy, ActualOffset, Indices); Offset -= ActualOffset; } else { const Type *ElTy = cast<SequentialType>(CompTy)->getElementType(); |