Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:13

0001 //===- LastRunTrackingAnalysis.h - Avoid running redundant pass -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This is an analysis pass to track a set of passes that have been run, so that
0010 // we can avoid running a pass again if there is no change since the last run of
0011 // the pass.
0012 //
0013 // In this analysis we track a set of passes S for each function with the
0014 // following transition rules:
0015 //   1. If pass P makes changes, set S = {P}.
0016 //   2. If pass P doesn't make changes, set S = S + {P}.
0017 //
0018 // Before running a pass P which satisfies P(P(x)) == P(x), we check if P is in
0019 // S. If so, we skip this pass since we know that there will be no change.
0020 //
0021 // Notes:
0022 //   1. Some transform passes have parameters that may vary in the optimization
0023 //   pipeline. We should check if parameters in current run is compatible with
0024 //   that in the last run.
0025 //   2. This pass only tracks at the module/function level. Loop passes are not
0026 //   supported for now.
0027 //
0028 //===----------------------------------------------------------------------===//
0029 
0030 #ifndef LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
0031 #define LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H
0032 
0033 #include "llvm/ADT/DenseMap.h"
0034 #include "llvm/IR/PassManager.h"
0035 #include <functional>
0036 
0037 namespace llvm {
0038 
0039 /// This class is used to track the last run of a set of module/function passes.
0040 /// Invalidation are conservatively handled by the pass manager if a pass
0041 /// doesn't explicitly preserve the result.
0042 /// If we want to skip a pass, we should define a unique ID \p PassID to
0043 /// identify the pass, which is usually a pointer to a static member. If a pass
0044 /// has parameters, they should be stored in a struct \p OptionT with a method
0045 /// bool isCompatibleWith(const OptionT& LastOpt) const to check compatibility.
0046 class LastRunTrackingInfo {
0047 public:
0048   using PassID = const void *;
0049   using OptionPtr = const void *;
0050   // CompatibilityCheckFn is a closure that stores the parameters of last run.
0051   using CompatibilityCheckFn = std::function<bool(OptionPtr)>;
0052 
0053   /// Check if we should skip a pass.
0054   /// \param ID The unique ID of the pass.
0055   /// \param Opt The parameters of the pass. If the pass has no parameters, use
0056   /// shouldSkip(PassID ID) instead.
0057   /// \return True if we should skip the pass.
0058   /// \sa shouldSkip(PassID ID)
0059   template <typename OptionT>
0060   bool shouldSkip(PassID ID, const OptionT &Opt) const {
0061     return shouldSkipImpl(ID, &Opt);
0062   }
0063   bool shouldSkip(PassID ID) const { return shouldSkipImpl(ID, nullptr); }
0064 
0065   /// Update the tracking info.
0066   /// \param ID The unique ID of the pass.
0067   /// \param Changed Whether the pass makes changes.
0068   /// \param Opt The parameters of the pass. It must have the same type as the
0069   /// parameters of the last run. If the pass has no parameters, use
0070   /// update(PassID ID, bool Changed) instead.
0071   /// \sa update(PassID ID, bool Changed)
0072   template <typename OptionT>
0073   void update(PassID ID, bool Changed, const OptionT &Opt) {
0074     updateImpl(ID, Changed, [Opt](OptionPtr Ptr) {
0075       return static_cast<const OptionT *>(Ptr)->isCompatibleWith(Opt);
0076     });
0077   }
0078   void update(PassID ID, bool Changed) {
0079     updateImpl(ID, Changed, CompatibilityCheckFn{});
0080   }
0081 
0082 private:
0083   bool shouldSkipImpl(PassID ID, OptionPtr Ptr) const;
0084   void updateImpl(PassID ID, bool Changed, CompatibilityCheckFn CheckFn);
0085 
0086   DenseMap<PassID, CompatibilityCheckFn> TrackedPasses;
0087 };
0088 
0089 /// A function/module analysis which provides an empty \c LastRunTrackingInfo.
0090 class LastRunTrackingAnalysis final
0091     : public AnalysisInfoMixin<LastRunTrackingAnalysis> {
0092   friend AnalysisInfoMixin<LastRunTrackingAnalysis>;
0093   static AnalysisKey Key;
0094 
0095 public:
0096   using Result = LastRunTrackingInfo;
0097   LastRunTrackingInfo run(Function &F, FunctionAnalysisManager &) {
0098     return LastRunTrackingInfo();
0099   }
0100   LastRunTrackingInfo run(Module &M, ModuleAnalysisManager &) {
0101     return LastRunTrackingInfo();
0102   }
0103 };
0104 
0105 } // namespace llvm
0106 
0107 #endif // LLVM_ANALYSIS_LASTRUNTRACKINGANALYSIS_H