mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-24 15:01:16 +01:00
CachedInterpreter: Software JIT Profiling Support
This commit is contained in:
parent
8a50676b83
commit
cde64b6a3d
@ -89,12 +89,23 @@ void CachedInterpreter::SingleStep()
|
|||||||
ExecuteOneBlock();
|
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 <bool profiled>
|
||||||
|
s32 CachedInterpreter::EndBlock(PowerPC::PowerPCState& ppc_state,
|
||||||
|
const EndBlockOperands<profiled>& operands)
|
||||||
{
|
{
|
||||||
const auto& [downcount, num_load_stores, num_fp_inst] = operands;
|
|
||||||
ppc_state.pc = ppc_state.npc;
|
ppc_state.pc = ppc_state.npc;
|
||||||
ppc_state.downcount -= downcount;
|
ppc_state.downcount -= operands.downcount;
|
||||||
PowerPC::UpdatePerformanceMonitor(downcount, num_load_stores, num_fp_inst, ppc_state);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,10 +211,23 @@ bool CachedInterpreter::HandleFunctionHooking(u32 address)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
js.downcountAmount += js.st.numCycles;
|
js.downcountAmount += js.st.numCycles;
|
||||||
Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst});
|
WriteEndBlock();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CachedInterpreter::WriteEndBlock()
|
||||||
|
{
|
||||||
|
if (IsProfilingEnabled())
|
||||||
|
{
|
||||||
|
Write(EndBlock<true>, {{js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst},
|
||||||
|
js.curBlock->profile_data.get()});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write(EndBlock<false>, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool CachedInterpreter::SetEmitterStateToFreeCodeRegion()
|
bool CachedInterpreter::SetEmitterStateToFreeCodeRegion()
|
||||||
{
|
{
|
||||||
const auto free = m_free_ranges.by_size_begin();
|
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& cpu = m_system.GetCPU();
|
||||||
auto& breakpoints = power_pc.GetBreakPoints();
|
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++)
|
for (u32 i = 0; i < code_block.m_num_instructions; i++)
|
||||||
{
|
{
|
||||||
PPCAnalyst::CodeOp& op = m_code_buffer[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)
|
if (op.branchIsIdleLoop)
|
||||||
Write(CheckIdle, {m_system.GetCoreTiming(), js.blockStart});
|
Write(CheckIdle, {m_system.GetCoreTiming(), js.blockStart});
|
||||||
if (op.canEndBlock)
|
if (op.canEndBlock)
|
||||||
Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst});
|
WriteEndBlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (code_block.m_broken)
|
if (code_block.m_broken)
|
||||||
{
|
{
|
||||||
Write(WriteBrokenBlockNPC, {nextPC});
|
Write(WriteBrokenBlockNPC, {nextPC});
|
||||||
Write(EndBlock, {js.downcountAmount, js.numLoadStoreInst, js.numFloatingPointInst});
|
WriteEndBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HasWriteFailed())
|
if (HasWriteFailed())
|
||||||
|
@ -54,6 +54,7 @@ private:
|
|||||||
void ExecuteOneBlock();
|
void ExecuteOneBlock();
|
||||||
|
|
||||||
bool HandleFunctionHooking(u32 address);
|
bool HandleFunctionHooking(u32 address);
|
||||||
|
void WriteEndBlock();
|
||||||
|
|
||||||
// Finds a free memory region and sets the code emitter to point at that region.
|
// 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.
|
// Returns false if no free memory region can be found.
|
||||||
@ -62,6 +63,8 @@ private:
|
|||||||
void FreeRanges();
|
void FreeRanges();
|
||||||
void ResetFreeMemoryRanges();
|
void ResetFreeMemoryRanges();
|
||||||
|
|
||||||
|
struct StartProfiledBlockOperands;
|
||||||
|
template <bool profiled>
|
||||||
struct EndBlockOperands;
|
struct EndBlockOperands;
|
||||||
struct InterpretOperands;
|
struct InterpretOperands;
|
||||||
struct InterpretAndCheckExceptionsOperands;
|
struct InterpretAndCheckExceptionsOperands;
|
||||||
@ -70,7 +73,10 @@ private:
|
|||||||
struct CheckHaltOperands;
|
struct CheckHaltOperands;
|
||||||
struct CheckIdleOperands;
|
struct CheckIdleOperands;
|
||||||
|
|
||||||
static s32 EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands& operands);
|
static s32 StartProfiledBlock(PowerPC::PowerPCState& ppc_state,
|
||||||
|
const StartProfiledBlockOperands& profile_data);
|
||||||
|
template <bool profiled>
|
||||||
|
static s32 EndBlock(PowerPC::PowerPCState& ppc_state, const EndBlockOperands<profiled>& operands);
|
||||||
template <bool write_pc>
|
template <bool write_pc>
|
||||||
static s32 Interpret(PowerPC::PowerPCState& ppc_state, const InterpretOperands& operands);
|
static s32 Interpret(PowerPC::PowerPCState& ppc_state, const InterpretOperands& operands);
|
||||||
template <bool write_pc>
|
template <bool write_pc>
|
||||||
@ -87,7 +93,13 @@ private:
|
|||||||
CachedInterpreterBlockCache m_block_cache;
|
CachedInterpreterBlockCache m_block_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CachedInterpreter::EndBlockOperands
|
struct CachedInterpreter::StartProfiledBlockOperands
|
||||||
|
{
|
||||||
|
JitBlock::ProfileData* profile_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CachedInterpreter::EndBlockOperands<false>
|
||||||
{
|
{
|
||||||
u32 downcount;
|
u32 downcount;
|
||||||
u32 num_load_stores;
|
u32 num_load_stores;
|
||||||
@ -95,6 +107,12 @@ struct CachedInterpreter::EndBlockOperands
|
|||||||
u32 : 32;
|
u32 : 32;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct CachedInterpreter::EndBlockOperands<true> : CachedInterpreter::EndBlockOperands<false>
|
||||||
|
{
|
||||||
|
JitBlock::ProfileData* profile_data;
|
||||||
|
};
|
||||||
|
|
||||||
struct CachedInterpreter::InterpretOperands
|
struct CachedInterpreter::InterpretOperands
|
||||||
{
|
{
|
||||||
Interpreter& interpreter;
|
Interpreter& interpreter;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user