reg_alloc: Fix cast-qual issue
This commit is contained in:
parent
60030a76d7
commit
d796d8e93d
20 changed files with 101 additions and 56 deletions
|
@ -86,6 +86,7 @@ add_library(dynarmic
|
||||||
ir/opt/dead_code_elimination_pass.cpp
|
ir/opt/dead_code_elimination_pass.cpp
|
||||||
ir/opt/identity_removal_pass.cpp
|
ir/opt/identity_removal_pass.cpp
|
||||||
ir/opt/ir_matcher.h
|
ir/opt/ir_matcher.h
|
||||||
|
ir/opt/naming_pass.cpp
|
||||||
ir/opt/passes.h
|
ir/opt/passes.h
|
||||||
ir/opt/polyfill_pass.cpp
|
ir/opt/polyfill_pass.cpp
|
||||||
ir/opt/verification_pass.cpp
|
ir/opt/verification_pass.cpp
|
||||||
|
|
|
@ -165,6 +165,7 @@ IR::Block A32AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
|
||||||
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||||
|
|
||||||
Optimization::PolyfillPass(ir_block, {});
|
Optimization::PolyfillPass(ir_block, {});
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
|
if (conf.HasOptimization(OptimizationFlag::GetSetElimination)) {
|
||||||
Optimization::A32GetSetElimination(ir_block, {.convert_nzc_to_nz = true});
|
Optimization::A32GetSetElimination(ir_block, {.convert_nzc_to_nz = true});
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
|
|
@ -333,6 +333,7 @@ IR::Block A64AddressSpace::GenerateIR(IR::LocationDescriptor descriptor) const {
|
||||||
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||||
|
|
||||||
Optimization::A64CallbackConfigPass(ir_block, conf);
|
Optimization::A64CallbackConfigPass(ir_block, conf);
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
||||||
Optimization::A64GetSetElimination(ir_block);
|
Optimization::A64GetSetElimination(ir_block);
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
|
|
@ -491,8 +491,7 @@ std::optional<DoNotFastmemMarker> ShouldFastmem(EmitContext& ctx, IR::Inst* inst
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto inst_offset = std::distance(ctx.block.begin(), IR::Block::iterator(inst));
|
const auto marker = std::make_tuple(ctx.block.Location(), inst->GetName());
|
||||||
const auto marker = std::make_tuple(ctx.block.Location(), inst_offset);
|
|
||||||
if (ctx.fastmem.ShouldFastmem(marker)) {
|
if (ctx.fastmem.ShouldFastmem(marker)) {
|
||||||
return marker;
|
return marker;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, std::ptrdiff_t>;
|
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||||
|
|
||||||
struct DoNotFastmemMarkerHash {
|
struct DoNotFastmemMarkerHash {
|
||||||
size_t operator()(const DoNotFastmemMarker& value) const {
|
size_t operator()(const DoNotFastmemMarker& value) const {
|
||||||
|
|
|
@ -336,7 +336,7 @@ private:
|
||||||
|
|
||||||
mutable std::mt19937 rand_gen;
|
mutable std::mt19937 rand_gen;
|
||||||
|
|
||||||
tsl::robin_set<IR::Inst*> defined_insts;
|
tsl::robin_set<const IR::Inst*> defined_insts;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -97,7 +97,7 @@ protected:
|
||||||
std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const override;
|
std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const override;
|
||||||
|
|
||||||
// Fastmem information
|
// Fastmem information
|
||||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, std::ptrdiff_t>;
|
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||||
struct FastmemPatchInfo {
|
struct FastmemPatchInfo {
|
||||||
u64 resume_rip;
|
u64 resume_rip;
|
||||||
u64 callback;
|
u64 callback;
|
||||||
|
|
|
@ -174,6 +174,7 @@ private:
|
||||||
|
|
||||||
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
IR::Block ir_block = A32::Translate(A32::LocationDescriptor{descriptor}, conf.callbacks, {conf.arch_version, conf.define_unpredictable_behaviour, conf.hook_hint_instructions});
|
||||||
Optimization::PolyfillPass(ir_block, polyfill_options);
|
Optimization::PolyfillPass(ir_block, polyfill_options);
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
||||||
Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true});
|
Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true});
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
@ -197,7 +198,9 @@ Jit::~Jit() = default;
|
||||||
HaltReason Jit::Run() {
|
HaltReason Jit::Run() {
|
||||||
ASSERT(!is_executing);
|
ASSERT(!is_executing);
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
SCOPE_EXIT { this->is_executing = false; };
|
SCOPE_EXIT {
|
||||||
|
this->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
const HaltReason hr = impl->Execute();
|
const HaltReason hr = impl->Execute();
|
||||||
|
|
||||||
|
@ -209,7 +212,9 @@ HaltReason Jit::Run() {
|
||||||
HaltReason Jit::Step() {
|
HaltReason Jit::Step() {
|
||||||
ASSERT(!is_executing);
|
ASSERT(!is_executing);
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
SCOPE_EXIT { this->is_executing = false; };
|
SCOPE_EXIT {
|
||||||
|
this->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
const HaltReason hr = impl->Step();
|
const HaltReason hr = impl->Step();
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ protected:
|
||||||
std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const override;
|
std::string LocationDescriptorToFriendlyName(const IR::LocationDescriptor&) const override;
|
||||||
|
|
||||||
// Fastmem information
|
// Fastmem information
|
||||||
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, std::ptrdiff_t>;
|
using DoNotFastmemMarker = std::tuple<IR::LocationDescriptor, unsigned>;
|
||||||
struct FastmemPatchInfo {
|
struct FastmemPatchInfo {
|
||||||
u64 resume_rip;
|
u64 resume_rip;
|
||||||
u64 callback;
|
u64 callback;
|
||||||
|
|
|
@ -72,7 +72,9 @@ public:
|
||||||
PerformRequestedCacheInvalidation();
|
PerformRequestedCacheInvalidation();
|
||||||
|
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
SCOPE_EXIT { this->is_executing = false; };
|
SCOPE_EXIT {
|
||||||
|
this->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: Check code alignment
|
// TODO: Check code alignment
|
||||||
|
|
||||||
|
@ -99,7 +101,9 @@ public:
|
||||||
PerformRequestedCacheInvalidation();
|
PerformRequestedCacheInvalidation();
|
||||||
|
|
||||||
is_executing = true;
|
is_executing = true;
|
||||||
SCOPE_EXIT { this->is_executing = false; };
|
SCOPE_EXIT {
|
||||||
|
this->is_executing = false;
|
||||||
|
};
|
||||||
|
|
||||||
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
|
const HaltReason hr = block_of_code.StepCode(&jit_state, GetCurrentSingleStep());
|
||||||
|
|
||||||
|
@ -273,6 +277,7 @@ private:
|
||||||
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
{conf.define_unpredictable_behaviour, conf.wall_clock_cntpct});
|
||||||
Optimization::PolyfillPass(ir_block, polyfill_options);
|
Optimization::PolyfillPass(ir_block, polyfill_options);
|
||||||
Optimization::A64CallbackConfigPass(ir_block, conf);
|
Optimization::A64CallbackConfigPass(ir_block, conf);
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
if (conf.HasOptimization(OptimizationFlag::GetSetElimination) && !conf.check_halt_on_memory_access) {
|
||||||
Optimization::A64GetSetElimination(ir_block);
|
Optimization::A64GetSetElimination(ir_block);
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
|
|
@ -35,10 +35,6 @@ EmitContext::EmitContext(RegAlloc& reg_alloc, IR::Block& block)
|
||||||
|
|
||||||
EmitContext::~EmitContext() = default;
|
EmitContext::~EmitContext() = default;
|
||||||
|
|
||||||
size_t EmitContext::GetInstOffset(IR::Inst* inst) const {
|
|
||||||
return static_cast<size_t>(std::distance(block.begin(), IR::Block::iterator(inst)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitContext::EraseInstruction(IR::Inst* inst) {
|
void EmitContext::EraseInstruction(IR::Inst* inst) {
|
||||||
block.Instructions().erase(inst);
|
block.Instructions().erase(inst);
|
||||||
inst->ClearArgs();
|
inst->ClearArgs();
|
||||||
|
|
|
@ -53,7 +53,6 @@ struct EmitContext {
|
||||||
EmitContext(RegAlloc& reg_alloc, IR::Block& block);
|
EmitContext(RegAlloc& reg_alloc, IR::Block& block);
|
||||||
virtual ~EmitContext();
|
virtual ~EmitContext();
|
||||||
|
|
||||||
size_t GetInstOffset(IR::Inst* inst) const;
|
|
||||||
void EraseInstruction(IR::Inst* inst);
|
void EraseInstruction(IR::Inst* inst);
|
||||||
|
|
||||||
virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0;
|
virtual FP::FPCR FPCR(bool fpcr_controlled = true) const = 0;
|
||||||
|
|
|
@ -19,7 +19,7 @@ std::optional<AxxEmitX64::DoNotFastmemMarker> AxxEmitX64::ShouldFastmem(AxxEmitC
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto marker = std::make_tuple(ctx.Location(), ctx.GetInstOffset(inst));
|
const auto marker = std::make_tuple(ctx.Location(), inst->GetName());
|
||||||
if (do_not_fastmem.count(marker) > 0) {
|
if (do_not_fastmem.count(marker) > 0) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,17 +168,14 @@ std::string DumpBlock(const IR::Block& block) {
|
||||||
}
|
}
|
||||||
ret += '\n';
|
ret += '\n';
|
||||||
|
|
||||||
std::map<const IR::Inst*, size_t> inst_to_index;
|
const auto arg_to_string = [](const IR::Value& arg) -> std::string {
|
||||||
size_t index = 0;
|
|
||||||
|
|
||||||
const auto arg_to_string = [&inst_to_index](const IR::Value& arg) -> std::string {
|
|
||||||
if (arg.IsEmpty()) {
|
if (arg.IsEmpty()) {
|
||||||
return "<null>";
|
return "<null>";
|
||||||
} else if (!arg.IsImmediate()) {
|
} else if (!arg.IsImmediate()) {
|
||||||
if (const auto iter = inst_to_index.find(arg.GetInst()); iter != inst_to_index.end()) {
|
if (const unsigned name = arg.GetInst()->GetName()) {
|
||||||
return fmt::format("%{}", iter->second);
|
return fmt::format("%{}", name);
|
||||||
}
|
}
|
||||||
return fmt::format("%<unknown inst {:016x}>", reinterpret_cast<u64>(arg.GetInst()));
|
return fmt::format("%<unnamed inst {:016x}>", reinterpret_cast<u64>(arg.GetInst()));
|
||||||
}
|
}
|
||||||
switch (arg.GetType()) {
|
switch (arg.GetType()) {
|
||||||
case Type::U1:
|
case Type::U1:
|
||||||
|
@ -209,7 +206,11 @@ std::string DumpBlock(const IR::Block& block) {
|
||||||
|
|
||||||
ret += fmt::format("[{:016x}] ", reinterpret_cast<u64>(&inst));
|
ret += fmt::format("[{:016x}] ", reinterpret_cast<u64>(&inst));
|
||||||
if (GetTypeOf(op) != Type::Void) {
|
if (GetTypeOf(op) != Type::Void) {
|
||||||
ret += fmt::format("%{:<5} = ", index);
|
if (inst.GetName()) {
|
||||||
|
ret += fmt::format("%{:<5} = ", inst.GetName());
|
||||||
|
} else {
|
||||||
|
ret += "noname = ";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret += " "; // '%00000 = ' -> 1 + 5 + 3 = 9 spaces
|
ret += " "; // '%00000 = ' -> 1 + 5 + 3 = 9 spaces
|
||||||
}
|
}
|
||||||
|
@ -233,7 +234,6 @@ std::string DumpBlock(const IR::Block& block) {
|
||||||
ret += fmt::format(" (uses: {})", inst.UseCount());
|
ret += fmt::format(" (uses: {})", inst.UseCount());
|
||||||
|
|
||||||
ret += '\n';
|
ret += '\n';
|
||||||
inst_to_index[&inst] = index++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret += "terminal = " + TerminalToString(block.GetTerminal()) + '\n';
|
ret += "terminal = " + TerminalToString(block.GetTerminal()) + '\n';
|
||||||
|
|
|
@ -141,12 +141,18 @@ public:
|
||||||
|
|
||||||
void ReplaceUsesWith(Value replacement);
|
void ReplaceUsesWith(Value replacement);
|
||||||
|
|
||||||
|
// IR name (i.e. instruction number in block). This is set in the naming pass. Treat 0 as an invalid name.
|
||||||
|
// This is used for debugging and fastmem instruction identification.
|
||||||
|
void SetName(unsigned value) { name = value; }
|
||||||
|
unsigned GetName() const { return name; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Use(const Value& value);
|
void Use(const Value& value);
|
||||||
void UndoUse(const Value& value);
|
void UndoUse(const Value& value);
|
||||||
|
|
||||||
Opcode op;
|
Opcode op;
|
||||||
size_t use_count = 0;
|
unsigned use_count = 0;
|
||||||
|
unsigned name = 0;
|
||||||
std::array<Value, max_arg_count> args;
|
std::array<Value, max_arg_count> args;
|
||||||
|
|
||||||
// Linked list of pseudooperations associated with this instruction.
|
// Linked list of pseudooperations associated with this instruction.
|
||||||
|
|
18
src/dynarmic/ir/opt/naming_pass.cpp
Normal file
18
src/dynarmic/ir/opt/naming_pass.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2023 MerryMage
|
||||||
|
* SPDX-License-Identifier: 0BSD
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "dynarmic/ir/basic_block.h"
|
||||||
|
#include "dynarmic/ir/microinstruction.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::Optimization {
|
||||||
|
|
||||||
|
void NamingPass(IR::Block& block) {
|
||||||
|
unsigned name = 1;
|
||||||
|
for (auto& inst : block) {
|
||||||
|
inst.SetName(name++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic::Optimization
|
|
@ -42,5 +42,6 @@ void ConstantPropagation(IR::Block& block);
|
||||||
void DeadCodeElimination(IR::Block& block);
|
void DeadCodeElimination(IR::Block& block);
|
||||||
void IdentityRemovalPass(IR::Block& block);
|
void IdentityRemovalPass(IR::Block& block);
|
||||||
void VerificationPass(const IR::Block& block);
|
void VerificationPass(const IR::Block& block);
|
||||||
|
void NamingPass(IR::Block& block);
|
||||||
|
|
||||||
} // namespace Dynarmic::Optimization
|
} // namespace Dynarmic::Optimization
|
||||||
|
|
|
@ -176,6 +176,7 @@ static void RunInstance(size_t run_number, ThumbTestEnv& test_env, A32Unicorn<Th
|
||||||
while (num_insts < instructions_to_execute_count) {
|
while (num_insts < instructions_to_execute_count) {
|
||||||
A32::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, A32::FPSCR{}};
|
A32::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, A32::FPSCR{}};
|
||||||
IR::Block ir_block = A32::Translate(descriptor, &test_env, {});
|
IR::Block ir_block = A32::Translate(descriptor, &test_env, {});
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true});
|
Optimization::A32GetSetElimination(ir_block, {.convert_nz_to_nzc = true});
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
Optimization::A32ConstantMemoryReads(ir_block, &test_env);
|
Optimization::A32ConstantMemoryReads(ir_block, &test_env);
|
||||||
|
|
|
@ -265,6 +265,8 @@ static void RunTestInstance(Dynarmic::A64::Jit& jit, A64Unicorn& uni, A64TestEnv
|
||||||
const auto get_code = [&jit_env](u64 vaddr) { return jit_env.MemoryReadCode(vaddr); };
|
const auto get_code = [&jit_env](u64 vaddr) { return jit_env.MemoryReadCode(vaddr); };
|
||||||
IR::Block ir_block = A64::Translate({instructions_start, FP::FPCR{fpcr}}, get_code, {});
|
IR::Block ir_block = A64::Translate({instructions_start, FP::FPCR{fpcr}}, get_code, {});
|
||||||
Optimization::A64CallbackConfigPass(ir_block, GetUserConfig(jit_env));
|
Optimization::A64CallbackConfigPass(ir_block, GetUserConfig(jit_env));
|
||||||
|
Optimization::NamingPass(ir_block);
|
||||||
|
|
||||||
fmt::print("IR:\n");
|
fmt::print("IR:\n");
|
||||||
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
|
|
||||||
|
@ -272,6 +274,7 @@ static void RunTestInstance(Dynarmic::A64::Jit& jit, A64Unicorn& uni, A64TestEnv
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
Optimization::ConstantPropagation(ir_block);
|
Optimization::ConstantPropagation(ir_block);
|
||||||
Optimization::DeadCodeElimination(ir_block);
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
|
||||||
fmt::print("Optimized IR:\n");
|
fmt::print("Optimized IR:\n");
|
||||||
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
|
|
||||||
|
|
|
@ -58,20 +58,23 @@ void PrintA32Instruction(u32 instruction) {
|
||||||
fmt::print("Name: {}\n", GetNameOfA32Instruction(instruction));
|
fmt::print("Name: {}\n", GetNameOfA32Instruction(instruction));
|
||||||
|
|
||||||
const A32::LocationDescriptor location{0, {}, {}};
|
const A32::LocationDescriptor location{0, {}, {}};
|
||||||
IR::Block block{location};
|
IR::Block ir_block{location};
|
||||||
const bool should_continue = A32::TranslateSingleInstruction(block, location, instruction);
|
const bool should_continue = A32::TranslateSingleInstruction(ir_block, location, instruction);
|
||||||
fmt::print("should_continue: {}\n\n", should_continue);
|
fmt::print("should_continue: {}\n\n", should_continue);
|
||||||
fmt::print("IR:\n");
|
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
|
||||||
|
|
||||||
Optimization::A32GetSetElimination(block, {});
|
Optimization::NamingPass(ir_block);
|
||||||
Optimization::DeadCodeElimination(block);
|
|
||||||
Optimization::ConstantPropagation(block);
|
fmt::print("IR:\n");
|
||||||
Optimization::DeadCodeElimination(block);
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
Optimization::IdentityRemovalPass(block);
|
|
||||||
|
Optimization::A32GetSetElimination(ir_block, {});
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::ConstantPropagation(ir_block);
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::IdentityRemovalPass(ir_block);
|
||||||
|
|
||||||
fmt::print("Optimized IR:\n");
|
fmt::print("Optimized IR:\n");
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintA64Instruction(u32 instruction) {
|
void PrintA64Instruction(u32 instruction) {
|
||||||
|
@ -79,20 +82,23 @@ void PrintA64Instruction(u32 instruction) {
|
||||||
fmt::print("Name: {}\n", GetNameOfA64Instruction(instruction));
|
fmt::print("Name: {}\n", GetNameOfA64Instruction(instruction));
|
||||||
|
|
||||||
const A64::LocationDescriptor location{0, {}};
|
const A64::LocationDescriptor location{0, {}};
|
||||||
IR::Block block{location};
|
IR::Block ir_block{location};
|
||||||
const bool should_continue = A64::TranslateSingleInstruction(block, location, instruction);
|
const bool should_continue = A64::TranslateSingleInstruction(ir_block, location, instruction);
|
||||||
fmt::print("should_continue: {}\n\n", should_continue);
|
fmt::print("should_continue: {}\n\n", should_continue);
|
||||||
fmt::print("IR:\n");
|
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
|
||||||
|
|
||||||
Optimization::A64GetSetElimination(block);
|
Optimization::NamingPass(ir_block);
|
||||||
Optimization::DeadCodeElimination(block);
|
|
||||||
Optimization::ConstantPropagation(block);
|
fmt::print("IR:\n");
|
||||||
Optimization::DeadCodeElimination(block);
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
Optimization::IdentityRemovalPass(block);
|
|
||||||
|
Optimization::A64GetSetElimination(ir_block);
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::ConstantPropagation(ir_block);
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::IdentityRemovalPass(ir_block);
|
||||||
|
|
||||||
fmt::print("Optimized IR:\n");
|
fmt::print("Optimized IR:\n");
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintThumbInstruction(u32 instruction) {
|
void PrintThumbInstruction(u32 instruction) {
|
||||||
|
@ -103,20 +109,23 @@ void PrintThumbInstruction(u32 instruction) {
|
||||||
fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(true, 0, (u8*)&instruction, inst_size));
|
fmt::print("{:08x} {}\n", instruction, Common::DisassembleAArch32(true, 0, (u8*)&instruction, inst_size));
|
||||||
|
|
||||||
const A32::LocationDescriptor location{0, A32::PSR{0x1F0}, {}};
|
const A32::LocationDescriptor location{0, A32::PSR{0x1F0}, {}};
|
||||||
IR::Block block{location};
|
IR::Block ir_block{location};
|
||||||
const bool should_continue = A32::TranslateSingleInstruction(block, location, instruction);
|
const bool should_continue = A32::TranslateSingleInstruction(ir_block, location, instruction);
|
||||||
fmt::print("should_continue: {}\n\n", should_continue);
|
fmt::print("should_continue: {}\n\n", should_continue);
|
||||||
fmt::print("IR:\n");
|
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
|
||||||
|
|
||||||
Optimization::A32GetSetElimination(block, {});
|
Optimization::NamingPass(ir_block);
|
||||||
Optimization::DeadCodeElimination(block);
|
|
||||||
Optimization::ConstantPropagation(block);
|
fmt::print("IR:\n");
|
||||||
Optimization::DeadCodeElimination(block);
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
Optimization::IdentityRemovalPass(block);
|
|
||||||
|
Optimization::A32GetSetElimination(ir_block, {});
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::ConstantPropagation(ir_block);
|
||||||
|
Optimization::DeadCodeElimination(ir_block);
|
||||||
|
Optimization::IdentityRemovalPass(ir_block);
|
||||||
|
|
||||||
fmt::print("Optimized IR:\n");
|
fmt::print("Optimized IR:\n");
|
||||||
fmt::print("{}\n", IR::DumpBlock(block));
|
fmt::print("{}\n", IR::DumpBlock(ir_block));
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExecEnv final : public Dynarmic::A32::UserCallbacks {
|
class ExecEnv final : public Dynarmic::A32::UserCallbacks {
|
||||||
|
|
Loading…
Reference in a new issue