aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp164
1 files changed, 99 insertions, 65 deletions
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index 45d3d4e..e3e4cb7 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -80,63 +80,93 @@ static void AddPredecessorToBlock(BasicBlock *Succ, BasicBlock *NewPred,
static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
assert(*succ_begin(BB) == Succ && "Succ is not successor of BB!");
- // Check to see if one of the predecessors of BB is already a predecessor of
- // Succ. If so, we cannot do the transformation if there are any PHI nodes
- // with incompatible values coming in from the two edges!
- //
- if (isa<PHINode>(Succ->front())) {
- SmallPtrSet<BasicBlock*, 16> BBPreds(pred_begin(BB), pred_end(BB));
- for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
- PI != PE; ++PI)
- if (BBPreds.count(*PI)) {
- // Loop over all of the PHI nodes checking to see if there are
- // incompatible values coming in.
- for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- // Loop up the entries in the PHI node for BB and for *PI if the
- // values coming in are non-equal, we cannot merge these two blocks
- // (instead we should insert a conditional move or something, then
- // merge the blocks).
- if (PN->getIncomingValueForBlock(BB) !=
- PN->getIncomingValueForBlock(*PI))
- return false; // Values are not equal...
+ DOUT << "Looking to fold " << BB->getNameStart() << " into "
+ << Succ->getNameStart() << "\n";
+ // Shortcut, if there is only a single predecessor is must be BB and merging
+ // is always safe
+ if (Succ->getSinglePredecessor()) return true;
+
+ typedef SmallPtrSet<Instruction*, 16> InstrSet;
+ InstrSet BBPHIs;
+
+ // Make a list of all phi nodes in BB
+ BasicBlock::iterator BBI = BB->begin();
+ while (isa<PHINode>(*BBI)) BBPHIs.insert(BBI++);
+
+ // Make a list of the predecessors of BB
+ typedef SmallPtrSet<BasicBlock*, 16> BlockSet;
+ BlockSet BBPreds(pred_begin(BB), pred_end(BB));
+
+ // Use that list to make another list of common predecessors of BB and Succ
+ BlockSet CommonPreds;
+ for (pred_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
+ PI != PE; ++PI)
+ if (BBPreds.count(*PI))
+ CommonPreds.insert(*PI);
+
+ // Shortcut, if there are no common predecessors, merging is always safe
+ if (CommonPreds.begin() == CommonPreds.end())
+ return true;
+
+ // Look at all the phi nodes in Succ, to see if they present a conflict when
+ // merging these blocks
+ for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PN = cast<PHINode>(I);
+
+ // If the incoming value from BB is again a PHINode in
+ // BB which has the same incoming value for *PI as PN does, we can
+ // merge the phi nodes and then the blocks can still be merged
+ PHINode *BBPN = dyn_cast<PHINode>(PN->getIncomingValueForBlock(BB));
+ if (BBPN && BBPN->getParent() == BB) {
+ for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end();
+ PI != PE; PI++) {
+ if (BBPN->getIncomingValueForBlock(*PI)
+ != PN->getIncomingValueForBlock(*PI)) {
+ DOUT << "Can't fold, phi node " << *PN->getNameStart() << " in "
+ << Succ->getNameStart() << " is conflicting with "
+ << BBPN->getNameStart() << " with regard to common predecessor "
+ << (*PI)->getNameStart() << "\n";
+ return false;
+ }
+ }
+ // Remove this phinode from the list of phis in BB, since it has been
+ // handled.
+ BBPHIs.erase(BBPN);
+ } else {
+ Value* Val = PN->getIncomingValueForBlock(BB);
+ for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end();
+ PI != PE; PI++) {
+ // See if the incoming value for the common predecessor is equal to the
+ // one for BB, in which case this phi node will not prevent the merging
+ // of the block.
+ if (Val != PN->getIncomingValueForBlock(*PI)) {
+ DOUT << "Can't fold, phi node " << *PN->getNameStart() << " in "
+ << Succ->getNameStart() << " is conflicting with regard to common "
+ << "predecessor " << (*PI)->getNameStart() << "\n";
+ return false;
}
}
- }
-
- // Finally, if BB has PHI nodes that are used by things other than the PHIs in
- // Succ and Succ has predecessors that are not Succ and not Pred, we cannot
- // fold these blocks, as we don't know whether BB dominates Succ or not to
- // update the PHI nodes correctly.
- if (!isa<PHINode>(BB->begin()) || Succ->getSinglePredecessor()) return true;
-
- // If the predecessors of Succ are only BB, handle it.
- bool IsSafe = true;
- for (pred_iterator PI = pred_begin(Succ), E = pred_end(Succ); PI != E; ++PI)
- if (*PI != BB) {
- IsSafe = false;
- break;
}
- if (IsSafe) return true;
-
- // If the PHI nodes in BB are only used by instructions in Succ, we are ok if
- // BB and Succ have no common predecessors.
- for (BasicBlock::iterator I = BB->begin(); isa<PHINode>(I); ++I) {
- PHINode *PN = cast<PHINode>(I);
- for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); UI != E;
- ++UI)
- if (cast<Instruction>(*UI)->getParent() != Succ)
+ }
+
+ // If there are any other phi nodes in BB that don't have a phi node in Succ
+ // to merge with, they must be moved to Succ completely. However, for any
+ // predecessors of Succ, branches will be added to the phi node that just
+ // point to itself. So, for any common predecessors, this must not cause
+ // conflicts.
+ for (InstrSet::iterator I = BBPHIs.begin(), E = BBPHIs.end();
+ I != E; I++) {
+ PHINode *PN = cast<PHINode>(*I);
+ for (BlockSet::iterator PI = CommonPreds.begin(), PE = CommonPreds.end();
+ PI != PE; PI++)
+ if (PN->getIncomingValueForBlock(*PI) != PN) {
+ DOUT << "Can't fold, phi node " << *PN->getNameStart() << " in "
+ << BB->getNameStart() << " is conflicting with regard to common "
+ << "predecessor " << (*PI)->getNameStart() << "\n";
return false;
+ }
}
-
- // Scan the predecessor sets of BB and Succ, making sure there are no common
- // predecessors. Common predecessors would cause us to build a phi node with
- // differing incoming values, which is not legal.
- SmallPtrSet<BasicBlock*, 16> BBPreds(pred_begin(BB), pred_end(BB));
- for (pred_iterator PI = pred_begin(Succ), E = pred_end(Succ); PI != E; ++PI)
- if (BBPreds.count(*PI))
- return false;
-
+
return true;
}
@@ -145,11 +175,8 @@ static bool CanPropagatePredecessorsForPHIs(BasicBlock *BB, BasicBlock *Succ) {
/// branch. If possible, eliminate BB.
static bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
BasicBlock *Succ) {
- // If our successor has PHI nodes, then we need to update them to include
- // entries for BB's predecessors, not for BB itself. Be careful though,
- // if this transformation fails (returns true) then we cannot do this
- // transformation!
- //
+ // Check to see if merging these blocks would cause conflicts for any of the
+ // phi nodes in BB or Succ. If not, we can safely merge.
if (!CanPropagatePredecessorsForPHIs(BB, Succ)) return false;
DOUT << "Killing Trivial BB: \n" << *BB;
@@ -171,6 +198,11 @@ static bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
if (isa<PHINode>(OldVal) && cast<PHINode>(OldVal)->getParent() == BB) {
PHINode *OldValPN = cast<PHINode>(OldVal);
for (unsigned i = 0, e = OldValPN->getNumIncomingValues(); i != e; ++i)
+ // Note that, since we are merging phi nodes and BB and Succ might
+ // have common predecessors, we could end up with a phi node with
+ // identical incoming branches. This will be cleaned up later (and
+ // will trigger asserts if we try to clean it up now, without also
+ // simplifying the corresponding conditional branch).
PN->addIncoming(OldValPN->getIncomingValue(i),
OldValPN->getIncomingBlock(i));
} else {
@@ -193,19 +225,21 @@ static bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
// users of the PHI nodes.
PN->eraseFromParent();
} else {
- // The instruction is alive, so this means that Succ must have
- // *ONLY* had BB as a predecessor, and the PHI node is still valid
- // now. Simply move it into Succ, because we know that BB
- // strictly dominated Succ.
+ // The instruction is alive, so this means that BB must dominate all
+ // predecessors of Succ (Since all uses of the PN are after its
+ // definition, so in Succ or a block dominated by Succ. If a predecessor
+ // of Succ would not be dominated by BB, PN would violate the def before
+ // use SSA demand). Therefore, we can simply move the phi node to the
+ // next block.
Succ->getInstList().splice(Succ->begin(),
BB->getInstList(), BB->begin());
// We need to add new entries for the PHI node to account for
// predecessors of Succ that the PHI node does not take into
- // account. At this point, since we know that BB dominated succ,
- // this means that we should any newly added incoming edges should
- // use the PHI node as the value for these edges, because they are
- // loop back edges.
+ // account. At this point, since we know that BB dominated succ and all
+ // of its predecessors, this means that we should any newly added
+ // incoming edges should use the PHI node itself as the value for these
+ // edges, because they are loop back edges.
for (unsigned i = 0, e = OldSuccPreds.size(); i != e; ++i)
if (OldSuccPreds[i] != BB)
PN->addIncoming(PN, OldSuccPreds[i]);