aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure/DataStructure.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-03-04 17:06:53 +0000
committerChris Lattner <sabre@nondot.org>2004-03-04 17:06:53 +0000
commitf590ced5c54bb64f0bf1cd5b377459f731324b3c (patch)
tree7e651f019bbbac4b9f7eb58ae58a305b87fa7baa /lib/Analysis/DataStructure/DataStructure.cpp
parent16437ff7054d745205d8d7ff529d569a26d683c8 (diff)
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
Diffstat (limited to 'lib/Analysis/DataStructure/DataStructure.cpp')
-rw-r--r--lib/Analysis/DataStructure/DataStructure.cpp36
1 files changed, 25 insertions, 11 deletions
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index beb4159f42..7eb6a65e29 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<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...