Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add built-in IR Interpreter profiler #19255

Merged
merged 7 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Common/UI/View.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ class View {
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; }
Expand Down
10 changes: 10 additions & 0 deletions Common/UI/ViewGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions Common/UI/ViewGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class ViewGroup : public View {
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; }

Expand Down
11 changes: 11 additions & 0 deletions Core/MIPS/IR/IRJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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);
Expand Down
31 changes: 30 additions & 1 deletion Core/MIPS/IR/IRJit.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "stddef.h"
#endif

// #define IR_PROFILING

namespace MIPSComp {

// TODO : Use arena allocators. For now let's just malloc.
Expand Down Expand Up @@ -98,6 +100,10 @@ class IRBlock {
void Finalize(int number);
void Destroy(int number);

#ifdef IR_PROFILING
JitBlockProfileStats profileStats_{};
#endif

private:
u64 CalculateHash() const;

Expand Down Expand Up @@ -129,7 +135,7 @@ class IRBlockCache : public JitBlockCacheDebugInterface {
}
}
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];
Expand All @@ -149,9 +155,32 @@ class IRBlockCache : public JitBlockCacheDebugInterface {
void RestoreSavedEmuHackOps(const std::vector<u32> &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;
}
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;

bool SupportsProfiling() const override {
#ifdef IR_PROFILING
return true;
#else
return false;
#endif
}

private:
u32 AddressToPage(u32 addr) const;

Expand Down
8 changes: 8 additions & 0 deletions Core/MIPS/IR/IRNativeCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -726,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;
Expand Down
2 changes: 2 additions & 0 deletions Core/MIPS/IR/IRNativeCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ class IRNativeBlockCacheDebugInterface : public JitBlockCacheDebugInterface {
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;
JitBlockProfileStats GetBlockProfileStats(int blockNum) const override;
void ComputeStats(BlockCacheStats &bcStats) const override;
bool IsValidBlock(int blockNum) const override;

Expand Down
30 changes: 28 additions & 2 deletions Core/MIPS/JitCommon/JitBlockCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,27 @@ struct JitBlockDebugInfo {
std::vector<std::string> targetDisasm;
};

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;
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 JitBlockMeta GetBlockMeta(int blockNum) const = 0;
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; }

virtual ~JitBlockCacheDebugInterface() {}
};
Expand Down Expand Up @@ -165,7 +179,19 @@ class JitBlockCache : public JitBlockCacheDebugInterface {
void RestoreSavedEmuHackOps(const std::vector<u32> &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;
}
JitBlockProfileStats GetBlockProfileStats(int blockNum) const override {
return JitBlockProfileStats{};
}

static int GetBlockExitSize();

Expand Down
Loading
Loading