Skip to content

Commit cacbe71

Browse files
authored
[Analysis] Avoid running transform passes that have just been run (#112092)
This patch adds a new analysis pass to track a set of passes and their parameters to see if we can avoid running transform passes that have just been run. The current implementation only skips redundant InstCombine runs. I will add support for other passes in follow-up patches. RFC link: https://discourse.llvm.org/t/rfc-pipeline-avoid-running-transform-passes-that-have-just-been-run/82467 Compile time improvement: http://llvm-compile-time-tracker.com/compare.php?from=76007138f4ffd4e0f510d12b5e8cad529c21f24d&to=64134cf07ea7eb39c60320087c0c5afdc16c3a2b&stat=instructions%3Au
1 parent f6617d6 commit cacbe71

20 files changed

+313
-6
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//===- LastRunTrackingAnalysis.h - Avoid running redundant pass -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This is an analysis pass to track a set of passes that have been run, so that
10+
// we can avoid running a pass again if there is no change since the last run of
11+
// the pass.
12+
//
13+
// In this analysis we track a set of passes S for each function with the
14+
// following transition rules:
15+
// 1. If pass P makes changes, set S = {P}.
16+
// 2. If pass P doesn't make changes, set S = S + {P}.
17+
//
18+
// Before running a pass P which satisfies P(P(x)) == P(x), we check if P is in
19+
// S. If so, we skip this pass since we know that there will be no change.
20+
//
21+
// Notes:
22+
// 1. Some transform passes have parameters that may vary in the optimization
23+
// pipeline. We should check if parameters in current run is compatible with
24+
// that in the last run.
25+
// 2. This pass only tracks at the module/function level. Loop passes are not
26+
// supported for now.
27+
//
28+
//===----------------------------------------------------------------------===//
29+
30+
#ifndef LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
31+
#define LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
32+
33+
#include "llvm/ADT/DenseMap.h"
34+
#include "llvm/IR/PassManager.h"
35+
#include <functional>
36+
37+
namespace llvm {
38+
39+
/// This class is used to track the last run of a set of module/function passes.
40+
/// Invalidation are conservatively handled by the pass manager if a pass
41+
/// doesn't explicitly preserve the result.
42+
/// If we want to skip a pass, we should define a unique ID \p PassID to
43+
/// identify the pass, which is usually a pointer to a static member. If a pass
44+
/// has parameters, they should be stored in a struct \p OptionT with a method
45+
/// bool isCompatibleWith(const OptionT& LastOpt) const to check compatibility.
46+
class LastRunTrackingInfo {
47+
public:
48+
using PassID = const void *;
49+
using OptionPtr = const void *;
50+
// CompatibilityCheckFn is a closure that stores the parameters of last run.
51+
using CompatibilityCheckFn = std::function<bool(OptionPtr)>;
52+
53+
/// Check if we should skip a pass.
54+
/// \param ID The unique ID of the pass.
55+
/// \param Opt The parameters of the pass. If the pass has no parameters, use
56+
/// shouldSkip(PassID ID) instead.
57+
/// \return True if we should skip the pass.
58+
/// \sa shouldSkip(PassID ID)
59+
template <typename OptionT>
60+
bool shouldSkip(PassID ID, const OptionT &Opt) const {
61+
return shouldSkipImpl(ID, &Opt);
62+
}
63+
bool shouldSkip(PassID ID) const { return shouldSkipImpl(ID, nullptr); }
64+
65+
/// Update the tracking info.
66+
/// \param ID The unique ID of the pass.
67+
/// \param Changed Whether the pass makes changes.
68+
/// \param Opt The parameters of the pass. It must have the same type as the
69+
/// parameters of the last run. If the pass has no parameters, use
70+
/// update(PassID ID, bool Changed) instead.
71+
/// \sa update(PassID ID, bool Changed)
72+
template <typename OptionT>
73+
void update(PassID ID, bool Changed, const OptionT &Opt) {
74+
updateImpl(ID, Changed, [Opt](OptionPtr Ptr) {
75+
return static_cast<const OptionT *>(Ptr)->isCompatibleWith(Opt);
76+
});
77+
}
78+
void update(PassID ID, bool Changed) {
79+
updateImpl(ID, Changed, CompatibilityCheckFn{});
80+
}
81+
82+
private:
83+
bool shouldSkipImpl(PassID ID, OptionPtr Ptr) const;
84+
void updateImpl(PassID ID, bool Changed, CompatibilityCheckFn CheckFn);
85+
86+
DenseMap<PassID, CompatibilityCheckFn> TrackedPasses;
87+
};
88+
89+
/// A function/module analysis which provides an empty \c LastRunTrackingInfo.
90+
class LastRunTrackingAnalysis final
91+
: public AnalysisInfoMixin<LastRunTrackingAnalysis> {
92+
friend AnalysisInfoMixin<LastRunTrackingAnalysis>;
93+
static AnalysisKey Key;
94+
95+
public:
96+
using Result = LastRunTrackingInfo;
97+
LastRunTrackingInfo run(Function &F, FunctionAnalysisManager &) {
98+
return LastRunTrackingInfo();
99+
}
100+
LastRunTrackingInfo run(Module &M, ModuleAnalysisManager &) {
101+
return LastRunTrackingInfo();
102+
}
103+
};
104+
105+
} // namespace llvm
106+
107+
#endif // LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H

llvm/include/llvm/Transforms/InstCombine/InstCombine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class InstCombinePass : public PassInfoMixin<InstCombinePass> {
4949
private:
5050
InstructionWorklist Worklist;
5151
InstCombineOptions Options;
52+
static char ID;
5253

5354
public:
5455
explicit InstCombinePass(InstCombineOptions Opts = {});

llvm/lib/Analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ add_llvm_component_library(LLVMAnalysis
7979
InstructionPrecedenceTracking.cpp
8080
InstructionSimplify.cpp
8181
InteractiveModelRunner.cpp
82+
LastRunTrackingAnalysis.cpp
8283
LazyBranchProbabilityInfo.cpp
8384
LazyBlockFrequencyInfo.cpp
8485
LazyCallGraph.cpp
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===- LastRunTrackingAnalysis.cpp - Avoid running redundant pass -*- C++ -*-=//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This is an analysis pass to track a set of passes that have been run, so that
10+
// we can avoid running a pass again if there is no change since the last run of
11+
// the pass.
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
16+
#include "llvm/ADT/Statistic.h"
17+
#include "llvm/Support/CommandLine.h"
18+
19+
using namespace llvm;
20+
21+
#define DEBUG_TYPE "last-run-tracking"
22+
STATISTIC(NumSkippedPasses, "Number of skipped passes");
23+
STATISTIC(NumLRTQueries, "Number of LastRunTracking queries");
24+
25+
static cl::opt<bool>
26+
DisableLastRunTracking("disable-last-run-tracking", cl::Hidden,
27+
cl::desc("Disable last run tracking"),
28+
cl::init(false));
29+
30+
bool LastRunTrackingInfo::shouldSkipImpl(PassID ID, OptionPtr Ptr) const {
31+
if (DisableLastRunTracking)
32+
return false;
33+
++NumLRTQueries;
34+
auto Iter = TrackedPasses.find(ID);
35+
if (Iter == TrackedPasses.end())
36+
return false;
37+
if (!Iter->second || Iter->second(Ptr)) {
38+
++NumSkippedPasses;
39+
return true;
40+
}
41+
return false;
42+
}
43+
44+
void LastRunTrackingInfo::updateImpl(PassID ID, bool Changed,
45+
CompatibilityCheckFn CheckFn) {
46+
if (Changed)
47+
TrackedPasses.clear();
48+
TrackedPasses[ID] = std::move(CheckFn);
49+
}
50+
51+
AnalysisKey LastRunTrackingAnalysis::Key;

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Analysis/InlineAdvisor.h"
4747
#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
4848
#include "llvm/Analysis/InstCount.h"
49+
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
4950
#include "llvm/Analysis/LazyCallGraph.h"
5051
#include "llvm/Analysis/LazyValueInfo.h"
5152
#include "llvm/Analysis/Lint.h"

llvm/lib/Passes/PassRegistry.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ MODULE_ANALYSIS("dxil-metadata", DXILMetadataAnalysis())
2525
MODULE_ANALYSIS("dxil-resource", DXILResourceAnalysis())
2626
MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
2727
MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
28+
MODULE_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis())
2829
MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
2930
MODULE_ANALYSIS("module-summary", ModuleSummaryIndexAnalysis())
3031
MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
@@ -286,6 +287,7 @@ FUNCTION_ANALYSIS(
286287
MachineFunctionAnalysis(static_cast<const LLVMTargetMachine *>(TM)))
287288
FUNCTION_ANALYSIS("gc-function", GCFunctionAnalysis())
288289
FUNCTION_ANALYSIS("inliner-size-estimator", InlineSizeEstimatorAnalysis())
290+
FUNCTION_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis())
289291
FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())
290292
FUNCTION_ANALYSIS("loops", LoopAnalysis())
291293
FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "llvm/Analysis/ConstantFolding.h"
4848
#include "llvm/Analysis/GlobalsModRef.h"
4949
#include "llvm/Analysis/InstructionSimplify.h"
50+
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
5051
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
5152
#include "llvm/Analysis/MemoryBuiltins.h"
5253
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
@@ -5545,8 +5546,15 @@ void InstCombinePass::printPipeline(
55455546
OS << '>';
55465547
}
55475548

