Skip to content

Commit e51d57d

Browse files
committed
[IndVars] Split loop predication out of optimizeLoopExits [NFC]
In the process of writing D69009, I realized we have two distinct sets of invariants within this single function, and basically no shared logic. The optimize loop exit transforms (including the new one in D69009) only care about *analyzeable* exits. Loop predication, on the other hand, has to reason about *all* exits. At the moment, we have the property (due to the requirement for an exact btc) that all exits are analyzeable, but that will likely change in the future as we add widenable condition support. llvm-svn: 375138
1 parent fc69ad0 commit e51d57d

File tree

1 file changed

+42
-11
lines changed

1 file changed

+42
-11
lines changed

llvm/lib/Transforms/Scalar/IndVarSimplify.cpp

+42-11
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,11 @@ class IndVarSimplify {
149149
bool rewriteNonIntegerIVs(Loop *L);
150150

151151
bool simplifyAndExtend(Loop *L, SCEVExpander &Rewriter, LoopInfo *LI);
152+
/// Try to eliminate loop exits based on analyzeable exit counts
152153
bool optimizeLoopExits(Loop *L, SCEVExpander &Rewriter);
154+
/// Try to form loop invariant tests for loop exits by changing how many
155+
/// iterations of the loop run when that is unobservable.
156+
bool predicateLoopExits(Loop *L, SCEVExpander &Rewriter);
153157

154158
bool canLoopBeDeleted(Loop *L, SmallVector<RewritePhi, 8> &RewritePhiSet);
155159
bool rewriteLoopExitValues(Loop *L, SCEVExpander &Rewriter);
@@ -2680,32 +2684,46 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
26802684
SmallVector<BasicBlock*, 16> ExitingBlocks;
26812685
L->getExitingBlocks(ExitingBlocks);
26822686

2683-
// Get a symbolic upper bound on the loop backedge taken count.
2684-
const SCEV *MaxExitCount = getMaxBackedgeTakenCount(*SE, *DT, L);
2685-
if (isa<SCEVCouldNotCompute>(MaxExitCount))
2686-
return false;
2687-
2688-
bool Changed = false;
2689-
for (BasicBlock *ExitingBB : ExitingBlocks) {
2687+
// Remove all exits which aren't both rewriteable and analyzeable.
2688+
auto NewEnd = llvm::remove_if(ExitingBlocks,
2689+
[&](BasicBlock *ExitingBB) {
26902690
// If our exitting block exits multiple loops, we can only rewrite the
26912691
// innermost one. Otherwise, we're changing how many times the innermost
26922692
// loop runs before it exits.
26932693
if (LI->getLoopFor(ExitingBB) != L)
2694-
continue;
2694+
return true;
26952695

26962696
// Can't rewrite non-branch yet.
26972697
BranchInst *BI = dyn_cast<BranchInst>(ExitingBB->getTerminator());
26982698
if (!BI)
2699-
continue;
2699+
return true;
27002700

27012701
// If already constant, nothing to do.
27022702
if (isa<Constant>(BI->getCondition()))
2703-
continue;
2703+
return true;
27042704

27052705
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
27062706
if (isa<SCEVCouldNotCompute>(ExitCount))
2707-
continue;
2707+
return true;
2708+
return false;
2709+
});
2710+
ExitingBlocks.erase(NewEnd, ExitingBlocks.end());
2711+
2712+
if (ExitingBlocks.empty())
2713+
return false;
2714+
2715+
// Get a symbolic upper bound on the loop backedge taken count.
2716+
const SCEV *MaxExitCount = getMaxBackedgeTakenCount(*SE, *DT, L);
2717+
if (isa<SCEVCouldNotCompute>(MaxExitCount))
2718+
return false;
27082719

2720+
bool Changed = false;
2721+
for (BasicBlock *ExitingBB : ExitingBlocks) {
2722+
BranchInst *BI = cast<BranchInst>(ExitingBB->getTerminator());
2723+
2724+
const SCEV *ExitCount = SE->getExitCount(L, ExitingBB);
2725+
assert(!isa<SCEVCouldNotCompute>(ExitCount) && "checked above");
2726+
27092727
// If we know we'd exit on the first iteration, rewrite the exit to
27102728
// reflect this. This does not imply the loop must exit through this
27112729
// exit; there may be an earlier one taken on the first iteration.
@@ -2756,6 +2774,14 @@ bool IndVarSimplify::optimizeLoopExits(Loop *L, SCEVExpander &Rewriter) {
27562774
// the loop, then we can discharge all other exits. (May fall out of
27572775
// previous TODO.)
27582776
}
2777+
return Changed;
2778+
}
2779+
2780+
bool IndVarSimplify::predicateLoopExits(Loop *L, SCEVExpander &Rewriter) {
2781+
SmallVector<BasicBlock*, 16> ExitingBlocks;
2782+
L->getExitingBlocks(ExitingBlocks);
2783+
2784+
bool Changed = false;
27592785

27602786
// Finally, see if we can rewrite our exit conditions into a loop invariant
27612787
// form. If we have a read-only loop, and we can tell that we must exit down
@@ -2971,7 +2997,12 @@ bool IndVarSimplify::run(Loop *L) {
29712997
// Eliminate redundant IV cycles.
29722998
NumElimIV += Rewriter.replaceCongruentIVs(L, DT, DeadInsts);
29732999

3000+
// Try to eliminate loop exits based on analyzeable exit counts
29743001
Changed |= optimizeLoopExits(L, Rewriter);
3002+
3003+
// Try to form loop invariant tests for loop exits by changing how many
3004+
// iterations of the loop run when that is unobservable.
3005+
Changed |= predicateLoopExits(L, Rewriter);
29753006

29763007
// If we have a trip count expression, rewrite the loop's exit condition
29773008
// using it.

0 commit comments

Comments
 (0)