[AArch64] Implement block profiling.

This is time based block profiling unlike the ARMv7 core.
I would like to add cycle counter based block profiling like the ARMv7 core, but it first requires writing a kernel module to enable the counters to userland applications
This commit is contained in:
Ryan Houdek 2015-05-20 22:23:59 -05:00
parent 12493c332c
commit eb94e742f1
2 changed files with 61 additions and 0 deletions

View File

@ -4,8 +4,10 @@
#include "Common/Arm64Emitter.h" #include "Common/Arm64Emitter.h"
#include "Common/Common.h" #include "Common/Common.h"
#include "Common/PerformanceCounter.h"
#include "Core/PatchEngine.h" #include "Core/PatchEngine.h"
#include "Core/PowerPC/Profiler.h"
#include "Core/PowerPC/JitArm64/Jit.h" #include "Core/PowerPC/JitArm64/Jit.h"
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h" #include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
#include "Core/PowerPC/JitArm64/JitArm64_Tables.h" #include "Core/PowerPC/JitArm64/JitArm64_Tables.h"
@ -106,6 +108,9 @@ void JitArm64::WriteExit(u32 destination)
{ {
DoDownCount(); DoDownCount();
if (Profiler::g_ProfileBlocks)
EndTimeProfile(js.curBlock);
//If nobody has taken care of this yet (this can be removed when all branches are done) //If nobody has taken care of this yet (this can be removed when all branches are done)
JitBlock *b = js.curBlock; JitBlock *b = js.curBlock;
JitBlock::LinkData linkData; JitBlock::LinkData linkData;
@ -140,6 +145,10 @@ void JitArm64::WriteExceptionExit(ARM64Reg dest)
STR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc)); STR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc));
gpr.Unlock(dest); gpr.Unlock(dest);
DoDownCount(); DoDownCount();
if (Profiler::g_ProfileBlocks)
EndTimeProfile(js.curBlock);
MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExceptions); MOVI2R(EncodeRegTo64(dest), (u64)&PowerPC::CheckExceptions);
BLR(EncodeRegTo64(dest)); BLR(EncodeRegTo64(dest));
LDR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc)); LDR(INDEX_UNSIGNED, dest, X29, PPCSTATE_OFF(npc));
@ -153,6 +162,9 @@ void JitArm64::WriteExceptionExit()
{ {
DoDownCount(); DoDownCount();
if (Profiler::g_ProfileBlocks)
EndTimeProfile(js.curBlock);
ARM64Reg WA = gpr.GetReg(); ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA); ARM64Reg XA = EncodeRegTo64(WA);
LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(pc)); LDR(INDEX_UNSIGNED, WA, X29, PPCSTATE_OFF(pc));
@ -173,6 +185,10 @@ void JitArm64::WriteExitDestInR(ARM64Reg Reg)
STR(INDEX_UNSIGNED, Reg, X29, PPCSTATE_OFF(pc)); STR(INDEX_UNSIGNED, Reg, X29, PPCSTATE_OFF(pc));
gpr.Unlock(Reg); gpr.Unlock(Reg);
DoDownCount(); DoDownCount();
if (Profiler::g_ProfileBlocks)
EndTimeProfile(js.curBlock);
MOVI2R(EncodeRegTo64(Reg), (u64)asm_routines.dispatcher); MOVI2R(EncodeRegTo64(Reg), (u64)asm_routines.dispatcher);
BR(EncodeRegTo64(Reg)); BR(EncodeRegTo64(Reg));
} }
@ -185,6 +201,32 @@ void JitArm64::DumpCode(const u8* start, const u8* end)
WARN_LOG(DYNA_REC, "Code dump from %p to %p:\n%s", start, end, output.c_str()); WARN_LOG(DYNA_REC, "Code dump from %p to %p:\n%s", start, end, output.c_str());
} }
void JitArm64::BeginTimeProfile(JitBlock* b)
{
b->ticCounter = 0;
b->ticStart = 0;
b->ticStop = 0;
MOVI2R(X1, (u64)QueryPerformanceCounter);
MOVI2R(X0, (u64)&b->ticStart);
BLR(X1);
}
void JitArm64::EndTimeProfile(JitBlock* b)
{
MOVI2R(X1, (u64)QueryPerformanceCounter);
MOVI2R(X0, (u64)&b->ticStop);
BLR(X1);
MOVI2R(X0, (u64)&b->ticStart);
LDR(INDEX_UNSIGNED, X1, X0, 0); // Start
LDR(INDEX_UNSIGNED, X2, X0, 8); // Stop
LDR(INDEX_UNSIGNED, X3, X0, 16); // Counter
SUB(X2, X2, X1);
ADD(X3, X3, X2);
STR(INDEX_UNSIGNED, X3, X0, 16);
}
void JitArm64::Run() void JitArm64::Run()
{ {
CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode; CompiledCode pExecAddr = (CompiledCode)asm_routines.enterCode;
@ -256,6 +298,21 @@ const u8* JitArm64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB
SetJumpTarget(bail); SetJumpTarget(bail);
} }
// Conditionally add profiling code.
if (Profiler::g_ProfileBlocks)
{
ARM64Reg WA = gpr.GetReg();
ARM64Reg WB = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA);
ARM64Reg XB = EncodeRegTo64(WB);
MOVI2R(XA, (u64)&b->runCount);
LDR(INDEX_UNSIGNED, XB, XA, 0);
ADD(XB, XB, 1);
STR(INDEX_UNSIGNED, XB, XA, 0);
gpr.Unlock(WA, WB);
// get start tic
BeginTimeProfile(b);
}
const u8 *normalEntry = GetCodePtr(); const u8 *normalEntry = GetCodePtr();
b->normalEntry = normalEntry; b->normalEntry = normalEntry;

View File

@ -200,6 +200,10 @@ private:
void DoDownCount(); void DoDownCount();
// Profiling
void BeginTimeProfile(JitBlock* b);
void EndTimeProfile(JitBlock* b);
// Exits // Exits
void WriteExit(u32 destination); void WriteExit(u32 destination);
void WriteExceptionExit(Arm64Gen::ARM64Reg dest); void WriteExceptionExit(Arm64Gen::ARM64Reg dest);