Index: include/llvm/Analysis/LoopAnalysisManager.h =================================================================== --- include/llvm/Analysis/LoopAnalysisManager.h +++ include/llvm/Analysis/LoopAnalysisManager.h @@ -35,6 +35,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/MemorySSA.h" @@ -60,6 +61,7 @@ TargetLibraryInfo &TLI; TargetTransformInfo &TTI; MemorySSA *MSSA; + BranchProbabilityInfo *BPI; }; /// Enables memory ssa as a dependency for loop passes. Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -166,7 +166,7 @@ void initializeImplicitNullChecksPass(PassRegistry&); void initializeIndVarSimplifyLegacyPassPass(PassRegistry&); void initializeIndirectBrExpandPassPass(PassRegistry&); -void initializeInductiveRangeCheckEliminationPass(PassRegistry&); +void initializeIRCELegacyPassPass(PassRegistry&); void initializeInferAddressSpacesPass(PassRegistry&); void initializeInferFunctionAttrsLegacyPassPass(PassRegistry&); void initializeInlineCostAnalysisPass(PassRegistry&); Index: include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h =================================================================== --- /dev/null +++ include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h @@ -0,0 +1,31 @@ +//===- InductiveRangeCheckElimination.h - IRCE ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides the interface for the Inductive Range Check Elimination +// loop pass. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_INDUCTIVERANGECHECKELIMINATION_H +#define LLVM_TRANSFORMS_SCALAR_INDUCTIVERANGECHECKELIMINATION_H + +#include "llvm/IR/PassManager.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" + +namespace llvm { + +class IRCEPass : public PassInfoMixin { +public: + PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, LPMUpdater &U); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_INDUCTIVERANGECHECKELIMINATION_H Index: include/llvm/Transforms/Scalar/LoopPassManager.h =================================================================== --- include/llvm/Transforms/Scalar/LoopPassManager.h +++ include/llvm/Transforms/Scalar/LoopPassManager.h @@ -42,6 +42,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/LoopInfo.h" @@ -272,6 +273,9 @@ /// \brief Runs the loop passes across every loop in the function. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) { + bool BPI_required = + AM.getCachedResult(F) != nullptr; + // Before we even compute any loop analyses, first run a miniature function // pass pipeline to put loops into their canonical form. Note that we can // directly build up function analyses after this as the function pass @@ -289,6 +293,9 @@ MemorySSA *MSSA = EnableMSSALoopDependency ? (&AM.getResult(F).getMSSA()) : nullptr; + // Get the analysis results needed by loop passes. + BranchProbabilityInfo *BPI = + BPI_required ? (&AM.getResult(F)) : nullptr; LoopStandardAnalysisResults LAR = {AM.getResult(F), AM.getResult(F), AM.getResult(F), @@ -296,7 +303,8 @@ AM.getResult(F), AM.getResult(F), AM.getResult(F), - MSSA}; + MSSA, + BPI}; // Setup the loop analysis manager from its proxy. It is important that // this is only done when there are loops to process and we have built the Index: lib/Passes/PassBuilder.cpp =================================================================== --- lib/Passes/PassBuilder.cpp +++ lib/Passes/PassBuilder.cpp @@ -103,6 +103,7 @@ #include "llvm/Transforms/Scalar/GuardWidening.h" #include "llvm/Transforms/Scalar/IVUsersPrinter.h" #include "llvm/Transforms/Scalar/IndVarSimplify.h" +#include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h" #include "llvm/Transforms/Scalar/JumpThreading.h" #include "llvm/Transforms/Scalar/LICM.h" #include "llvm/Transforms/Scalar/LoopAccessAnalysisPrinter.h" Index: lib/Passes/PassRegistry.def =================================================================== --- lib/Passes/PassRegistry.def +++ lib/Passes/PassRegistry.def @@ -238,6 +238,7 @@ LOOP_PASS("simplify-cfg", LoopSimplifyCFGPass()) LOOP_PASS("strength-reduce", LoopStrengthReducePass()) LOOP_PASS("indvars", IndVarSimplifyPass()) +LOOP_PASS("irce", IRCEPass()) LOOP_PASS("unroll-full", LoopFullUnrollPass()) LOOP_PASS("unswitch", SimpleLoopUnswitchPass()) LOOP_PASS("print-access-info", LoopAccessInfoPrinterPass(dbgs())) Index: lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp =================================================================== --- lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -42,7 +42,7 @@ // } // //===----------------------------------------------------------------------===// - +#include "llvm/Transforms/Scalar/InductiveRangeCheckElimination.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" @@ -52,6 +52,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Analysis/BranchProbabilityInfo.h" +#include "llvm/Analysis/LoopAnalysisManager.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" @@ -239,13 +240,27 @@ SmallVectorImpl &Checks); }; -class InductiveRangeCheckElimination : public LoopPass { +class InductiveRangeCheckElimination { + ScalarEvolution &SE; + BranchProbabilityInfo &BPI; + DominatorTree &DT; + LoopInfo &LI; + +public: + InductiveRangeCheckElimination(ScalarEvolution &SE, + BranchProbabilityInfo &BPI, DominatorTree &DT, + LoopInfo &LI) + : SE(SE), BPI(BPI), DT(DT), LI(LI) {} + + bool run(Loop *L, function_ref LPMAddNewLoop); +}; + +class IRCELegacyPass : public LoopPass { public: static char ID; - InductiveRangeCheckElimination() : LoopPass(ID) { - initializeInductiveRangeCheckEliminationPass( - *PassRegistry::getPassRegistry()); + IRCELegacyPass() : LoopPass(ID) { + initializeIRCELegacyPassPass(*PassRegistry::getPassRegistry()); } void getAnalysisUsage(AnalysisUsage &AU) const override { @@ -258,14 +273,14 @@ } // end anonymous namespace -char InductiveRangeCheckElimination::ID = 0; +char IRCELegacyPass::ID = 0; -INITIALIZE_PASS_BEGIN(InductiveRangeCheckElimination, "irce", +INITIALIZE_PASS_BEGIN(IRCELegacyPass, "irce", "Inductive range check elimination", false, false) INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopPass) -INITIALIZE_PASS_END(InductiveRangeCheckElimination, "irce", - "Inductive range check elimination", false, false) +INITIALIZE_PASS_END(IRCELegacyPass, "irce", "Inductive range check elimination", + false, false) StringRef InductiveRangeCheck::rangeCheckKindToStr( InductiveRangeCheck::RangeCheckKind RCK) { @@ -585,7 +600,7 @@ // Create the appropriate loop structure needed to describe a cloned copy of // `Original`. The clone is described by `VM`. Loop *createClonedLoopStructure(Loop *Original, Loop *Parent, - ValueToValueMapTy &VM); + ValueToValueMapTy &VM, bool isSubloop); // Rewrite the iteration space of the loop denoted by (LS, Preheader). The // iteration space of the rewritten loop ends at ExitLoopAt. The start of the @@ -637,8 +652,8 @@ LLVMContext &Ctx; ScalarEvolution &SE; DominatorTree &DT; - LPPassManager &LPM; LoopInfo &LI; + function_ref LPMAddNewLoop; // Information about the original loop we started out with. Loop &OriginalLoop; @@ -658,12 +673,13 @@ LoopStructure MainLoopStructure; public: - LoopConstrainer(Loop &L, LoopInfo &LI, LPPassManager &LPM, + LoopConstrainer(Loop &L, LoopInfo &LI, + function_ref LPMAddNewLoop, const LoopStructure &LS, ScalarEvolution &SE, DominatorTree &DT, InductiveRangeCheck::Range R) : F(*L.getHeader()->getParent()), Ctx(L.getHeader()->getContext()), - SE(SE), DT(DT), LPM(LPM), LI(LI), OriginalLoop(L), Range(R), - MainLoopStructure(LS) {} + SE(SE), DT(DT), LI(LI), LPMAddNewLoop(LPMAddNewLoop), OriginalLoop(L), + Range(R), MainLoopStructure(LS) {} // Entry point for the algorithm. Returns true on success. bool run(); @@ -1396,13 +1412,14 @@ } Loop *LoopConstrainer::createClonedLoopStructure(Loop *Original, Loop *Parent, - ValueToValueMapTy &VM) { + ValueToValueMapTy &VM, + bool isSubloop) { Loop &New = *LI.AllocateLoop(); if (Parent) Parent->addChildLoop(&New); else LI.addTopLevelLoop(&New); - LPM.addLoop(New); + LPMAddNewLoop(&New, isSubloop); // Add all of the blocks in Original to the new loop. for (auto *BB : Original->blocks()) @@ -1411,7 +1428,7 @@ // Add all of the subloops to the new loop. for (Loop *SubLoop : *Original) - createClonedLoopStructure(SubLoop, &New, VM); + createClonedLoopStructure(SubLoop, &New, VM, true); return &New; } @@ -1562,12 +1579,12 @@ Loop *PreL = nullptr, *PostL = nullptr; if (!PreLoop.Blocks.empty()) { PreL = createClonedLoopStructure( - &OriginalLoop, OriginalLoop.getParentLoop(), PreLoop.Map); + &OriginalLoop, OriginalLoop.getParentLoop(), PreLoop.Map, false); } if (!PostLoop.Blocks.empty()) { PostL = createClonedLoopStructure( - &OriginalLoop, OriginalLoop.getParentLoop(), PostLoop.Map); + &OriginalLoop, OriginalLoop.getParentLoop(), PostLoop.Map, false); } // This function canonicalizes the loop into Loop-Simplify and LCSSA forms. @@ -1738,12 +1755,47 @@ return Ret; } -bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { +PreservedAnalyses IRCEPass::run(Loop &L, LoopAnalysisManager &AM, + LoopStandardAnalysisResults &AR, + LPMUpdater &U) { + Function *F = L.getHeader()->getParent(); + const auto &FAM = + AM.getResult(L, AR).getManager(); + auto *BPI = FAM.getCachedResult(*F); + if (!BPI) + report_fatal_error( + "IRCEPass: BranchProbabilityAnalysis not cached at a higher level"); + + InductiveRangeCheckElimination IRCE(AR.SE, *BPI, AR.DT, AR.LI); + auto LPMAddNewLoop = [&U](Loop *NL, bool subloop) { + if (!subloop) + U.addSiblingLoops(NL); + }; + bool Changed = IRCE.run(&L, LPMAddNewLoop); + if (!Changed) + return PreservedAnalyses::all(); + + return getLoopPassPreservedAnalyses(); +} + +bool IRCELegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) { if (skipLoop(L)) return false; + ScalarEvolution &SE = getAnalysis().getSE(); + BranchProbabilityInfo &BPI = + getAnalysis().getBPI(); + auto &DT = getAnalysis().getDomTree(); + auto &LI = getAnalysis().getLoopInfo(); + InductiveRangeCheckElimination IRCE(SE, BPI, DT, LI); + auto LPMAddNewLoop = [&LPM](Loop *NL, bool) { LPM.addLoop(*NL); }; + return IRCE.run(L, LPMAddNewLoop); +} + +bool InductiveRangeCheckElimination::run( + Loop *L, function_ref LPMAddNewLoop) { if (L->getBlocks().size() >= LoopSizeCutoff) { - DEBUG(dbgs() << "irce: giving up constraining loop, too large\n";); + DEBUG(dbgs() << "irce: giving up constraining loop, too large\n"); return false; } @@ -1755,9 +1807,6 @@ LLVMContext &Context = Preheader->getContext(); SmallVector RangeChecks; - ScalarEvolution &SE = getAnalysis().getSE(); - BranchProbabilityInfo &BPI = - getAnalysis().getBPI(); for (auto BBI : L->getBlocks()) if (BranchInst *TBI = dyn_cast(BBI->getTerminator())) @@ -1823,9 +1872,8 @@ if (!SafeIterRange.hasValue()) return false; - auto &DT = getAnalysis().getDomTree(); - LoopConstrainer LC(*L, getAnalysis().getLoopInfo(), LPM, - LS, SE, DT, SafeIterRange.getValue()); + LoopConstrainer LC(*L, LI, LPMAddNewLoop, LS, SE, DT, + SafeIterRange.getValue()); bool Changed = LC.run(); if (Changed) { @@ -1855,5 +1903,5 @@ } Pass *llvm::createInductiveRangeCheckEliminationPass() { - return new InductiveRangeCheckElimination; + return new IRCELegacyPass(); } Index: lib/Transforms/Scalar/LoopDistribute.cpp =================================================================== --- lib/Transforms/Scalar/LoopDistribute.cpp +++ lib/Transforms/Scalar/LoopDistribute.cpp @@ -995,7 +995,8 @@ auto &LAM = AM.getResult(F).getManager(); std::function GetLAA = [&](Loop &L) -> const LoopAccessInfo & { - LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, TLI, TTI, nullptr}; + LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, + TLI, TTI, nullptr, nullptr}; return LAM.getResult(L, AR); }; Index: lib/Transforms/Scalar/LoopLoadElimination.cpp =================================================================== --- lib/Transforms/Scalar/LoopLoadElimination.cpp +++ lib/Transforms/Scalar/LoopLoadElimination.cpp @@ -666,8 +666,8 @@ auto &LAM = AM.getResult(F).getManager(); bool Changed = eliminateLoadsAcrossLoops( F, LI, DT, [&](Loop &L) -> const LoopAccessInfo & { - LoopStandardAnalysisResults AR = {AA, AC, DT, LI, - SE, TLI, TTI, nullptr}; + LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, + TLI, TTI, nullptr, nullptr}; return LAM.getResult(L, AR); }); Index: lib/Transforms/Scalar/Scalar.cpp =================================================================== --- lib/Transforms/Scalar/Scalar.cpp +++ lib/Transforms/Scalar/Scalar.cpp @@ -52,7 +52,7 @@ initializeGVNHoistLegacyPassPass(Registry); initializeGVNSinkLegacyPassPass(Registry); initializeFlattenCFGPassPass(Registry); - initializeInductiveRangeCheckEliminationPass(Registry); + initializeIRCELegacyPassPass(Registry); initializeIndVarSimplifyLegacyPassPass(Registry); initializeInferAddressSpacesPass(Registry); initializeJumpThreadingPass(Registry); Index: lib/Transforms/Vectorize/LoopVectorize.cpp =================================================================== --- lib/Transforms/Vectorize/LoopVectorize.cpp +++ lib/Transforms/Vectorize/LoopVectorize.cpp @@ -8672,7 +8672,8 @@ auto &LAM = AM.getResult(F).getManager(); std::function GetLAA = [&](Loop &L) -> const LoopAccessInfo & { - LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, TLI, TTI, nullptr}; + LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, + TLI, TTI, nullptr, nullptr}; return LAM.getResult(L, AR); }; bool Changed = Index: test/Transforms/IRCE/add-metadata-pre-post-loops.ll =================================================================== --- test/Transforms/IRCE/add-metadata-pre-post-loops.ll +++ test/Transforms/IRCE/add-metadata-pre-post-loops.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; test that the pre and post loops have loop metadata which disables any further ; loop optimizations. Index: test/Transforms/IRCE/bad-loop-structure.ll =================================================================== --- test/Transforms/IRCE/bad-loop-structure.ll +++ test/Transforms/IRCE/bad-loop-structure.ll @@ -1,4 +1,5 @@ ; RUN: opt -S -irce -irce-print-changed-loops=true < %s | FileCheck %s +; RUN: opt -S -passes='require,loop(irce)' -irce-print-changed-loops=true < %s | FileCheck %s ; CHECK-NOT: irce Index: test/Transforms/IRCE/bad_expander.ll =================================================================== --- test/Transforms/IRCE/bad_expander.ll +++ test/Transforms/IRCE/bad_expander.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1" target triple = "x86_64-unknown-linux-gnu" Index: test/Transforms/IRCE/bug-loop-varying-upper-limit.ll =================================================================== --- test/Transforms/IRCE/bug-loop-varying-upper-limit.ll +++ test/Transforms/IRCE/bug-loop-varying-upper-limit.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce-print-changed-loops -S -verify-loop-info -irce -verify < %s 2>&1 | FileCheck %s +; RUN: opt -irce-print-changed-loops -S -verify-loop-info -passes='require,loop(irce)' -verify < %s 2>&1 | FileCheck %s ; CHECK-NOT: constrained loop Index: test/Transforms/IRCE/bug-mismatched-types.ll =================================================================== --- test/Transforms/IRCE/bug-mismatched-types.ll +++ test/Transforms/IRCE/bug-mismatched-types.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -S < %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -S < %s ; These test cases don't check the correctness of the transform, but ; that -irce does not crash in the presence of certain things in Index: test/Transforms/IRCE/clamp.ll =================================================================== --- test/Transforms/IRCE/clamp.ll +++ test/Transforms/IRCE/clamp.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; The test demonstrates that incorrect behavior of Clamp may lead to incorrect ; calculation of post-loop exit condition. Index: test/Transforms/IRCE/conjunctive-checks.ll =================================================================== --- test/Transforms/IRCE/conjunctive-checks.ll +++ test/Transforms/IRCE/conjunctive-checks.ll @@ -1,4 +1,5 @@ ; RUN: opt -S -verify-loop-info -irce < %s | FileCheck %s +; RUN: opt -S -verify-loop-info -passes='require,loop(irce)' < %s | FileCheck %s define void @f_0(i32 *%arr, i32 *%a_len_ptr, i32 %n, i1* %cond_buf) { ; CHECK-LABEL: @f_0( Index: test/Transforms/IRCE/correct-loop-info.ll =================================================================== --- test/Transforms/IRCE/correct-loop-info.ll +++ test/Transforms/IRCE/correct-loop-info.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -irce < %s -S | FileCheck %s +; RUN: opt -passes='require,loop(irce)' < %s -S | FileCheck %s ; REQUIRES: asserts Index: test/Transforms/IRCE/decrementing-loop.ll =================================================================== --- test/Transforms/IRCE/decrementing-loop.ll +++ test/Transforms/IRCE/decrementing-loop.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -S < %s | FileCheck %s define void @decrementing_loop(i32 *%arr, i32 *%a_len_ptr, i32 %n) { entry: Index: test/Transforms/IRCE/empty_ranges.ll =================================================================== --- test/Transforms/IRCE/empty_ranges.ll +++ test/Transforms/IRCE/empty_ranges.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S ; Make sure that IRCE doesn't apply in case of empty ranges. ; (i + 30 < 40) if i in [-30, 10). Index: test/Transforms/IRCE/eq_ne.ll =================================================================== --- test/Transforms/IRCE/eq_ne.ll +++ test/Transforms/IRCE/eq_ne.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in.bounds ; CHECK: irce: in function test_01u: constrained Loop at depth 1 containing: %loop
,%in.bounds Index: test/Transforms/IRCE/low-becount.ll =================================================================== --- test/Transforms/IRCE/low-becount.ll +++ test/Transforms/IRCE/low-becount.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce-print-changed-loops -verify-loop-info -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -irce-print-changed-loops -verify-loop-info -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK-NOT: constrained Loop Index: test/Transforms/IRCE/multiple-access-no-preloop.ll =================================================================== --- test/Transforms/IRCE/multiple-access-no-preloop.ll +++ test/Transforms/IRCE/multiple-access-no-preloop.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -S < %s | FileCheck %s define void @multiple_access_no_preloop( i32* %arr_a, i32* %a_len_ptr, i32* %arr_b, i32* %b_len_ptr, i32 %n) { Index: test/Transforms/IRCE/not-likely-taken.ll =================================================================== --- test/Transforms/IRCE/not-likely-taken.ll +++ test/Transforms/IRCE/not-likely-taken.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' < %s 2>&1 | FileCheck %s ; CHECK-NOT: constrained Loop @@ -37,4 +38,4 @@ } !0 = !{i32 0, i32 2147483647} -!1 = !{!"branch_weights", i32 1, i32 1} \ No newline at end of file +!1 = !{!"branch_weights", i32 1, i32 1} Index: test/Transforms/IRCE/only-lower-check.ll =================================================================== --- test/Transforms/IRCE/only-lower-check.ll +++ test/Transforms/IRCE/only-lower-check.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce-print-range-checks -irce-print-changed-loops -verify-loop-info -irce < %s 2>&1 | FileCheck %s +; RUN: opt -irce-print-range-checks -irce-print-changed-loops -verify-loop-info -passes='require,loop(irce)' < %s 2>&1 | FileCheck %s ; CHECK: irce: loop has 1 inductive range checks: ; CHECK-NEXT: InductiveRangeCheck: Index: test/Transforms/IRCE/only-upper-check.ll =================================================================== --- test/Transforms/IRCE/only-upper-check.ll +++ test/Transforms/IRCE/only-upper-check.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -irce-print-range-checks -irce-print-changed-loops %s -S 2>&1 | FileCheck %s ; CHECK: irce: loop has 1 inductive range checks: ; CHECK-NEXT:InductiveRangeCheck: Index: test/Transforms/IRCE/pre_post_loops.ll =================================================================== --- test/Transforms/IRCE/pre_post_loops.ll +++ test/Transforms/IRCE/pre_post_loops.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in.bounds ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop
,%in.bounds Index: test/Transforms/IRCE/range_intersect_miscompile.ll =================================================================== --- test/Transforms/IRCE/range_intersect_miscompile.ll +++ test/Transforms/IRCE/range_intersect_miscompile.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK-LABEL: irce: in function test_01: constrained Loop at depth 1 containing: ; CHECK-LABEL: irce: in function test_02: constrained Loop at depth 1 containing: Index: test/Transforms/IRCE/ranges_of_different_types.ll =================================================================== --- test/Transforms/IRCE/ranges_of_different_types.ll +++ test/Transforms/IRCE/ranges_of_different_types.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; Make sure we can eliminate range check with signed latch, unsigned IRC and ; positive offset. The safe iteration space is: Index: test/Transforms/IRCE/single-access-no-preloop.ll =================================================================== --- test/Transforms/IRCE/single-access-no-preloop.ll +++ test/Transforms/IRCE/single-access-no-preloop.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -S < %s | FileCheck %s define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { entry: Index: test/Transforms/IRCE/single-access-with-preloop.ll =================================================================== --- test/Transforms/IRCE/single-access-with-preloop.ll +++ test/Transforms/IRCE/single-access-with-preloop.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce -S < %s | FileCheck %s +; RUN: opt -verify-loop-info -passes='require,loop(irce)' -S < %s | FileCheck %s define void @single_access_with_preloop(i32 *%arr, i32 *%a_len_ptr, i32 %n, i32 %offset) { entry: Index: test/Transforms/IRCE/skip-profitability-checks.ll =================================================================== --- test/Transforms/IRCE/skip-profitability-checks.ll +++ test/Transforms/IRCE/skip-profitability-checks.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce-skip-profitability-checks -S -verify-loop-info -irce < %s | FileCheck %s +; RUN: opt -irce-skip-profitability-checks -S -verify-loop-info -passes='require,loop(irce)' < %s | FileCheck %s define void @single_access_no_preloop_no_offset(i32 *%arr, i32 *%a_len_ptr, i32 %n) { ; CHECK-LABEL: @single_access_no_preloop_no_offset( Index: test/Transforms/IRCE/stride_more_than_1.ll =================================================================== --- test/Transforms/IRCE/stride_more_than_1.ll +++ test/Transforms/IRCE/stride_more_than_1.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in.bounds ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop
,%in.bounds Index: test/Transforms/IRCE/unhandled.ll =================================================================== --- test/Transforms/IRCE/unhandled.ll +++ test/Transforms/IRCE/unhandled.ll @@ -1,4 +1,5 @@ ; RUN: opt -irce-print-changed-loops -verify-loop-info -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -irce-print-changed-loops -verify-loop-info -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK-NOT: constrained Loop at depth Index: test/Transforms/IRCE/unsigned_comparisons_ugt.ll =================================================================== --- test/Transforms/IRCE/unsigned_comparisons_ugt.ll +++ test/Transforms/IRCE/unsigned_comparisons_ugt.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in.bounds ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop
,%in.bounds Index: test/Transforms/IRCE/unsigned_comparisons_ult.ll =================================================================== --- test/Transforms/IRCE/unsigned_comparisons_ult.ll +++ test/Transforms/IRCE/unsigned_comparisons_ult.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' -S < %s 2>&1 | FileCheck %s ; CHECK: irce: in function test_01: constrained Loop at depth 1 containing: %loop
,%in.bounds ; CHECK: irce: in function test_02: constrained Loop at depth 1 containing: %loop
,%in.bounds Index: test/Transforms/IRCE/with-parent-loops.ll =================================================================== --- test/Transforms/IRCE/with-parent-loops.ll +++ test/Transforms/IRCE/with-parent-loops.ll @@ -1,4 +1,5 @@ ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s +; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require,loop(irce)' < %s 2>&1 | FileCheck %s ; This test checks if we update the LoopInfo correctly in the presence ; of parents, uncles and cousins. Index: unittests/Transforms/Scalar/LoopPassManagerTest.cpp =================================================================== --- unittests/Transforms/Scalar/LoopPassManagerTest.cpp +++ unittests/Transforms/Scalar/LoopPassManagerTest.cpp @@ -10,6 +10,7 @@ #include "llvm/Transforms/Scalar/LoopPassManager.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -304,6 +305,7 @@ // those. FAM.registerPass([&] { return AAManager(); }); FAM.registerPass([&] { return AssumptionAnalysis(); }); + FAM.registerPass([&] { return BranchProbabilityAnalysis(); }); FAM.registerPass([&] { return ScalarEvolutionAnalysis(); }); FAM.registerPass([&] { return TargetLibraryAnalysis(); }); FAM.registerPass([&] { return TargetIRAnalysis(); });