Fix BU datastructures with povray!
authorChris Lattner <sabre@nondot.org>
Thu, 4 Mar 2004 17:06:53 +0000 (17:06 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 4 Mar 2004 17:06:53 +0000 (17:06 +0000)
The problem was that we were merging a field of a node with a value that was
deleted.  Thanks to bugpoint for reducing povray to a nice small 3 function
example.  :)

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

lib/Analysis/DataStructure/DataStructure.cpp

index beb4159f42a0d20dd9c340940da6521406a6f7c0..7eb6a65e2956b3784c1d9dd55a3dac733c630f73 100644 (file)
@@ -81,10 +81,11 @@ DSNode::DSNode(const Type *T, DSGraph *G)
 // DSNode copy constructor... do not copy over the referrers list!
 DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
   : NumReferrers(0), Size(N.Size), ParentGraph(G),
-    Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) {
-  if (!NullLinks)
+    Ty(N.Ty), NodeType(N.NodeType) {
+  if (!NullLinks) {
     Links = N.Links;
-  else
+    Globals = N.Globals;
+  } else
     Links.resize(N.Links.size()); // Create the appropriate number of null links
   G->addNode(this);
   ++NumNodeAllocated;
@@ -631,6 +632,8 @@ void DSNode::mergeGlobals(const std::vector<GlobalValue*> &RHS) {
 void DSNode::MergeNodes(DSNodeHandle& CurNodeH, DSNodeHandle& NH) {
   assert(CurNodeH.getOffset() >= NH.getOffset() &&
          "This should have been enforced in the caller.");
+  assert(CurNodeH.getNode()->getParentGraph()==NH.getNode()->getParentGraph() &&
+         "Cannot merge two nodes that are not in the same graph!");
 
   // Now we know that Offset >= NH.Offset, so convert it so our "Offset" (with
   // respect to NH.Offset) is now zero.  NOffset is the distance from the base
@@ -782,6 +785,9 @@ DSNodeHandle ReachabilityCloner::getClonedNH(const DSNodeHandle &SrcNH) {
   if (!NH.isNull())    // Node already mapped?
     return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
 
+  // FIXME if SrcNH has globals and the dest graph contains the same globals, we
+  // could use 'merge' to do this work more efficiently!
+
   DSNode *DN = new DSNode(*SN, &Dest, true /* Null out all links */);
   DN->maskNodeTypes(BitsToKeep);
   NH = DN;
@@ -824,6 +830,7 @@ DSNodeHandle ReachabilityCloner::getClonedNH(const DSNodeHandle &SrcNH) {
     if (CloneFlags & DSGraph::UpdateInlinedGlobals)
       Dest.getInlinedGlobals().insert(GV);
   }
+  NH.getNode()->mergeGlobals(SN->getGlobals());
 
   return DSNodeHandle(NH.getNode(), NH.getOffset()+SrcNH.getOffset());
 }
@@ -913,6 +920,7 @@ void ReachabilityCloner::merge(const DSNodeHandle &NH,
         if (CloneFlags & DSGraph::UpdateInlinedGlobals)
           Dest.getInlinedGlobals().insert(GV);
       }
+      NH.getNode()->mergeGlobals(SN->getGlobals());
     }
   } else {
     // We cannot handle this case without allocating a temporary node.  Fall
@@ -964,19 +972,25 @@ void ReachabilityCloner::merge(const DSNodeHandle &NH,
       // wrapping), but if the current node gets collapsed due to
       // recursive merging, we must make sure to merge in all remaining
       // links at offset zero.
-      unsigned MergeOffset = 0;
       DSNode *CN = SCNH.getNode();
-      if (CN->getSize() != 1)
-        MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize();
+      unsigned MergeOffset =
+        ((i << DS::PointerShift)+SCNH.getOffset()) % CN->getSize();
       
-      DSNodeHandle &Link = CN->getLink(MergeOffset);
-      if (!Link.isNull()) {
+      DSNodeHandle Tmp = CN->getLink(MergeOffset);
+      if (!Tmp.isNull()) {
         // Perform the recursive merging.  Make sure to create a temporary NH,
         // because the Link can disappear in the process of recursive merging.
-        DSNodeHandle Tmp = Link;
         merge(Tmp, SrcEdge);
       } else {
-        merge(Link, SrcEdge);
+        Tmp.mergeWith(getClonedNH(SrcEdge));
+        // Merging this could cause all kinds of recursive things to happen,
+        // culminating in the current node being eliminated.  Since this is
+        // possible, make sure to reaquire the link from 'CN'.
+
+        unsigned MergeOffset = 0;
+        CN = SCNH.getNode();
+        MergeOffset = ((i << DS::PointerShift)+SCNH.getOffset()) %CN->getSize();
+        CN->getLink(MergeOffset).mergeWith(Tmp);
       }
     }
   }
@@ -1240,7 +1254,7 @@ void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
     // Map the return node pointer over.
     if (!CS.getRetVal().isNull())
       RC.merge(CS.getRetVal(), Graph.getReturnNodeFor(F));
-    
+
     // If requested, copy all of the calls.
     if (!(CloneFlags & DontCloneCallNodes)) {
       // Copy the function calls list...