diff options
author | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-12-05 17:17:26 +0000 |
---|---|---|
committer | Vikram S. Adve <vadve@cs.uiuc.edu> | 2002-12-05 17:17:26 +0000 |
commit | c102cb7359dae81390c851783d07cc6d5d1ee136 (patch) | |
tree | 5558e222204cc5091306c129c1b19dd309e7696b /lib/Analysis/DataStructure/DataStructure.cpp | |
parent | 86764d778e833a314dcca5b9694ba42fa2476d66 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4933 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/DataStructure/DataStructure.cpp')
-rw-r--r-- | lib/Analysis/DataStructure/DataStructure.cpp | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index d26213fc48..1c79c79605 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/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(); |