Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PPU LLVM: implement ppu_finalize #9662

Merged
merged 1 commit into from Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
98 changes: 78 additions & 20 deletions rpcs3/Emu/Cell/PPUThread.cpp
Expand Up @@ -110,6 +110,7 @@ const ppu_decoder<ppu_interpreter_fast> g_ppu_interpreter_fast;
const ppu_decoder<ppu_itype> g_ppu_itype;

extern void ppu_initialize();
extern void ppu_finalize(const ppu_module& info);
extern void ppu_initialize(const ppu_module& info);
static void ppu_initialize2(class jit_compiler& jit, const ppu_module& module_part, const std::string& cache_path, const std::string& obj_name);
extern void ppu_execute_syscall(ppu_thread& ppu, u64 code);
Expand Down Expand Up @@ -1921,6 +1922,83 @@ extern bool ppu_stdcx(ppu_thread& ppu, u32 addr, u64 reg_value)
return ppu_store_reservation<u64>(ppu, addr, reg_value);
}

#ifdef LLVM_AVAILABLE
namespace
{
// Compiled PPU module info
struct jit_module
{
std::vector<u64*> vars;
std::vector<ppu_function_t> funcs;
std::shared_ptr<jit_compiler> pjit;
};

struct jit_module_manager
{
shared_mutex mutex;
std::unordered_map<std::string, jit_module> map;

jit_module& get(const std::string& name)
{
std::lock_guard lock(mutex);
return map.emplace(name, jit_module{}).first->second;
}

void remove(const std::string& name) noexcept
{
std::lock_guard lock(mutex);

const auto found = map.find(name);

if (found == map.end()) [[unlikely]]
{
ppu_log.error("Failed to remove module %s", name);
return;
}

map.erase(found);
}
};
}
#endif

extern void ppu_finalize(const ppu_module& info)
{
// Get cache path for this executable
std::string cache_path;

if (info.name.empty())
{
// Don't remove main module from memory
return;
}
else
{
// Get PPU cache location
cache_path = fs::get_cache_dir() + "cache/";

const std::string dev_flash = vfs::get("/dev_flash/");

if (info.path.starts_with(dev_flash) || Emu.GetCat() == "1P")
{
// Don't remove dev_flash prx from memory
return;
}
else if (!Emu.GetTitleID().empty())
{
cache_path += Emu.GetTitleID();
cache_path += '/';
}

// Add PPU hash and filename
fmt::append(cache_path, "ppu-%s-%s/", fmt::base57(info.sha1), info.path.substr(info.path.find_last_of('/') + 1));
}

#ifdef LLVM_AVAILABLE
g_fxo->get<jit_module_manager>()->remove(cache_path + info.name);
#endif
}

extern void ppu_initialize()
{
const auto _main = g_fxo->get<ppu_module>();
Expand Down Expand Up @@ -2056,14 +2134,6 @@ extern void ppu_initialize(const ppu_module& info)
// Initialize progress dialog
g_progr = "Compiling PPU modules...";

// Compiled PPU module info
struct jit_module
{
std::vector<u64*> vars;
std::vector<ppu_function_t> funcs;
std::shared_ptr<jit_compiler> pjit;
};

struct jit_core_allocator
{
const s32 thread_count = g_cfg.core.llvm_threads ? std::min<s32>(g_cfg.core.llvm_threads, limit()) : limit();
Expand All @@ -2077,18 +2147,6 @@ extern void ppu_initialize(const ppu_module& info)
}
};

struct jit_module_manager
{
shared_mutex mutex;
std::unordered_map<std::string, jit_module> map;

jit_module& get(const std::string& name)
{
std::lock_guard lock(mutex);
return map.emplace(name, jit_module{}).first->second;
}
};

// Permanently loaded compiled PPU modules (name -> data)
jit_module& jit_mod = g_fxo->get<jit_module_manager>()->get(cache_path + info.name);

Expand Down
3 changes: 3 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_overlay.cpp
Expand Up @@ -15,6 +15,7 @@
extern std::shared_ptr<lv2_overlay> ppu_load_overlay(const ppu_exec_object&, const std::string& path);

extern void ppu_initialize(const ppu_module&);
extern void ppu_finalize(const ppu_module&);

LOG_CHANNEL(sys_overlay);

Expand Down Expand Up @@ -118,5 +119,7 @@ error_code sys_overlay_unload_module(u32 ovlmid)
vm::dealloc(seg.addr);
}

ppu_finalize(*_main);

return CELL_OK;
}
3 changes: 3 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_prx.cpp
Expand Up @@ -18,6 +18,7 @@
extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, const std::string&);
extern void ppu_unload_prx(const lv2_prx& prx);
extern void ppu_initialize(const ppu_module&);
extern void ppu_finalize(const ppu_module&);

LOG_CHANNEL(sys_prx);

Expand Down Expand Up @@ -590,6 +591,8 @@ error_code _sys_prx_unload_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sy

ppu_unload_prx(*prx);

ppu_finalize(*prx);

//s32 result = prx->exit ? prx->exit() : CELL_OK;

return CELL_OK;
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/Emu/System.cpp
Expand Up @@ -69,6 +69,7 @@ atomic_t<u64> g_watchdog_hold_ctr{0};
extern void ppu_load_exec(const ppu_exec_object&);
extern void spu_load_exec(const spu_exec_object&);
extern void ppu_initialize(const ppu_module&);
extern void ppu_finalize(const ppu_module&);
extern void ppu_unload_prx(const lv2_prx&);
extern std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object&, const std::string&);

Expand Down Expand Up @@ -1227,6 +1228,8 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
idm::remove<lv2_obj, lv2_prx>(idm::last_id());
lock.lock();
ppu_unload_prx(*prx);
lock.unlock();
ppu_finalize(*prx);
g_progr_fdone++;
continue;
}
Expand Down