aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/TransformInternals.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2001-11-08 20:19:56 +0000
committerChris Lattner <sabre@nondot.org>2001-11-08 20:19:56 +0000
commitc0b90e7dd575ba59035334397722d677231a8f13 (patch)
tree467e1fe4d7aba862ad59e87e82f69be25dea0b71 /lib/Transforms/TransformInternals.cpp
parent837bb2ce96f6c812bec6d0bdc9726bcb7fa8e850 (diff)
Improve raising significantly
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1214 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/TransformInternals.cpp')
-rw-r--r--lib/Transforms/TransformInternals.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Transforms/TransformInternals.cpp b/lib/Transforms/TransformInternals.cpp
index e7eef2d21f..ac8181b722 100644
--- a/lib/Transforms/TransformInternals.cpp
+++ b/lib/Transforms/TransformInternals.cpp
@@ -8,6 +8,7 @@
#include "TransformInternals.h"
#include "llvm/Method.h"
#include "llvm/Type.h"
+#include "llvm/ConstPoolVals.h"
// TargetData Hack: Eventually we will have annotations given to us by the
// backend so that we know stuff about type size and alignments. For now
@@ -87,3 +88,44 @@ void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
}
+// 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
+// case we update offset to be the offset we actually obtained. The resultant
+// leaf type is returned.
+//
+// If StopEarly is set to true (the default), the first object with the
+// specified type is returned, even if it is a struct type itself. In this
+// case, this routine will not drill down to the leaf type. Set StopEarly to
+// false if you want a leaf
+//
+const Type *getStructOffsetType(const Type *Ty, unsigned &Offset,
+ vector<ConstPoolVal*> &Offsets,
+ bool StopEarly = true) {
+ if (!isa<StructType>(Ty) || (Offset == 0 && StopEarly)) {
+ Offset = 0; // Return the offset that we were able to acheive
+ return Ty; // Return the leaf type
+ }
+
+ assert(Offset < TD.getTypeSize(Ty) && "Offset not in struct!");
+ const StructType *STy = cast<StructType>(Ty);
+ 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(ConstPoolUInt::get(Type::UByteTy, i));
+
+ unsigned SubOffs = Offset - SL->MemberOffsets[i];
+ const Type *LeafTy = getStructOffsetType(STy->getElementTypes()[i], SubOffs,
+ Offsets);
+ Offset = SL->MemberOffsets[i] + SubOffs;
+ return LeafTy;
+}