Remove spurious caller pointer in DSCallSite.
authorVikram S. Adve <vadve@cs.uiuc.edu>
Sun, 20 Oct 2002 21:41:02 +0000 (21:41 +0000)
committerVikram S. Adve <vadve@cs.uiuc.edu>
Sun, 20 Oct 2002 21:41:02 +0000 (21:41 +0000)
Also add functions to access pointer argument nodes cleanly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4235 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DSGraph.h
include/llvm/Analysis/DataStructure/DSGraph.h
lib/Analysis/DataStructure/BottomUpClosure.cpp
lib/Analysis/DataStructure/DataStructure.cpp
lib/Analysis/DataStructure/Local.cpp
lib/Analysis/DataStructure/Steensgaard.cpp
lib/Analysis/DataStructure/TopDownClosure.cpp

index dc8f1adcf54cea7237f835c1490cf2648f4fe5d7..80ad040c1b9f5624138df7a202eb0b3aa475c087 100644 (file)
@@ -362,26 +362,27 @@ inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
 /// the DSNode handles for the function arguments.
 /// 
 class DSCallSite: public std::vector<DSNodeHandle> {
-  Function* caller;
   CallInst* callInst;
   DSCallSite();                         // do not implement
 
 public:
-  DSCallSite(Function& _caller, CallInst& _callInst)
-    : caller(&_caller), callInst(&_callInst) { }
+  DSCallSite(CallInst& _callInst) : callInst(&_callInst) { }
 
   // Copy constructor with helper for cloning nodes.  The helper should be a
   // model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
   // should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
   // If no helper is specified, this defaults to a simple copy constructor.
   template<typename _CopierFunction>
-  DSCallSite::DSCallSite(const DSCallSite& FromCall,
-                         _CopierFunction nodeCopier = *(_CopierFunction*) 0);
-
-  Function&     getCaller() const           { return *caller; }
-  CallInst&     getCallInst() const         { return *callInst; }
-  DSNodeHandle  getReturnValueNode() const  { return (*this)[0]; }
-  DSNodeHandle  getCalleeNode() const       { return (*this)[1]; }
+  DSCallSite(const DSCallSite& FromCall,
+             _CopierFunction nodeCopier = *(_CopierFunction*) 0);
+
+  Function&     getCaller()                const;
+  CallInst&     getCallInst()              const { return *callInst; }
+  DSNodeHandle  getReturnValueNode()       const { return (*this)[0]; }
+  DSNodeHandle  getCalleeNode()            const { return (*this)[1]; }
+  unsigned      getNumPtrArgs()            const { return (size() - 2); }
+  DSNodeHandle  getPtrArgNode(unsigned i)  const { assert(i < getNumPtrArgs());
+                                                   return (*this)[i+2]; }
 };
 
 