5549+
char InstCombinePass::ID = 0;
5550+
55485551
PreservedAnalyses InstCombinePass::run(Function &F,
55495552
FunctionAnalysisManager &AM) {
5553+
auto &LRT = AM.getResult<LastRunTrackingAnalysis>(F);
5554+
// No changes since last InstCombine pass, exit early.
5555+
if (LRT.shouldSkip(&ID))
5556+
return PreservedAnalyses::all();
5557+
55505558
auto &AC = AM.getResult<AssumptionAnalysis>(F);
55515559
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
55525560
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
@@ -5562,12 +5570,16 @@ PreservedAnalyses InstCombinePass::run(Function &F,
55625570
auto *BPI = AM.getCachedResult<BranchProbabilityAnalysis>(F);
55635571

55645572
if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, TTI, DT, ORE,
5565-
BFI, BPI, PSI, Options))
5573+
BFI, BPI, PSI, Options)) {
55665574
// No changes, all analyses are preserved.
5575+
LRT.update(&ID, /*Changed=*/false);
55675576
return PreservedAnalyses::all();
5577+
}
55685578

55695579
// Mark all the analyses that instcombine updates as preserved.
55705580
PreservedAnalyses PA;
5581+
LRT.update(&ID, /*Changed=*/true);
5582+
PA.preserve<LastRunTrackingAnalysis>();
55715583
PA.preserveSet<CFGAnalyses>();
55725584
return PA;
55735585
}

