mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 03:32:55 +00:00
SPU/Savestates: Remove reservation hack, allow its saving
This commit is contained in:
parent
e209dc1229
commit
9f6c5381a1
@ -4521,6 +4521,18 @@ class spu_llvm_recompiler : public spu_recompiler_base, public cpu_translator
|
||||
std::array<usz, s_reg_max> store_context_last_id = fill_array<usz>(0); // Protects against illegal forward ordering
|
||||
std::array<usz, s_reg_max> store_context_first_id = fill_array<usz>(usz{umax}); // Protects against illegal past store elimination (backwards ordering is not implemented)
|
||||
std::array<usz, s_reg_max> store_context_ctr = fill_array<usz>(1); // Store barrier cointer
|
||||
|
||||
bool does_gpr_barrier_proceed_last_store(u32 i) const noexcept
|
||||
{
|
||||
const usz counter = store_context_ctr[i];
|
||||
return counter != 1 && counter > store_context_last_id[i];
|
||||
}
|
||||
|
||||
bool does_gpr_barrier_preceed_first_store(u32 i) const noexcept
|
||||
{
|
||||
const usz counter = store_context_ctr[i];
|
||||
return counter != 1 && counter < store_context_first_id[i];
|
||||
}
|
||||
};
|
||||
|
||||
struct function_info
|
||||
@ -6019,7 +6031,7 @@ public:
|
||||
for (u32 i = 0; i < 128; i++)
|
||||
{
|
||||
// Check if the store is beyond the last barrier
|
||||
if (auto& bs = bqbi->store[i]; bs && bqbi->store_context_last_id[i] == bqbi->store_context_ctr[i])
|
||||
if (auto& bs = bqbi->store[i]; bs && !bqbi->does_gpr_barrier_proceed_last_store(i))
|
||||
{
|
||||
for (auto& [a, b] : m_blocks)
|
||||
{
|
||||
@ -6107,7 +6119,7 @@ public:
|
||||
auto* cur = work_list[wi];
|
||||
if (std::count(killers.begin(), killers.end(), cur))
|
||||
{
|
||||
work2_list.emplace_back(cur, bb_to_info[cur] && bb_to_info[cur]->store_context_first_id[i] > 1);
|
||||
work2_list.emplace_back(cur, bb_to_info[cur] && bb_to_info[cur]->does_gpr_barrier_preceed_first_store(i));
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -6145,17 +6157,7 @@ public:
|
||||
{
|
||||
auto [cur, found_user] = work2_list[wi];
|
||||
|
||||
if (cur == bs->getParent())
|
||||
{
|
||||
if (found_user)
|
||||
{
|
||||
// Reset: store is being used and preserved by ensure_gpr_stores()
|
||||
killers.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
ensure(cur != bs->getParent());
|
||||
|
||||
if (!found_user && wi >= work_list_tail_blocks_max_index)
|
||||
{
|
||||
@ -6170,6 +6172,18 @@ public:
|
||||
|
||||
for (auto* p : llvm::predecessors(cur))
|
||||
{
|
||||
if (p == bs->getParent())
|
||||
{
|
||||
if (found_user)
|
||||
{
|
||||
// Reset: store is being used and preserved by ensure_gpr_stores()
|
||||
killers.clear();
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!worked_on[p])
|
||||
{
|
||||
worked_on[p] = true;
|
||||
@ -6181,6 +6195,11 @@ public:
|
||||
work2_list.push_back(std::make_pair(p, true));
|
||||
}
|
||||
}
|
||||
|
||||
if (killers.empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Finally erase the dead store
|
||||
@ -6207,7 +6226,7 @@ public:
|
||||
for (u32 i = 0; i < 128; i++)
|
||||
{
|
||||
// If store isn't erased, try to sink it
|
||||
if (auto& bs = block_q[bi]->store[i]; bs && block_q[bi]->bb->targets.size() > 1 && block_q[bi]->store_context_last_id[i] == block_q[bi]->store_context_ctr[i])
|
||||
if (auto& bs = block_q[bi]->store[i]; bs && block_q[bi]->bb->targets.size() > 1 && !block_q[bi]->does_gpr_barrier_proceed_last_store(i))
|
||||
{
|
||||
std::map<u32, block_info*, std::greater<>> sucs;
|
||||
|
||||
|
@ -2022,6 +2022,20 @@ spu_thread::spu_thread(utils::serial& ar, lv2_spu_group* group)
|
||||
|
||||
serialize_common(ar);
|
||||
|
||||
raddr = ::narrow<u32>(ar.pop<u64>());
|
||||
|
||||
if (raddr)
|
||||
{
|
||||
// Acquire reservation
|
||||
if (!vm::check_addr(raddr))
|
||||
{
|
||||
fmt::throw_exception("SPU Serialization: Reservation address is not accessible! (addr=0x%x)", raddr);
|
||||
}
|
||||
|
||||
rtime = vm::reservation_acquire(raddr);
|
||||
mov_rdata(rdata, *vm::get_super_ptr<spu_rdata_t>(raddr));
|
||||
}
|
||||
|
||||
status_npc.raw().npc = pc | u8{interrupts_enabled};
|
||||
|
||||
if (get_type() == spu_type::threaded)
|
||||
@ -2058,8 +2072,8 @@ void spu_thread::save(utils::serial& ar)
|
||||
|
||||
if (raddr)
|
||||
{
|
||||
// Lose reservation at savestate load with an event if one existed at savestate save
|
||||
set_events(SPU_EVENT_LR);
|
||||
// Last check for reservation-lost event
|
||||
get_events(SPU_EVENT_LR);
|
||||
}
|
||||
|
||||
ar(index);
|
||||
@ -2073,6 +2087,9 @@ void spu_thread::save(utils::serial& ar)
|
||||
|
||||
serialize_common(ar);
|
||||
|
||||
// Let's save it as u64 for future proofing
|
||||
ar(u64{raddr});
|
||||
|
||||
if (get_type() == spu_type::threaded)
|
||||
{
|
||||
for (const auto& [key, q] : spuq)
|
||||
|
Loading…
x
Reference in New Issue
Block a user