mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 15:00:17 +02:00
This has the Frontend and OpcodeDispatcher select their operating mode depending on the incoming code segment long-mode flag. Adds some asserts since currently it is unexpected if the configuration changes at runtime. This is fairly straightforward for an initial setup but isn't fully fleshed out. Right now FEX's x86 tables aren't setup in a way to support choosing a different instruction decoding depending on runtime operating mode change, so that would break in interesting ways. Primarily this just gets FEX setup to start piping the operating mode through from the frontend to the backend. This is a long term task, so it is going to take a long time to iron out all the issues.
103 lines
3.0 KiB
C++
103 lines
3.0 KiB
C++
// SPDX-License-Identifier: MIT
|
|
/*
|
|
$info$
|
|
meta: ir|opts ~ IR to IR Optimization
|
|
tags: ir|opts
|
|
desc: Defines which passes are run, and runs them
|
|
$end_info$
|
|
*/
|
|
|
|
#include "Interface/Context/Context.h"
|
|
#include "Interface/IR/PassManager.h"
|
|
#include "Interface/IR/Passes.h"
|
|
#include "Interface/IR/Passes/RegisterAllocationPass.h"
|
|
|
|
#include <FEXCore/Config/Config.h>
|
|
#include <FEXCore/Utils/Profiler.h>
|
|
|
|
namespace FEXCore::IR {
|
|
class IREmitter;
|
|
|
|
void PassManager::Finalize() {
|
|
if (!PassManagerDumpIR()) {
|
|
// Not configured to dump any IR, just return.
|
|
return;
|
|
}
|
|
|
|
auto it = Passes.begin();
|
|
// Walk the passes and add them where asked.
|
|
if (PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::BEFOREOPT) {
|
|
// Insert at the start.
|
|
it = InsertAt(it, Debug::CreateIRDumper());
|
|
++it; // Skip what we inserted.
|
|
}
|
|
|
|
if ((PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::BEFOREPASS) ||
|
|
(PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::AFTERPASS)) {
|
|
|
|
bool SkipFirstBefore = PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::BEFOREOPT;
|
|
for (; it != Passes.end();) {
|
|
if (PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::BEFOREPASS) {
|
|
if (SkipFirstBefore) {
|
|
// If we need to skip the first one, then continue.
|
|
SkipFirstBefore = false;
|
|
++it;
|
|
continue;
|
|
}
|
|
|
|
// Insert before
|
|
it = InsertAt(it, Debug::CreateIRDumper());
|
|
++it; // Skip what we inserted.
|
|
}
|
|
|
|
++it; // Skip current pass.
|
|
if (PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::AFTERPASS) {
|
|
// Insert after
|
|
it = InsertAt(it, Debug::CreateIRDumper());
|
|
++it; // Skip what we inserted.
|
|
}
|
|
}
|
|
}
|
|
if (PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::AFTEROPT) {
|
|
if (!(PassManagerDumpIR() & FEXCore::Config::PassManagerDumpIR::AFTERPASS)) {
|
|
// Insert final IRDumper.
|
|
InsertAt(Passes.end(), Debug::CreateIRDumper());
|
|
}
|
|
}
|
|
}
|
|
|
|
void PassManager::AddDefaultPasses(FEXCore::Context::ContextImpl* ctx) {
|
|
FEX_CONFIG_OPT(DisablePasses, O0);
|
|
|
|
if (!DisablePasses()) {
|
|
InsertPass(CreateX87StackOptimizationPass(ctx->HostFeatures, ctx->Config.Is64BitMode ? IR::OpSize::i64Bit : IR::OpSize::i32Bit));
|
|
InsertPass(CreateConstProp(ctx->HostFeatures.SupportsTSOImm9));
|
|
InsertPass(CreateDeadFlagCalculationEliminination());
|
|
}
|
|
}
|
|
|
|
void PassManager::AddDefaultValidationPasses() {
|
|
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
|
|
InsertValidationPass(Validation::CreateIRValidation(), "IRValidation");
|
|
#endif
|
|
}
|
|
|
|
void PassManager::InsertRegisterAllocationPass(FEXCore::Context::ContextImpl* ctx) {
|
|
InsertPass(IR::CreateRegisterAllocationPass(&ctx->CPUID), "RA");
|
|
}
|
|
|
|
void PassManager::Run(IREmitter* IREmit) {
|
|
FEXCORE_PROFILE_SCOPED("PassManager::Run");
|
|
|
|
for (const auto& Pass : Passes) {
|
|
Pass->Run(IREmit);
|
|
}
|
|
|
|
#if defined(ASSERTIONS_ENABLED) && ASSERTIONS_ENABLED
|
|
for (const auto& Pass : ValidationPasses) {
|
|
Pass->Run(IREmit);
|
|
}
|
|
#endif
|
|
}
|
|
} // namespace FEXCore::IR
|