1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

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
This commit is contained in:
Vikram S. Adve 2002-12-05 17:17:26 +00:00
parent dbc34a2a95
commit ab3a68a7c3

View File

@ -470,37 +470,46 @@ void DSNode::mergeWith(const DSNodeHandle &NH, unsigned Offset) {
} }
assert((NodeType & DSNode::DEAD) == 0); assert((NodeType & DSNode::DEAD) == 0);
// Make all of the outgoing links of N now be outgoing links of this. This // Make all of the outgoing links of N now be outgoing links of
// can cause recursive merging! // 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) { for (unsigned i = 0; i < NSize; i += DS::PointerSize) {
DSNodeHandle &Link = N->getLink(i); DSNodeHandle &Link = N->getLink(i);
if (Link.getNode()) { if (Link.getNode()) {
addEdgeTo((i+NOffset) % getSize(), Link); DSNode *TempNode = Temp.getNode(); // get current version of "this" node
// It's possible that after adding the new edge that some recursive // Compute the offset into the current node at which to
// merging just occured, causing THIS node to get merged into oblivion. // merge this link. In the common case, this is a linear
// If that happens, we must not try to merge any more edges into it! // relation to the offset in the original node (with
// // wrapping), but if the current node gets collapsed due to
if (Size == 0) // recursive merging, we must make sure to merge in all remaining
return; // Node is now dead // links at offset zero.
if (Size == 1) unsigned MergeOffset = 0;
break; // Node got collapsed 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. // Now that there are no outgoing edges, all of the Links are dead.
N->Links.clear(); N->Links.clear();
N->Size = 0; N->Size = 0;
N->Ty = Type::VoidTy; N->Ty = Type::VoidTy;
// Merge the node types // Merge the node types
NodeType |= N->NodeType; TempNode->NodeType |= N->NodeType;
N->NodeType = DEAD; // N is now a dead node. N->NodeType = DEAD; // N is now a dead node.
// Merge the globals list... // Merge the globals list...
if (!N->Globals.empty()) { if (!N->Globals.empty()) {
MergeSortedVectors(Globals, N->Globals); MergeSortedVectors(TempNode->Globals, N->Globals);
// Delete the globals from the old node... // Delete the globals from the old node...
N->Globals.clear(); N->Globals.clear();