SPU LLVM: implement bisect helper (debugging tool)

Added two new settings: SPU LLVM Lower/Upper Bound
By manipulating values, conditionally avoid compiling programs.
It uses hash of the programs (64-bit start hash of SHA-1).
Programs which aren't compiled run with interpreter.
This commit is contained in:
Nekotekina 2020-04-04 15:36:05 +03:00
parent 18dbd788e6
commit 8053d2602a
2 changed files with 41 additions and 8 deletions

View File

@ -465,6 +465,29 @@ void spu_cache::initialize()
const u32 start = func.lower_bound;
const u32 size0 = ::size32(func.data);
be_t<u64> hash_start;
{
sha1_context ctx;
u8 output[20];
sha1_starts(&ctx);
sha1_update(&ctx, reinterpret_cast<const u8*>(func.data.data()), func.data.size() * 4);
sha1_finish(&ctx, output);
std::memcpy(&hash_start, output, sizeof(hash_start));
}
// Check hash against allowed bounds
const bool inverse_bounds = g_cfg.core.spu_llvm_lower_bound > g_cfg.core.spu_llvm_upper_bound;
if ((!inverse_bounds && (hash_start < g_cfg.core.spu_llvm_lower_bound || hash_start > g_cfg.core.spu_llvm_upper_bound)) ||
(inverse_bounds && (hash_start < g_cfg.core.spu_llvm_lower_bound && hash_start > g_cfg.core.spu_llvm_upper_bound)))
{
spu_log.error("[Debug] Skipped function %s", fmt::base57(hash_start));
g_progr_pdone++;
result++;
continue;
}
// Initialize LS with function data only
for (u32 i = 0, pos = start; i < size0; i++, pos += 4)
{
@ -8848,7 +8871,15 @@ struct spu_fast : public spu_recompiler_base
// Install pointer carefully
const bool added = !add_loc->compiled && add_loc->compiled.compare_and_swap_test(nullptr, fn);
if (added)
// Check hash against allowed bounds
const bool inverse_bounds = g_cfg.core.spu_llvm_lower_bound > g_cfg.core.spu_llvm_upper_bound;
if ((!inverse_bounds && (m_hash_start < g_cfg.core.spu_llvm_lower_bound || m_hash_start > g_cfg.core.spu_llvm_upper_bound)) ||
(inverse_bounds && (m_hash_start < g_cfg.core.spu_llvm_lower_bound && m_hash_start > g_cfg.core.spu_llvm_upper_bound)))
{
spu_log.error("[Debug] Skipped function %s", fmt::base57(be_t<u64>{m_hash_start}));
}
else if (added)
{
// Send work to LLVM compiler thread
g_fxo->get<spu_llvm_thread>()->registered.push(m_hash_start, add_loc);

View File

@ -52,6 +52,8 @@ struct cfg_root : cfg::node
cfg::_bool hook_functions{ this, "Hook static functions" };
cfg::set_entry load_libraries{ this, "Load libraries" };
cfg::_bool hle_lwmutex{ this, "HLE lwmutex" }; // Force alternative lwmutex/lwcond implementation
cfg::uint64 spu_llvm_lower_bound{ this, "SPU LLVM Lower Bound" };
cfg::uint64 spu_llvm_upper_bound{ this, "SPU LLVM Upper Bound", 0xffff'ffff'ffff'ffff };
cfg::_int<10, 3000> clocks_scale{ this, "Clocks scale", 100, true }; // Changing this from 100 (percentage) may affect game speed in unexpected ways
cfg::_enum<sleep_timers_accuracy_level> sleep_timers_accuracy{ this, "Sleep Timers Accuracy",
@ -75,12 +77,12 @@ struct cfg_root : cfg::node
cfg::string dev_usb000{ this, "/dev_usb000/", "$(EmulatorDir)dev_usb000/" };
cfg::string dev_bdvd{ this, "/dev_bdvd/" }; // Not mounted
cfg::string app_home{ this, "/app_home/" }; // Not mounted
std::string get_dev_flash() const
{
return get(dev_flash, "dev_flash/");
}
cfg::_bool host_root{ this, "Enable /host_root/" };
cfg::_bool init_dirs{ this, "Initialize Directories", true };
@ -135,7 +137,7 @@ struct cfg_root : cfg::node
cfg::_int<0, 30000000> driver_recovery_timeout{ this, "Driver Recovery Timeout", 1000000, true };
cfg::_int<0, 16667> driver_wakeup_delay{ this, "Driver Wake-Up Delay", 1, true };
cfg::_int<1, 1800> vblank_rate{ this, "Vblank Rate", 60, true }; // Changing this from 60 may affect game speed in unexpected ways
cfg::_bool decr_memory_layout{ this, "DECR memory layout", false}; // Force enable increased allowed main memory range as DECR console
cfg::_bool decr_memory_layout{ this, "DECR memory layout", false}; // Force enable increased allowed main memory range as DECR console
struct node_vk : cfg::node
{
@ -252,7 +254,7 @@ struct cfg_root : cfg::node
cfg::_enum<np_psn_status> psn_status{this, "PSN status", np_psn_status::disabled};
cfg::string psn_npid{this, "NPID", ""};
} net{this};
struct node_misc : cfg::node
{
node_misc(cfg::node* _this) : cfg::node(_this, "Miscellaneous") {}
@ -267,11 +269,11 @@ struct cfg_root : cfg::node
cfg::string gdb_server{ this, "GDB Server", "127.0.0.1:2345" };
cfg::_bool silence_all_logs{ this, "Silence All Logs", false, true };
cfg::string title_format{ this, "Window Title Format", "FPS: %F | %R | %V | %T [%t]", true };
} misc{ this };
cfg::log_entry log{ this, "Log" };
std::string name;
};