SPU: Use bitset to reduce memory for compiler instance

This commit is contained in:
Eladash 2024-04-12 15:35:28 +03:00 committed by Elad Ashkenazi
parent 622894a7e3
commit 7dc4ccc87d
2 changed files with 15 additions and 17 deletions

View file

@ -2482,9 +2482,9 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
workload.push_back(entry_point); workload.push_back(entry_point);
std::memset(m_regmod.data(), 0xff, sizeof(m_regmod)); std::memset(m_regmod.data(), 0xff, sizeof(m_regmod));
std::memset(m_use_ra.data(), 0xff, sizeof(m_use_ra)); m_use_ra.reset();
std::memset(m_use_rb.data(), 0xff, sizeof(m_use_rb)); m_use_rb.reset();
std::memset(m_use_rc.data(), 0xff, sizeof(m_use_rc)); m_use_rc.reset();
m_targets.clear(); m_targets.clear();
m_preds.clear(); m_preds.clear();
m_preds[entry_point]; m_preds[entry_point];
@ -2579,11 +2579,11 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
if (auto iflags = g_spu_iflag.decode(data)) if (auto iflags = g_spu_iflag.decode(data))
{ {
if (+iflags & +spu_iflag::use_ra) if (+iflags & +spu_iflag::use_ra)
m_use_ra[pos / 4] = op.ra; m_use_ra.set(pos / 4);
if (+iflags & +spu_iflag::use_rb) if (+iflags & +spu_iflag::use_rb)
m_use_rb[pos / 4] = op.rb; m_use_rb.set(pos / 4);
if (+iflags & +spu_iflag::use_rc) if (+iflags & +spu_iflag::use_rc)
m_use_rc[pos / 4] = op.rc; m_use_rc.set(pos / 4);
} }
// Analyse instruction // Analyse instruction
@ -3010,11 +3010,6 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
m_regmod[pos / 4] = s_reg_mfc_size; m_regmod[pos / 4] = s_reg_mfc_size;
break; break;
} }
case MFC_Cmd:
{
m_use_rb[pos / 4] = s_reg_mfc_eal;
break;
}
default: break; default: break;
} }
@ -3461,10 +3456,13 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
reg_save = op.rt; reg_save = op.rt;
} }
for (auto* _use : {&m_use_ra, &m_use_rb, &m_use_rc}) for (auto _use : std::initializer_list<std::pair<u32, bool>>{{op.ra, m_use_ra.test(ia / 4)}
, {op.rb, m_use_rb.test(ia / 4)}, {op.rc, m_use_rc.test(ia / 4)}})
{ {
if (u8 reg = (*_use)[ia / 4]; reg < s_reg_max) if (_use.second)
{ {
const u32 reg = _use.first;
// Register reg use only if it happens before reg mod // Register reg use only if it happens before reg mod
if (!block.reg_mod[reg]) if (!block.reg_mod[reg])
{ {
@ -3479,7 +3477,7 @@ spu_program spu_recompiler_base::analyse(const be_t<u32>* ls, u32 entry_point, s
} }
} }
if (m_use_rb[ia / 4] == s_reg_mfc_eal) if (type == spu_itype::WRCH && op.ra == MFC_Cmd)
{ {
// Expand MFC_Cmd reg use // Expand MFC_Cmd reg use
for (u8 reg : {s_reg_mfc_lsa, s_reg_mfc_tag, s_reg_mfc_size}) for (u8 reg : {s_reg_mfc_lsa, s_reg_mfc_tag, s_reg_mfc_size})

View file

@ -202,9 +202,9 @@ protected:
// GPR modified by the instruction (-1 = not set) // GPR modified by the instruction (-1 = not set)
std::array<u8, 0x10000> m_regmod; std::array<u8, 0x10000> m_regmod;
std::array<u8, 0x10000> m_use_ra; std::bitset<0x10000> m_use_ra;
std::array<u8, 0x10000> m_use_rb; std::bitset<0x10000> m_use_rb;
std::array<u8, 0x10000> m_use_rc; std::bitset<0x10000> m_use_rc;
// List of possible targets for the instruction (entry shouldn't exist for simple instructions) // List of possible targets for the instruction (entry shouldn't exist for simple instructions)
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_targets; std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_targets;