Skip to content

Commit 452714f

Browse files
committed
[BPI] Keep BPI available in loop passes through LoopStandardAnalysisResults
This is analogous to D86156 (which preserves "lossy" BFI in loop passes). Lossy means that the analysis preserved may not be up to date with regards to new blocks that are added in loop passes, but BPI will not contain stale pointers to basic blocks that are deleted by the loop passes. This is achieved through BasicBlockCallbackVH in BPI, which calls eraseBlock that updates the data structures in BPI whenever a basic block is deleted. This patch does not have any changes in the upstream pipeline, since none of the loop passes in the pipeline use BPI currently. However, since BPI wasn't previously preserved in loop passes, the loop predication pass was invoking BPI *on the entire function* every time it ran in an LPM. This caused massive compile time in our downstream LPM invocation which contained loop predication. See updated test with an invocation of a loop-pipeline containing loop predication and -debug-pass turned ON. Reviewed-By: asbirlea, modimo Differential Revision: https://reviews.llvm.org/D110438
1 parent afb30fc commit 452714f

File tree

10 files changed

+42
-33
lines changed

10 files changed

+42
-33
lines changed

llvm/include/llvm/Analysis/LoopAnalysisManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct LoopStandardAnalysisResults {
5858
TargetLibraryInfo &TLI;
5959
TargetTransformInfo &TTI;
6060
BlockFrequencyInfo *BFI;
61+
BranchProbabilityInfo *BPI;
6162
MemorySSA *MSSA;
6263
};
6364

llvm/include/llvm/Transforms/Scalar/LoopPassManager.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,12 @@ class FunctionToLoopPassAdaptor
421421
explicit FunctionToLoopPassAdaptor(std::unique_ptr<PassConceptT> Pass,
422422
bool UseMemorySSA = false,
423423
bool UseBlockFrequencyInfo = false,
424+
bool UseBranchProbabilityInfo = false,
424425
bool LoopNestMode = false)
425426
: Pass(std::move(Pass)), LoopCanonicalizationFPM(),
426427
UseMemorySSA(UseMemorySSA),
427428
UseBlockFrequencyInfo(UseBlockFrequencyInfo),
429+
UseBranchProbabilityInfo(UseBranchProbabilityInfo),
428430
LoopNestMode(LoopNestMode) {
429431
LoopCanonicalizationFPM.addPass(LoopSimplifyPass());
430432
LoopCanonicalizationFPM.addPass(LCSSAPass());
@@ -446,6 +448,7 @@ class FunctionToLoopPassAdaptor
446448

447449
bool UseMemorySSA = false;
448450
bool UseBlockFrequencyInfo = false;
451+
bool UseBranchProbabilityInfo = false;
449452
const bool LoopNestMode;
450453
};
451454

@@ -457,13 +460,14 @@ template <typename LoopPassT>
457460
inline std::enable_if_t<is_detected<HasRunOnLoopT, LoopPassT>::value,
458461
FunctionToLoopPassAdaptor>
459462
createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA = false,
460-
bool UseBlockFrequencyInfo = false) {
463+
bool UseBlockFrequencyInfo = false,
464+
bool UseBranchProbabilityInfo = false) {
461465
using PassModelT =
462466
detail::PassModel<Loop, LoopPassT, PreservedAnalyses, LoopAnalysisManager,
463467
LoopStandardAnalysisResults &, LPMUpdater &>;
464468
return FunctionToLoopPassAdaptor(
465469
std::make_unique<PassModelT>(std::forward<LoopPassT>(Pass)), UseMemorySSA,
466-
UseBlockFrequencyInfo, false);
470+
UseBlockFrequencyInfo, UseBranchProbabilityInfo, false);
467471
}
468472

469473
/// If \p Pass is a loop-nest pass, \p Pass will first be wrapped into a
@@ -472,24 +476,26 @@ template <typename LoopNestPassT>
472476
inline std::enable_if_t<!is_detected<HasRunOnLoopT, LoopNestPassT>::value,
473477
FunctionToLoopPassAdaptor>
474478
createFunctionToLoopPassAdaptor(LoopNestPassT &&Pass, bool UseMemorySSA = false,
475-
bool UseBlockFrequencyInfo = false) {
479+
bool UseBlockFrequencyInfo = false,
480+
bool UseBranchProbabilityInfo = false) {
476481
LoopPassManager LPM;
477482
LPM.addPass(std::forward<LoopNestPassT>(Pass));
478483
using PassModelT =
479484
detail::PassModel<Loop, LoopPassManager, PreservedAnalyses,
480485
LoopAnalysisManager, LoopStandardAnalysisResults &,
481486
LPMUpdater &>;
482487
return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
483-
UseMemorySSA, UseBlockFrequencyInfo, true);
488+
UseMemorySSA, UseBlockFrequencyInfo,
489+
UseBranchProbabilityInfo, true);
484490
}
485491

