From cde64b6a3d174e3e5e92fa399286fa9513d8fce6 Mon Sep 17 00:00:00 2001 From: mitaclaw <140017135+mitaclaw@users.noreply.github.com> Date: Sat, 20 Apr 2024 02:01:07 -0700 Subject: [PATCH] CachedInterpreter: Software JIT Profiling Support --- .../CachedInterpreter/CachedInterpreter.cpp | 41 +++++++++++++++---- .../CachedInterpreter/CachedInterpreter.h | 22 +++++++++- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 0960b77fb7..594f560f10 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -89,12 +89,23 @@ void CachedInterpreter::SingleStep() ExecuteOneBlock(); } -s32 CachedInterpreter::EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands& operands) +s32 CachedInterpreter::StartProfiledBlock(PowerPC::PowerPCState& ppc_state, + const StartProfiledBlockOperands& operands) +{ + JitBlock::ProfileData::BeginProfiling(operands.profile_data); + return sizeof(AnyCallback) + sizeof(operands); +} + +template +s32 CachedInterpreter::EndBlock(PowerPC::PowerPCState& ppc_state, + const EndBlockOperands& operands) { - const auto& [downcount, num_load_stores, num_fp_inst] = operands; ppc_state.pc = ppc_state.npc; - ppc_state.downcount -= downcount; - PowerPC::UpdatePerformanceMonitor(downcount, num_load_stores, num_fp_inst, ppc_state); + ppc_state.downcount -= operands.downcount; + PowerPC::UpdatePerformanceMonitor(operands.downcount, operands.num_load_stores, + operands.num_fp_inst, ppc_state); + if constexpr (profiled) + JitBlock::ProfileData::EndProfiling(operands.profile_data, operands.downcount); return 0; } @@ -200,10 +211,23 @@ bool CachedInterpreter::HandleFunctionHooking(u32 address) return false; js.downcountAmount += js.st.numCycles; - Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst}); + WriteEndBlock(); return true; } +void CachedInterpreter::WriteEndBlock() +{ + if (IsProfilingEnabled()) + { + Write(EndBlock, {{js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst}, + js.curBlock->profile_data.get()}); + } + else + { + Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst}); + } +} + bool CachedInterpreter::SetEmitterStateToFreeCodeRegion() { const auto free = m_free_ranges.by_size_begin(); @@ -306,6 +330,9 @@ bool CachedInterpreter::DoJit(u32 em_address, JitBlock* b, u32 nextPC) auto& cpu = m_system.GetCPU(); auto& breakpoints = power_pc.GetBreakPoints(); + if (IsProfilingEnabled()) + Write(StartProfiledBlock, {js.curBlock->profile_data.get()}); + for (u32 i = 0; i < code_block.m_num_instructions; i++) { PPCAnalyst::CodeOp& op = m_code_buffer[i]; @@ -357,13 +384,13 @@ bool CachedInterpreter::DoJit(u32 em_address, JitBlock* b, u32 nextPC) if (op.branchIsIdleLoop) Write(CheckIdle, {m_system.GetCoreTiming(), js.blockStart}); if (op.canEndBlock) - Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst}); + WriteEndBlock(); } } if (code_block.m_broken) { Write(WriteBrokenBlockNPC, {nextPC}); - Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst}); + WriteEndBlock(); } if (HasWriteFailed()) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h index 8b4752dbb8..92da1cd473 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h @@ -54,6 +54,7 @@ private: void ExecuteOneBlock(); bool HandleFunctionHooking(u32 address); + void WriteEndBlock(); // Finds a free memory region and sets the code emitter to point at that region. // Returns false if no free memory region can be found. @@ -62,6 +63,8 @@ private: void FreeRanges(); void ResetFreeMemoryRanges(); + struct StartProfiledBlockOperands; + template struct EndBlockOperands; struct InterpretOperands; struct InterpretAndCheckExceptionsOperands; @@ -70,7 +73,10 @@ private: struct CheckHaltOperands; struct CheckIdleOperands; - static s32 EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands& operands); + static s32 StartProfiledBlock(PowerPC::PowerPCState& ppc_state, + const StartProfiledBlockOperands& profile_data); + template + static s32 EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands& operands); template static s32 Interpret(PowerPC::PowerPCState& ppc_state, const InterpretOperands& operands); template @@ -87,7 +93,13 @@ private: CachedInterpreterBlockCache m_block_cache; }; -struct CachedInterpreter::EndBlockOperands +struct CachedInterpreter::StartProfiledBlockOperands +{ + JitBlock::ProfileData* profile_data; +}; + +template <> +struct CachedInterpreter::EndBlockOperands { u32 downcount; u32 num_load_stores; @@ -95,6 +107,12 @@ struct CachedInterpreter::EndBlockOperands u32 : 32; }; +template <> +struct CachedInterpreter::EndBlockOperands : CachedInterpreter::EndBlockOperands +{ + JitBlock::ProfileData* profile_data; +}; + struct CachedInterpreter::InterpretOperands { Interpreter& interpreter;