From ba1ced77c3deb33897df07d5174498b41c898f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 12:01:59 +0200 Subject: [PATCH 1/7] IRJit block profiling basics --- Core/MIPS/IR/IRJit.cpp | 11 +++++++++++ Core/MIPS/IR/IRJit.h | 14 ++++++++++++++ Core/MIPS/JitCommon/JitBlockCache.h | 11 ++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 3bf42f33c8..07c7a54162 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -40,6 +40,7 @@ #include "Core/MIPS/IR/IRNativeCommon.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/Reporting.h" +#include "Common/TimeUtil.h" namespace MIPSComp { @@ -257,7 +258,17 @@ void IRJit::RunLoopUntil(u64 globalticks) { u32 opcode = inst & 0xFF000000; if (opcode == MIPS_EMUHACK_OPCODE) { IRBlock *block = blocks_.GetBlockUnchecked(inst & 0xFFFFFF); + +#ifdef IR_PROFILING + { + TimeSpan span; + mips->pc = IRInterpret(mips, block->GetInstructions()); + block->profileStats_.executions += 1; + block->profileStats_.totalNanos += span.ElapsedNanos(); + } +#else mips->pc = IRInterpret(mips, block->GetInstructions()); +#endif // Note: this will "jump to zero" on a badly constructed block missing exits. if (!Memory::IsValid4AlignedAddress(mips->pc)) { Core_ExecException(mips->pc, block->GetOriginalStart(), ExecExceptionType::JUMP); diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index 07523d092a..09651e8848 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -33,6 +33,8 @@ #include "stddef.h" #endif +// #define IR_PROFILING + namespace MIPSComp { // TODO : Use arena allocators. For now let's just malloc. @@ -98,6 +100,10 @@ public: void Finalize(int number); void Destroy(int number); +#ifdef IR_PROFILING + JitBlockProfileStats profileStats_{}; +#endif + private: u64 CalculateHash() const; @@ -152,6 +158,14 @@ public: void ComputeStats(BlockCacheStats &bcStats) const override; int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override; + bool SupportsProfiling() const override { +#ifdef IR_PROFILING + return true; +#else + return false; +#endif + } + private: u32 AddressToPage(u32 addr) const; diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index aa8db04f15..ab3ea74e04 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -103,13 +103,22 @@ struct JitBlockDebugInfo { std::vector targetDisasm; }; +struct JitBlockProfileStats { + int64_t executions; + int64_t totalNanos; +}; + class JitBlockCacheDebugInterface { public: virtual int GetNumBlocks() const = 0; virtual int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const = 0; - virtual JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const = 0; + virtual JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const = 0; // Expensive + virtual JitBlockProfileStats GetBlockProfileStats(int blockNum) const { // Cheap + return JitBlockProfileStats{}; + } virtual void ComputeStats(BlockCacheStats &bcStats) const = 0; virtual bool IsValidBlock(int blockNum) const = 0; + virtual bool SupportsProfiling() const { return false; } virtual ~JitBlockCacheDebugInterface() {} }; From feeddbabe3949289a789afd35f4dc3b0afc2eef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 16:13:38 +0200 Subject: [PATCH 2/7] Redesign the jit compare screen a bit (add a top bar) --- Core/MIPS/IR/IRJit.h | 2 +- UI/JitCompareScreen.cpp | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index 09651e8848..1c32d0b08a 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -135,7 +135,7 @@ public: } } bool IsValidBlock(int blockNum) const override { - return blockNum < (int)blocks_.size() && blocks_[blockNum].IsValid(); + return blockNum >= 0 && blockNum < (int)blocks_.size() && blocks_[blockNum].IsValid(); } IRBlock *GetBlockUnchecked(int blockNum) { return &blocks_[blockNum]; diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index 53f45a316e..73b18543e4 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -15,16 +15,27 @@ void JitCompareScreen::CreateViews() { root_ = new LinearLayout(ORIENT_HORIZONTAL); - ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT))); LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - ScrollView *midColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); + LinearLayout *mainView = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + LinearLayout *topBar = mainView->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + topBar->Add(new Button(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock); + topBar->Add(new Button(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock); + blockAddr_ = topBar->Add(new TextEdit("", dev->T("Block address"), "")); + blockAddr_->OnEnter.Handle(this, &JitCompareScreen::OnAddressChange); + blockName_ = topBar->Add(new TextView(dev->T("No block"))); + blockStats_ = topBar->Add(new TextView("")); + + LinearLayout *comparisonView = mainView->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0f))); + + ScrollView *midColumnScroll = comparisonView->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); midColumn->SetTag("JitCompareLeftDisasm"); leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); leftDisasm_->SetSpacing(0.0f); - ScrollView *rightColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(2.0f))); + ScrollView *rightColumnScroll = comparisonView->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); rightColumnScroll->SetTag("JitCompareRightDisasm"); LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); @@ -32,17 +43,11 @@ void JitCompareScreen::CreateViews() { leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock); leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); - leftColumn->Add(new Choice(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock); - leftColumn->Add(new Choice(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock); leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock); leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock); leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock); leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); - blockName_ = leftColumn->Add(new TextView(dev->T("No block"))); - blockAddr_ = leftColumn->Add(new TextEdit("", dev->T("Block address"), "", new LayoutParams(FILL_PARENT, WRAP_CONTENT))); - blockAddr_->OnTextChange.Handle(this, &JitCompareScreen::OnAddressChange); - blockStats_ = leftColumn->Add(new TextView("")); EventParams ignore{}; OnCurrentBlock(ignore); From c538ce8bf08580857627f927fba5f375b1f03d3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 16:17:19 +0200 Subject: [PATCH 3/7] .. --- UI/JitCompareScreen.cpp | 2 +- UI/JitCompareScreen.h | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index 73b18543e4..3d94797ad6 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -69,7 +69,7 @@ void JitCompareScreen::UpdateDisasm() { } char temp[256]; - snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks()); + snprintf(temp, sizeof(temp), "%d/%d", currentBlock_, blockCacheDebug->GetNumBlocks()); blockName_->SetText(temp); if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) { diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h index 027f3e7bb6..ab92ef7c33 100644 --- a/UI/JitCompareScreen.h +++ b/UI/JitCompareScreen.h @@ -23,7 +23,14 @@ private: UI::EventReturn OnAddressChange(UI::EventParams &e); UI::EventReturn OnShowStats(UI::EventParams &e); - int currentBlock_ = -1; + // To switch, change the below things and call RecreateViews(); + enum ViewMode { + BLOCK_LIST, + DISASM, + }; + ViewMode viewMode_ = DISASM; + int currentBlock_ = -1; // For DISASM mode + std::vector blockList_; // for BLOCK_LIST mode UI::TextView *blockName_; UI::TextEdit *blockAddr_; From 3bb74ea9adacc648fb513192b471e91fbbff0a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 18:16:33 +0200 Subject: [PATCH 4/7] Rework the JitCompare window to hold a list of blocks, and allow some filtering and browsing --- Common/UI/View.h | 2 +- Common/UI/ViewGroup.cpp | 10 + Common/UI/ViewGroup.h | 1 + Core/MIPS/IR/IRJit.h | 8 + Core/MIPS/IR/IRNativeCommon.cpp | 4 + Core/MIPS/IR/IRNativeCommon.h | 1 + Core/MIPS/JitCommon/JitBlockCache.h | 18 +- UI/JitCompareScreen.cpp | 302 +++++++++++++++++----------- UI/JitCompareScreen.h | 35 +++- 9 files changed, 258 insertions(+), 123 deletions(-) diff --git a/Common/UI/View.h b/Common/UI/View.h index c75b96fcfe..5648b064ce 100644 --- a/Common/UI/View.h +++ b/Common/UI/View.h @@ -462,7 +462,7 @@ public: Visibility GetVisibility() const { return visibility_; } const std::string &Tag() const { return tag_; } - void SetTag(const std::string &str) { tag_ = str; } + void SetTag(std::string_view str) { tag_ = str; } // Fake RTTI virtual bool IsViewGroup() const { return false; } diff --git a/Common/UI/ViewGroup.cpp b/Common/UI/ViewGroup.cpp index fd7881ea39..9b7c82beec 100644 --- a/Common/UI/ViewGroup.cpp +++ b/Common/UI/ViewGroup.cpp @@ -67,6 +67,16 @@ bool ViewGroup::ContainsSubview(const View *view) const { return false; } +int ViewGroup::IndexOfSubview(const View *view) const { + int index = 0; + for (const View *subview : views_) { + if (subview == view) + return index; + index++; + } + return -1; +} + void ViewGroup::Clear() { for (View *view : views_) { delete view; diff --git a/Common/UI/ViewGroup.h b/Common/UI/ViewGroup.h index 9ccde20aec..da2e4e5fd0 100644 --- a/Common/UI/ViewGroup.h +++ b/Common/UI/ViewGroup.h @@ -65,6 +65,7 @@ public: bool CanBeFocused() const override { return false; } bool IsViewGroup() const override { return true; } bool ContainsSubview(const View *view) const override; + int IndexOfSubview(const View *view) const; virtual void SetBG(const Drawable &bg) { bg_ = bg; } diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index 1c32d0b08a..deeffe8ff7 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -155,6 +155,14 @@ public: void RestoreSavedEmuHackOps(const std::vector &saved); JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const override; + JitBlockMeta GetBlockMeta(int blockNum) const override { + JitBlockMeta meta{}; + if (IsValidBlock(blockNum)) { + meta.valid = true; + blocks_[blockNum].GetRange(meta.addr, meta.sizeInBytes); + } + return meta; + } void ComputeStats(BlockCacheStats &bcStats) const override; int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override; diff --git a/Core/MIPS/IR/IRNativeCommon.cpp b/Core/MIPS/IR/IRNativeCommon.cpp index 754435e8c6..cf9d597823 100644 --- a/Core/MIPS/IR/IRNativeCommon.cpp +++ b/Core/MIPS/IR/IRNativeCommon.cpp @@ -718,6 +718,10 @@ bool IRNativeBlockCacheDebugInterface::IsValidBlock(int blockNum) const { return irBlocks_.IsValidBlock(blockNum); } +JitBlockMeta IRNativeBlockCacheDebugInterface::GetBlockMeta(int blockNum) const { + return irBlocks_.GetBlockMeta(blockNum); +} + int IRNativeBlockCacheDebugInterface::GetNumBlocks() const { return irBlocks_.GetNumBlocks(); } diff --git a/Core/MIPS/IR/IRNativeCommon.h b/Core/MIPS/IR/IRNativeCommon.h index eae86ada35..dd2f3878a4 100644 --- a/Core/MIPS/IR/IRNativeCommon.h +++ b/Core/MIPS/IR/IRNativeCommon.h @@ -165,6 +165,7 @@ public: int GetNumBlocks() const override; int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override; JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const override; + JitBlockMeta GetBlockMeta(int blockNum) const override; void ComputeStats(BlockCacheStats &bcStats) const override; bool IsValidBlock(int blockNum) const override; diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index ab3ea74e04..793650af29 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -103,6 +103,12 @@ struct JitBlockDebugInfo { std::vector targetDisasm; }; +struct JitBlockMeta { + bool valid; + uint32_t addr; + uint32_t sizeInBytes; +}; + struct JitBlockProfileStats { int64_t executions; int64_t totalNanos; @@ -113,6 +119,7 @@ public: virtual int GetNumBlocks() const = 0; virtual int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const = 0; virtual JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const = 0; // Expensive + virtual JitBlockMeta GetBlockMeta(int blockNum) const = 0; virtual JitBlockProfileStats GetBlockProfileStats(int blockNum) const { // Cheap return JitBlockProfileStats{}; } @@ -174,7 +181,16 @@ public: void RestoreSavedEmuHackOps(const std::vector &saved); int GetNumBlocks() const override { return num_blocks_; } - bool IsValidBlock(int blockNum) const override { return blockNum < num_blocks_ && !blocks_[blockNum].invalid; } + bool IsValidBlock(int blockNum) const override { return blockNum >= 0 && blockNum < num_blocks_ && !blocks_[blockNum].invalid; } + JitBlockMeta GetBlockMeta(int blockNum) const override { + JitBlockMeta meta{}; + if (IsValidBlock(blockNum)) { + meta.valid = true; + meta.addr = blocks_[blockNum].originalAddress; + meta.sizeInBytes = blocks_[blockNum].originalSize; + } + return meta; + } static int GetBlockExitSize(); diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index 3d94797ad6..be447fc604 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -1,3 +1,5 @@ +#include + #include "UI/JitCompareScreen.h" #include "Core/MemMap.h" @@ -6,6 +8,24 @@ #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitState.h" +JitCompareScreen::JitCompareScreen() : UIDialogScreenWithBackground() { + FillBlockList(); +} + +void JitCompareScreen::Flip() { + using namespace UI; + switch (viewMode_) { + case ViewMode::DISASM: + comparisonView_->SetVisibility(V_VISIBLE); + blockListView_->SetVisibility(V_GONE); + break; + case ViewMode::BLOCK_LIST: + comparisonView_->SetVisibility(V_GONE); + blockListView_->SetVisibility(V_VISIBLE); + break; + } +} + // Three panes: Block chooser, MIPS view, ARM/x86 view void JitCompareScreen::CreateViews() { auto di = GetI18NCategory(I18NCat::DIALOG); @@ -18,39 +38,130 @@ void JitCompareScreen::CreateViews() { ScrollView *leftColumnScroll = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(200, FILL_PARENT))); LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); - LinearLayout *mainView = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); - LinearLayout *topBar = mainView->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - topBar->Add(new Button(dev->T("Prev")))->OnClick.Handle(this, &JitCompareScreen::OnPrevBlock); - topBar->Add(new Button(dev->T("Next")))->OnClick.Handle(this, &JitCompareScreen::OnNextBlock); - blockAddr_ = topBar->Add(new TextEdit("", dev->T("Block address"), "")); + comparisonView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + LinearLayout *blockTopBar = comparisonView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + blockTopBar->Add(new Button(dev->T("Back to list")))->OnClick.Add([this](UI::EventParams &e) { + viewMode_ = ViewMode::BLOCK_LIST; + Flip(); + return UI::EVENT_DONE; + }); + blockTopBar->Add(new Button(dev->T("Prev")))->OnClick.Add([=](UI::EventParams &e) { + currentBlock_--; + UpdateDisasm(); + return UI::EVENT_DONE; + }); + blockTopBar->Add(new Button(dev->T("Next")))->OnClick.Add([=](UI::EventParams &e) { + currentBlock_++; + UpdateDisasm(); + return UI::EVENT_DONE; + }); + blockTopBar->Add(new Button(dev->T("Random")))->OnClick.Add([=](UI::EventParams &e) { + if (blockList_.empty()) { + return UI::EVENT_DONE; + } + currentBlock_ = rand() % blockList_.size(); + UpdateDisasm(); + return UI::EVENT_DONE; + }); + + blockAddr_ = blockTopBar->Add(new TextEdit("", dev->T("Block address"), "")); blockAddr_->OnEnter.Handle(this, &JitCompareScreen::OnAddressChange); - blockName_ = topBar->Add(new TextView(dev->T("No block"))); - blockStats_ = topBar->Add(new TextView("")); + blockName_ = blockTopBar->Add(new TextView(dev->T("No block"))); + blockStats_ = blockTopBar->Add(new TextView("")); - LinearLayout *comparisonView = mainView->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0f))); + LinearLayout *columns = comparisonView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(1.0f))); - ScrollView *midColumnScroll = comparisonView->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + ScrollView *midColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); LinearLayout *midColumn = midColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); midColumn->SetTag("JitCompareLeftDisasm"); leftDisasm_ = midColumn->Add(new LinearLayout(ORIENT_VERTICAL)); leftDisasm_->SetSpacing(0.0f); - ScrollView *rightColumnScroll = comparisonView->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + ScrollView *rightColumnScroll = columns->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); rightColumnScroll->SetTag("JitCompareRightDisasm"); LinearLayout *rightColumn = rightColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); rightDisasm_->SetSpacing(0.0f); - leftColumn->Add(new Choice(dev->T("Current")))->OnClick.Handle(this, &JitCompareScreen::OnCurrentBlock); - leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); - leftColumn->Add(new Choice(dev->T("Random")))->OnClick.Handle(this, &JitCompareScreen::OnRandomBlock); - leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomFPUBlock); - leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Handle(this, &JitCompareScreen::OnRandomVFPUBlock); + blockListView_ = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + blockListView_->SetVisibility(V_GONE); + blockListContainer_ = blockListView_->Add(new LinearLayout(ORIENT_VERTICAL)); + + // leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); + leftColumn->Add(new Choice(dev->T("All")))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::ALL_BLOCKS; + viewMode_ = ViewMode::BLOCK_LIST; + UpdateDisasm(); + return UI::EVENT_DONE; + }); + leftColumn->Add(new Choice(dev->T("FPU")))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::FPU_BLOCKS; + viewMode_ = ViewMode::BLOCK_LIST; + UpdateDisasm(); + return UI::EVENT_DONE; + }); + leftColumn->Add(new Choice(dev->T("VFPU")))->OnClick.Add([=](UI::EventParams &e) { + listType_ = ListType::VFPU_BLOCKS; + viewMode_ = ViewMode::BLOCK_LIST; + UpdateDisasm(); + return UI::EVENT_DONE; + }); leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); + UpdateDisasm(); +} - EventParams ignore{}; - OnCurrentBlock(ignore); +void JitCompareScreen::FillBlockList() { + JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + blockList_.clear(); + for (int i = 0; i < blockCacheDebug->GetNumBlocks(); i++) { + if (!blockCacheDebug->IsValidBlock(i)) { + continue; + } + + switch (listType_) { + case ListType::ALL_BLOCKS: + blockList_.push_back(i); + break; + case ListType::FPU_BLOCKS: + case ListType::VFPU_BLOCKS: + { + const int flags = listType_ == ListType::FPU_BLOCKS ? IS_FPU : IS_VFPU; + JitBlockMeta meta = blockCacheDebug->GetBlockMeta(i); + if (meta.valid) { + for (u32 addr = meta.addr; addr < meta.addr + meta.sizeInBytes; addr += 4) { + MIPSOpcode opcode = Memory::Read_Instruction(addr); + if (MIPSGetInfo(opcode) & flags) { + blockList_.push_back(i); + break; + } + } + } + } + default: + break; + } + } + + if (listSort_ == ListSort::BLOCK_NUM) { + // Already sorted, effectively. + return; + } + if (listSort_ != ListSort::BLOCK_LENGTH_DESC) { + return; + } + + std::sort(blockList_.begin(), blockList_.end(), [=](const int &a_index, const int &b_index) { + JitBlockMeta a_meta = blockCacheDebug->GetBlockMeta(a_index); + JitBlockMeta b_meta = blockCacheDebug->GetBlockMeta(b_index); + + switch (listSort_) { + case ListSort::BLOCK_LENGTH_DESC: + return a_meta.sizeInBytes > b_meta.sizeInBytes; // reverse for descending + default: + return false; + } + }); } void JitCompareScreen::UpdateDisasm() { @@ -64,50 +175,76 @@ void JitCompareScreen::UpdateDisasm() { } JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCacheDebug->IsValidBlock(currentBlock_)) { - return; + if (viewMode_ == ViewMode::DISASM && (currentBlock_ < 0 || currentBlock_ >= (int)blockList_.size())) { + viewMode_ = ViewMode::BLOCK_LIST; } - char temp[256]; - snprintf(temp, sizeof(temp), "%d/%d", currentBlock_, blockCacheDebug->GetNumBlocks()); - blockName_->SetText(temp); + FillBlockList(); + Flip(); - if (currentBlock_ < 0 || !blockCacheDebug || currentBlock_ >= blockCacheDebug->GetNumBlocks()) { - auto dev = GetI18NCategory(I18NCat::DEVELOPER); - leftDisasm_->Add(new TextView(dev->T("No block"))); - rightDisasm_->Add(new TextView(dev->T("No block"))); - blockStats_->SetText(""); - return; - } + if (viewMode_ == ViewMode::DISASM) { + char temp[256]; + snprintf(temp, sizeof(temp), "%d/%d", currentBlock_, (int)blockList_.size()); + blockName_->SetText(temp); - JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(currentBlock_); + int blockNum = blockList_[currentBlock_]; - snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress); - blockAddr_->SetText(temp); - - // Alright. First generate the MIPS disassembly. - - // TODO: Need a way to communicate branch continuing. - for (const auto &line : debugInfo.origDisasm) { - leftDisasm_->Add(new TextView(line))->SetFocusable(true); - } - - // TODO : When we have both target and IR, need a third column. - if (debugInfo.targetDisasm.size()) { - for (const auto &line : debugInfo.targetDisasm) { - rightDisasm_->Add(new TextView(line))->SetFocusable(true); + if (!blockCacheDebug->IsValidBlock(blockNum)) { + auto dev = GetI18NCategory(I18NCat::DEVELOPER); + leftDisasm_->Add(new TextView(dev->T("No block"))); + rightDisasm_->Add(new TextView(dev->T("No block"))); + blockStats_->SetText(""); + return; } + + JitBlockDebugInfo debugInfo = blockCacheDebug->GetBlockDebugInfo(blockNum); + snprintf(temp, sizeof(temp), "%08x", debugInfo.originalAddress); + blockAddr_->SetText(temp); + + // Alright. First generate the MIPS disassembly. + + // TODO: Need a way to communicate branch continuing. + for (const auto &line : debugInfo.origDisasm) { + leftDisasm_->Add(new TextView(line, FLAG_DYNAMIC_ASCII, false))->SetFocusable(true); + } + + // TODO : When we have both target and IR, need a third column. + if (debugInfo.targetDisasm.size()) { + for (const auto &line : debugInfo.targetDisasm) { + rightDisasm_->Add(new TextView(line, FLAG_DYNAMIC_ASCII, false))->SetFocusable(true); + } + } else { + for (const auto &line : debugInfo.irDisasm) { + rightDisasm_->Add(new TextView(line, FLAG_DYNAMIC_ASCII, false))->SetFocusable(true); + } + } + + int numMips = leftDisasm_->GetNumSubviews(); + int numHost = rightDisasm_->GetNumSubviews(); + snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips); + blockStats_->SetText(temp); } else { - for (const auto &line : debugInfo.irDisasm) { - rightDisasm_->Add(new TextView(line))->SetFocusable(true); + blockListContainer_->Clear(); + for (int i = 0; i < std::min(100, (int)blockList_.size()); i++) { + JitBlockMeta meta = blockCacheDebug->GetBlockMeta(blockList_[i]); + + char temp[512], small[512]; + snprintf(temp, sizeof(temp), "%08x: %d instrs", meta.addr, meta.sizeInBytes / 4); + snprintf(small, sizeof(small), "Small text"); + Choice *blockChoice = blockListContainer_->Add(new Choice(temp, small)); + blockChoice->OnClick.Handle(this, &JitCompareScreen::OnBlockClick); } } +} - int numMips = leftDisasm_->GetNumSubviews(); - int numHost = rightDisasm_->GetNumSubviews(); - - snprintf(temp, sizeof(temp), "%d to %d : %d%%", numMips, numHost, 100 * numHost / numMips); - blockStats_->SetText(temp); +UI::EventReturn JitCompareScreen::OnBlockClick(UI::EventParams &e) { + int blockIndex = blockListContainer_->IndexOfSubview(e.v); + if (blockIndex >= 0) { + viewMode_ = ViewMode::DISASM; + currentBlock_ = blockIndex; + UpdateDisasm(); + } + return UI::EVENT_DONE; } UI::EventReturn JitCompareScreen::OnAddressChange(UI::EventParams &e) { @@ -169,18 +306,6 @@ UI::EventReturn JitCompareScreen::OnSelectBlock(UI::EventParams &e) { return UI::EVENT_DONE; } -UI::EventReturn JitCompareScreen::OnPrevBlock(UI::EventParams &e) { - currentBlock_--; - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnNextBlock(UI::EventParams &e) { - currentBlock_++; - UpdateDisasm(); - return UI::EVENT_DONE; -} - UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { std::lock_guard guard(MIPSComp::jitLock); if (!MIPSComp::jit) { @@ -200,40 +325,7 @@ UI::EventReturn JitCompareScreen::OnBlockAddress(UI::EventParams &e) { return UI::EVENT_DONE; } -UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - - JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface(); - if (!blockCache) - return UI::EVENT_DONE; - - int numBlocks = blockCache->GetNumBlocks(); - if (numBlocks > 0) { - int tries = 100; - while (tries-- > 0) { - currentBlock_ = rand() % numBlocks; - if (blockCache->IsValidBlock(currentBlock_)) { - break; - } - } - } - UpdateDisasm(); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnRandomVFPUBlock(UI::EventParams &e) { - OnRandomBlock(IS_VFPU); - return UI::EVENT_DONE; -} - -UI::EventReturn JitCompareScreen::OnRandomFPUBlock(UI::EventParams &e) { - OnRandomBlock(IS_FPU); - return UI::EVENT_DONE; -} - +/* void JitCompareScreen::OnRandomBlock(int flag) { std::lock_guard guard(MIPSComp::jitLock); if (!MIPSComp::jit) { @@ -270,21 +362,7 @@ void JitCompareScreen::OnRandomBlock(int flag) { currentBlock_ = -1; } UpdateDisasm(); -} - -UI::EventReturn JitCompareScreen::OnCurrentBlock(UI::EventParams &e) { - std::lock_guard guard(MIPSComp::jitLock); - if (!MIPSComp::jit) { - return UI::EVENT_DONE; - } - JitBlockCache *blockCache = MIPSComp::jit->GetBlockCache(); - if (!blockCache) - return UI::EVENT_DONE; - currentBlock_ = blockCache->GetBlockNumberFromAddress(currentMIPS->pc); - UpdateDisasm(); - return UI::EVENT_DONE; -} - +}*/ void AddressPromptScreen::CreatePopupContents(UI::ViewGroup *parent) { using namespace UI; diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h index ab92ef7c33..14b07f60de 100644 --- a/UI/JitCompareScreen.h +++ b/UI/JitCompareScreen.h @@ -4,31 +4,48 @@ class JitCompareScreen : public UIDialogScreenWithBackground { public: + JitCompareScreen(); void CreateViews() override; const char *tag() const override { return "JitCompare"; } private: + void Flip(); void UpdateDisasm(); - UI::EventReturn OnRandomBlock(UI::EventParams &e); - UI::EventReturn OnRandomFPUBlock(UI::EventParams &e); - UI::EventReturn OnRandomVFPUBlock(UI::EventParams &e); - void OnRandomBlock(int flag); - UI::EventReturn OnCurrentBlock(UI::EventParams &e); + // Uses the current ListType + void FillBlockList(); + + UI::LinearLayout *comparisonView_; + UI::ScrollView *blockListView_; + UI::LinearLayout *blockListContainer_; + UI::EventReturn OnSelectBlock(UI::EventParams &e); - UI::EventReturn OnPrevBlock(UI::EventParams &e); - UI::EventReturn OnNextBlock(UI::EventParams &e); UI::EventReturn OnBlockAddress(UI::EventParams &e); UI::EventReturn OnAddressChange(UI::EventParams &e); UI::EventReturn OnShowStats(UI::EventParams &e); + UI::EventReturn OnBlockClick(UI::EventParams &e); // To switch, change the below things and call RecreateViews(); - enum ViewMode { + enum class ViewMode { BLOCK_LIST, DISASM, }; - ViewMode viewMode_ = DISASM; + enum class ListType { + ALL_BLOCKS, + FPU_BLOCKS, + VFPU_BLOCKS, + }; + enum class ListSort { + BLOCK_NUM, + BLOCK_LENGTH_DESC, + TIME_SPENT, + EXECUTIONS, + }; + ViewMode viewMode_ = ViewMode::BLOCK_LIST; + ListType listType_ = ListType::ALL_BLOCKS; + ListSort listSort_ = ListSort::BLOCK_LENGTH_DESC; + int currentBlock_ = -1; // For DISASM mode std::vector blockList_; // for BLOCK_LIST mode From 9b312dc19f6bc9265b37e81be7e6661cd0a3aa19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 18:45:57 +0200 Subject: [PATCH 5/7] More UI rework --- UI/JitCompareScreen.cpp | 46 +++++++++++++++++++++++++++++++---------- UI/JitCompareScreen.h | 3 ++- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index be447fc604..c436410e42 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -39,18 +39,19 @@ void JitCompareScreen::CreateViews() { LinearLayout *leftColumn = leftColumnScroll->Add(new LinearLayout(ORIENT_VERTICAL)); comparisonView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + comparisonView_->SetVisibility(V_VISIBLE); LinearLayout *blockTopBar = comparisonView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - blockTopBar->Add(new Button(dev->T("Back to list")))->OnClick.Add([this](UI::EventParams &e) { + blockTopBar->Add(new Button("", ImageID("I_ARROW_UP")))->OnClick.Add([this](UI::EventParams &e) { viewMode_ = ViewMode::BLOCK_LIST; Flip(); return UI::EVENT_DONE; }); - blockTopBar->Add(new Button(dev->T("Prev")))->OnClick.Add([=](UI::EventParams &e) { + blockTopBar->Add(new Button("", ImageID("I_ARROW_LEFT")))->OnClick.Add([=](UI::EventParams &e) { currentBlock_--; UpdateDisasm(); return UI::EVENT_DONE; }); - blockTopBar->Add(new Button(dev->T("Next")))->OnClick.Add([=](UI::EventParams &e) { + blockTopBar->Add(new Button("", ImageID("I_ARROW_RIGHT")))->OnClick.Add([=](UI::EventParams &e) { currentBlock_++; UpdateDisasm(); return UI::EVENT_DONE; @@ -83,9 +84,16 @@ void JitCompareScreen::CreateViews() { rightDisasm_ = rightColumn->Add(new LinearLayout(ORIENT_VERTICAL)); rightDisasm_->SetSpacing(0.0f); - blockListView_ = root_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + blockListView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); blockListView_->SetVisibility(V_GONE); - blockListContainer_ = blockListView_->Add(new LinearLayout(ORIENT_VERTICAL)); + + LinearLayout *listTopBar = blockListView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); + listTopBar->Add(new Button(dev->T("Sort...")))->OnClick.Add([this](UI::EventParams &e) { + return UI::EVENT_DONE; + }); + + ScrollView *blockScroll = blockListView_->Add(new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); + blockListContainer_ = blockScroll->Add(new LinearLayout(ORIENT_VERTICAL)); // leftColumn->Add(new Choice(dev->T("By Address")))->OnClick.Handle(this, &JitCompareScreen::OnSelectBlock); leftColumn->Add(new Choice(dev->T("All")))->OnClick.Add([=](UI::EventParams &e) { @@ -106,6 +114,7 @@ void JitCompareScreen::CreateViews() { UpdateDisasm(); return UI::EVENT_DONE; }); + leftColumn->Add(new Choice(dev->T("Stats")))->OnClick.Handle(this, &JitCompareScreen::OnShowStats); leftColumn->Add(new Choice(di->T("Back")))->OnClick.Handle(this, &UIScreen::OnBack); UpdateDisasm(); @@ -147,17 +156,32 @@ void JitCompareScreen::FillBlockList() { // Already sorted, effectively. return; } - if (listSort_ != ListSort::BLOCK_LENGTH_DESC) { - return; - } std::sort(blockList_.begin(), blockList_.end(), [=](const int &a_index, const int &b_index) { - JitBlockMeta a_meta = blockCacheDebug->GetBlockMeta(a_index); - JitBlockMeta b_meta = blockCacheDebug->GetBlockMeta(b_index); - + // First, check metadata sorts. switch (listSort_) { case ListSort::BLOCK_LENGTH_DESC: + { + JitBlockMeta a_meta = blockCacheDebug->GetBlockMeta(a_index); + JitBlockMeta b_meta = blockCacheDebug->GetBlockMeta(b_index); return a_meta.sizeInBytes > b_meta.sizeInBytes; // reverse for descending + } + case ListSort::BLOCK_LENGTH_ASC: + { + JitBlockMeta a_meta = blockCacheDebug->GetBlockMeta(a_index); + JitBlockMeta b_meta = blockCacheDebug->GetBlockMeta(b_index); + return a_meta.sizeInBytes < b_meta.sizeInBytes; + } + default: + break; + } + JitBlockProfileStats a_stats = blockCacheDebug->GetBlockProfileStats(a_index); + JitBlockProfileStats b_stats = blockCacheDebug->GetBlockProfileStats(b_index); + switch (listSort_) { + case ListSort::EXECUTIONS: + return a_stats.executions > b_stats.executions; + case ListSort::TIME_SPENT: + return a_stats.totalNanos > b_stats.totalNanos; default: return false; } diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h index 14b07f60de..4f449381cc 100644 --- a/UI/JitCompareScreen.h +++ b/UI/JitCompareScreen.h @@ -17,7 +17,7 @@ private: void FillBlockList(); UI::LinearLayout *comparisonView_; - UI::ScrollView *blockListView_; + UI::LinearLayout *blockListView_; UI::LinearLayout *blockListContainer_; UI::EventReturn OnSelectBlock(UI::EventParams &e); @@ -39,6 +39,7 @@ private: enum class ListSort { BLOCK_NUM, BLOCK_LENGTH_DESC, + BLOCK_LENGTH_ASC, TIME_SPENT, EXECUTIONS, }; From 5583dc10d5272068fd145e54073d8d4e8398e435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 18:58:33 +0200 Subject: [PATCH 6/7] Hook up profiling, something is wrong --- Core/MIPS/IR/IRJit.h | 2 +- UI/JitCompareScreen.cpp | 38 +++++++++++++++++++++++++++++++++++--- UI/JitCompareScreen.h | 1 + 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index deeffe8ff7..171bebe3bf 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -33,7 +33,7 @@ #include "stddef.h" #endif -// #define IR_PROFILING +#define IR_PROFILING namespace MIPSComp { diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index c436410e42..245a205ed1 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -87,8 +87,34 @@ void JitCompareScreen::CreateViews() { blockListView_ = root_->Add(new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(1.0f))); blockListView_->SetVisibility(V_GONE); + // Should match the ListSort enum + static ContextMenuItem sortMenu[] = { + { "Block number", "I_ARROW_UP" }, + { "Block length", "I_ARROW_DOWN" }, + { "Block length", "I_ARROW_UP" }, + { "Time spent", "I_ARROW_DOWN" }, + { "Executions", "I_ARROW_DOWN" }, + }; + int sortCount = ARRAY_SIZE(sortMenu); + if (MIPSComp::jit) { + JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface(); + if (!blockCacheDebug->SupportsProfiling()) { + sortCount -= 2; + } + } + LinearLayout *listTopBar = blockListView_->Add(new LinearLayout(ORIENT_HORIZONTAL, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT))); - listTopBar->Add(new Button(dev->T("Sort...")))->OnClick.Add([this](UI::EventParams &e) { + Button *sortButton = new Button(dev->T("Sort...")); + listTopBar->Add(sortButton)->OnClick.Add([this, sortButton, sortCount](UI::EventParams &e) { + PopupContextMenuScreen *contextMenu = new UI::PopupContextMenuScreen(sortMenu, sortCount, I18NCat::DEVELOPER, sortButton); + screenManager()->push(contextMenu); + contextMenu->OnChoice.Add([=](EventParams &e) -> UI::EventReturn { + if (e.a < (int)ListSort::MAX) { + listSort_ = (ListSort)e.a; + UpdateDisasm(); + } + return UI::EVENT_DONE; + }); return UI::EVENT_DONE; }); @@ -251,9 +277,15 @@ void JitCompareScreen::UpdateDisasm() { blockListContainer_->Clear(); for (int i = 0; i < std::min(100, (int)blockList_.size()); i++) { JitBlockMeta meta = blockCacheDebug->GetBlockMeta(blockList_[i]); - char temp[512], small[512]; - snprintf(temp, sizeof(temp), "%08x: %d instrs", meta.addr, meta.sizeInBytes / 4); + if (blockCacheDebug->SupportsProfiling()) { + JitBlockProfileStats stats = blockCacheDebug->GetBlockProfileStats(blockList_[i]); + int execs = (int)stats.executions; + double us = (double)stats.totalNanos / 1000.0; + snprintf(temp, sizeof(temp), "%08x: %d instrs (%d exec, %0.2f us)", meta.addr, meta.sizeInBytes / 4, execs, us); + } else { + snprintf(temp, sizeof(temp), "%08x: %d instrs", meta.addr, meta.sizeInBytes / 4); + } snprintf(small, sizeof(small), "Small text"); Choice *blockChoice = blockListContainer_->Add(new Choice(temp, small)); blockChoice->OnClick.Handle(this, &JitCompareScreen::OnBlockClick); diff --git a/UI/JitCompareScreen.h b/UI/JitCompareScreen.h index 4f449381cc..03403343f8 100644 --- a/UI/JitCompareScreen.h +++ b/UI/JitCompareScreen.h @@ -42,6 +42,7 @@ private: BLOCK_LENGTH_ASC, TIME_SPENT, EXECUTIONS, + MAX }; ViewMode viewMode_ = ViewMode::BLOCK_LIST; ListType listType_ = ListType::ALL_BLOCKS; From 294593f741a3e7ed204b25854c82fe588d71c7e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 5 Jun 2024 19:12:08 +0200 Subject: [PATCH 7/7] Fix IR profiling --- Core/MIPS/IR/IRJit.h | 9 ++++++++- Core/MIPS/IR/IRNativeCommon.cpp | 4 ++++ Core/MIPS/IR/IRNativeCommon.h | 1 + Core/MIPS/JitCommon/JitBlockCache.h | 7 ++++--- UI/JitCompareScreen.cpp | 11 +++++++---- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Core/MIPS/IR/IRJit.h b/Core/MIPS/IR/IRJit.h index 171bebe3bf..744715836c 100644 --- a/Core/MIPS/IR/IRJit.h +++ b/Core/MIPS/IR/IRJit.h @@ -33,7 +33,7 @@ #include "stddef.h" #endif -#define IR_PROFILING +// #define IR_PROFILING namespace MIPSComp { @@ -163,6 +163,13 @@ public: } return meta; } + JitBlockProfileStats GetBlockProfileStats(int blockNum) const { // Cheap +#ifdef IR_PROFILING + return blocks_[blockNum].profileStats_; +#else + return JitBlockProfileStats{}; +#endif + } void ComputeStats(BlockCacheStats &bcStats) const override; int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override; diff --git a/Core/MIPS/IR/IRNativeCommon.cpp b/Core/MIPS/IR/IRNativeCommon.cpp index cf9d597823..e0a0b4d099 100644 --- a/Core/MIPS/IR/IRNativeCommon.cpp +++ b/Core/MIPS/IR/IRNativeCommon.cpp @@ -730,6 +730,10 @@ int IRNativeBlockCacheDebugInterface::GetBlockNumberFromStartAddress(u32 em_addr return irBlocks_.GetBlockNumberFromStartAddress(em_address, realBlocksOnly); } +JitBlockProfileStats IRNativeBlockCacheDebugInterface::GetBlockProfileStats(int blockNum) const { + return irBlocks_.GetBlockProfileStats(blockNum); +} + void IRNativeBlockCacheDebugInterface::GetBlockCodeRange(int blockNum, int *startOffset, int *size) const { int blockOffset = irBlocks_.GetBlock(blockNum)->GetTargetOffset(); int endOffset = backend_->GetNativeBlock(blockNum)->checkedOffset; diff --git a/Core/MIPS/IR/IRNativeCommon.h b/Core/MIPS/IR/IRNativeCommon.h index dd2f3878a4..a5ccea28f4 100644 --- a/Core/MIPS/IR/IRNativeCommon.h +++ b/Core/MIPS/IR/IRNativeCommon.h @@ -166,6 +166,7 @@ public: int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override; JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const override; JitBlockMeta GetBlockMeta(int blockNum) const override; + JitBlockProfileStats GetBlockProfileStats(int blockNum) const override; void ComputeStats(BlockCacheStats &bcStats) const override; bool IsValidBlock(int blockNum) const override; diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 793650af29..cfd363b69e 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -120,9 +120,7 @@ public: virtual int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const = 0; virtual JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const = 0; // Expensive virtual JitBlockMeta GetBlockMeta(int blockNum) const = 0; - virtual JitBlockProfileStats GetBlockProfileStats(int blockNum) const { // Cheap - return JitBlockProfileStats{}; - } + virtual JitBlockProfileStats GetBlockProfileStats(int blockNum) const = 0; virtual void ComputeStats(BlockCacheStats &bcStats) const = 0; virtual bool IsValidBlock(int blockNum) const = 0; virtual bool SupportsProfiling() const { return false; } @@ -191,6 +189,9 @@ public: } return meta; } + JitBlockProfileStats GetBlockProfileStats(int blockNum) const override { + return JitBlockProfileStats{}; + } static int GetBlockExitSize(); diff --git a/UI/JitCompareScreen.cpp b/UI/JitCompareScreen.cpp index 245a205ed1..1d1630dd14 100644 --- a/UI/JitCompareScreen.cpp +++ b/UI/JitCompareScreen.cpp @@ -47,12 +47,14 @@ void JitCompareScreen::CreateViews() { return UI::EVENT_DONE; }); blockTopBar->Add(new Button("", ImageID("I_ARROW_LEFT")))->OnClick.Add([=](UI::EventParams &e) { - currentBlock_--; + if (currentBlock_ >= 1) + currentBlock_--; UpdateDisasm(); return UI::EVENT_DONE; }); blockTopBar->Add(new Button("", ImageID("I_ARROW_RIGHT")))->OnClick.Add([=](UI::EventParams &e) { - currentBlock_++; + if (currentBlock_ < blockList_.size() - 1) + currentBlock_++; UpdateDisasm(); return UI::EVENT_DONE; }); @@ -276,10 +278,11 @@ void JitCompareScreen::UpdateDisasm() { } else { blockListContainer_->Clear(); for (int i = 0; i < std::min(100, (int)blockList_.size()); i++) { - JitBlockMeta meta = blockCacheDebug->GetBlockMeta(blockList_[i]); + int blockNum = blockList_[i]; + JitBlockMeta meta = blockCacheDebug->GetBlockMeta(blockNum); char temp[512], small[512]; if (blockCacheDebug->SupportsProfiling()) { - JitBlockProfileStats stats = blockCacheDebug->GetBlockProfileStats(blockList_[i]); + JitBlockProfileStats stats = blockCacheDebug->GetBlockProfileStats(blockNum); int execs = (int)stats.executions; double us = (double)stats.totalNanos / 1000.0; snprintf(temp, sizeof(temp), "%08x: %d instrs (%d exec, %0.2f us)", meta.addr, meta.sizeInBytes / 4, execs, us);