486492
/// If \p Pass is an instance of \c LoopPassManager, the returned adaptor will
487493
/// be in loop-nest mode if the pass manager contains only loop-nest passes.
488494
template <>
489495
inline FunctionToLoopPassAdaptor
490-
createFunctionToLoopPassAdaptor<LoopPassManager>(LoopPassManager &&LPM,
491-
bool UseMemorySSA,
492-
bool UseBlockFrequencyInfo) {
496+
createFunctionToLoopPassAdaptor<LoopPassManager>(
497+
LoopPassManager &&LPM, bool UseMemorySSA, bool UseBlockFrequencyInfo,
498+
bool UseBranchProbabilityInfo) {
493499
// Check if LPM contains any loop pass and if it does not, returns an adaptor
494500
// in loop-nest mode.
495501
using PassModelT =
@@ -499,7 +505,7 @@ createFunctionToLoopPassAdaptor<LoopPassManager>(LoopPassManager &&LPM,
499505
bool LoopNestMode = (LPM.getNumLoopPasses() == 0);
500506
return FunctionToLoopPassAdaptor(std::make_unique<PassModelT>(std::move(LPM)),
501507
UseMemorySSA, UseBlockFrequencyInfo,
502-
LoopNestMode);
508+
UseBranchProbabilityInfo, LoopNestMode);
503509
}
504510

505511
/// Pass for printing a loop's contents as textual IR.

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,8 +1302,11 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
13021302
bool UseMemorySSA = (Name == "loop-mssa");
13031303
bool UseBFI = llvm::any_of(
13041304
InnerPipeline, [](auto Pipeline) { return Pipeline.Name == "licm"; });
1305+
bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1306+
return Pipeline.Name == "loop-predication";
1307+
});
13051308
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1306-
UseBFI));
1309+
UseBFI, UseBPI));
13071310
return Error::success();
13081311
}
13091312
if (auto Count = parseRepeatPassName(Name)) {

llvm/lib/Transforms/Scalar/LoopDistribute.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,8 +1057,8 @@ PreservedAnalyses LoopDistributePass::run(Function &F,
10571057
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
10581058
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
10591059
[&](Loop &L) -> const LoopAccessInfo & {
1060-
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
1061-
TLI, TTI, nullptr, nullptr};
1060+
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
1061+
TLI, TTI, nullptr, nullptr, nullptr};
10621062
return LAM.getResult<LoopAccessAnalysis>(L, AR);
10631063
};
10641064

llvm/lib/Transforms/Scalar/LoopLoadElimination.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,8 +721,8 @@ PreservedAnalyses LoopLoadEliminationPass::run(Function &F,
721721
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
722722
bool Changed = eliminateLoadsAcrossLoops(
723723
F, LI, DT, BFI, PSI, &SE, &AC, [&](Loop &L) -> const LoopAccessInfo & {
724-
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
725-
TLI, TTI, nullptr, nullptr};
724+
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
725+
TLI, TTI, nullptr, nullptr, nullptr};
726726
return LAM.getResult<LoopAccessAnalysis>(L, AR);
727727
});
728728

llvm/lib/Transforms/Scalar/LoopPassManager.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "llvm/Analysis/AssumptionCache.h"
1111
#include "llvm/Analysis/BasicAliasAnalysis.h"
1212
#include "llvm/Analysis/BlockFrequencyInfo.h"
13+
#include "llvm/Analysis/BranchProbabilityInfo.h"
1314
#include "llvm/Analysis/GlobalsModRef.h"
1415
#include "llvm/Analysis/MemorySSA.h"
1516
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
@@ -207,6 +208,10 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
207208
BlockFrequencyInfo *BFI = UseBlockFrequencyInfo && F.hasProfileData()
208209
? (&AM.getResult<BlockFrequencyAnalysis>(F))
209210
: nullptr;
211+
BranchProbabilityInfo *BPI =
212+
UseBranchProbabilityInfo && F.hasProfileData()
213+
? (&AM.getResult<BranchProbabilityAnalysis>(F))
214+
: nullptr;
210215
LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
211216
AM.getResult<AssumptionAnalysis>(F),
212217
AM.getResult<DominatorTreeAnalysis>(F),
@@ -215,6 +220,7 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
215220
AM.getResult<TargetLibraryAnalysis>(F),
216221
AM.getResult<TargetIRAnalysis>(F),
217222
BFI,
223+
BPI,
218224
MSSA};
219225

