summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff options
context:
space:
mode:
authorVikram S. Adve <vadve@cs.uiuc.edu>2002-12-05 17:17:26 +0000
committerVikram S. Adve <vadve@cs.uiuc.edu>2002-12-05 17:17:26 +0000
commitbfff743897a529cb203eff0dc1722a6c3befc0b8 (patch)
treea3871b42c93cc8e24c43bd4e586e6df3a5ecfba5 /llvm/lib/Analysis/DataStructure/DataStructure.cpp
parenta4a10fe88bca186ef451e7f0a0a8acc6b8e19965 (diff)
downloadbcm5719-llvm-bfff743897a529cb203eff0dc1722a6c3befc0b8.tar.gz
bcm5719-llvm-bfff743897a529cb203eff0dc1722a6c3befc0b8.zip
Cute bug fix: when moving links from N to this, some links could have
been missed if node *this got merged away due to recursive merging! Also, links were not moved correctly if a node is collapsed. llvm-svn: 4933
Diffstat (limited to 'llvm/lib/Analysis/DataStructure/DataStructure.cpp')
-rw-r--r--llvm/lib/Analysis/DataStructure/DataStructure.cpp37
1 files changed, 23 insertions, 14 deletions
diff --git a/llvm/lib/Analysis/DataStructure/DataStructure.cpp b/llvm/lib/Analysis/DataStructure/DataStructure.cpp
index d26213fc482..1c79c79605b 100644
--- a/llvm/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/llvm/lib/Analysis/DataStructure/DataStructure.cpp
@@ -470,37 +470,46 @@ void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
}
assert((NodeType & DSNode::DEAD) == 0);
- // Make all of the outgoing links of N now be outgoing links of this. This
- // can cause recursive merging!
+ // Make all of the outgoing links of N now be outgoing links of
+ // this. This can cause recursive merging! Note that such merging may
+ // cause the current node to be merged into some other node, and so go away.
+ // To make sure we can find the resulting node, we use a level of
+ // indirection through DSNodeHandle Temp. This handle will always
+ // point to the node that resulting from any potential merge.
//
+ DSNodeHandle Temp = this;
for (unsigned i = 0; i < NSize; i += DS::PointerSize) {
DSNodeHandle &Link = N->getLink(i);
if (Link.getNode()) {
- addEdgeTo((i+NOffset) % getSize(), Link);
-
- // It's possible that after adding the new edge that some recursive
- // merging just occured, causing THIS node to get merged into oblivion.
- // If that happens, we must not try to merge any more edges into it!
- //
- if (Size == 0)
- return; // Node is now dead
- if (Size == 1)
- break; // Node got collapsed
+ DSNode *TempNode = Temp.getNode(); // get current version of "this" node
+
+ // Compute the offset into the current node at which to
+ // merge this link. In the common case, this is a linear
+ // relation to the offset in the original node (with
+ // 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;
+ if (TempNode->Size != 1)
+ MergeOffset = (i+NOffset) % TempNode->getSize();
+ TempNode->addEdgeTo(MergeOffset, Link);
}
}
+ DSNode *TempNode = Temp.getNode();
+
// Now that there are no outgoing edges, all of the Links are dead.
N->Links.clear();
N->Size = 0;
N->Ty = Type::VoidTy;
// Merge the node types
- NodeType |= N->NodeType;
+ TempNode->NodeType |= N->NodeType;
N->NodeType = DEAD; // N is now a dead node.
// Merge the globals list...
if (!N->Globals.empty()) {
- MergeSortedVectors(Globals, N->Globals);
+ MergeSortedVectors(TempNode->Globals, N->Globals);
// Delete the globals from the old node...
N->Globals.clear();
OpenPOWER on IntegriCloud