index dc8f1adcf54cea7237f835c1490cf2648f4fe5d7..80ad040c1b9f5624138df7a202eb0b3aa475c087 100644 (file)
@@ -362,26 +362,27 @@ inline void DSNodeHandle::mergeWith(const DSNodeHandle &Node) {
 /// the DSNode handles for the function arguments.
 /// 
 class DSCallSite: public std::vector<DSNodeHandle> {
-  Function* caller;
   CallInst* callInst;
   DSCallSite();                         // do not implement
 
 public:
-  DSCallSite(Function& _caller, CallInst& _callInst)
-    : caller(&_caller), callInst(&_callInst) { }
+  DSCallSite(CallInst& _callInst) : callInst(&_callInst) { }
 
   // Copy constructor with helper for cloning nodes.  The helper should be a
   // model of unary_function<const DSNodeHandle*, DSNodeHandle>, i.e., it
   // should take a pointer to DSNodeHandle and return a fresh DSNodeHandle.
   // If no helper is specified, this defaults to a simple copy constructor.
   template<typename _CopierFunction>
-  DSCallSite::DSCallSite(const DSCallSite& FromCall,
-                         _CopierFunction nodeCopier = *(_CopierFunction*) 0);
-
-  Function&     getCaller() const           { return *caller; }
-  CallInst&     getCallInst() const         { return *callInst; }
-  DSNodeHandle  getReturnValueNode() const  { return (*this)[0]; }
-  DSNodeHandle  getCalleeNode() const       { return (*this)[1]; }
+  DSCallSite(const DSCallSite& FromCall,
+             _CopierFunction nodeCopier = *(_CopierFunction*) 0);
+
+  Function&     getCaller()                const;
+  CallInst&     getCallInst()              const { return *callInst; }
+  DSNodeHandle  getReturnValueNode()       const { return (*this)[0]; }
+  DSNodeHandle  getCalleeNode()            const { return (*this)[1]; }
+  unsigned      getNumPtrArgs()            const { return (size() - 2); }
+  DSNodeHandle  getPtrArgNode(unsigned i)  const { assert(i < getNumPtrArgs());
+                                                   return (*this)[i+2]; }
 };
 
 
index b6748d8e38bdf2c6f70a998a5056f8eb67c27b46..52b473883ccd7f6ceb6b7284ed8a33ad7c9f075a 100644 (file)
@@ -60,13 +60,13 @@ static void ResolveArguments(DSCallSite &Call, Function &F,
                              map<Value*, DSNodeHandle> &ValueMap) {
   // Resolve all of the function arguments...
   Function::aiterator AI = F.abegin();
-  for (unsigned i = 2, e = Call.size(); i != e; ++i) {
+  for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i) {
     // Advance the argument iterator to the first pointer argument...
     while (!isPointerType(AI->getType())) ++AI;
     
     // Add the link from the argument scalar to the provided value
     DSNodeHandle &NN = ValueMap[AI];
-    NN.addEdgeTo(Call[i]);
+    NN.addEdgeTo(Call.getPtrArgNode(i));
     ++AI;
   }
 }
@@ -111,10 +111,6 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
           // Must be a function type, so this cast MUST succeed.
           Function &FI = cast<Function>(*Callees[c]);
 
-          // Record that this is a call site of FI.
-          assert(&Call.getCaller() == &F && "Invalid caller in DSCallSite?");
-          CallSites[&FI].push_back(Call);
-
           if (&FI == &F) {
             // Self recursion... simply link up the formal arguments with the
             // actual arguments...
@@ -143,6 +139,11 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
             DEBUG(std::cerr << "\t\t[BU] Got graph for " << FI.getName()
                   << " in: " << F.getName() << "\n");
 
+            // Record that the original DSCallSite was a call site of FI.
+            // This may or may not have been known when the DSCallSite was
+            // originally created.
+            CallSites[&FI].push_back(Call);
+
             // Clone the callee's graph into the current graph, keeping
             // track of where scalars in the old graph _used_ to point,
             // and of the new nodes matching nodes of the old graph.
index 3a55c5420b16eed749eceeb8e0bb688a12eaca33..356736289c000ffb3e1d8617bbc7324d58f19d8a 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "llvm/Analysis/DSGraph.h"
 #include "llvm/Function.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/iOther.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Target/TargetData.h"
 #include "Support/STLExtras.h"
@@ -351,12 +353,15 @@ void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
   }
 }
 
+// Define here to avoid including iOther.h and BasicBlock.h in DSGraph.h
+Function& DSCallSite::getCaller() const {
+  return * callInst->getParent()->getParent();
+}
 
 template<typename _CopierFunction>
 DSCallSite::DSCallSite(const DSCallSite& FromCall,
                        _CopierFunction nodeCopier)
   : std::vector<DSNodeHandle>(),
