Skip to content

Commit

Permalink
[Analysis] Avoid running transform passes that have just been run (#1…
Browse files Browse the repository at this point in the history
…12092)

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
  • Loading branch information
dtcxzyw authored Nov 6, 2024
1 parent f6617d6 commit cacbe71
Show file tree
Hide file tree
Showing 20 changed files with 313 additions and 6 deletions.
107 changes: 107 additions & 0 deletions llvm/include/llvm/Analysis/LastRunTrackingAnalysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//===- LastRunTrackingAnalysis.h - Avoid running redundant pass -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is an analysis pass to track a set of passes that have been run, so that
// we can avoid running a pass again if there is no change since the last run of
// the pass.
//
// In this analysis we track a set of passes S for each function with the
// following transition rules:
// 1. If pass P makes changes, set S = {P}.
// 2. If pass P doesn't make changes, set S = S + {P}.
//
// Before running a pass P which satisfies P(P(x)) == P(x), we check if P is in
// S. If so, we skip this pass since we know that there will be no change.
//
// Notes:
// 1. Some transform passes have parameters that may vary in the optimization
// pipeline. We should check if parameters in current run is compatible with
// that in the last run.
// 2. This pass only tracks at the module/function level. Loop passes are not
// supported for now.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
#define LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/PassManager.h"
#include <functional>

namespace llvm {

/// This class is used to track the last run of a set of module/function passes.
/// Invalidation are conservatively handled by the pass manager if a pass
/// doesn't explicitly preserve the result.
/// If we want to skip a pass, we should define a unique ID \p PassID to
/// identify the pass, which is usually a pointer to a static member. If a pass
/// has parameters, they should be stored in a struct \p OptionT with a method
/// bool isCompatibleWith(const OptionT& LastOpt) const to check compatibility.
class LastRunTrackingInfo {
public:
using PassID = const void *;
using OptionPtr = const void *;
// CompatibilityCheckFn is a closure that stores the parameters of last run.
using CompatibilityCheckFn = std::function<bool(OptionPtr)>;

/// Check if we should skip a pass.
/// \param ID The unique ID of the pass.
/// \param Opt The parameters of the pass. If the pass has no parameters, use
/// shouldSkip(PassID ID) instead.
/// \return True if we should skip the pass.
/// \sa shouldSkip(PassID ID)
template <typename OptionT>
bool shouldSkip(PassID ID, const OptionT &Opt) const {
return shouldSkipImpl(ID, &Opt);
}
bool shouldSkip(PassID ID) const { return shouldSkipImpl(ID, nullptr); }

/// Update the tracking info.
/// \param ID The unique ID of the pass.
/// \param Changed Whether the pass makes changes.
/// \param Opt The parameters of the pass. It must have the same type as the
/// parameters of the last run. If the pass has no parameters, use
/// update(PassID ID, bool Changed) instead.
/// \sa update(PassID ID, bool Changed)
template <typename OptionT>
void update(PassID ID, bool Changed, const OptionT &Opt) {
updateImpl(ID, Changed, [Opt](OptionPtr Ptr) {
return static_cast<const OptionT *>(Ptr)->isCompatibleWith(Opt);
});
}
void update(PassID ID, bool Changed) {
updateImpl(ID, Changed, CompatibilityCheckFn{});
}

private:
bool shouldSkipImpl(PassID ID, OptionPtr Ptr) const;
void updateImpl(PassID ID, bool Changed, CompatibilityCheckFn CheckFn);

DenseMap<PassID, CompatibilityCheckFn> TrackedPasses;
};

/// A function/module analysis which provides an empty \c LastRunTrackingInfo.
class LastRunTrackingAnalysis final
: public AnalysisInfoMixin<LastRunTrackingAnalysis> {
friend AnalysisInfoMixin<LastRunTrackingAnalysis>;
static AnalysisKey Key;

public:
using Result = LastRunTrackingInfo;
LastRunTrackingInfo run(Function &F, FunctionAnalysisManager &) {
return LastRunTrackingInfo();
}
LastRunTrackingInfo run(Module &M, ModuleAnalysisManager &) {
return LastRunTrackingInfo();
}
};

} // namespace llvm

