* Remove the concept of a critical shadow node
authorChris Lattner <sabre@nondot.org>
Tue, 16 Apr 2002 20:39:59 +0000 (20:39 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 16 Apr 2002 20:39:59 +0000 (20:39 +0000)
* Make the function pointer argument explicit for a call nodes
* Eliminate unreachable global values
* Merge call nodes that are identical

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

lib/Analysis/DataStructure/ComputeClosure.cpp
lib/Analysis/DataStructure/DataStructure.cpp
lib/Analysis/DataStructure/EliminateNodes.cpp
lib/Analysis/DataStructure/FunctionRepBuilder.cpp
lib/Analysis/DataStructure/NodeImpl.cpp

index 30c21a332270ff5c95527c3fb574b1853947f626..67309e8c77d18e9c08d1df2321d8f5355c7893b0 100644 (file)
@@ -100,6 +100,8 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) {
   NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode);
   while (NI != CallNodes.end()) {
     CallDSNode *CN = *NI;
+    // FIXME: This should work based on the pointer val set of the first arg
+    // link (which is the function to call)
     Function *F = CN->getCall()->getCalledFunction();
 
     if (NumInlines++ == 100) {      // CUTE hack huh?
@@ -181,14 +183,14 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) {
                                   RetVals));
 
       // If the call node has arguments, process them now!
-      assert(Args.size() == CN->getNumArgs() &&
+      assert(Args.size() == CN->getNumArgs()-1 &&
              "Call node doesn't match function?");
 
       for (unsigned i = 0, e = Args.size(); i != e; ++i) {
         // Now we make all of the nodes inside of the incorporated method
         // point to the real arguments values, not to the shadow nodes for the
         // argument.
-        ResolveNodesTo(Args[i], CN->getArgValues(i));
+        ResolveNodesTo(Args[i], CN->getArgValues(i+1));
       }
 
       // Loop through the nodes, deleting alloca nodes in the inlined function.
@@ -231,4 +233,18 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) {
     // Move on to the next call node...
     NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode);
   }
+
+  // Drop references to globals...
+  CallMap.clear();
+
+  bool Changed = true;
+  while (Changed) {
+    // Eliminate shadow nodes that are not distinguishable from some other
+    // node in the graph...
+    //
+    Changed = UnlinkUndistinguishableNodes();
+
+    // Eliminate shadow nodes that are now extraneous due to linking...
+    Changed |= RemoveUnreachableNodes();
+  }
 }
index 01ef27383cefa63c2b5277451996fae280408088..248ed918bb6df0d4777f8923fff5df726537b065 100644 (file)
@@ -56,7 +56,7 @@ void DataStructure::print(std::ostream &O, Module *M) const {
     if (!(*I)->isExternal()) {
 
       string Filename = "ds." + (*I)->getName() + ".dot";
-      O << "Writing '" << Filename << "'...\n";
+      O << "Writing '" << Filename << "'...";
       ofstream F(Filename.c_str());
       if (F.good()) {
         F << "digraph DataStructures {\n"
@@ -72,9 +72,12 @@ void DataStructure::print(std::ostream &O, Module *M) const {
       } else {
         O << "  error opening file for writing!\n";
       }
-      
-      O << (*I)->getName() << " " << getDSGraph(*I).getGraphSize() << " "
-        << getClosedDSGraph(*I).getGraphSize() << "\n";
+
+      if (Time) 
+        O << " [" << getDSGraph(*I).getGraphSize() << ", "
+          << getClosedDSGraph(*I).getGraphSize() << "]\n";
+      else
+        O << "\n";
     }
 }
 
index 6b22f69617dfbe1aa4462256136b2a28e3780293..edd8285bc81d1d1f5460039280618fccf121c4ea 100644 (file)
@@ -53,23 +53,6 @@ static void DestroyFirstNodeOfPair(DSNode *N1, DSNode *N2) {
     assert(RanOnce && "Node on user set but cannot find the use!");
   }
 
-  // If we are about to eliminate a call node that returns a pointer, make the
-  // shadow node it points to not be critical anymore!
-  //
-  if (isa<CallDSNode>(N1) && N1->getNumLinks()) {
-    assert(N1->getNumLinks() == 1 && "Call node can only return one pointer!");
-    PointerValSet &PVS = N1->getLink(0);
-    
-    for (unsigned i = 0, e = PVS.size(); i != e; ++i)
-      if (ShadowDSNode *Shad = dyn_cast<ShadowDSNode>(PVS[i].Node))
-        if (Shad->isCriticalNode()) {
-          Shad->resetCriticalMark();  // Only unmark _ONE_ node..
-          break;
-        }
-
-  }
-
-
   N1->removeAllIncomingEdges();
   delete N1;
 }
