[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp Local.cpp Printer.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Nov 1 18:14:01 PST 2002


Changes in directory llvm/lib/Analysis/DataStructure:

BottomUpClosure.cpp updated: 1.26 -> 1.27
DataStructure.cpp updated: 1.37 -> 1.38
Local.cpp updated: 1.23 -> 1.24
Printer.cpp updated: 1.27 -> 1.28

---
Log message:

Stop representing scalars as explicit nodes in the graph.  Now the only
nodes in the graph are memory objects, which is very nice.  This also greatly 
reduces the size and memory footprint for DSGraphs.  For example, the local
DSGraph for llu went from 65 to 13 nodes with this change.  As a side bonus,
dot seems to lay out the graphs slightly better too.  :)



---
Diffs of the changes:

Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.26 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.27
--- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.26	Thu Oct 31 17:24:00 2002
+++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp	Fri Nov  1 18:13:20 2002
@@ -16,8 +16,7 @@
 static RegisterAnalysis<BUDataStructures>
 X("budatastructure", "Bottom-up Data Structure Analysis Closure");
 
-// TODO: FIXME
-namespace DataStructureAnalysis {
+namespace DataStructureAnalysis { // TODO: FIXME: Eliminate
   // isPointerType - Return true if this first class type is big enough to hold
   // a pointer.
   //
@@ -60,14 +59,12 @@
                              map<Value*, DSNodeHandle> &ValueMap) {
   // Resolve all of the function arguments...
   Function::aiterator AI = F.abegin();
-  for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i) {
+  for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i, ++AI) {
     // 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.getPtrArg(i));
-    ++AI;
+    ValueMap[AI].mergeWith(Call.getPtrArg(i));
   }
 }
 
@@ -118,8 +115,7 @@
             DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
 
             // Handle the return value if present...
-            if (Call.getRetVal().getNode())
-              Graph->getRetNode().mergeWith(Call.getRetVal());
+            Graph->getRetNode().mergeWith(Call.getRetVal());
 
             // Resolve the arguments in the call to the actual values...
             ResolveArguments(Call, F, Graph->getValueMap());
@@ -143,11 +139,12 @@
             // 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.
+#if 1  /// FIXME: Reenable
             std::vector<DSCallSite> &CallSitesForFunc = CallSites[&FI];
             CallSitesForFunc.push_back(Call);
             CallSitesForFunc.back().setResolvingCaller(&F);
             CallSitesForFunc.back().setCallee(0);
-
+#endif
             // 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.
@@ -163,8 +160,8 @@
             // Resolve the arguments in the call to the actual values...
             ResolveArguments(Call, FI, OldValMap);
 
-            if (Call.getRetVal().getNode())// Handle the return value if present
-              RetVal.mergeWith(Call.getRetVal());
+            // Handle the return value if present...
+            RetVal.mergeWith(Call.getRetVal());
 
             // Erase the entry in the Callees vector
             Callees.erase(Callees.begin()+c--);
@@ -172,9 +169,10 @@
           } else if (FI.getName() == "printf" || FI.getName() == "sscanf" ||
                      FI.getName() == "fprintf" || FI.getName() == "open" ||
                      FI.getName() == "sprintf") {
-            // FIXME: These special cases should go away when we can define
-            // functions that take a variable number of arguments.
+            // FIXME: These special cases (eg printf) should go away when we can
+            // define functions that take a variable number of arguments.
 
+            // FIXME: at the very least, this should update mod/ref info
             // Erase the entry in the globals vector
             Callees.erase(Callees.begin()+c--);
           }


Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.37 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.38
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.37	Thu Oct 31 16:41:15 2002
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp	Fri Nov  1 18:13:20 2002
@@ -16,8 +16,7 @@
 
 using std::vector;
 
