From f590ced5c54bb64f0bf1cd5b377459f731324b3c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 4 Mar 2004 17:06:53 +0000 Subject: [PATCH] Fix BU datastructures with povray! 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 | 36 ++++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index beb4159f42a..7eb6a65e295 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -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 &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...