diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp | 120 | 
1 files changed, 85 insertions, 35 deletions
diff --git a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index 58469749600e..30e4822b6769 100644 --- a/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/llvm/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -47,6 +47,7 @@  #include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/None.h"  #include "llvm/ADT/Optional.h" +#include "llvm/ADT/PriorityWorklist.h"  #include "llvm/ADT/SmallPtrSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringRef.h" @@ -55,8 +56,8 @@  #include "llvm/Analysis/LoopAnalysisManager.h"  #include "llvm/Analysis/LoopInfo.h"  #include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/PostDominators.h"  #include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/Analysis/ScalarEvolutionExpander.h"  #include "llvm/Analysis/ScalarEvolutionExpressions.h"  #include "llvm/IR/BasicBlock.h"  #include "llvm/IR/CFG.h" @@ -87,6 +88,7 @@  #include "llvm/Transforms/Utils/Cloning.h"  #include "llvm/Transforms/Utils/LoopSimplify.h"  #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/Transforms/Utils/ScalarEvolutionExpander.h"  #include "llvm/Transforms/Utils/ValueMapper.h"  #include <algorithm>  #include <cassert> @@ -242,20 +244,25 @@ public:    bool run(Loop *L, function_ref<void(Loop *, bool)> LPMAddNewLoop);  }; -class IRCELegacyPass : public LoopPass { +class IRCELegacyPass : public FunctionPass {  public:    static char ID; -  IRCELegacyPass() : LoopPass(ID) { +  IRCELegacyPass() : FunctionPass(ID) {      initializeIRCELegacyPassPass(*PassRegistry::getPassRegistry());    }    void getAnalysisUsage(AnalysisUsage &AU) const override {      AU.addRequired<BranchProbabilityInfoWrapperPass>(); -    getLoopAnalysisUsage(AU); +    AU.addRequired<DominatorTreeWrapperPass>(); +    AU.addPreserved<DominatorTreeWrapperPass>(); +    AU.addRequired<LoopInfoWrapperPass>(); +    AU.addPreserved<LoopInfoWrapperPass>(); +    AU.addRequired<ScalarEvolutionWrapperPass>(); +    AU.addPreserved<ScalarEvolutionWrapperPass>();    } -  bool runOnLoop(Loop *L, LPPassManager &LPM) override; +  bool runOnFunction(Function &F) override;  };  } // end anonymous namespace @@ -265,7 +272,9 @@ char IRCELegacyPass::ID = 0;  INITIALIZE_PASS_BEGIN(IRCELegacyPass, "irce",                        "Inductive range check elimination", false, false)  INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopPass) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)  INITIALIZE_PASS_END(IRCELegacyPass, "irce", "Inductive range check elimination",                      false, false) @@ -866,7 +875,14 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,    const SCEV *IndVarStart = SE.getAddExpr(StartNext, Addend);    const SCEV *Step = SE.getSCEV(StepCI); -  ConstantInt *One = ConstantInt::get(IndVarTy, 1); +  const SCEV *FixedRightSCEV = nullptr; + +  // If RightValue resides within loop (but still being loop invariant), +  // regenerate it as preheader. +  if (auto *I = dyn_cast<Instruction>(RightValue)) +    if (L.contains(I->getParent())) +      FixedRightSCEV = RightSCEV; +    if (IsIncreasing) {      bool DecreasedRightValueByOne = false;      if (StepCI->isOne()) { @@ -928,10 +944,9 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,      if (LatchBrExitIdx == 0) {        // We need to increase the right value unless we have already decreased        // it virtually when we replaced EQ with SGT. -      if (!DecreasedRightValueByOne) { -        IRBuilder<> B(Preheader->getTerminator()); -        RightValue = B.CreateAdd(RightValue, One); -      } +      if (!DecreasedRightValueByOne) +        FixedRightSCEV = +            SE.getAddExpr(RightSCEV, SE.getOne(RightSCEV->getType()));      } else {        assert(!DecreasedRightValueByOne &&               "Right value can be decreased only for LatchBrExitIdx == 0!"); @@ -995,10 +1010,9 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,      if (LatchBrExitIdx == 0) {        // We need to decrease the right value unless we have already increased        // it virtually when we replaced EQ with SLT. -      if (!IncreasedRightValueByOne) { -        IRBuilder<> B(Preheader->getTerminator()); -        RightValue = B.CreateSub(RightValue, One); -      } +      if (!IncreasedRightValueByOne) +        FixedRightSCEV = +            SE.getMinusSCEV(RightSCEV, SE.getOne(RightSCEV->getType()));      } else {        assert(!IncreasedRightValueByOne &&               "Right value can be increased only for LatchBrExitIdx == 0!"); @@ -1012,9 +1026,14 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE,    assert(!L.contains(LatchExit) && "expected an exit block!");    const DataLayout &DL = Preheader->getModule()->getDataLayout(); -  Value *IndVarStartV = -      SCEVExpander(SE, DL, "irce") -          .expandCodeFor(IndVarStart, IndVarTy, Preheader->getTerminator()); +  SCEVExpander Expander(SE, DL, "irce"); +  Instruction *Ins = Preheader->getTerminator(); + +  if (FixedRightSCEV) +    RightValue = +        Expander.expandCodeFor(FixedRightSCEV, FixedRightSCEV->getType(), Ins); + +  Value *IndVarStartV = Expander.expandCodeFor(IndVarStart, IndVarTy, Ins);    IndVarStartV->setName("indvar.start");    LoopStructure Result; @@ -1747,27 +1766,41 @@ IntersectUnsignedRange(ScalarEvolution &SE,    return Ret;  } -PreservedAnalyses IRCEPass::run(Loop &L, LoopAnalysisManager &AM, -                                LoopStandardAnalysisResults &AR, -                                LPMUpdater &U) { -  Function *F = L.getHeader()->getParent(); -  const auto &FAM = -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L, AR).getManager(); -  auto *BPI = FAM.getCachedResult<BranchProbabilityAnalysis>(*F); -  InductiveRangeCheckElimination IRCE(AR.SE, BPI, AR.DT, AR.LI); -  auto LPMAddNewLoop = [&U](Loop *NL, bool IsSubloop) { +PreservedAnalyses IRCEPass::run(Function &F, FunctionAnalysisManager &AM) { +  auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F); +  auto &DT = AM.getResult<DominatorTreeAnalysis>(F); +  auto &BPI = AM.getResult<BranchProbabilityAnalysis>(F); +  LoopInfo &LI = AM.getResult<LoopAnalysis>(F); + +  InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI); + +  bool Changed = false; + +  for (const auto &L : LI) { +    Changed |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr, +                            /*PreserveLCSSA=*/false); +    Changed |= formLCSSARecursively(*L, DT, &LI, &SE); +  } + +  SmallPriorityWorklist<Loop *, 4> Worklist; +  appendLoopsToWorklist(LI, Worklist); +  auto LPMAddNewLoop = [&Worklist](Loop *NL, bool IsSubloop) {      if (!IsSubloop) -      U.addSiblingLoops(NL); +      appendLoopsToWorklist(*NL, Worklist);    }; -  bool Changed = IRCE.run(&L, LPMAddNewLoop); + +  while (!Worklist.empty()) { +    Loop *L = Worklist.pop_back_val(); +    Changed |= IRCE.run(L, LPMAddNewLoop); +  } +    if (!Changed)      return PreservedAnalyses::all(); -    return getLoopPassPreservedAnalyses();  } -bool IRCELegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) { -  if (skipLoop(L)) +bool IRCELegacyPass::runOnFunction(Function &F) { +  if (skipFunction(F))      return false;    ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE(); @@ -1776,10 +1809,27 @@ bool IRCELegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {    auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();    auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();    InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI); -  auto LPMAddNewLoop = [&LPM](Loop *NL, bool /* IsSubLoop */) { -    LPM.addLoop(*NL); + +  bool Changed = false; + +  for (const auto &L : LI) { +    Changed |= simplifyLoop(L, &DT, &LI, &SE, nullptr, nullptr, +                            /*PreserveLCSSA=*/false); +    Changed |= formLCSSARecursively(*L, DT, &LI, &SE); +  } + +  SmallPriorityWorklist<Loop *, 4> Worklist; +  appendLoopsToWorklist(LI, Worklist); +  auto LPMAddNewLoop = [&](Loop *NL, bool IsSubloop) { +    if (!IsSubloop) +      appendLoopsToWorklist(*NL, Worklist);    }; -  return IRCE.run(L, LPMAddNewLoop); + +  while (!Worklist.empty()) { +    Loop *L = Worklist.pop_back_val(); +    Changed |= IRCE.run(L, LPMAddNewLoop); +  } +  return Changed;  }  bool InductiveRangeCheckElimination::run(  | 