-// TODO: FIXME
-namespace DataStructureAnalysis {
+namespace DataStructureAnalysis {   // TODO: FIXME
   // isPointerType - Return true if this first class type is big enough to hold
   // a pointer.
   //
@@ -538,14 +537,15 @@
 
 // cloneInto - Clone the specified DSGraph into the current graph, returning the
 // Return node of the graph.  The translated ValueMap for the old function is
-// filled into the OldValMap member.  If StripLocals is set to true, Scalar and
-// Alloca markers are removed from the graph, as the graph is being cloned into
-// a calling function's graph.
+// filled into the OldValMap member.  If StripAllocas is set to true, Alloca
+// markers are removed from the graph, as the graph is being cloned into a
+// calling function's graph.
 //
 DSNodeHandle DSGraph::cloneInto(const DSGraph &G, 
                                 std::map<Value*, DSNodeHandle> &OldValMap,
                                 std::map<const DSNode*, DSNode*> &OldNodeMap,
-                                bool StripScalars, bool StripAllocas) {
+                                bool StripScalars,  // FIXME: Kill StripScalars
+                                bool StripAllocas) {
   assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
 
   unsigned FN = Nodes.size();           // First new node...
@@ -564,8 +564,7 @@
     Nodes[i]->remapLinks(OldNodeMap);
 
   // Remove local markers as specified
-  unsigned char StripBits = (StripScalars ? DSNode::ScalarNode : 0) |
-                            (StripAllocas ? DSNode::AllocaNode : 0);
+  unsigned char StripBits = StripAllocas ? DSNode::AllocaNode : 0;
   if (StripBits)
     for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
       Nodes[i]->NodeType &= ~StripBits;
@@ -574,7 +573,8 @@
   for (std::map<Value*, DSNodeHandle>::const_iterator I = G.ValueMap.begin(),
          E = G.ValueMap.end(); I != E; ++I) {
     DSNodeHandle &H = OldValMap[I->first];
-    H = DSNodeHandle(OldNodeMap[I->second.getNode()], I->second.getOffset());
+    H.setNode(OldNodeMap[I->second.getNode()]);
+    H.setOffset(I->second.getOffset());
 
     if (isa<GlobalValue>(I->first)) {  // Is this a global?
       std::map<Value*, DSNodeHandle>::iterator GVI = ValueMap.find(I->first);
@@ -655,11 +655,8 @@
   // Mark any incoming arguments as incomplete...
   if (markFormalArgs && Func)
     for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I)
-      if (isPointerType(I->getType()) && ValueMap.find(I) != ValueMap.end()) {
-        DSNodeHandle &INH = ValueMap[I];
-        if (INH.getNode() && INH.hasLink(0))
-          markIncompleteNode(ValueMap[I].getLink(0)->getNode());
-      }
+      if (isPointerType(I->getType()) && ValueMap.find(I) != ValueMap.end())
+        markIncompleteNode(ValueMap[I].getNode());
 
   // Mark stuff passed into functions calls as being incomplete...
   for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) {
@@ -667,17 +664,16 @@
     // Then the return value is certainly incomplete!
     markIncompleteNode(Call.getRetVal().getNode());
 
-    // The call does not make the function argument incomplete...
- 
-    // All arguments to the function call are incomplete though!
+    // All objects pointed to by function arguments are incomplete though!
     for (unsigned i = 0, e = Call.getNumPtrArgs(); i != e; ++i)
       markIncompleteNode(Call.getPtrArg(i).getNode());
   }
 
-  // Mark all of the nodes pointed to by global or cast nodes as incomplete...
+  // Mark all of the nodes pointed to by global nodes as incomplete...
   for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
     if (Nodes[i]->NodeType & DSNode::GlobalNode) {
       DSNode *N = Nodes[i];
+      // FIXME: Make more efficient by looking over Links directly
       for (unsigned i = 0, e = N->getSize(); i != e; ++i)
         if (DSNodeHandle *DSNH = N->getLink(i))
           markIncompleteNode(DSNH->getNode());
@@ -706,9 +702,7 @@
     return true;
 
   // Is it a function node or some other trivially unused global?
-  if (N->NodeType != 0 &&
-      (N->NodeType & ~DSNode::GlobalNode) == 0 && 
-      N->getSize() == 0 &&
+  if ((N->NodeType & ~DSNode::GlobalNode) == 0 && N->getSize() == 0 &&
       N->getReferrers().size() == N->getGlobals().size()) {
 
     // Remove the globals from the ValueMap, so that the referrer count will go
@@ -758,6 +752,7 @@
   if (N == 0) return;
 
   Alive.insert(N);
+  // FIXME: Make more efficient by looking over Links directly
   for (unsigned i = 0, e = N->getSize(); i != e; ++i)
     if (DSNodeHandle *DSNH = N->getLink(i))
       if (!Alive.count(DSNH->getNode()))
@@ -887,7 +882,7 @@
   markGlobalsIteration(GlobalNodes, Calls, Alive, FilterCalls);
 
   // Free up references to dead globals from the ValueMap
-  std::set<DSNode*>::iterator I=GlobalNodes.begin(), E=GlobalNodes.end();
+  std::set<DSNode*>::iterator I = GlobalNodes.begin(), E = GlobalNodes.end();
   for( ; I != E; ++I)
     if (Alive.count(*I) == 0)
       removeRefsToGlobal(*I, G.getValueMap());
@@ -931,20 +926,21 @@
       markAlive(FunctionCalls[i].getCallee().getNode(), Alive);
     }
 
+  // Mark all nodes reachable by scalar nodes as alive...
+  for (std::map<Value*, DSNodeHandle>::iterator I = ValueMap.begin(),
+         E = ValueMap.end(); I != E; ++I)
+    markAlive(I->second.getNode(), Alive);
+
 #if 0
-  for (unsigned i = 0, e = OrigFunctionCalls.size(); i != e; ++i)
-    for (unsigned j = 0, e = OrigFunctionCalls[i].size(); j != e; ++j)
-      markAlive(OrigFunctionCalls[i][j].getNode(), Alive);
+  // Marge all nodes reachable by global nodes, as alive.  Isn't this covered by
+  // the ValueMap?
+  //
+  if (KeepAllGlobals)
+    for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
+      if (Nodes[i]->NodeType & DSNode::GlobalNode)
+        markAlive(Nodes[i], Alive);
 #endif
 
-  // Mark all nodes reachable by scalar nodes (and global nodes, if
-  // keeping them was specified) as alive...
-  unsigned char keepBits = DSNode::ScalarNode |
-                           (KeepAllGlobals ? DSNode::GlobalNode : 0);
-  for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
-    if (Nodes[i]->NodeType & keepBits)
-      markAlive(Nodes[i], Alive);
-
   // The return value is alive as well...
   markAlive(RetNode.getNode(), Alive);
 
@@ -952,7 +948,7 @@
   // This also marks all nodes reachable from such nodes as alive.
   // Of course, if KeepAllGlobals is specified, they would be live already.
   if (!KeepAllGlobals)
-    markGlobalsAlive(*this, Alive, ! KeepCalls);
+    markGlobalsAlive(*this, Alive, !KeepCalls);
 
   // Loop over all unreachable nodes, dropping their references...
   vector<DSNode*> DeadNodes;


Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.23 llvm/lib/Analysis/DataStructure/Local.cpp:1.24
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.23	Thu Oct 31 00:52:26 2002
+++ llvm/lib/Analysis/DataStructure/Local.cpp	Fri Nov  1 18:13:20 2002
@@ -61,7 +61,6 @@
     vector<DSNode*> &Nodes;
     DSNodeHandle &RetNode;               // Node that gets returned...
     map<Value*, DSNodeHandle> &ValueMap;
-    map<GlobalValue*, DSNodeHandle> GlobalScalarValueMap;
     vector<DSCallSite> &FunctionCalls;
 
   public:
@@ -107,23 +106,21 @@
     /// createNode - Create a new DSNode, ensuring that it is properly added to
     /// the graph.
     ///
-    DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty);
-
-    /// getValueNode - Return a DSNode that corresponds the the specified LLVM
-    /// 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);
+    DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty = 0) {
+      DSNode *N = new DSNode(NodeType, Ty);   // Create the node
+      Nodes.push_back(N);                     // Add node to nodes list
+      return N;
+    }
 
-    /// getValueDest - Return the DSNode that the actual value points to.  This
-    /// is the same thing as: getLink(getValueNode(V))
+    /// setDestTo - Set the ValueMap entry for the specified value to point to
+    /// the specified destination.  If the Value already points to a node, make
+    /// sure to merge the two destinations together.
     ///
-    DSNodeHandle &getValueDest(Value &V);
+    void setDestTo(Value &V, const DSNodeHandle &NH);
 
-    /// getGlobalNode - Just like getValueNode, except the global node itself is
-    /// returned, not a scalar node pointing to a global.
+    /// getValueDest - Return the DSNode that the actual value points to. 
     ///
-    DSNodeHandle &getGlobalNode(GlobalValue &V);
+    DSNodeHandle getValueDest(Value &V);
 
     /// getLink - This method is used to return the specified link in the
     /// specified node if one exists.  If a link does not already exist (it's
@@ -148,78 +145,34 @@
 //
 
 
-// createNode - Create a new DSNode, ensuring that it is properly added to the
-// graph.
-//
-DSNode *GraphBuilder::createNode(DSNode::NodeTy NodeType, const Type *Ty) {
-  DSNode *N = new DSNode(NodeType, Ty);
-  Nodes.push_back(N);
-  return N;
-}
+/// getValueDest - Return the DSNode that the actual value points to.
+///
+DSNodeHandle GraphBuilder::getValueDest(Value &V) {
+  if (Constant *C = dyn_cast<Constant>(&V)) {
+    // FIXME: Return null NH for constants like 10 or null
+    // FIXME: Handle constant exprs here.
 
+    return 0;   // Constant doesn't point to anything.
+  }
 
-// getGlobalNode - Just like getValueNode, except the global node itself is
-// returned, not a scalar node pointing to a global.
-//
-DSNodeHandle &GraphBuilder::getGlobalNode(GlobalValue &V) {
   DSNodeHandle &NH = ValueMap[&V];
-  if (NH.getNode()) return NH;       // Already have a node?  Just return it...
-
-  // Create a new global node for this global variable...
-  DSNode *G = createNode(DSNode::GlobalNode, V.getType()->getElementType());
-  G->addGlobal(&V);
-
-  // If this node has outgoing edges, make sure to recycle the same node for
-  // each use.  For functions and other global variables, this is unneccesary,
-  // so avoid excessive merging by cloning these nodes on demand.
-  //
-  NH.setNode(G);
-  return NH;
-}
-
-
-// getValueNode - Return a DSNode that corresponds the the specified LLVM value.
-// 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) {
-  assert(isPointerType(V.getType()) && "Should only use pointer scalars!");
+  if (NH.getNode())
+    return NH;     // Already have a node?  Just return it...
 
+  // Otherwise we need to create a new node to point to...
+  DSNode *N;
   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 NH;
-    
+    // Create a new global node for this global variable...
+    N = createNode(DSNode::GlobalNode, GV->getType()->getElementType());
+    N->addGlobal(GV);
   } 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;
+    // Otherwise just create a shadow node
+    N = createNode(DSNode::ShadowNode);
   }
-}
 
-/// getValueDest - Return the DSNode that the actual value points to.  This is
-/// the same thing as: getLink(getValueNode(V), 0)
-///
-DSNodeHandle &GraphBuilder::getValueDest(Value &V) {
-  return getLink(getValueNode(V));
+  NH.setNode(N);      // Remember that we are pointing to it...
+  NH.setOffset(0);
+  return NH;
 }
 
 
@@ -235,12 +188,25 @@
   if (Link) return *Link;
 
   // If the link hasn't been created yet, make and return a new shadow node
-  DSNode *N = createNode(DSNode::ShadowNode, 0);
+  DSNode *N = createNode(DSNode::ShadowNode);
   Node.setLink(LinkNo, N);
   return *Node.getLink(LinkNo);
 }
 
 
