1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

SPU LLVM: Another fix for Game Collection's precompilation

This commit is contained in:
Eladash 2023-09-01 15:07:46 +03:00 committed by Elad Ashkenazi
parent 26b3970485
commit a9810ccb72
4 changed files with 66 additions and 33 deletions

View File

@ -270,6 +270,30 @@ public:
return {}; return {};
} }
const T& operator[](usz index) const noexcept
{
lf_queue_iterator<T> result = begin();
while (--index != umax)
{
result++;
}
return *result;
}
T& operator[](usz index) noexcept
{
lf_queue_iterator<T> result = begin();
while (--index != umax)
{
result++;
}
return *result;
}
lf_queue_slice& pop_front() lf_queue_slice& pop_front()
{ {
delete std::exchange(m_head, std::exchange(m_head->m_link, nullptr)); delete std::exchange(m_head, std::exchange(m_head->m_link, nullptr));
@ -315,6 +339,23 @@ class lf_queue final
public: public:
constexpr lf_queue() = default; constexpr lf_queue() = default;
lf_queue(lf_queue&& other) noexcept
{
m_head.release(other.m_head.exchange(0));
}
lf_queue& operator=(lf_queue&& other) noexcept
{
if (this == std::addressof(other))
{
return *this;
}
delete load(m_head);
m_head.release(other.m_head.exchange(0));
return *this;
}
~lf_queue() ~lf_queue()
{ {
delete load(m_head); delete load(m_head);

View File

@ -3907,6 +3907,8 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
main_ppu_module& _main = g_fxo->get<main_ppu_module>(); main_ppu_module& _main = g_fxo->get<main_ppu_module>();
_main = {}; _main = {};
auto current_cache = std::move(g_fxo->get<spu_cache>());
if (!ppu_load_exec(obj, true, path)) if (!ppu_load_exec(obj, true, path))
{ {
// Abort // Abort
@ -3916,11 +3918,13 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
if (std::memcmp(main_module.sha1, _main.sha1, sizeof(_main.sha1)) == 0) if (std::memcmp(main_module.sha1, _main.sha1, sizeof(_main.sha1)) == 0)
{ {
g_fxo->get<spu_cache>() = std::move(current_cache);
break; break;
} }
if (!_main.analyse(0, _main.elf_entry, _main.seg0_code_end, _main.applied_pathes, [](){ return Emu.IsStopped(); })) if (!_main.analyse(0, _main.elf_entry, _main.seg0_code_end, _main.applied_pathes, [](){ return Emu.IsStopped(); }))
{ {
g_fxo->get<spu_cache>() = std::move(current_cache);
break; break;
} }
@ -3929,8 +3933,10 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
_main.name = ' '; // Make ppu_finalize work _main.name = ' '; // Make ppu_finalize work
Emu.ConfigurePPUCache(!Emu.IsPathInsideDir(_main.path, g_cfg_vfs.get_dev_flash())); Emu.ConfigurePPUCache(!Emu.IsPathInsideDir(_main.path, g_cfg_vfs.get_dev_flash()));
ppu_initialize(_main); ppu_initialize(_main);
spu_cache::initialize(false);
ppu_finalize(_main); ppu_finalize(_main);
_main = {}; _main = {};
g_fxo->get<spu_cache>() = std::move(current_cache);
break; break;
} }
@ -3945,6 +3951,7 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
} }
g_fxo->get<main_ppu_module>() = std::move(main_module); g_fxo->get<main_ppu_module>() = std::move(main_module);
g_fxo->get<spu_cache>().collect_funcs_to_precompile = true;
Emu.ConfigurePPUCache(); Emu.ConfigurePPUCache();
}); });

View File

@ -516,20 +516,6 @@ spu_cache::~spu_cache()
{ {
} }
struct spu_section_data
{
struct data_t
{
u32 vaddr;
std::basic_string<u32> inst_data;
std::vector<u32> funcs;
};
shared_mutex mtx;
atomic_t<bool> had_been_used = false;
std::vector<data_t> data;
};
extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 size) extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 size)
{ {
if (vaddr % 4) if (vaddr % 4)
@ -549,9 +535,9 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
return; return;
} }
g_fxo->need<spu_section_data>(); g_fxo->need<spu_cache>();
if (g_fxo->get<spu_section_data>().had_been_used) if (!g_fxo->get<spu_cache>().collect_funcs_to_precompile)
{ {
return; return;
} }
@ -559,7 +545,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
std::basic_string<u32> data(size / 4, 0); std::basic_string<u32> data(size / 4, 0);
std::memcpy(data.data(), ls_data_vaddr, size); std::memcpy(data.data(), ls_data_vaddr, size);
spu_section_data::data_t obj{vaddr, std::move(data)}; spu_cache::precompile_data_t obj{vaddr, std::move(data)};
obj.funcs = spu_thread::discover_functions(vaddr, { reinterpret_cast<const u8*>(ls_data_vaddr), size }, vaddr != 0, umax); obj.funcs = spu_thread::discover_functions(vaddr, { reinterpret_cast<const u8*>(ls_data_vaddr), size }, vaddr != 0, umax);
@ -576,19 +562,7 @@ extern void utilize_spu_data_segment(u32 vaddr, const void* ls_data_vaddr, u32 s
spu_log.notice("Found %u SPU functions", obj.funcs.size()); spu_log.notice("Found %u SPU functions", obj.funcs.size());
std::lock_guard lock(g_fxo->get<spu_section_data>().mtx); g_fxo->get<spu_cache>().precompile_funcs.push(std::move(obj));
for (const auto& data : g_fxo->get<spu_section_data>().data)
{
// TODO: More robust duplicates filtering
if (data.vaddr == vaddr && data.inst_data.starts_with(obj.inst_data))
{
spu_log.notice("Avoided duplicate SPU segment");
return;
}
}
g_fxo->get<spu_section_data>().data.emplace_back(std::move(obj));
} }
std::deque<spu_program> spu_cache::get() std::deque<spu_program> spu_cache::get()
@ -693,8 +667,8 @@ void spu_cache::initialize(bool build_existing_cache)
atomic_t<usz> fnext{}; atomic_t<usz> fnext{};
atomic_t<u8> fail_flag{0}; atomic_t<u8> fail_flag{0};
auto data_list = std::move(g_fxo->get<spu_section_data>().data); auto data_list = g_fxo->get<spu_cache>().precompile_funcs.pop_all();
g_fxo->get<spu_section_data>().had_been_used = true; g_fxo->get<spu_cache>().collect_funcs_to_precompile = false;
u32 total_precompile = 0; u32 total_precompile = 0;
@ -717,7 +691,7 @@ void spu_cache::initialize(bool build_existing_cache)
else else
{ {
total_precompile = 0; total_precompile = 0;
data_list.clear(); data_list = {};
} }
atomic_t<usz> data_indexer = 0; atomic_t<usz> data_indexer = 0;

View File

@ -35,6 +35,17 @@ public:
void add(const struct spu_program& func); void add(const struct spu_program& func);
static void initialize(bool build_existing_cache = true); static void initialize(bool build_existing_cache = true);
struct precompile_data_t
{
u32 vaddr;
std::basic_string<u32> inst_data;
std::vector<u32> funcs;
};
bool collect_funcs_to_precompile = true;
lf_queue<precompile_data_t> precompile_funcs;
}; };
struct spu_program struct spu_program