forked from OSchip/llvm-project
Fix for PR3944: make mem2reg O(N) instead of O(N^2) in the number of
incoming edges for a block with many predecessors. llvm-svn: 69312
This commit is contained in:
parent
72dc8452a3
commit
929207fd1d
|
@ -890,22 +890,9 @@ NextIteration:
|
||||||
// If we are inserting any phi nodes into this BB, they will already be in the
|
// If we are inserting any phi nodes into this BB, they will already be in the
|
||||||
// block.
|
// block.
|
||||||
if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
|
if (PHINode *APN = dyn_cast<PHINode>(BB->begin())) {
|
||||||
// Pred may have multiple edges to BB. If so, we want to add N incoming
|
|
||||||
// values to each PHI we are inserting on the first time we see the edge.
|
|
||||||
// Check to see if APN already has incoming values from Pred. This also
|
|
||||||
// prevents us from modifying PHI nodes that are not currently being
|
|
||||||
// inserted.
|
|
||||||
bool HasPredEntries = false;
|
|
||||||
for (unsigned i = 0, e = APN->getNumIncomingValues(); i != e; ++i) {
|
|
||||||
if (APN->getIncomingBlock(i) == Pred) {
|
|
||||||
HasPredEntries = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have PHI nodes to update, compute the number of edges from Pred to
|
// If we have PHI nodes to update, compute the number of edges from Pred to
|
||||||
// BB.
|
// BB.
|
||||||
if (!HasPredEntries) {
|
if (PhiToAllocaMap.count(APN)) {
|
||||||
// We want to be able to distinguish between PHI nodes being inserted by
|
// We want to be able to distinguish between PHI nodes being inserted by
|
||||||
// this invocation of mem2reg from those phi nodes that already existed in
|
// this invocation of mem2reg from those phi nodes that already existed in
|
||||||
// the IR before mem2reg was run. We determine that APN is being inserted
|
// the IR before mem2reg was run. We determine that APN is being inserted
|
||||||
|
@ -983,14 +970,19 @@ NextIteration:
|
||||||
succ_iterator I = succ_begin(BB), E = succ_end(BB);
|
succ_iterator I = succ_begin(BB), E = succ_end(BB);
|
||||||
if (I == E) return;
|
if (I == E) return;
|
||||||
|
|
||||||
// Handle the last successor without using the worklist. This allows us to
|
// Keep track of the successors so we don't visit the same successor twice
|
||||||
// handle unconditional branches directly, for example.
|
SmallPtrSet<BasicBlock*, 8> VisitedSuccs;
|
||||||
--E;
|
|
||||||
for (; I != E; ++I)
|
|
||||||
Worklist.push_back(RenamePassData(*I, BB, IncomingVals));
|
|
||||||
|
|
||||||
|
// Handle the first successor without using the worklist.
|
||||||
|
VisitedSuccs.insert(*I);
|
||||||
Pred = BB;
|
Pred = BB;
|
||||||
BB = *I;
|
BB = *I;
|
||||||
|
++I;
|
||||||
|
|
||||||
|
for (; I != E; ++I)
|
||||||
|
if (VisitedSuccs.insert(*I))
|
||||||
|
Worklist.push_back(RenamePassData(*I, Pred, IncomingVals));
|
||||||
|
|
||||||
goto NextIteration;
|
goto NextIteration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue