Files
gps/tools/local/circt/include/llvm/Analysis/LastRunTrackingAnalysis.h
T
2026-07-12 11:01:51 +03:00

110 lines
4.2 KiB
C++

//===- 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 "llvm/Support/Compiler.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:
LLVM_ABI bool shouldSkipImpl(PassID ID, OptionPtr Ptr) const;
LLVM_ABI 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>;
LLVM_ABI 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