/* $info$ tags: ir|opts $end_info$ */ #pragma once #include #include #include #include #include #include namespace FEXCore::HLE { class SyscallHandler; } namespace FEXCore::IR { class PassManager; class IREmitter; using ShouldExitHandler = std::function; class Pass { public: virtual ~Pass() = default; virtual bool Run(IREmitter *IREmit) = 0; void RegisterPassManager(PassManager *_Manager) { Manager = _Manager; } protected: PassManager *Manager; }; class PassManager final { friend class SyscallOptimization; public: void AddDefaultPasses(FEXCore::Context::Context *ctx, bool InlineConstants, bool StaticRegisterAllocation); void AddDefaultValidationPasses(); Pass* InsertPass(std::unique_ptr Pass, std::string Name = "") { Pass->RegisterPassManager(this); auto PassPtr = Passes.emplace_back(std::move(Pass)).get(); if (!Name.empty()) { NameToPassMaping[Name] = PassPtr; } return PassPtr; } void InsertRegisterAllocationPass(bool OptimizeSRA, bool SupportsAVX); bool Run(IREmitter *IREmit); void RegisterExitHandler(ShouldExitHandler Handler) { ExitHandler = std::move(Handler); } bool HasPass(std::string Name) const { return NameToPassMaping.contains(Name); } template T* GetPass(std::string Name) { return dynamic_cast(NameToPassMaping[Name]); } Pass* GetPass(std::string Name) { return NameToPassMaping[Name]; } void RegisterSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) { SyscallHandler = Handler; } protected: ShouldExitHandler ExitHandler; FEXCore::HLE::SyscallHandler *SyscallHandler; private: std::vector> Passes; std::unordered_map NameToPassMaping; #if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED std::vector> ValidationPasses; void InsertValidationPass(std::unique_ptr Pass, std::string Name = "") { Pass->RegisterPassManager(this); auto PassPtr = ValidationPasses.emplace_back(std::move(Pass)).get(); if (!Name.empty()) { NameToPassMaping[Name] = PassPtr; } } #endif FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); }; }