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:
parent
dbc34a2a95
commit
ab3a68a7c3
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user