@@ -80,9 +63,10 @@ static void DestroyFirstNodeOfPair(DSNode *N1, DSNode *N2) {
 //
 static bool isIndistinguishableNode(DSNode *DN) {
   if (DN->getReferrers().empty()) {       // No referrers...
-    if (isa<ShadowDSNode>(DN) || isa<AllocDSNode>(DN))
+    if (isa<ShadowDSNode>(DN) || isa<AllocDSNode>(DN)) {
+      delete DN;
       return true;  // Node is trivially dead
-    else
+    else
       return false;
   }
   
@@ -328,17 +312,30 @@ bool FunctionDSGraph::RemoveUnreachableNodes() {
       }
   }
 
-  // Loop over the global nodes, removing nodes that have no edges into them.
-  //
+  // Loop over the global nodes, removing nodes that have no edges into them or
+  // out of them.
+  // 
   for (std::vector<GlobalDSNode*>::iterator I = GlobalNodes.begin();
        I != GlobalNodes.end(); )
-    if ((*I)->getReferrers().empty()) {       // No referrers...
-      delete *I;
-      I = GlobalNodes.erase(I);                     // Remove the node...
-      Changed = true;
+    if ((*I)->getReferrers().empty()) {
+      GlobalDSNode *GDN = *I;
+      bool NoLinks = true;    // Make sure there are no outgoing links...
+      for (unsigned i = 0, e = GDN->getNumLinks(); i != e; ++i)
+        if (!GDN->getLink(i).empty()) {
+          NoLinks = false;
+          break;
+        }
+      if (NoLinks) {
+        delete GDN;
+        I = GlobalNodes.erase(I);                     // Remove the node...
+        Changed = true;
+      } else {
+        ++I;
+      }
     } else {
       ++I;
     }
+  
   return Changed;
 }
 
index 2afede5dfa0e85756bae05f2effad29ac3a85e0b..6dc2930243cf86f1b31d6ee7aff14ed08251becb 100644 (file)
@@ -69,7 +69,7 @@ void InitVisitor::visitCallInst(CallInst *CI) {
     // Create a critical shadow node to represent the memory object that the
     // return value points to...
     ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(),
-                                          Func->getParent(), true);
+                                          Func->getParent());
     Rep->ShadowNodes.push_back(Shad);
     
     // The return value of the function is a pointer to the shadow value
@@ -88,7 +88,7 @@ void InitVisitor::visitCallInst(CallInst *CI) {
   // Loop over all of the operands of the call instruction (except the first
   // one), to look for global variable references...
   //
-  for_each(CI->op_begin()+1, CI->op_end(),   // Skip first arg
+  for_each(CI->op_begin(), CI->op_end(),
            bind_obj(this, &InitVisitor::visitOperand));
 }
 
@@ -150,7 +150,7 @@ void FunctionRepBuilder::initializeWorkList(Function *Func) {
       // Add a shadow value for it to represent what it is pointing to and add
       // this to the value map...
       ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(),
-                                            Func->getParent(), true);
+                                            Func->getParent());
       ShadowNodes.push_back(Shad);
       ValueMap[Arg].add(PointerVal(Shad), Arg);
       
@@ -296,12 +296,8 @@ void FunctionRepBuilder::visitStoreInst(StoreInst *SI) {
 
 void FunctionRepBuilder::visitCallInst(CallInst *CI) {
   CallDSNode *DSN = CallMap[CI];
-   
-  unsigned PtrNum = 0, i = 0;
-  if (isa<Function>(CI->getOperand(0)))
-    ++i;          // Not an Indirect function call? Skip the function pointer...
-
-  for (unsigned e = CI->getNumOperands(); i != e; ++i)
+  unsigned PtrNum = 0;
+  for (unsigned i = 0, e = CI->getNumOperands(); i != e; ++i)
     if (isa<PointerType>(CI->getOperand(i)->getType()))
       DSN->addArgValue(PtrNum++, ValueMap[CI->getOperand(i)]);
 }
@@ -333,6 +329,22 @@ FunctionDSGraph::FunctionDSGraph(Function *F) : Func(F) {
   RetNode     = Builder.getRetNode();
   ValueMap    = Builder.getValueMap();
 
+  // Remove all entries in the value map that consist of global values pointing
+  // at things.  They can only point to their node, so there is no use keeping
+  // them.
+  //
+  for (map<Value*, PointerValSet>::iterator I = ValueMap.begin(),
+         E = ValueMap.end(); I != E;)
+    if (isa<GlobalValue>(I->first)) {
+#if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER
+      I = ValueMap.erase(I);
+#else
+      ValueMap.erase(I);            // This is really lame.
+      I = ValueMap.begin();         // GCC's stdc++ lib doesn't return an it!
+#endif
+    } else
+      ++I;
+
   bool Changed = true;
   while (Changed) {
     // Eliminate shadow nodes that are not distinguishable from some other
index 47a7dc28e65119592fd00f6dfd87a683c44ddc30..732ab6a99509139db3d85cb87500bf8c98462fe7 100644 (file)
@@ -40,8 +40,8 @@ bool GlobalDSNode::isEquivalentTo(DSNode *Node) const {
 //
 bool CallDSNode::isEquivalentTo(DSNode *Node) const {
   if (CallDSNode *C = dyn_cast<CallDSNode>(Node)) {
-    if (C->CI->getCalledFunction() != CI->getCalledFunction() ||
-        getReferrers().size() != C->getReferrers().size())
+    if (getReferrers().size() != C->getReferrers().size() ||
+        C->getType() != getType())
       return false; // Quick check...
 
     // Check that the outgoing links are identical...
@@ -70,7 +70,6 @@ bool CallDSNode::isEquivalentTo(DSNode *Node) const {
 //
 bool ShadowDSNode::isEquivalentTo(DSNode *Node) const {
   return getType() == Node->getType();
-  return !isCriticalNode();              // Must not be a critical node...
 }
 
 
@@ -237,31 +236,31 @@ GlobalDSNode::GlobalDSNode(GlobalValue *V)
 
 string GlobalDSNode::getCaption() const {
   stringstream OS;
+  if (isa<Function>(Val))
+    OS << "fn ";
+  else
+    OS << "global ";
+
   WriteTypeSymbolic(OS, getType(), Val->getParent());
-  return "global " + OS.str() + " %" + Val->getName();
+  return OS.str() + " %" + Val->getName();
 }
 
 
-ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, bool C = false)
-  : DSNode(ShadowNode, Ty) {
+ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M) : DSNode(ShadowNode, Ty) {
   Mod = M;
   ShadowParent = 0;
-  CriticalNode = C;
 }
 
 ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, ShadowDSNode *ShadParent)
   : DSNode(ShadowNode, Ty) {
   Mod = M;
   ShadowParent = ShadParent;
-  CriticalNode = false;
 }
 
 std::string ShadowDSNode::getCaption() const {
   stringstream OS;
-  if (CriticalNode) OS << "# ";
   OS << "shadow ";
   WriteTypeSymbolic(OS, getType(), Mod);
-  if (CriticalNode) OS << " #";
   return OS.str();
 }
 
@@ -281,10 +280,7 @@ void ShadowDSNode::mapNode(map<const DSNode*, DSNode*> &NodeMap,
 
 CallDSNode::CallDSNode(CallInst *ci) : DSNode(CallNode, ci->getType()), CI(ci) {
   unsigned NumPtrs = 0;
-  if (!isa<Function>(ci->getOperand(0)))
-    NumPtrs++;   // Include the method pointer...
-
-  for (unsigned i = 1, e = ci->getNumOperands(); i != e; ++i)
+  for (unsigned i = 0, e = ci->getNumOperands(); i != e; ++i)
     if (isa<PointerType>(ci->getOperand(i)->getType()))
       NumPtrs++;
   ArgLinks.resize(NumPtrs);
@@ -334,7 +330,7 @@ void FunctionDSGraph::printFunction(std::ostream &O,
   O << "\n";
   for (std::map<Value*, PointerValSet>::const_iterator I = ValueMap.begin(),
          E = ValueMap.end(); I != E; ++I) {
-    if (I->second.size()) {  // Only output nodes with edges...
+    if (I->second.size()) {             // Only output nodes with edges...
       stringstream OS;
       WriteTypeSymbolic(OS, I->first->getType(), Func->getParent());