[LoopDeletion] NFC: Move phi node value setting into prepass

Recommit NFC patch (rL306157) where I missed incrementing the basic block iterator,
which caused loop deletion tests to hang due to infinite loop.
Had reverted it in rL306162.

rL306157 commit message:
Currently, the implementation of delete dead loops has a special case
when the loop being deleted is never executed. This special case
(updating of exit block's incoming values for phis) can be
run as a prepass for non-executable loops before performing
the actual deletion.

llvm-svn: 306254
This commit is contained in:
Anna Thomas 2017-06-25 21:13:58 +00:00
parent 4c6cd4ccb7
commit e7cb633d29
1 changed files with 14 additions and 11 deletions

View File

@ -35,16 +35,15 @@ STATISTIC(NumDeleted, "Number of loops deleted");
/// loop. The first kind (\p isLoopDead) is where only invariant values from /// loop. The first kind (\p isLoopDead) is where only invariant values from
/// within the loop are used outside of it. The second kind (\p /// within the loop are used outside of it. The second kind (\p
/// isLoopNeverExecuted) is where the loop is provably never executed. We can /// isLoopNeverExecuted) is where the loop is provably never executed. We can
/// always remove never executed loops since they will not cause any /// always remove never executed loops since they will not cause any difference
/// difference to program behaviour. /// to program behaviour.
/// ///
/// This also updates the relevant analysis information in \p DT, \p SE, and \p /// This also updates the relevant analysis information in \p DT, \p SE, and \p
/// LI. It also updates the loop PM if an updater struct is provided. /// LI. It also updates the loop PM if an updater struct is provided.
// TODO: This function will be used by loop-simplifyCFG as well. So, move this // TODO: This function will be used by loop-simplifyCFG as well. So, move this
// to LoopUtils.cpp // to LoopUtils.cpp
static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE, static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
LoopInfo &LI, bool LoopIsNeverExecuted, LoopInfo &LI, LPMUpdater *Updater = nullptr);
LPMUpdater *Updater = nullptr);
/// Determines if a loop is dead. /// Determines if a loop is dead.
/// ///
/// This assumes that we've already checked for unique exit and exiting blocks, /// This assumes that we've already checked for unique exit and exiting blocks,
@ -168,7 +167,14 @@ static bool deleteLoopIfDead(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
BasicBlock *ExitBlock = L->getUniqueExitBlock(); BasicBlock *ExitBlock = L->getUniqueExitBlock();
if (ExitBlock && isLoopNeverExecuted(L)) { if (ExitBlock && isLoopNeverExecuted(L)) {
deleteDeadLoop(L, DT, SE, LI, true /* LoopIsNeverExecuted */, Updater); // Set incoming value to undef for phi nodes in the exit block.
BasicBlock::iterator BI = ExitBlock->begin();
while (PHINode *P = dyn_cast<PHINode>(BI)) {
for (unsigned i = 0; i < P->getNumIncomingValues(); i++)
P->setIncomingValue(i, UndefValue::get(P->getType()));
BI++;
}
deleteDeadLoop(L, DT, SE, LI, Updater);
++NumDeleted; ++NumDeleted;
return true; return true;
} }
@ -196,15 +202,14 @@ static bool deleteLoopIfDead(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
if (isa<SCEVCouldNotCompute>(S)) if (isa<SCEVCouldNotCompute>(S))
return Changed; return Changed;
deleteDeadLoop(L, DT, SE, LI, false /* LoopIsNeverExecuted */, Updater); deleteDeadLoop(L, DT, SE, LI, Updater);
++NumDeleted; ++NumDeleted;
return true; return true;
} }
static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE, static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
LoopInfo &LI, bool LoopIsNeverExecuted, LoopInfo &LI, LPMUpdater *Updater) {
LPMUpdater *Updater) {
assert(L->isLCSSAForm(DT) && "Expected LCSSA!"); assert(L->isLCSSAForm(DT) && "Expected LCSSA!");
auto *Preheader = L->getLoopPreheader(); auto *Preheader = L->getLoopPreheader();
assert(Preheader && "Preheader should exist!"); assert(Preheader && "Preheader should exist!");
@ -246,8 +251,6 @@ static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
// other incoming values. Given the loop has dedicated exits, all other // other incoming values. Given the loop has dedicated exits, all other
// incoming values must be from the exiting blocks. // incoming values must be from the exiting blocks.
int PredIndex = 0; int PredIndex = 0;
if (LoopIsNeverExecuted)
P->setIncomingValue(PredIndex, UndefValue::get(P->getType()));
P->setIncomingBlock(PredIndex, Preheader); P->setIncomingBlock(PredIndex, Preheader);
// Removes all incoming values from all other exiting blocks (including // Removes all incoming values from all other exiting blocks (including
// duplicate values from an exiting block). // duplicate values from an exiting block).