+/// setDestTo - Set the ValueMap entry for the specified value to point to the
+/// specified destination.  If the Value already points to a node, make sure to
+/// merge the two destinations together.
+///
+void GraphBuilder::setDestTo(Value &V, const DSNodeHandle &NH) {
+  DSNodeHandle &AINH = ValueMap[&V];
+  if (AINH.getNode() == 0)   // Not pointing to anything yet?
+    AINH = NH;               // Just point directly to NH
+  else
+    AINH.mergeWith(NH);
+}
+
+
 //===----------------------------------------------------------------------===//
 // Specific instruction type handler implementations...
 //
@@ -249,10 +215,7 @@
 /// object, pointing the scalar to it.
 ///
 void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
-  DSNode *New = createNode(NodeType, 0);
-
-  // Make the scalar point to the new node...
-  getValueNode(AI).addEdgeTo(New);
+  setDestTo(AI, createNode(NodeType));
 }
 
 // PHINode - Make the scalar for the PHI node point to all of the things the
@@ -261,14 +224,14 @@
 void GraphBuilder::visitPHINode(PHINode &PN) {
   if (!isPointerType(PN.getType())) return; // Only pointer PHIs
 
-  DSNodeHandle &ScalarDest = getValueDest(PN);
+  DSNodeHandle &PNDest = ValueMap[&PN];
   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
-    if (!isa<ConstantPointerNull>(PN.getIncomingValue(i)))
-      ScalarDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
+    PNDest.mergeWith(getValueDest(*PN.getIncomingValue(i)));
 }
 
 void GraphBuilder::visitGetElementPtrInst(GetElementPtrInst &GEP) {
   DSNodeHandle Value = getValueDest(*GEP.getOperand(0));
+  if (Value.getNode() == 0) return;
 
   unsigned Offset = 0;
   const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
@@ -278,7 +241,7 @@
 
   // If the node had to be folded... exit quickly
   if (TopTypeRec.Ty == Type::VoidTy) {
-    getValueNode(GEP).addEdgeTo(Value);  // GEP result points to folded node
+    setDestTo(GEP, Value);  // GEP result points to folded node
     return;
   }
 
@@ -297,7 +260,7 @@
       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
+        setDestTo(GEP, Value);  // GEP result points to folded node
         return;
       } else {
         // This is a pointer to the first byte of the node.  Make sure that we
@@ -346,56 +309,51 @@
   Value.setOffset(Value.getOffset()+Offset);
 
   // Value is now the pointer we want to GEP to be...
-  getValueNode(GEP).addEdgeTo(Value);
+  setDestTo(GEP, Value);
 }
 
 void GraphBuilder::visitLoadInst(LoadInst &LI) {
-  DSNodeHandle &Ptr = getValueDest(*LI.getOperand(0));
+  DSNodeHandle Ptr = getValueDest(*LI.getOperand(0));
+  if (Ptr.getNode() == 0) return;
+
+  // Make that the node is read from...
   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));