#endif // LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
1 change: 1 addition & 0 deletions llvm/include/llvm/Transforms/InstCombine/InstCombine.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class InstCombinePass : public PassInfoMixin<InstCombinePass> {
private:
InstructionWorklist Worklist;
InstCombineOptions Options;
static char ID;

public:
explicit InstCombinePass(InstCombineOptions Opts = {});
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ add_llvm_component_library(LLVMAnalysis
InstructionPrecedenceTracking.cpp
InstructionSimplify.cpp
InteractiveModelRunner.cpp
LastRunTrackingAnalysis.cpp
LazyBranchProbabilityInfo.cpp
LazyBlockFrequencyInfo.cpp
LazyCallGraph.cpp
Expand Down
51 changes: 51 additions & 0 deletions llvm/lib/Analysis/LastRunTrackingAnalysis.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//===- LastRunTrackingAnalysis.cpp - Avoid running redundant pass -*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This is an analysis pass to track a set of passes that have been run, so that
// we can avoid running a pass again if there is no change since the last run of
// the pass.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/LastRunTrackingAnalysis.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;

#define DEBUG_TYPE "last-run-tracking"
STATISTIC(NumSkippedPasses, "Number of skipped passes");
STATISTIC(NumLRTQueries, "Number of LastRunTracking queries");

static cl::opt<bool>
DisableLastRunTracking("disable-last-run-tracking", cl::Hidden,
cl::desc("Disable last run tracking"),
cl::init(false));

bool LastRunTrackingInfo::shouldSkipImpl(PassID ID, OptionPtr Ptr) const {
if (DisableLastRunTracking)
return false;
++NumLRTQueries;
auto Iter = TrackedPasses.find(ID);
if (Iter == TrackedPasses.end())
return false;
if (!Iter->second || Iter->second(Ptr)) {
++NumSkippedPasses;
return true;
}
return false;
}

void LastRunTrackingInfo::updateImpl(PassID ID, bool Changed,
CompatibilityCheckFn CheckFn) {
if (Changed)
TrackedPasses.clear();
TrackedPasses[ID] = std::move(CheckFn);
}

AnalysisKey LastRunTrackingAnalysis::Key;
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineSizeEstimatorAnalysis.h"
#include "llvm/Analysis/InstCount.h"
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/Lint.h"
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ MODULE_ANALYSIS("dxil-metadata", DXILMetadataAnalysis())
MODULE_ANALYSIS("dxil-resource", DXILResourceAnalysis())
MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
MODULE_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis())
MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
MODULE_ANALYSIS("module-summary", ModuleSummaryIndexAnalysis())
MODULE_ANALYSIS("no-op-module", NoOpModuleAnalysis())
Expand Down Expand Up @@ -286,6 +287,7 @@ FUNCTION_ANALYSIS(
MachineFunctionAnalysis(static_cast<const LLVMTargetMachine *>(TM)))
FUNCTION_ANALYSIS("gc-function", GCFunctionAnalysis())
FUNCTION_ANALYSIS("inliner-size-estimator", InlineSizeEstimatorAnalysis())
FUNCTION_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis())
FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())
FUNCTION_ANALYSIS("loops", LoopAnalysis())
FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())
Expand Down
14 changes: 13 additions & 1 deletion llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/InstructionSimplify.h"
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/MemoryBuiltins.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
Expand Down Expand Up @@ -5545,8 +5546,15 @@ void InstCombinePass::printPipeline(
OS << '>';
}

char InstCombinePass::ID = 0;

PreservedAnalyses InstCombinePass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &LRT = AM.getResult<LastRunTrackingAnalysis>(F);
// No changes since last InstCombine pass, exit early.
if (LRT.shouldSkip(&ID))
return PreservedAnalyses::all();

