From f6fcadcabea5ab41108e02802dcefb22ee81e370 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 10 Feb 2026 22:05:45 +0000 Subject: [PATCH] better opt --- src/dynarmic/src/dynarmic/ir/opt_passes.cpp | 43 ++++++++++----------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp index cccf6bac8d..2bd2e3a1d5 100644 --- a/src/dynarmic/src/dynarmic/ir/opt_passes.cpp +++ b/src/dynarmic/src/dynarmic/ir/opt_passes.cpp @@ -511,8 +511,8 @@ static void A64GetSetElimination(IR::Block& block) { struct RegisterInfo { IR::Value register_value; TrackingType tracking_type; - bool set_instruction_present = false; Iterator last_set_instruction; + bool set_instruction_present = false; }; std::array reg_info; std::array vec_info; @@ -524,26 +524,25 @@ static void A64GetSetElimination(IR::Block& block) { info.last_set_instruction->Invalidate(); block.Instructions().erase(info.last_set_instruction); } - info.register_value = value; info.tracking_type = tracking_type; info.set_instruction_present = true; info.last_set_instruction = set_inst; }; - const auto do_get = [](RegisterInfo& info, Iterator get_inst, TrackingType tracking_type) { - // A sequence like - // SetX r1 -> GetW r1, is just reading off the lowest 32-bits of the register - auto const is_lower_32 = tracking_type == TrackingType::W - && info.tracking_type == TrackingType::X; + const auto do_get = [&block](RegisterInfo& info, Iterator get_inst, TrackingType tracking_type) { if (!info.register_value.IsEmpty() && info.tracking_type == tracking_type) { get_inst->ReplaceUsesWith(info.register_value); - } else if (!info.register_value.IsEmpty() && is_lower_32) { + } else if (!info.register_value.IsEmpty() + && tracking_type == TrackingType::W + && info.tracking_type == TrackingType::X) { + // A sequence like + // SetX r1 -> GetW r1, is just reading off the lowest 32-bits of the register if (info.register_value.IsImmediate()) { - ReplaceUsesWith(*get_inst, true, u32(info.register_value.GetImmediateAsU64() & 0xffff'ffff)); + ReplaceUsesWith(*get_inst, true, u32(info.register_value.GetImmediateAsU64())); } else { - info = {}; - info.register_value = IR::Value(&*get_inst); - info.tracking_type = tracking_type; + A64::IREmitter ir{block}; + ir.SetInsertionPointBefore(&*get_inst); + get_inst->ReplaceUsesWith(ir.LeastSignificantWord(IR::U64{info.register_value})); } } else { info = {}; @@ -556,27 +555,27 @@ static void A64GetSetElimination(IR::Block& block) { switch (opcode) { case IR::Opcode::A64GetW: { const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef()); - do_get(reg_info.at(index), inst, TrackingType::W); + do_get(reg_info[index], inst, TrackingType::W); break; } case IR::Opcode::A64GetX: { const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef()); - do_get(reg_info.at(index), inst, TrackingType::X); + do_get(reg_info[index], inst, TrackingType::X); break; } case IR::Opcode::A64GetS: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_get(vec_info.at(index), inst, TrackingType::S); + do_get(vec_info[index], inst, TrackingType::S); break; } case IR::Opcode::A64GetD: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_get(vec_info.at(index), inst, TrackingType::D); + do_get(vec_info[index], inst, TrackingType::D); break; } case IR::Opcode::A64GetQ: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_get(vec_info.at(index), inst, TrackingType::Q); + do_get(vec_info[index], inst, TrackingType::Q); break; } case IR::Opcode::A64GetSP: { @@ -589,27 +588,27 @@ static void A64GetSetElimination(IR::Block& block) { } case IR::Opcode::A64SetW: { const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef()); - do_set(reg_info.at(index), inst->GetArg(1), inst, TrackingType::W); + do_set(reg_info[index], inst->GetArg(1), inst, TrackingType::W); break; } case IR::Opcode::A64SetX: { const size_t index = A64::RegNumber(inst->GetArg(0).GetA64RegRef()); - do_set(reg_info.at(index), inst->GetArg(1), inst, TrackingType::X); + do_set(reg_info[index], inst->GetArg(1), inst, TrackingType::X); break; } case IR::Opcode::A64SetS: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::S); + do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::S); break; } case IR::Opcode::A64SetD: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::D); + do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::D); break; } case IR::Opcode::A64SetQ: { const size_t index = A64::VecNumber(inst->GetArg(0).GetA64VecRef()); - do_set(vec_info.at(index), inst->GetArg(1), inst, TrackingType::Q); + do_set(vec_info[index], inst->GetArg(1), inst, TrackingType::Q); break; } case IR::Opcode::A64SetSP: {