+    setDestTo(LI, getLink(Ptr));
 }
 
 void GraphBuilder::visitStoreInst(StoreInst &SI) {
-  DSNodeHandle &Dest = getValueDest(*SI.getOperand(1));
-  Dest.getNode()->NodeType |= DSNode::Modified;
   const Type *StoredTy = SI.getOperand(0)->getType();
+  DSNodeHandle Dest = getValueDest(*SI.getOperand(1));
+  if (Dest.getNode() == 0) return;
+
+  // Make that the node is written to...
+  Dest.getNode()->NodeType |= DSNode::Modified;
 
   // Ensure a typerecord exists...
   Dest.getNode()->getTypeRec(StoredTy, Dest.getOffset());
 
   // Avoid adding edges from null, or processing non-"pointer" stores
-  if (isPointerType(StoredTy) &&
-      !isa<ConstantPointerNull>(SI.getOperand(0))) {
+  if (isPointerType(StoredTy))
     Dest.addEdgeTo(getValueDest(*SI.getOperand(0)));
-  }
 }
 
 void GraphBuilder::visitReturnInst(ReturnInst &RI) {
-  if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()) &&
-      !isa<ConstantPointerNull>(RI.getOperand(0))) {
-    DSNodeHandle &Value = getValueDest(*RI.getOperand(0));
-    Value.mergeWith(RetNode);
-    RetNode = Value;
-  }
+  if (RI.getNumOperands() && isPointerType(RI.getOperand(0)->getType()))
+    RetNode.mergeWith(getValueDest(*RI.getOperand(0)));
 }
 
 void GraphBuilder::visitCallInst(CallInst &CI) {
   // Set up the return value...
   DSNodeHandle RetVal;
   if (isPointerType(CI.getType()))
-    RetVal = getLink(getValueNode(CI));
+    RetVal = getValueDest(CI);
 
-  DSNodeHandle Callee;
-  // Special case for a direct call, avoid creating spurious scalar node...
-  if (GlobalValue *GV = dyn_cast<GlobalValue>(CI.getOperand(0)))
-    Callee = getGlobalNode(*GV);
-  else
-    Callee = getLink(getValueNode(*CI.getOperand(0)));
+  DSNodeHandle Callee = getValueDest(*CI.getOperand(0));
 
   std::vector<DSNodeHandle> Args;
   Args.reserve(CI.getNumOperands()-1);
@@ -403,7 +361,7 @@
   // Calculate the arguments vector...
   for (unsigned i = 1, e = CI.getNumOperands(); i != e; ++i)
     if (isPointerType(CI.getOperand(i)->getType()))
-      Args.push_back(getLink(getValueNode(*CI.getOperand(i))));
+      Args.push_back(getValueDest(*CI.getOperand(i)));
 
   // Add a new function call entry...
   FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args));
