-
Notifications
You must be signed in to change notification settings - Fork 12.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Analysis] Avoid running transform passes that have just been run (#1…
…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
Showing
20 changed files
with
313 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.