Skip to content

Commit

Permalink
Implement SPU recompiler cache
Browse files Browse the repository at this point in the history
Shared between ASMJIT/LLVM recompilers
Cache is compiled at startup
SPU LLVM loads cache but doesn't create it (temporary limitation)
  • Loading branch information
Nekotekina committed May 6, 2018
1 parent e27ab4e commit c4233a4
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 40 deletions.
16 changes: 16 additions & 0 deletions rpcs3/Emu/Cell/PPUThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "PPUInterpreter.h"
#include "PPUAnalyser.h"
#include "PPUModule.h"
#include "SPURecompiler.h"
#include "lv2/sys_sync.h"
#include "lv2/sys_prx.h"
#include "Utilities/GDBDebugServer.h"
Expand Down Expand Up @@ -1086,6 +1087,21 @@ extern void ppu_initialize()
return;
}

// New PPU cache location
const std::string ppu_cache = fmt::format("%sdata/%s/ppu-%s-%s/",
fs::get_config_dir(),
Emu.GetTitleID(),
fmt::base57(_main->sha1),
Emu.GetBoot().substr(Emu.GetBoot().find_last_of('/') + 1));

if (!fs::create_path(ppu_cache))
{
fmt::throw_exception("Failed to create cache directory: %s (%s)", ppu_cache, fs::g_tls_error);
}

// Initialize SPU cache
spu_cache::initialize(ppu_cache);

// Initialize main module
ppu_initialize(*_main);

Expand Down
27 changes: 18 additions & 9 deletions rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,20 @@ spu_function_t spu_recompiler::get(u32 lsa)
// Initialize if necessary
if (!m_spurt)
{
m_cache = fxm::get<spu_cache>();
m_spurt = fxm::get_always<spu_runtime>();
}

// Simple atomic read
return m_spurt->m_dispatcher[lsa / 4];
}

spu_function_t spu_recompiler::compile(const std::vector<u32>& func)
spu_function_t spu_recompiler::compile(std::vector<u32>&& func_rv)
{
// Initialize if necessary
if (!m_spurt)
{
m_cache = fxm::get<spu_cache>();
m_spurt = fxm::get_always<spu_runtime>();
}

Expand All @@ -80,16 +82,18 @@ spu_function_t spu_recompiler::compile(const std::vector<u32>& func)
lock.lock();
}

// Try to find existing function
{
const auto found = m_spurt->m_map.find(func);
// Try to find existing function, register new one if necessary
const auto fn_info = m_spurt->m_map.emplace(std::move(func_rv), nullptr);

if (found != m_spurt->m_map.end() && found->second)
{
return found->second;
}
auto& fn_location = fn_info.first->second;

if (fn_location)
{
return fn_location;
}

auto& func = fn_info.first->first;

using namespace asmjit;

SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode);
Expand Down Expand Up @@ -811,7 +815,7 @@ spu_function_t spu_recompiler::compile(const std::vector<u32>& func)
}

// Register function
m_spurt->m_map[func] = fn;
fn_location = fn;

// Generate a dispatcher (übertrampoline)
std::vector<u32> addrv{func[0]};
Expand Down Expand Up @@ -1043,6 +1047,11 @@ spu_function_t spu_recompiler::compile(const std::vector<u32>& func)
fs::file(Emu.GetCachePath() + "SPUJIT.log", fs::write + fs::append).write(log);
}

if (m_cache)
{
m_cache->add(func);
}

return fn;
}

Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/SPUASMJITRecompiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class spu_recompiler : public spu_recompiler_base

virtual spu_function_t get(u32 lsa) override;

virtual spu_function_t compile(const std::vector<u32>& func) override;
virtual spu_function_t compile(std::vector<u32>&&) override;

private:
// emitter:
Expand Down
Loading

0 comments on commit c4233a4

Please sign in to comment.