-    caller(&FromCall.getCaller()),
     callInst(&FromCall.getCallInst()) {
 
   reserve(FromCall.size());
@@ -547,15 +552,15 @@ void DSGraph::markIncompleteNodes(bool markFormalArgs) {
 
   // Mark stuff passed into functions calls as being incomplete...
   for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
-    DSCallSite &Args = FunctionCalls[i];
+    DSCallSite &Call = FunctionCalls[i];
     // Then the return value is certainly incomplete!
-    markIncompleteNode(Args.getReturnValueNode().getNode());
+    markIncompleteNode(Call.getReturnValueNode().getNode());
 
     // The call does not make the function argument incomplete...
  
     // All arguments to the function call are incomplete though!
-    for (unsigned i = 2, e = Args.size(); i != e; ++i)
-      markIncompleteNode(Args[i].getNode());
+    for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
+      markIncompleteNode(Call.getPtrArgNode(i).getNode());
   }
 
   // Mark all of the nodes pointed to by global or cast nodes as incomplete...
index 15b3a96b8774ffcf8ae5bb159cf1437967c23f1f..037e36197c8c9a4ea11a9614c71bb077bb277717 100644 (file)
@@ -356,7 +356,7 @@ void GraphBuilder::visitReturnInst(ReturnInst &RI) {
 
 void GraphBuilder::visitCallInst(CallInst &CI) {
   // Add a new function call entry...
-  FunctionCalls.push_back(DSCallSite(G.getFunction(), CI));
+  FunctionCalls.push_back(DSCallSite(CI));
   DSCallSite &Args = FunctionCalls.back();
 
   // Set up the return value...
index 9bc3db79e73b24da6655b78ed4ec9f80930279ae..f0072a02abbc8c2c13f5294d32a51db53f2141ee 100644 (file)
@@ -91,14 +91,14 @@ void Steens::ResolveFunctionCall(Function *F,
     RetVal.mergeWith(Call.getReturnValueNode());
 
   // Loop over all pointer arguments, resolving them to their provided pointers
-  unsigned ArgIdx = 2; // Skip retval and function to call...
+  unsigned PtrArgIdx = 0;
   for (Function::aiterator AI = F->abegin(), AE = F->aend(); AI != AE; ++AI) {
     std::map<Value*, DSNodeHandle>::iterator I = ValMap.find(AI);
     if (I != ValMap.end())    // If its a pointer argument...
-      I->second.addEdgeTo(Call[ArgIdx++]);
+      I->second.addEdgeTo(Call.getPtrArgNode(PtrArgIdx++));
   }
 
-  assert(ArgIdx == Call.size() && "Argument resolution mismatch!");
+  assert(PtrArgIdx == Call.getNumPtrArgs() && "Argument resolution mismatch!");
 }
 
 
index 1ceaedbe60b06d1b62044c4d95ac664f5ec4a896..f4b7017b2eaafd4166b341b8caa3ce4c833f51c1 100644 (file)
@@ -53,14 +53,14 @@ void TDDataStructures::ResolveCallSite(DSGraph &Graph,
   Function &F = Graph.getFunction();
   Function::aiterator AI = F.abegin();
 
-  for (unsigned i = 2, e = CallSite.size(); i != e; ++i, ++AI) {
+  for (unsigned i = 0, e = CallSite.getNumPtrArgs(); i != e; ++i, ++AI) {
     // Advance the argument iterator to the first pointer argument...
     while (!DataStructureAnalysis::isPointerType(AI->getType())) ++AI;
     
     // TD ...Merge the formal arg scalar with the actual arg node
     DSNodeHandle &NodeForFormal = Graph.getNodeForValue(AI);
     if (NodeForFormal.getNode())
-      NodeForFormal.mergeWith(CallSite[i]);
+      NodeForFormal.mergeWith(CallSite.getPtrArgNode(i));
   }
   
   // Merge returned node in the caller with the "return" node in callee
@@ -68,6 +68,13 @@ void TDDataStructures::ResolveCallSite(DSGraph &Graph,
     Graph.getRetNode().mergeWith(CallSite.getReturnValueNode());
 }
 
+
+static DSNodeHandle copyHelper(const DSNodeHandle* fromNode,
+                               std::map<const DSNode*, DSNode*> *NodeMap) {
+  return DSNodeHandle((*NodeMap)[fromNode->getNode()], fromNode->getOffset());
+}
+
+
 DSGraph &TDDataStructures::calculateGraph(Function &F) {
   // Make sure this graph has not already been calculated, or that we don't get
   // into an infinite loop with mutually recursive functions.
@@ -128,12 +135,8 @@ DSGraph &TDDataStructures::calculateGraph(Function &F) {
 
       // Make a temporary copy of the call site, and transform the argument node
       // pointers.
-      DSCallSite TmpCallSite = CallSite;
-      for (unsigned i = 0, e = CallSite.size(); i != e; ++i) {
-        const DSNode *OldNode = TmpCallSite[i].getNode();
-        TmpCallSite[i].setNode(OldNodeMap[OldNode]);
-      }
-
+      DSCallSite TmpCallSite(CallSite, std::bind2nd(std::ptr_fun(&copyHelper),
+                                                    &OldNodeMap));
       ResolveCallSite(*Graph, CallSite);
     }
   }