4646#include " llvm/Transforms/Utils/Local.h"
4747#include " llvm/Transforms/Utils/LoopUtils.h"
4848#include < cassert>
49+ #include < map>
4950#include < utility>
5051#include < vector>
5152
@@ -428,22 +429,15 @@ static bool hasSupportedLoopDepth(ArrayRef<Loop *> LoopList,
428429}
429430
430431static bool isComputableLoopNest (ScalarEvolution *SE,
431- ArrayRef<Loop *> LoopList) {
432+ ArrayRef<Loop *> LoopList,
433+ std::map<const Loop *, const SCEV *> &LoopBTC) {
432434 for (Loop *L : LoopList) {
433435 const SCEV *ExitCountOuter = SE->getBackedgeTakenCount (L);
436+ LoopBTC[L] = ExitCountOuter;
434437 if (isa<SCEVCouldNotCompute>(ExitCountOuter)) {
435438 LLVM_DEBUG (dbgs () << " Couldn't compute backedge count\n " );
436439 return false ;
437440 }
438- // A loop with a backedge that isn't taken, e.g. an unconditional branch
439- // true, isn't really a loop and we don't want to consider it as a
440- // candidate.
441- if (ExitCountOuter && /* SkipLoopsWithZeroBTC && */ ExitCountOuter->isZero ()) {
442- LLVM_DEBUG (dbgs () << " The loop back-edge isn't taken, rejecting single "
443- " iteration loop\n " );
444- LLVM_DEBUG (L->dump ());
445- return false ;
446- }
447441 if (L->getNumBackEdges () != 1 ) {
448442 LLVM_DEBUG (dbgs () << " NumBackEdges is not equal to 1\n " );
449443 return false ;
@@ -561,7 +555,8 @@ class LoopInterchangeProfitability {
561555 // / Check if the loop interchange is profitable.
562556 bool isProfitable (const Loop *InnerLoop, const Loop *OuterLoop,
563557 unsigned InnerLoopId, unsigned OuterLoopId,
564- CharMatrix &DepMatrix, CacheCostManager &CCM);
558+ CharMatrix &DepMatrix, CacheCostManager &CCM,
559+ std::map<const Loop *, const SCEV *> &LoopBTC);
565560
566561private:
567562 int getInstrOrderCost ();
@@ -618,14 +613,17 @@ struct LoopInterchange {
618613 DependenceInfo *DI = nullptr ;
619614 DominatorTree *DT = nullptr ;
620615 LoopStandardAnalysisResults *AR = nullptr ;
621-
622616 // / Interface to emit optimization remarks.
623617 OptimizationRemarkEmitter *ORE;
618+ // A cache to avoid recalculating the backedge-taken count for a loop.
619+ std::map<const Loop *, const SCEV *> LoopBTC;
624620
625621 LoopInterchange (ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
626622 DominatorTree *DT, LoopStandardAnalysisResults *AR,
627- OptimizationRemarkEmitter *ORE)
628- : SE(SE), LI(LI), DI(DI), DT(DT), AR(AR), ORE(ORE) {}
623+ OptimizationRemarkEmitter *ORE,
624+ std::map<const Loop *, const SCEV *> &&LoopBTC)
625+ : SE(SE), LI(LI), DI(DI), DT(DT), AR(AR), ORE(ORE),
626+ LoopBTC (std::move(LoopBTC)) {}
629627
630628 bool run (Loop *L) {
631629 if (L->getParentLoop ())
@@ -717,7 +715,7 @@ struct LoopInterchange {
717715 LLVM_DEBUG (dbgs () << " Loops are legal to interchange\n " );
718716 LoopInterchangeProfitability LIP (OuterLoop, InnerLoop, SE, ORE);
719717 if (!LIP.isProfitable (InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,
720- DependencyMatrix, CCM)) {
718+ DependencyMatrix, CCM, LoopBTC )) {
721719 LLVM_DEBUG (dbgs () << " Interchanging loops not profitable.\n " );
722720 return false ;
723721 }
@@ -1477,7 +1475,30 @@ std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization(
14771475
14781476bool LoopInterchangeProfitability::isProfitable (
14791477 const Loop *InnerLoop, const Loop *OuterLoop, unsigned InnerLoopId,
1480- unsigned OuterLoopId, CharMatrix &DepMatrix, CacheCostManager &CCM) {
1478+ unsigned OuterLoopId, CharMatrix &DepMatrix, CacheCostManager &CCM,
1479+ std::map<const Loop *, const SCEV *> &LoopBTC) {
1480+
1481+ auto *InnerBTC = LoopBTC[InnerLoop];
1482+ auto *OuterBTC = LoopBTC[OuterLoop];
1483+ assert (InnerBTC && OuterBTC &&
1484+ " Loop BTC should exist in cache but not found" );
1485+ // A loop with a backedge that isn't taken, e.g. an unconditional branch
1486+ // true, isn't really a loop and we don't want to consider it as a
1487+ // candidate.
1488+ // TODO: when interchange is forced, we should probably also allow
1489+ // interchange for these loops, and thus this logic should be moved just
1490+ // below the cost-model ignore check below. But this check is done first
1491+ // to avoid the issue in #163954.
1492+ if (InnerBTC && InnerBTC->isZero ()) {
1493+ LLVM_DEBUG (dbgs () << " Inner loop back-edge isn't taken, rejecting "
1494+ " single iteration loop\n " );
1495+ return false ;
1496+ }
1497+ if (OuterBTC && OuterBTC->isZero ()) {
1498+ LLVM_DEBUG (dbgs () << " Outer loop back-edge isn't taken, rejecting "
1499+ " single iteration loop\n " );
1500+ return false ;
1501+ }
14811502
14821503 // Return true if interchange is forced and the cost-model ignored.
14831504 if (Profitabilities.size () == 1 && Profitabilities[0 ] == RuleTy::Ignore)
@@ -2114,6 +2135,7 @@ PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
21142135 LPMUpdater &U) {
21152136 Function &F = *LN.getParent ();
21162137 SmallVector<Loop *, 8 > LoopList (LN.getLoops ());
2138+ std::map<const Loop *, const SCEV *> LoopBTC;
21172139
21182140 if (MaxMemInstrCount < 1 ) {
21192141 LLVM_DEBUG (dbgs () << " MaxMemInstrCount should be at least 1" );
@@ -2125,7 +2147,7 @@ PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
21252147 if (!hasSupportedLoopDepth (LoopList, ORE))
21262148 return PreservedAnalyses::all ();
21272149 // Ensure computable loop nest.
2128- if (!isComputableLoopNest (&AR.SE , LoopList)) {
2150+ if (!isComputableLoopNest (&AR.SE , LoopList, LoopBTC )) {
21292151 LLVM_DEBUG (dbgs () << " Not valid loop candidate for interchange\n " );
21302152 return PreservedAnalyses::all ();
21312153 }
@@ -2138,7 +2160,9 @@ PreservedAnalyses LoopInterchangePass::run(LoopNest &LN,
21382160 });
21392161
21402162 DependenceInfo DI (&F, &AR.AA , &AR.SE , &AR.LI );
2141- if (!LoopInterchange (&AR.SE , &AR.LI , &DI, &AR.DT , &AR, &ORE).run (LN))
2163+ if (!LoopInterchange (&AR.SE , &AR.LI , &DI, &AR.DT , &AR, &ORE,
2164+ std::move (LoopBTC))
2165+ .run (LN))
21422166 return PreservedAnalyses::all ();
21432167 U.markLoopNestChanged (true );
21442168 return getLoopPassPreservedAnalyses ();
0 commit comments