llvm/test/Other/new-pm-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
; CHECK-O-NEXT: Running pass: GlobalOptPass
119119
; CHECK-O-NEXT: Running pass: PromotePass
120120
; CHECK-O-NEXT: Running pass: InstCombinePass
121+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
121122
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
122123
; CHECK-O-NEXT: Running analysis: AAManager
123124
; CHECK-O-NEXT: Running analysis: BasicAA

llvm/test/Other/new-pm-lto-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
; CHECK-O23SZ-NEXT: Running pass: ConstantMergePass
6868
; CHECK-O23SZ-NEXT: Running pass: DeadArgumentEliminationPass
6969
; CHECK-O23SZ-NEXT: Running pass: InstCombinePass
70+
; CHECK-O23SZ-NEXT: Running analysis: LastRunTrackingAnalysis
7071
; CHECK-O23SZ-NEXT: Running pass: AggressiveInstCombinePass
7172
; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass
7273
; CHECK-O23SZ-NEXT: Running pass: ExpandVariadicsPass

llvm/test/Other/new-pm-thinlto-postlink-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
5555
; CHECK-O-NEXT: Running pass: PromotePass
5656
; CHECK-O-NEXT: Running pass: InstCombinePass
57+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
5758
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
5859
; CHECK-O-NEXT: Running analysis: AAManager
5960
; CHECK-O-NEXT: Running analysis: BasicAA

llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
4040
; CHECK-O-NEXT: Running pass: PromotePass
4141
; CHECK-O-NEXT: Running pass: InstCombinePass
42+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
4243
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
4344
; CHECK-O-NEXT: Running analysis: AAManager
4445
; CHECK-O-NEXT: Running analysis: BasicAA

llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
4949
; CHECK-O-NEXT: Running pass: PromotePass
5050
; CHECK-O-NEXT: Running pass: InstCombinePass
51+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
5152
; CHECK-O-NEXT: Running analysis: AAManager on foo
5253
; CHECK-O-NEXT: Running analysis: BasicAA
5354
; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA

llvm/test/Other/new-pm-thinlto-prelink-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
; CHECK-O-NEXT: Running pass: GlobalOptPass
8787
; CHECK-O-NEXT: Running pass: PromotePass
8888
; CHECK-O-NEXT: Running pass: InstCombinePass
89+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
8990
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
9091
; CHECK-O-NEXT: Running analysis: AAManager
9192
; CHECK-O-NEXT: Running analysis: BasicAA

llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
; CHECK-O-NEXT: Running pass: GlobalOptPass
5151
; CHECK-O-NEXT: Running pass: PromotePass
5252
; CHECK-O-NEXT: Running pass: InstCombinePass
53+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
5354
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
5455
; CHECK-O-NEXT: Running analysis: AAManager
5556
; CHECK-O-NEXT: Running analysis: BasicAA
@@ -122,6 +123,7 @@
122123
; CHECK-O23SZ-NEXT: Invalidating analysis: LazyValueAnalysis
123124
; CHECK-O-NEXT: Running pass: SimplifyCFGPass
124125
; CHECK-O-NEXT: Running pass: InstCombinePass
126+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
125127
; CHECK-O-NEXT: Running analysis: BlockFrequencyAnalysis on foo
126128
; CHECK-O-NEXT: Running analysis: BranchProbabilityAnalysis on foo
127129
; CHECK-O-NEXT: Running analysis: LoopAnalysis on foo

llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
; CHECK-O-NEXT: Running pass: GlobalOptPass
5454
; CHECK-O-NEXT: Running pass: PromotePass
5555
; CHECK-O-NEXT: Running pass: InstCombinePass
56+
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
5657
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis on foo
5758
; CHECK-O-NEXT: Running analysis: AAManager on foo
5859
; CHECK-O-NEXT: Running analysis: BasicAA

llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ cleanup: ; preds = %loop
3333
define i32 @main() {
3434
; CHECK-LABEL: @main(
3535
; CHECK-NEXT: entry:
36-
; CHECK-NEXT: call void @print(i32 4)
37-
; CHECK-NEXT: call void @print(i32 5), !noalias !0
38-
; CHECK-NEXT: call void @print(i32 6), !noalias !3
36+
; CHECK-NEXT: tail call void @print(i32 4)
37+
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
38+
; CHECK-NEXT: tail call void @print(i32 5), !noalias [[META0]]
39+
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
40+
; CHECK-NEXT: tail call void @print(i32 6), !noalias [[META3]]
3941
; CHECK-NEXT: ret i32 0
4042
;
4143
entry:

llvm/test/Transforms/Coroutines/coro-retcon.ll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ define i32 @main() {
4343
; CHECK-LABEL: @main(
4444
; CHECK-NEXT: entry:
4545
; CHECK-NEXT: tail call void @print(i32 4)
46-
; CHECK-NEXT: tail call void @print(i32 5), !noalias !0
47-
; CHECK-NEXT: tail call void @print(i32 6), !noalias !3
46+
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
47+
; CHECK-NEXT: tail call void @print(i32 5), !noalias [[META0]]
48+
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
49+
; CHECK-NEXT: tail call void @print(i32 6), !noalias [[META3]]
4850
; CHECK-NEXT: ret i32 0
4951
;
5052
; CORO-LABEL: @main(

llvm/unittests/Analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(ANALYSIS_TEST_SOURCES
3333
InlineCostTest.cpp
3434
IRSimilarityIdentifierTest.cpp
3535
IVDescriptorsTest.cpp
36+
LastRunTrackingAnalysisTest.cpp
3637
LazyCallGraphTest.cpp
3738
LoadsTest.cpp
3839
LoopInfoTest.cpp

0 commit comments

Comments
 (0)