From ef1ecbcd0fa3d98f980598574dee07fb25e573af Mon Sep 17 00:00:00 2001 From: LinesPrower Date: Thu, 4 Jun 2009 16:00:37 +0000 Subject: [PATCH] Fixed profiled ReJIT. It's very experimental though. Makes a great performance boost, but is way too unsafe. However it seems to work fine on games I've tested. Can be enabled from ini-file (ProfiledReJIT = True in [Core]). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3321 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/ConfigManager.cpp | 1 + Source/Core/Core/Src/CoreParameter.h | 1 + Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp | 15 ++++++++------- Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp | 1 + .../Core/Core/Src/PowerPC/JitCommon/JitCache.cpp | 1 + Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h | 2 ++ 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/Src/ConfigManager.cpp b/Source/Core/Core/Src/ConfigManager.cpp index 0cd3803c07..187a188e81 100644 --- a/Source/Core/Core/Src/ConfigManager.cpp +++ b/Source/Core/Core/Src/ConfigManager.cpp @@ -223,6 +223,7 @@ void SConfig::LoadSettings() ini.Get("Core", "SlotA", (int*)&m_EXIDevice[0], EXIDEVICE_MEMORYCARD_A); ini.Get("Core", "SlotB", (int*)&m_EXIDevice[1], EXIDEVICE_MEMORYCARD_B); ini.Get("Core", "SerialPort1", (int*)&m_EXIDevice[2], EXIDEVICE_DUMMY); + ini.Get("Core", "ProfiledReJIT", &m_LocalCoreStartupParameter.bJITProfiledReJIT, false); char sidevicenum[16]; for (int i = 0; i < 4; ++i) { diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index 1011ed359c..923713f873 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -55,6 +55,7 @@ struct SCoreStartupParameter bool bJITPairedOff; bool bJITSystemRegistersOff; bool bJITBranchOff; + bool bJITProfiledReJIT; bool bUseDualCore; bool bDSPThread; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index ff31c83c1e..bb0d721248 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -138,6 +138,7 @@ Fix profiled loads/stores to work safely. On 32-bit, one solution is to #include "JitAsm.h" #include "Jit.h" #include "../../HW/GPFifo.h" +#include "../../Core.h" using namespace Gen; namespace IREmitter { @@ -1287,17 +1288,18 @@ static void regWriteExit(RegInfo& RI, InstLoc dest) { if (isImm(*dest)) { RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++); } else { - RI.Jit->MOV(32, R(EAX), regLocForInst(RI, dest)); + if (!regLocForInst(RI, dest).IsSimpleReg(EAX)) + RI.Jit->MOV(32, R(EAX), regLocForInst(RI, dest)); RI.Jit->WriteExitDestInEAX(RI.exitNumber++); } } -static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { +static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile, bool MakeProfile) { //printf("Writing block: %x\n", js.blockStart); RegInfo RI(Jit, ibuild->getFirstInst(), ibuild->getNumInsts()); RI.Build = ibuild; RI.UseProfile = UseProfile; - RI.MakeProfile = false;//!RI.UseProfile; + RI.MakeProfile = MakeProfile; // Pass to compute liveness ibuild->StartBackPass(); for (unsigned int index = (unsigned int)RI.IInfo.size() - 1; index != -1U; --index) { @@ -2268,13 +2270,12 @@ static void DoWriteCode(IRBuilder* ibuild, Jit64* Jit, bool UseProfile) { } void Jit64::WriteCode() { - DoWriteCode(&ibuild, this, false); + DoWriteCode(&ibuild, this, false, Core::GetStartupParameter().bJITProfiledReJIT); } void ProfiledReJit() { - u8* x = (u8*)jit.GetCodePtr(); jit.SetCodePtr(jit.js.rewriteStart); - DoWriteCode(&jit.ibuild, &jit, true); + DoWriteCode(&jit.ibuild, &jit, true, false); jit.js.curBlock->codeSize = (int)(jit.GetCodePtr() - jit.js.rewriteStart); - jit.SetCodePtr(x); + jit.GetBlockCache()->FinalizeBlock(jit.js.curBlock->blockNum, jit.jo.enableBlocklink, jit.js.curBlock->normalEntry); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp index 86237fd386..9cf158194f 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/Jit.cpp @@ -428,6 +428,7 @@ namespace CPUCompare SetJumpTarget(skip); const u8 *normalEntry = GetCodePtr(); + b->normalEntry = normalEntry; if (ImHereDebug) ABI_CallFunction((void *)&ImHere); //Used to get a trace of the last few blocks before a crash, sometimes VERY useful diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 4890590a39..c2190b1991 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -168,6 +168,7 @@ bool JitBlock::ContainsAddress(u32 em_address) b.exitPtrs[1] = 0; b.linkStatus[0] = false; b.linkStatus[1] = false; + b.blockNum = num_blocks; num_blocks++; //commit the current block return num_blocks - 1; } diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h index 95ff2534c2..15c49cf266 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.h @@ -46,6 +46,7 @@ struct JitBlock u32 codeSize; u32 originalSize; int runCount; // for profiling. + int blockNum; #ifdef _WIN32 // we don't really need to save start and stop @@ -55,6 +56,7 @@ struct JitBlock LARGE_INTEGER ticCounter; // for profiling - time. #endif const u8 *checkedEntry; + const u8 *normalEntry; bool invalid; int flags;