@@ -411,8 +369,12 @@
 
 /// Handle casts...
 void GraphBuilder::visitCastInst(CastInst &CI) {
-  if (isPointerType(CI.getType()) && isPointerType(CI.getOperand(0)->getType()))
-    getValueNode(CI).addEdgeTo(getLink(getValueNode(*CI.getOperand(0))));
+  if (isPointerType(CI.getType())) {
+    if (isPointerType(CI.getOperand(0)->getType()))
+      setDestTo(CI, getValueDest(*CI.getOperand(0)));
+    else
+      ; // FIXME: "Other" node
+  }
 }
 
 


Index: llvm/lib/Analysis/DataStructure/Printer.cpp
diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.27 llvm/lib/Analysis/DataStructure/Printer.cpp:1.28
--- llvm/lib/Analysis/DataStructure/Printer.cpp:1.27	Mon Oct 21 08:47:57 2002
+++ llvm/lib/Analysis/DataStructure/Printer.cpp	Fri Nov  1 18:13:20 2002
@@ -36,7 +36,6 @@
     OS << "\n";
   }
 
-  if (N->NodeType & DSNode::ScalarNode) OS << "S";
   if (N->NodeType & DSNode::AllocaNode) OS << "A";
   if (N->NodeType & DSNode::NewNode   ) OS << "N";
   if (N->NodeType & DSNode::GlobalNode) OS << "G";
