// SPDX-License-Identifier: GPL-3.0-or-later #ifndef RCC_CODEGEN_MACHINEPASSMANAGER_H #define RCC_CODEGEN_MACHINEPASSMANAGER_H #include "rcc/CodeGen/InstructionDescriptor.h" #include "rcc/CodeGen/MachineFunctionAnalysisManager.h" #include "rcc/CodeGen/MachineFunctionProperties.h" #include "rcc/IR/PassInstrumentation.h" #include #include #include #include #include namespace rcc { class CompilationUnit; class MachineFunction; class TargetDescription; struct MachinePassRegistrationMetadata { std::vector Parameters; PassThreadSafety ThreadSafety = PassThreadSafety::NotThreadSafe; MachinePassChanges DeclaredChanges = MachinePassChanges::all(); }; struct MachinePassContract final : MachinePassRegistrationMetadata { std::string Name; MachineFunctionProperties Requires; MachineFunctionProperties Sets; MachineFunctionProperties Clears; std::vector RequiredAnalyses; std::optional VerificationStage; }; struct MachinePassResult final { bool Changed = false; MachinePassChanges Changes; PreservedAnalyses Preserved = PreservedAnalyses::none(); }; struct CompilationUnitPassContract final { std::string Name; std::vector RequiredAnalyses; std::vector Parameters; MachinePassChanges DeclaredChanges = MachinePassChanges::all(); }; struct CompilationUnitPassResult final { bool Changed = false; MachinePassChanges Changes; PreservedAnalyses PreservedUnitAnalyses = PreservedAnalyses::none(); PreservedAnalyses PreservedFunctionAnalyses = PreservedAnalyses::none(); }; class MachineFunctionPass { public: MachineFunctionPass() = default; MachineFunctionPass(const MachineFunctionPass &) = delete; MachineFunctionPass &operator=(const MachineFunctionPass &) = delete; virtual ~MachineFunctionPass() = default; [[nodiscard]] virtual const MachinePassContract &contract() const noexcept = 0; [[nodiscard]] virtual Expected run(MachineFunction &Function, const TargetDescription &Target, MachineFunctionAnalysisManager &Analyses) = 0; }; class CompilationUnitPass { public: CompilationUnitPass() = default; CompilationUnitPass(const CompilationUnitPass &) = delete; CompilationUnitPass &operator=(const CompilationUnitPass &) = delete; virtual ~CompilationUnitPass() = default; [[nodiscard]] virtual const CompilationUnitPassContract &contract() const noexcept = 0; [[nodiscard]] virtual Expected run(CompilationUnit &Unit, const TargetDescription &Target, CompilationUnitAnalysisManager &UnitAnalyses, MachineFunctionAnalysisManager &FunctionAnalyses) = 0; }; struct MachinePassManagerOptions final { bool VerifyBefore = true; bool VerifyEach = true; bool DetectUnreportedChanges = false; }; template <> struct PassManagerCallbacks final { using PassList = std::vector>; [[nodiscard]] static Expected validate(const MachineFunctionPass &Pass); [[nodiscard]] static Expected run(const PassList &Passes, const MachinePassManagerOptions &Options, MachineFunction &Function, const TargetDescription &Target, MachineFunctionAnalysisManager &Analyses, MachinePassInstrumentation *Instrumentation = nullptr); [[nodiscard]] static Expected runFunctions(const PassList &Passes, const MachinePassManagerOptions &Options, CompilationUnit &Unit, const TargetDescription &Target, const MachineFunctionAnalysisManager &AnalysisPrototype, std::size_t ThreadCount, MachinePassInstrumentation *Instrumentation = nullptr); }; using MachineFunctionPassManager = PassManager; struct CompilationUnitPassManagerOptions final { bool VerifyBefore = true; bool VerifyEach = true; }; template <> struct PassManagerCallbacks final { using PassList = std::vector>; [[nodiscard]] static Expected validate(const CompilationUnitPass &Pass); [[nodiscard]] static Expected run(const PassList &Passes, const CompilationUnitPassManagerOptions &Options, CompilationUnit &Unit, const TargetDescription &Target, CompilationUnitAnalysisManager &UnitAnalyses, MachineFunctionAnalysisManager &FunctionAnalyses, MachinePassInstrumentation *Instrumentation = nullptr); }; using CompilationUnitPassManager = PassManager; } // namespace rcc #endif // RCC_CODEGEN_MACHINEPASSMANAGER_H