From f6a9ac73b49cdc60ce0b4b955c6aded492d7303e Mon Sep 17 00:00:00 2001 From: Elad Ashkenazi <18193363+elad335@users.noreply.github.com> Date: Sat, 31 Aug 2024 15:33:20 +0300 Subject: [PATCH] SPU LLVM: Upgrade constants propagation --- rpcs3/Emu/Cell/SPUCommonRecompiler.cpp | 101 +++++-------------------- 1 file changed, 17 insertions(+), 84 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index 77d74b6a8b3e..3a0bc1c5d749 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -4277,13 +4277,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s { const u32 orig = bb.reg_origin_abs[i]; - if (orig < 0x40000) - { - auto& src = ::at32(m_bbs, orig); - bb.reg_const[i] = src.reg_const[i]; - bb.reg_val32[i] = src.reg_val32[i]; - } - if (!bb.reg_save_dom[i] && bb.reg_use[i] && (orig == 0x40000 || orig + 2 == 0)) { // Destroy offset if external reg value is used @@ -4317,71 +4310,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s // Propagate some constants switch (last_inst) { - case spu_itype::IL: - { - bb.reg_const[op.rt] = true; - bb.reg_val32[op.rt] = op.si16; - break; - } - case spu_itype::ILA: - { - bb.reg_const[op.rt] = true; - bb.reg_val32[op.rt] = op.i18; - break; - } - case spu_itype::ILHU: - { - bb.reg_const[op.rt] = true; - bb.reg_val32[op.rt] = op.i16 << 16; - break; - } - case spu_itype::ILH: - { - bb.reg_const[op.rt] = true; - bb.reg_val32[op.rt] = op.i16 << 16 | op.i16; - break; - } - case spu_itype::IOHL: - { - bb.reg_val32[op.rt] = bb.reg_val32[op.rt] | op.i16; - break; - } - case spu_itype::ORI: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra]; - bb.reg_val32[op.rt] = bb.reg_val32[op.ra] | op.si10; - break; - } - case spu_itype::OR: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb]; - bb.reg_val32[op.rt] = bb.reg_val32[op.ra] | bb.reg_val32[op.rb]; - break; - } - case spu_itype::AI: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra]; - bb.reg_val32[op.rt] = bb.reg_val32[op.ra] + op.si10; - break; - } - case spu_itype::A: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb]; - bb.reg_val32[op.rt] = bb.reg_val32[op.ra] + bb.reg_val32[op.rb]; - break; - } - case spu_itype::SFI: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra]; - bb.reg_val32[op.rt] = op.si10 - bb.reg_val32[op.ra]; - break; - } - case spu_itype::SF: - { - bb.reg_const[op.rt] = bb.reg_const[op.ra] && bb.reg_const[op.rb]; - bb.reg_val32[op.rt] = bb.reg_val32[op.rb] - bb.reg_val32[op.ra]; - break; - } case spu_itype::STQD: { if (op.ra == s_reg_sp && bb.stack_sub != 0x80000000 && bb.reg_save_dom[op.rt]) @@ -4410,15 +4338,10 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s bb.reg_load_mod[op.rt] = 0x80000000 + op.si10 * 16 - bb.stack_sub; } - // Clear const - bb.reg_const[op.rt] = false; break; } default: { - // Clear const if reg is modified here - if (u8 reg = m_regmod[ia / 4]; reg < s_reg_max) - bb.reg_const[reg] = false; break; } } @@ -4426,12 +4349,6 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s // $SP is modified if (m_regmod[ia / 4] == s_reg_sp) { - if (bb.reg_const[s_reg_sp]) - { - // Making $SP a constant is a funny thing too. - bb.stack_sub = 0x80000000; - } - if (bb.stack_sub != 0x80000000) { switch (last_inst) @@ -6227,7 +6144,7 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s atomic16.get_rdatomic = true; // Go above and beyond and also set the constant for it - set_const_value(op.rt, MFC_GETLLAR_SUCCESS); + //set_const_value(op.rt, MFC_GETLLAR_SUCCESS); invalidate = false; } } @@ -7066,6 +6983,22 @@ spu_program spu_recompiler_base::analyse(const be_t* ls, u32 entry_point, s fmt::append(func_hash, "%s", fmt::base57(output)); } + for (auto& [addr, block] : infos) + { + auto& bb = ::at32(m_bbs, addr); + + for (u32 i = 0; i < s_reg_max; i++) + { + const auto& reg = block->start_reg_state[i]; + + if (reg.is_const()) + { + bb.reg_const[i] = true; + bb.reg_val32[i] = reg.value; + } + } + } + for (const auto& [pc_commited, pattern] : atomic16_all) { if (!pattern.active)