aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure/Local.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-10-31 05:45:02 +0000
committerChris Lattner <sabre@nondot.org>2002-10-31 05:45:02 +0000
commit8f0a16eac6e406d041af54471497453f50f52a64 (patch)
treecdc45de502e936ef84c23a5be0766d5bb08f6e29 /lib/Analysis/DataStructure/Local.cpp
parentdb94ca13b86c89358b19c91a5b1b79d9b24859ca (diff)
This fixes all kinds of problems with array handling. There are still bugs to
be fixed, but we are getting much closer now. * Make DSNode::TypeRec a full fledged DSTypeRec type. * Add methods used to update and access the typerecords elements * Add methods to query if and to cause a node to be completely folded * DSGraph construction doesn't use the allocation type for anything at all, now nodes get their type information based on how they are used. * Fixed a bug with global value handling introduced in the last checkin * GEP support is now much better, arrays are handled correctly. The array flag is now updated in type records. There are still cases that are not handled yet (we do not detect pessimizations), but getting much closer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4465 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/DataStructure/Local.cpp')
-rw-r--r--lib/Analysis/DataStructure/Local.cpp111
1 files changed, 80 insertions, 31 deletions
diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp
index 210bbec023..0cdb0e16a9 100644
--- a/lib/Analysis/DataStructure/Local.cpp
+++ b/lib/Analysis/DataStructure/Local.cpp
@@ -61,6 +61,7 @@ namespace {
vector<DSNode*> &Nodes;
DSNodeHandle &RetNode; // Node that gets returned...
map<Value*, DSNodeHandle> &ValueMap;
+ map<GlobalValue*, DSNodeHandle> GlobalScalarValueMap;
vector<DSCallSite> &FunctionCalls;
public:
@@ -112,7 +113,7 @@ namespace {
/// value. This either returns the already existing node, or creates a new
/// one and adds it to the graph, if none exists.
///
- DSNodeHandle getValueNode(Value &V);
+ DSNodeHandle &getValueNode(Value &V);
/// getValueDest - Return the DSNode that the actual value points to. This
/// is basically the same thing as: getLink(getValueNode(V), 0)
@@ -184,25 +185,37 @@ DSNodeHandle &GraphBuilder::getGlobalNode(GlobalValue &V) {
// This either returns the already existing node, or creates a new one and adds
// it to the graph, if none exists.
//
-DSNodeHandle GraphBuilder::getValueNode(Value &V) {
+DSNodeHandle &GraphBuilder::getValueNode(Value &V) {
assert(isPointerType(V.getType()) && "Should only use pointer scalars!");
- DSNodeHandle &NH = ValueMap[&V];
- if (NH.getNode()) return NH; // Already have a node? Just return it...
-
- // Otherwise we need to create a new scalar node...
- DSNode *N = createNode(DSNode::ScalarNode, V.getType());
-
- // If this is a global value, create the global pointed to.
if (GlobalValue *GV = dyn_cast<GlobalValue>(&V)) {
+ // The GlobalScalarValueMap keeps track of the scalar nodes that point to
+ // global values... The ValueMap contains pointers to the global memory
+ // object itself, not the scalar constant that points to the memory.
+ //
+ DSNodeHandle &NH = GlobalScalarValueMap[GV];
+ if (NH.getNode()) return NH;
+
+ // If this is a global value, create the global pointed to.
+ DSNode *N = createNode(DSNode::ScalarNode, V.getType());
+ NH.setOffset(0);
+ NH.setNode(N);
+
N->addEdgeTo(0, getGlobalNode(*GV));
- return DSNodeHandle(N, 0);
+ return NH;
+
} else {
+ DSNodeHandle &NH = ValueMap[&V];
+ if (NH.getNode())
+ return NH; // Already have a node? Just return it...
+
+ // Otherwise we need to create a new scalar node...
+ DSNode *N = createNode(DSNode::ScalarNode, V.getType());
+
NH.setOffset(0);
NH.setNode(N);
+ return NH;
}
-
- return NH;
}
/// getValueDest - Return the DSNode that the actual value points to. This
@@ -220,27 +233,25 @@ DSNodeHandle &GraphBuilder::getValueDest(Value &V) {
/// type should be linked to if we need to create a new node.
///
DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node,
- unsigned LinkNo, const Type *FieldTy) {
+ unsigned LinkNo,
+ const Type *FieldTy // FIXME: eliminate
+ ) {
DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
-
DSNodeHandle *Link = Node.getLink(LinkNo);
if (Link) return *Link;
-
- // If the link hasn't been created yet, make and return a new shadow node of
- // the appropriate type for FieldTy...
- //
+#if 0 // FIXME: delete
// If we are indexing with a typed pointer, then the thing we are pointing
// to is of the pointed type. If we are pointing to it with an integer
// (because of cast to an integer), we represent it with a void type.
//
- const Type *ReqTy;
+ const Type *ReqTy = 0;
if (const PointerType *Ptr = dyn_cast<PointerType>(FieldTy))
ReqTy = Ptr->getElementType();
- else
- ReqTy = Type::VoidTy;
+#endif
- DSNode *N = createNode(DSNode::ShadowNode, ReqTy);
+ // If the link hasn't been created yet, make and return a new shadow node
+ DSNode *N = createNode(DSNode::ShadowNode, 0);
Node.setLink(LinkNo, N);
return *Node.getLink(LinkNo);
}
@@ -254,8 +265,7 @@ DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node,
/// object, pointing the scalar to it.
///
void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
- //DSNode *New = createNode(NodeType, Type::VoidTy);
- DSNode *New = createNode(NodeType, AI.getAllocatedType());
+ DSNode *New = createNode(NodeType, 0);
// Make the scalar point to the new node...
getValueNode(AI).addEdgeTo(New);
@@ -277,18 +287,50 @@ void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
unsigned Offset = 0;
- const Type *CurTy = GEP.getOperand(0)->getType();
+ const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
+ const Type *CurTy = PTy->getElementType();
+ DSTypeRec &TopTypeRec =
+ Value.getNode()->getTypeRec(PTy->getElementType(), Value.getOffset());
+
+ // If the node had to be folded... exit quickly
+ if (TopTypeRec.Ty == Type::VoidTy) {
+ getValueNode(GEP).addEdgeTo(Value); // GEP result points to folded node
+ return;
+ }
+
+ // Handle the pointer index specially...
+ if (GEP.getNumOperands() > 1 &&
+ GEP.getOperand(1) != ConstantSInt::getNullValue(Type::LongTy)) {
+
+ // If we already know this is an array being accessed, don't do anything...
+ if (!TopTypeRec.isArray) {
+ TopTypeRec.isArray = true;
+
+ // If we are treating some inner field pointer as an array, fold the node
+ // up because we cannot handle it right. This can come because of
+ // something like this: &((&Pt->X)[1]) == &Pt->Y
+ //
+ if (Value.getOffset()) {
+ // Value is now the pointer we want to GEP to be...
+ Value.getNode()->foldNodeCompletely();
+ getValueNode(GEP).addEdgeTo(Value); // GEP result points to folded node
+ return;
+ } else {
+ // This is a pointer to the first byte of the node. Make sure that we
+ // are pointing to the outter most type in the node.
+ // FIXME: We need to check one more case here...
+ }
+ }
+ }
- for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i)
+ // All of these subscripts are indexing INTO the elements we have...
+ for (unsigned i = 2, e = GEP.getNumOperands(); i < e; ++i)
if (GEP.getOperand(i)->getType() == Type::LongTy) {
// Get the type indexing into...
const SequentialType *STy = cast<SequentialType>(CurTy);
CurTy = STy->getElementType();
if (ConstantSInt *CS = dyn_cast<ConstantSInt>(GEP.getOperand(i))) {
- if (isa<PointerType>(STy))
- std::cerr << "Pointer indexing not handled yet!\n";
- else
- Offset += CS->getValue()*TD.getTypeSize(CurTy);
+ Offset += CS->getValue()*TD.getTypeSize(CurTy);
} else {
// Variable index into a node. We must merge all of the elements of the
// sequential type here.
@@ -326,6 +368,9 @@ void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
void GraphBuilder::visitLoadInst(LoadInst &LI) {
DSNodeHandle &Ptr = getValueDest(*LI.getOperand(0));
Ptr.getNode()->NodeType |= DSNode::Read;
+
+ // Ensure a typerecord exists...
+ Ptr.getNode()->getTypeRec(LI.getType(), Ptr.getOffset());
if (isPointerType(LI.getType()))
getValueNode(LI).addEdgeTo(getLink(Ptr, 0, LI.getType()));
@@ -334,9 +379,13 @@ void GraphBuilder::visitLoadInst(LoadInst &LI) {
void GraphBuilder::visitStoreInst(StoreInst &SI) {
DSNodeHandle &Dest = getValueDest(*SI.getOperand(1));
Dest.getNode()->NodeType |= DSNode::Modified;
+ const Type *StoredTy = SI.getOperand(0)->getType();
+
+ // Ensure a typerecord exists...
+ Dest.getNode()->getTypeRec(StoredTy, Dest.getOffset());
// Avoid adding edges from null, or processing non-"pointer" stores
- if (isPointerType(SI.getOperand(0)->getType()) &&
+ if (isPointerType(StoredTy) &&
!isa<ConstantPointerNull>(SI.getOperand(0))) {
Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
}