Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- PassManager.h --- Pass management for CodeGen ------------*- 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 header defines the pass manager interface for codegen. The codegen
0010 // pipeline consists of only machine function passes. There is no container
0011 // relationship between IR module/function and machine function in terms of pass
0012 // manager organization. So there is no need for adaptor classes (for example
0013 // ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
0014 // machine function passes, there is no proxy classes to handle cross-IR-unit
0015 // invalidation. IR analysis results are provided for machine function passes by
0016 // their respective analysis managers such as ModuleAnalysisManager and
0017 // FunctionAnalysisManager.
0018 //
0019 //===----------------------------------------------------------------------===//
0020 
0021 #ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
0022 #define LLVM_CODEGEN_MACHINEPASSMANAGER_H
0023 
0024 #include "llvm/ADT/FunctionExtras.h"
0025 #include "llvm/ADT/SmallVector.h"
0026 #include "llvm/CodeGen/MachineFunction.h"
0027 #include "llvm/IR/PassManager.h"
0028 #include "llvm/IR/PassManagerInternal.h"
0029 #include "llvm/Support/Error.h"
0030 
0031 namespace llvm {
0032 class Module;
0033 class Function;
0034 class MachineFunction;
0035 
0036 extern template class AnalysisManager<MachineFunction>;
0037 using MachineFunctionAnalysisManager = AnalysisManager<MachineFunction>;
0038 
0039 /// An RAII based helper class to modify MachineFunctionProperties when running
0040 /// pass. Define a MFPropsModifier in PassT::run to set
0041 /// MachineFunctionProperties properly.
0042 template <typename PassT> class MFPropsModifier {
0043 public:
0044   MFPropsModifier(const PassT &P_, MachineFunction &MF_) : P(P_), MF(MF_) {
0045     auto &MFProps = MF.getProperties();
0046 #ifndef NDEBUG
0047     if constexpr (has_get_required_properties_v<PassT>) {
0048       auto &MFProps = MF.getProperties();
0049       auto RequiredProperties = P.getRequiredProperties();
0050       if (!MFProps.verifyRequiredProperties(RequiredProperties)) {
0051         errs() << "MachineFunctionProperties required by " << PassT::name()
0052                << " pass are not met by function " << MF.getName() << ".\n"
0053                << "Required properties: ";
0054         RequiredProperties.print(errs());
0055         errs() << "\nCurrent properties: ";
0056         MFProps.print(errs());
0057         errs() << '\n';
0058         report_fatal_error("MachineFunctionProperties check failed");
0059       }
0060     }
0061 #endif // NDEBUG
0062     if constexpr (has_get_cleared_properties_v<PassT>)
0063       MFProps.reset(P.getClearedProperties());
0064   }
0065 
0066   ~MFPropsModifier() {
0067     if constexpr (has_get_set_properties_v<PassT>) {
0068       auto &MFProps = MF.getProperties();
0069       MFProps.set(P.getSetProperties());
0070     }
0071   }
0072 
0073 private:
0074   const PassT &P;
0075   MachineFunction &MF;
0076 
0077   template <typename T>
0078   using has_get_required_properties_t =
0079       decltype(std::declval<T &>().getRequiredProperties());
0080 
0081   template <typename T>
0082   using has_get_set_properties_t =
0083       decltype(std::declval<T &>().getSetProperties());
0084 
0085   template <typename T>
0086   using has_get_cleared_properties_t =
0087       decltype(std::declval<T &>().getClearedProperties());
0088 
0089   template <typename T>
0090   static constexpr bool has_get_required_properties_v =
0091       is_detected<has_get_required_properties_t, T>::value;
0092 
0093   template <typename T>
0094   static constexpr bool has_get_set_properties_v =
0095       is_detected<has_get_set_properties_t, T>::value;
0096 
0097   template <typename T>
0098   static constexpr bool has_get_cleared_properties_v =
0099       is_detected<has_get_cleared_properties_t, T>::value;
0100 };
0101 
0102 // Additional deduction guide to suppress warning.
0103 template <typename PassT>
0104 MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier<PassT>;
0105 
0106 using MachineFunctionAnalysisManagerModuleProxy =
0107     InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;
0108 
0109 template <>
0110 bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
0111     Module &M, const PreservedAnalyses &PA,
0112     ModuleAnalysisManager::Invalidator &Inv);
0113 extern template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
0114                                                 Module>;
0115 using MachineFunctionAnalysisManagerFunctionProxy =
0116     InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Function>;
0117 
0118 template <>
0119 bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
0120     Function &F, const PreservedAnalyses &PA,
0121     FunctionAnalysisManager::Invalidator &Inv);
0122 extern template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager,
0123                                                 Function>;
0124 
0125 extern template class OuterAnalysisManagerProxy<ModuleAnalysisManager,
0126                                                 MachineFunction>;
0127 /// Provide the \c ModuleAnalysisManager to \c Function proxy.
0128 using ModuleAnalysisManagerMachineFunctionProxy =
0129     OuterAnalysisManagerProxy<ModuleAnalysisManager, MachineFunction>;
0130 
0131 class FunctionAnalysisManagerMachineFunctionProxy
0132     : public AnalysisInfoMixin<FunctionAnalysisManagerMachineFunctionProxy> {
0133 public:
0134   class Result {
0135   public:
0136     explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
0137 
0138     Result(Result &&Arg) : FAM(std::move(Arg.FAM)) {
0139       // We have to null out the analysis manager in the moved-from state
0140       // because we are taking ownership of the responsibilty to clear the
0141       // analysis state.
0142       Arg.FAM = nullptr;
0143     }
0144 
0145     Result &operator=(Result &&RHS) {
0146       FAM = RHS.FAM;
0147       // We have to null out the analysis manager in the moved-from state
0148       // because we are taking ownership of the responsibilty to clear the
0149       // analysis state.
0150       RHS.FAM = nullptr;
0151       return *this;
0152     }
0153 
0154     /// Accessor for the analysis manager.
0155     FunctionAnalysisManager &getManager() { return *FAM; }
0156 
0157     /// Handler for invalidation of the outer IR unit, \c IRUnitT.
0158     ///
0159     /// If the proxy analysis itself is not preserved, we assume that the set of
0160     /// inner IR objects contained in IRUnit may have changed.  In this case,
0161     /// we have to call \c clear() on the inner analysis manager, as it may now
0162     /// have stale pointers to its inner IR objects.
0163     ///
0164     /// Regardless of whether the proxy analysis is marked as preserved, all of
0165     /// the analyses in the inner analysis manager are potentially invalidated
0166     /// based on the set of preserved analyses.
0167     bool invalidate(MachineFunction &IR, const PreservedAnalyses &PA,
0168                     MachineFunctionAnalysisManager::Invalidator &Inv);
0169 
0170   private:
0171     FunctionAnalysisManager *FAM;
0172   };
0173 
0174   explicit FunctionAnalysisManagerMachineFunctionProxy(
0175       FunctionAnalysisManager &FAM)
0176       : FAM(&FAM) {}
0177 
0178   /// Run the analysis pass and create our proxy result object.
0179   ///
0180   /// This doesn't do any interesting work; it is primarily used to insert our
0181   /// proxy result object into the outer analysis cache so that we can proxy
0182   /// invalidation to the inner analysis manager.
0183   Result run(MachineFunction &, MachineFunctionAnalysisManager &) {
0184     return Result(*FAM);
0185   }
0186 
0187   static AnalysisKey Key;
0188 
0189 private:
0190   FunctionAnalysisManager *FAM;
0191 };
0192 
0193 class FunctionToMachineFunctionPassAdaptor
0194     : public PassInfoMixin<FunctionToMachineFunctionPassAdaptor> {
0195 public:
0196   using PassConceptT =
0197       detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
0198 
0199   explicit FunctionToMachineFunctionPassAdaptor(
0200       std::unique_ptr<PassConceptT> Pass)
0201       : Pass(std::move(Pass)) {}
0202 
0203   /// Runs the function pass across every function in the function.
0204   PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
0205   void printPipeline(raw_ostream &OS,
0206                      function_ref<StringRef(StringRef)> MapClassName2PassName);
0207 
0208   static bool isRequired() { return true; }
0209 
0210 private:
0211   std::unique_ptr<PassConceptT> Pass;
0212 };
0213 
0214 template <typename MachineFunctionPassT>
0215 FunctionToMachineFunctionPassAdaptor
0216 createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
0217   using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
0218                                        MachineFunctionAnalysisManager>;
0219   // Do not use make_unique, it causes too many template instantiations,
0220   // causing terrible compile times.
0221   return FunctionToMachineFunctionPassAdaptor(
0222       std::unique_ptr<FunctionToMachineFunctionPassAdaptor::PassConceptT>(
0223           new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
0224 }
0225 
0226 template <>
0227 PreservedAnalyses
0228 PassManager<MachineFunction>::run(MachineFunction &,
0229                                   AnalysisManager<MachineFunction> &);
0230 extern template class PassManager<MachineFunction>;
0231 
0232 /// Convenience typedef for a pass manager over functions.
0233 using MachineFunctionPassManager = PassManager<MachineFunction>;
0234 
0235 /// Returns the minimum set of Analyses that all machine function passes must
0236 /// preserve.
0237 PreservedAnalyses getMachineFunctionPassPreservedAnalyses();
0238 
0239 } // end namespace llvm
0240 
0241 #endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H