diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index eef1ac6420..ff39c19096 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -160,7 +160,6 @@ void IRRestoreRounding() { #endif } -// We cannot use NEON on ARM32 here until we make it a hard dependency. We can, however, on ARM64. u32 IRInterpret(MIPSState *mips, const IRInst *inst) { while (true) { switch (inst->op) { diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index a11b882630..94f85dcb83 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -294,21 +294,20 @@ int IRBlockCache::GetBlockNumFromIRArenaOffset(int offset) const { high = mid - 1; } } - -#ifndef _DEBUG - // Then, in debug builds, cross check the result. + return found; +#if 1 return found; #else - // TODO: Optimize if we need to call this often. + // Cross check the result. This is not fast so normally not enabled. Called a lot when IR_PROFILING is on. for (int i = 0; i < (int)blocks_.size(); i++) { if (blocks_[i].GetIRArenaOffset() == offset) { _dbg_assert_(i == found); return i; } } -#endif _dbg_assert_(found == -1); return -1; +#endif } std::vector IRBlockCache::FindInvalidatedBlockNumbers(u32 address, u32 lengthInBytes) { diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 6cf805a6e5..13365cea13 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -102,17 +102,18 @@ struct JitBlockDebugInfo { std::vector targetDisasm; }; +struct JitBlockProfileStats { + int64_t executions; + int64_t totalNanos; +}; + +// Only used for debugging, so keeping it tight is not that important. struct JitBlockMeta { bool valid; uint32_t addr; uint32_t sizeInBytes; }; -struct JitBlockProfileStats { - int64_t executions; - int64_t totalNanos; -}; - class JitBlockCacheDebugInterface { public: virtual int GetNumBlocks() const = 0; diff --git a/UI/ImDebugger/ImJitViewer.cpp b/UI/ImDebugger/ImJitViewer.cpp index b3a6f9d66b..490e932de0 100644 --- a/UI/ImDebugger/ImJitViewer.cpp +++ b/UI/ImDebugger/ImJitViewer.cpp @@ -7,6 +7,7 @@ #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitState.h" +#include "Core/MIPS/IR/IRJit.h" void ImJitViewerWindow::GoToBlockAtAddr(u32 addr) { for (auto &block : blockList_) { @@ -95,6 +96,10 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) { cb.addr = meta.addr; cb.sizeInBytes = meta.sizeInBytes; cb.blockNum = i; +#ifdef IR_PROFILING + JitBlockProfileStats stats = blockCacheDebug->GetBlockProfileStats(i); + cb.profileStats = stats; +#endif blockList_.push_back(cb); } @@ -104,13 +109,14 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) { } const ImGuiTableColumnSortSpecs *spec = &sortSpecs_->Specs[0]; int delta = 0; - if (spec->ColumnUserID == 0) { - delta = (int)a.blockNum - (int)b.blockNum; - } else - if (spec->ColumnUserID == 1) { - delta = (int)a.addr - (int)b.addr; - } else if (spec->ColumnUserID == 2) { - delta = a.sizeInBytes - b.sizeInBytes; + switch (spec->ColumnUserID) { + case 0: delta = (int)a.blockNum - (int)b.blockNum; break; + case 1: delta = (int)a.addr - (int)b.addr; break; + case 2: delta = a.sizeInBytes - b.sizeInBytes; break; +#ifdef IR_PROFILING + case 3: delta = a.profileStats.executions - b.profileStats.executions; break; + case 4: delta = a.profileStats.totalNanos - b.profileStats.totalNanos; break; +#endif } if (delta == 0) { return a.addr < b.addr; @@ -143,11 +149,21 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) { // For separate scrolling. ImGui::BeginChild("LeftPane", ImVec2(0, 0), true, ImGuiWindowFlags_HorizontalScrollbar); - - if (ImGui::BeginTable("blocks", 3, ImGuiTableFlags_Sortable | ImGuiTableFlags_Resizable)) { +#ifdef IR_PROFILING + const int numColumns = (core == CPUCore::IR_INTERPRETER) ? 5 : 3; +#else + const int numColumns = 3; +#endif + if (ImGui::BeginTable("blocks", numColumns, ImGuiTableFlags_Sortable | ImGuiTableFlags_Resizable)) { ImGui::TableSetupColumn("Num", 0, 0, 0); ImGui::TableSetupColumn("Addr", 0, 0, 1); ImGui::TableSetupColumn("Size", 0, 0, 2); +#ifdef IR_PROFILING + if (numColumns == 5) { + ImGui::TableSetupColumn("Exec", 0, 0, 3); + ImGui::TableSetupColumn("Ns", 0, 0, 4); + } +#endif ImGui::TableHeadersRow(); sortSpecs_ = ImGui::TableGetSortSpecs(); @@ -176,6 +192,16 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) { ImGui::TableNextColumn(); ImGui::Text("%d", block.sizeInBytes); + +#ifdef IR_PROFILING + if (numColumns == 5) { + ImGui::TableNextColumn(); + ImGui::Text("%d", block.profileStats.executions); + + ImGui::TableNextColumn(); + ImGui::Text("%0.3f ms", (double)block.profileStats.totalNanos * 0.000001); + } +#endif } } diff --git a/UI/ImDebugger/ImJitViewer.h b/UI/ImDebugger/ImJitViewer.h index 87a379c21a..d756e1a40d 100644 --- a/UI/ImDebugger/ImJitViewer.h +++ b/UI/ImDebugger/ImJitViewer.h @@ -6,6 +6,7 @@ #include "Core/Debugger/DebugInterface.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" +#include "Core/MIPS/IR/IRJit.h" struct ImConfig; struct ImControl; @@ -24,6 +25,9 @@ private: u32 addr; int sizeInBytes; int blockNum; +#ifdef IR_PROFILING + JitBlockProfileStats profileStats; +#endif }; std::vector blockList_; int curBlockNum_ = -1;