LLVM: progress dialog

This commit is contained in:
Nekotekina 2017-01-22 22:03:57 +03:00 committed by Ivan
parent 6cf006b02b
commit 78ecb115f3
3 changed files with 72 additions and 18 deletions

View File

@ -116,8 +116,6 @@ extern std::string ppu_get_variable_name(const std::string& module, u32 vnid);
extern void sys_initialize_tls(ppu_thread&, u64, u32, u32, u32); extern void sys_initialize_tls(ppu_thread&, u64, u32, u32, u32);
extern void ppu_initialize(const std::string& name, const std::vector<ppu_function>& set);
extern u32 g_ps3_sdk_version; extern u32 g_ps3_sdk_version;
// Function lookup table. Not supposed to grow after emulation start. // Function lookup table. Not supposed to grow after emulation start.
@ -1278,17 +1276,17 @@ void ppu_load_exec(const ppu_exec_object& elf)
} }
// Analyse executable // Analyse executable
const auto funcs = ppu_analyse(segments, sections, 0); std::vector<ppu_function> main_funcs = ppu_analyse(segments, sections, 0);
ppu_validate(vfs::get(Emu.GetPath()), funcs, 0); ppu_validate(vfs::get(Emu.GetPath()), main_funcs, 0);
for (const auto& pair : funcs) // Append
{ exec_set.insert(exec_set.cend(),
exec_set.emplace_back(pair); std::make_move_iterator(main_funcs.begin()),
} std::make_move_iterator(main_funcs.end()));
// Initialize interpreter/recompiler // Share function list
ppu_initialize("", exec_set); fxm::make<std::vector<ppu_function>>(std::move(exec_set));
// Set SDK version // Set SDK version
g_ps3_sdk_version = sdk_version; g_ps3_sdk_version = sdk_version;
@ -1315,6 +1313,8 @@ void ppu_load_exec(const ppu_exec_object& elf)
// Initialize main thread // Initialize main thread
auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize); auto ppu = idm::make_ptr<ppu_thread>("main_thread", primary_prio, primary_stacksize);
ppu->cmd_push({ppu_cmd::initialize, 0});
// TODO: adjust for liblv2 loading option // TODO: adjust for liblv2 loading option
if (!g_cfg_load_liblv2) if (!g_cfg_load_liblv2)
{ {

View File

@ -38,6 +38,7 @@
#include "Utilities/JIT.h" #include "Utilities/JIT.h"
#include "PPUTranslator.h" #include "PPUTranslator.h"
#include "Modules/cellMsgDialog.h"
#endif #endif
enum class ppu_decoder_type enum class ppu_decoder_type
@ -57,6 +58,7 @@ cfg::map_entry<ppu_decoder_type> g_cfg_ppu_decoder(cfg::root.core, "PPU Decoder"
const ppu_decoder<ppu_interpreter_precise> s_ppu_interpreter_precise; const ppu_decoder<ppu_interpreter_precise> s_ppu_interpreter_precise;
const ppu_decoder<ppu_interpreter_fast> s_ppu_interpreter_fast; const ppu_decoder<ppu_interpreter_fast> s_ppu_interpreter_fast;
static void ppu_initialize();
extern void ppu_execute_syscall(ppu_thread& ppu, u64 code); extern void ppu_execute_syscall(ppu_thread& ppu, u64 code);
extern void ppu_execute_function(ppu_thread& ppu, u32 index); extern void ppu_execute_function(ppu_thread& ppu, u32 index);
@ -164,6 +166,11 @@ void ppu_thread::cpu_task()
cmd_pop(), ppu_execute_function(*this, arg); cmd_pop(), ppu_execute_function(*this, arg);
break; break;
} }
case ppu_cmd::initialize:
{
cmd_pop(), ppu_initialize();
break;
}
default: default:
{ {
fmt::throw_exception("Unknown ppu_cmd(0x%x)" HERE, (u32)type); fmt::throw_exception("Unknown ppu_cmd(0x%x)" HERE, (u32)type);
@ -510,9 +517,11 @@ static bool adde_carry(u64 a, u64 b, bool c)
#endif #endif
} }
extern void ppu_initialize(const std::string& name, const std::vector<ppu_function>& funcs) static void ppu_initialize()
{ {
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || funcs.empty()) const auto _funcs = fxm::get_always<std::vector<ppu_function>>();
if (g_cfg_ppu_decoder.get() != ppu_decoder_type::llvm || _funcs->empty())
{ {
if (!Emu.GetCPUThreadStop()) if (!Emu.GetCPUThreadStop())
{ {
@ -555,7 +564,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
using namespace llvm; using namespace llvm;
// Create LLVM module // Create LLVM module
std::unique_ptr<Module> module = std::make_unique<Module>(name, g_llvm_ctx); std::unique_ptr<Module> module = std::make_unique<Module>("", g_llvm_ctx);
// Initialize target // Initialize target
module->setTargetTriple(Triple::normalize(sys::getProcessTriple())); module->setTargetTriple(Triple::normalize(sys::getProcessTriple()));
@ -568,7 +577,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
const auto _func = FunctionType::get(_void, { translator->GetContextType()->getPointerTo() }, false); const auto _func = FunctionType::get(_void, { translator->GetContextType()->getPointerTo() }, false);
// Initialize function list // Initialize function list
for (const auto& info : funcs) for (const auto& info : *_funcs)
{ {
if (info.size) if (info.size)
{ {
@ -608,11 +617,48 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
pm.add(createCFGSimplificationPass()); pm.add(createCFGSimplificationPass());
//pm.add(createLintPass()); // Check //pm.add(createLintPass()); // Check
// Translate functions // Initialize message dialog
for (const auto& info : funcs) const auto dlg = Emu.GetCallbacks().get_msg_dialog();
dlg->type.se_normal = true;
dlg->type.bg_invisible = true;
dlg->type.progress_bar_count = 1;
dlg->on_close = [](s32 status)
{ {
Emu.CallAfter([]()
{
// Abort everything
Emu.Stop();
});
};
Emu.CallAfter([=]()
{
dlg->Create("Recompiling PPU executable.\nPlease wait...");
});
// Translate functions
for (size_t fi = 0; fi < _funcs->size(); fi++)
{
if (Emu.IsStopped())
{
LOG_SUCCESS(PPU, "LLVM: Translation cancelled");
return;
}
auto& info = _funcs->at(fi);
if (info.size) if (info.size)
{ {
// Update dialog
Emu.CallAfter([=, max = _funcs->size()]()
{
dlg->ProgressBarSetMsg(0, fmt::format("Compiling %u of %u", fi + 1, max));
if (fi * 100 / max != (fi + 1) * 100 / max)
dlg->ProgressBarInc(0, 1);
});
// Translate
const auto func = translator->TranslateToIR(info, vm::_ptr<u32>(info.addr)); const auto func = translator->TranslateToIR(info, vm::_ptr<u32>(info.addr));
// Run optimization passes // Run optimization passes
@ -699,6 +745,13 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
mpm.add(createDeadInstEliminationPass()); mpm.add(createDeadInstEliminationPass());
mpm.run(*module); mpm.run(*module);
// Update dialog
Emu.CallAfter([=]()
{
dlg->ProgressBarSetMsg(0, "Generating code...");
dlg->ProgressBarInc(0, 100);
});
std::string result; std::string result;
raw_string_ostream out(result); raw_string_ostream out(result);
@ -711,7 +764,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
if (verifyModule(*module, &out)) if (verifyModule(*module, &out))
{ {
out.flush(); out.flush();
LOG_ERROR(PPU, "{%s} LLVM: Translation failed:\n%s", name, result); LOG_ERROR(PPU, "LLVM: Translation failed:\n%s", result);
return; return;
} }
@ -730,7 +783,7 @@ extern void ppu_initialize(const std::string& name, const std::vector<ppu_functi
memory_helper::free_reserved_memory(s_ppu_compiled, 0x100000000); // TODO memory_helper::free_reserved_memory(s_ppu_compiled, 0x100000000); // TODO
// Get and install function addresses // Get and install function addresses
for (const auto& info : funcs) for (const auto& info : *_funcs)
{ {
if (info.size) if (info.size)
{ {

View File

@ -14,6 +14,7 @@ enum class ppu_cmd : u32
set_args, // Set general-purpose args (+arg cmd) set_args, // Set general-purpose args (+arg cmd)
lle_call, // Load addr and rtoc at *arg or *gpr[arg] and execute lle_call, // Load addr and rtoc at *arg or *gpr[arg] and execute
hle_call, // Execute function by index (arg) hle_call, // Execute function by index (arg)
initialize, // ppu_initialize()
}; };
class ppu_thread : public cpu_thread class ppu_thread : public cpu_thread