220226
// Setup the loop analysis manager from its proxy. It is important that
@@ -335,6 +341,8 @@ PreservedAnalyses FunctionToLoopPassAdaptor::run(Function &F,
335341
PA.preserve<ScalarEvolutionAnalysis>();
336342
if (UseBlockFrequencyInfo && F.hasProfileData())
337343
PA.preserve<BlockFrequencyAnalysis>();
344+
if (UseBranchProbabilityInfo && F.hasProfileData())
345+
PA.preserve<BranchProbabilityAnalysis>();
338346
if (UseMemorySSA)
339347
PA.preserve<MemorySSAAnalysis>();
340348
return PA;

llvm/lib/Transforms/Scalar/LoopPredication.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,10 @@ PreservedAnalyses LoopPredicationPass::run(Loop &L, LoopAnalysisManager &AM,
367367
LoopStandardAnalysisResults &AR,
368368
LPMUpdater &U) {
369369
Function *F = L.getHeader()->getParent();
370-
// For the new PM, we also can't use BranchProbabilityInfo as an analysis
371-
// pass. Function analyses need to be preserved across loop transformations
372-
// but BPI is not preserved, hence a newly built one is needed.
373-
BranchProbabilityInfo BPI(*F, AR.LI, &AR.TLI, &AR.DT, nullptr);
374370
std::unique_ptr<MemorySSAUpdater> MSSAU;
375371
if (AR.MSSA)
376372
MSSAU = std::make_unique<MemorySSAUpdater>(AR.MSSA);
377-
LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI, &BPI,
373+
LoopPredication LP(&AR.AA, &AR.DT, &AR.SE, &AR.LI, AR.BPI,
378374
MSSAU ? MSSAU.get() : nullptr);
379375
if (!LP.runOnLoop(&L))
380376
return PreservedAnalyses::all();

llvm/lib/Transforms/Utils/LoopVersioning.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ PreservedAnalyses LoopVersioningPass::run(Function &F,
357357

358358
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
359359
auto GetLAA = [&](Loop &L) -> const LoopAccessInfo & {
360-
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
361-
TLI, TTI, nullptr, nullptr};
360+
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
361+
TLI, TTI, nullptr, nullptr, nullptr};
362362
return LAM.getResult<LoopAccessAnalysis>(L, AR);
363363
};
364364

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10557,8 +10557,8 @@ PreservedAnalyses LoopVectorizePass::run(Function &F,
1055710557
auto &LAM = AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
1055810558
std::function<const LoopAccessInfo &(Loop &)> GetLAA =
1055910559
[&](Loop &L) -> const LoopAccessInfo & {
10560-
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
10561-
TLI, TTI, nullptr, nullptr};
10560+
LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE,
10561+
TLI, TTI, nullptr, nullptr, nullptr};
1056210562
return LAM.getResult<LoopAccessAnalysis>(L, AR);
1056310563
};
1056410564
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);

llvm/test/Transforms/LoopPredication/preserve-bpi.ll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
1-
; RUN: opt -mtriple=x86_64 -passes='require<scalar-evolution>,require<branch-prob>,loop-mssa(loop-predication,licm,simple-loop-unswitch<nontrivial>,loop-simplifycfg)' -debug-pass-manager -debug-only=branch-prob -S < %s 2>&1 | FileCheck %s
1+
; RUN: opt -mtriple=x86_64 -passes='loop-mssa(loop-predication,licm,simple-loop-unswitch<nontrivial>,loop-simplifycfg)' -debug-pass-manager -debug-only=branch-prob -S < %s 2>&1 | FileCheck %s
22

33
; REQUIRES: asserts
44

5+
; This test is to solely check that we do not run BPI every single time loop
6+
; predication is invoked (since BPI is preserved as part of
7+
; LoopStandardAnalysisResults).
58
declare void @llvm.experimental.guard(i1, ...)
69

7-
; CHECK: Running pass: RequireAnalysisPass<{{.*}}BranchProbabilityAnalysis
8-
; CHECK-NEXT: Running analysis: BranchProbabilityAnalysis on unsigned_loop_0_to_n_ult_check
9-
; CHECK-NEXT: Running analysis: PostDominatorTreeAnalysis on unsigned_loop_0_to_n_ult_check
10-
; CHECK-NEXT: ---- Branch Probability Info : unsigned_loop_0_to_n_ult_check ----
11-
; CHECK: Running pass: LoopSimplifyPass on unsigned_loop_0_to_n_ult_check
1210
; CHECK: Running pass: LoopPredicationPass on Loop at depth 1
13-
; CHECK-NEXT: ---- Branch Probability Info : unsigned_loop_0_to_n_ult_check ----
14-
; CHECK: Running pass: LICMPass on Loop at depth 1
11+
; CHECK-NEXT: Running pass: LICMPass on Loop at depth 1
1512
; CHECK-NEXT: Running pass: SimpleLoopUnswitchPass on Loop at depth 1
1613
; CHECK-NEXT: Running pass: LoopPredicationPass on Loop at depth 1
17-
; CHECK-NEXT: ---- Branch Probability Info : unsigned_loop_0_to_n_ult_check ----
18-
; CHECK: Running pass: LICMPass on Loop at depth 1
14+
; CHECK-NEXT: Running pass: LICMPass on Loop at depth 1
1915
; CHECK-NEXT: Running pass: SimpleLoopUnswitchPass on Loop at depth 1
2016
; CHECK-NEXT: Running pass: LoopSimplifyCFGPass on Loop at depth 1
21-
; CHECK-NEXT: Invalidating analysis: BranchProbabilityAnalysis on unsigned_loop_0_to_n_ult_check
2217

2318

2419
define i32 @unsigned_loop_0_to_n_ult_check(i32* %array, i32 %length, i32 %n) {

0 commit comments

Comments
 (0)