@@ -49,15 +48,6 @@
     OS << "\n";
   }
 
-  if ((N->NodeType & DSNode::ScalarNode) && G) {
-    const std::map<Value*, DSNodeHandle> &VM = G->getValueMap();
-    for (std::map<Value*, DSNodeHandle>::const_iterator I = VM.begin(),
-           E = VM.end(); I != E; ++I)
-      if (I->second.getNode() == N) {
-        WriteAsOperand(OS, I->first, false, true, M);
-        OS << "\n";
-      }
-  }
   return OS.str();
 }
 
@@ -94,6 +84,23 @@
   ///
   static void addCustomGraphFeatures(const DSGraph *G,
                                      GraphWriter<const DSGraph*> &GW) {
+    // Add scalar nodes to the graph...
+    const std::map<Value*, DSNodeHandle> &VM = G->getValueMap();
+    for (std::map<Value*, DSNodeHandle>::const_iterator I = VM.begin();
+         I != VM.end(); ++I)
+      if (!isa<GlobalValue>(I->first)) {
+        std::stringstream OS;
+        WriteAsOperand(OS, I->first, false, true, G->getFunction().getParent());
+        GW.emitSimpleNode(I->first, "plaintext=circle", OS.str());
+        
+        // Add edge from return node to real destination
+        int EdgeDest = I->second.getOffset();
+        if (EdgeDest == 0) EdgeDest = -1;
+        GW.emitEdge(I->first, -1, I->second.getNode(),
+                    EdgeDest, "arrowtail=tee,color=gray63");
+      }
+
+
     // Output the returned value pointer...
     if (G->getRetNode().getNode() != 0) {
       // Output the return node...





More information about the llvm-commits mailing list