// SPDX-License-Identifier: MIT /* $info$ tags: ir|opts $end_info$ */ #pragma once #include #include #include #include #include #include #include #include namespace FEXCore::Context { class ContextImpl; } 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 InlineCallOptimization; public: void AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool InlineConstants, bool StaticRegisterAllocation); void AddDefaultValidationPasses(); Pass* InsertPass(fextl::unique_ptr Pass, fextl::string Name = "") { auto PassPtr = InsertAt(Passes.end(), 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(fextl::string Name) const { return NameToPassMaping.contains(Name); } template T* GetPass(fextl::string Name) { return dynamic_cast(NameToPassMaping[Name]); } Pass* GetPass(fextl::string Name) { return NameToPassMaping[Name]; } void RegisterSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) { SyscallHandler = Handler; } void Finalize(); protected: ShouldExitHandler ExitHandler; FEXCore::HLE::SyscallHandler *SyscallHandler; private: using PassArrayType = fextl::vector>; PassArrayType::iterator InsertAt(PassArrayType::iterator pos, fextl::unique_ptr Pass) { Pass->RegisterPassManager(this); return Passes.insert(pos, std::move(Pass)); } PassArrayType Passes; fextl::unordered_map NameToPassMaping; #if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED fextl::vector> ValidationPasses; void InsertValidationPass(fextl::unique_ptr Pass, fextl::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); FEX_CONFIG_OPT(PassManagerDumpIR, PASSMANAGERDUMPIR); }; }