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:
parent
26b3970485
commit
a9810ccb72
@ -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);
|
||||||
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user