auto &AC = AM.getResult<AssumptionAnalysis>(F);
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
Expand All @@ -5562,12 +5570,16 @@ PreservedAnalyses InstCombinePass::run(Function &F,
auto *BPI = AM.getCachedResult<BranchProbabilityAnalysis>(F);

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

// Mark all the analyses that instcombine updates as preserved.
PreservedAnalyses PA;
LRT.update(&ID, /*Changed=*/true);
PA.preserve<LastRunTrackingAnalysis>();
PA.preserveSet<CFGAnalyses>();
return PA;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
; CHECK-O-NEXT: Running analysis: AAManager
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-lto-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
; CHECK-O23SZ-NEXT: Running pass: ConstantMergePass
; CHECK-O23SZ-NEXT: Running pass: DeadArgumentEliminationPass
; CHECK-O23SZ-NEXT: Running pass: InstCombinePass
; CHECK-O23SZ-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O23SZ-NEXT: Running pass: AggressiveInstCombinePass
; CHECK-EP-Peephole-NEXT: Running pass: NoOpFunctionPass
; CHECK-O23SZ-NEXT: Running pass: ExpandVariadicsPass
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running analysis: AAManager
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running analysis: AAManager
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: AAManager on foo
; CHECK-O-NEXT: Running analysis: BasicAA
; CHECK-O-NEXT: Running analysis: ScopedNoAliasAA
Expand Down
1 change: 1 addition & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
; CHECK-O-NEXT: Running analysis: AAManager
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
; CHECK-O-NEXT: Running analysis: AAManager
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down Expand Up @@ -122,6 +123,7 @@
; CHECK-O23SZ-NEXT: Invalidating analysis: LazyValueAnalysis
; CHECK-O-NEXT: Running pass: SimplifyCFGPass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: BlockFrequencyAnalysis on foo
; CHECK-O-NEXT: Running analysis: BranchProbabilityAnalysis on foo
; CHECK-O-NEXT: Running analysis: LoopAnalysis on foo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
; CHECK-O-NEXT: Running pass: GlobalOptPass
; CHECK-O-NEXT: Running pass: PromotePass
; CHECK-O-NEXT: Running pass: InstCombinePass
; CHECK-O-NEXT: Running analysis: LastRunTrackingAnalysis
; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis on foo
; CHECK-O-NEXT: Running analysis: AAManager on foo
; CHECK-O-NEXT: Running analysis: BasicAA
Expand Down
8 changes: 5 additions & 3 deletions llvm/test/Transforms/Coroutines/coro-retcon-opaque-ptr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ cleanup: ; preds = %loop
define i32 @main() {
; CHECK-LABEL: @main(
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @print(i32 4)
; CHECK-NEXT: call void @print(i32 5), !noalias !0
; CHECK-NEXT: call void @print(i32 6), !noalias !3
; CHECK-NEXT: tail call void @print(i32 4)
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
; CHECK-NEXT: tail call void @print(i32 5), !noalias [[META0]]
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
; CHECK-NEXT: tail call void @print(i32 6), !noalias [[META3]]
; CHECK-NEXT: ret i32 0
;
entry:
Expand Down
6 changes: 4 additions & 2 deletions llvm/test/Transforms/Coroutines/coro-retcon.ll
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ define i32 @main() {
; CHECK-LABEL: @main(
; CHECK-NEXT: entry:
; CHECK-NEXT: tail call void @print(i32 4)
; CHECK-NEXT: tail call void @print(i32 5), !noalias !0
; CHECK-NEXT: tail call void @print(i32 6), !noalias !3
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META0:![0-9]+]])
; CHECK-NEXT: tail call void @print(i32 5), !noalias [[META0]]
; CHECK-NEXT: tail call void @llvm.experimental.noalias.scope.decl(metadata [[META3:![0-9]+]])
; CHECK-NEXT: tail call void @print(i32 6), !noalias [[META3]]
; CHECK-NEXT: ret i32 0
;
; CORO-LABEL: @main(
Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ set(ANALYSIS_TEST_SOURCES
InlineCostTest.cpp
IRSimilarityIdentifierTest.cpp
IVDescriptorsTest.cpp
LastRunTrackingAnalysisTest.cpp
LazyCallGraphTest.cpp
LoadsTest.cpp
LoopInfoTest.cpp
Expand Down
Loading

0 comments on commit cacbe71

Please sign in to comment.