mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
Merge pull request #19193 from hrydgard/ir-interpreter-opts
IRInterpreter: Enable some optimizations that accidentally were only enabled on non-ARM64.
This commit is contained in:
commit
84d9e30c0f
@ -44,6 +44,7 @@ Arm64JitBackend::Arm64JitBackend(JitOptions &jitopt, IRBlockCache &blocks)
|
|||||||
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
||||||
jo.enablePointerify = false;
|
jo.enablePointerify = false;
|
||||||
}
|
}
|
||||||
|
jo.optimizeForInterpreter = false;
|
||||||
#ifdef MASKED_PSP_MEMORY
|
#ifdef MASKED_PSP_MEMORY
|
||||||
jo.enablePointerify = false;
|
jo.enablePointerify = false;
|
||||||
#endif
|
#endif
|
||||||
|
@ -277,7 +277,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
|
|||||||
IRWriter simplified;
|
IRWriter simplified;
|
||||||
IRWriter *code = &ir;
|
IRWriter *code = &ir;
|
||||||
if (!js.hadBreakpoints) {
|
if (!js.hadBreakpoints) {
|
||||||
static const IRPassFunc passes[] = {
|
std::vector<IRPassFunc> passes{
|
||||||
&ApplyMemoryValidation,
|
&ApplyMemoryValidation,
|
||||||
&RemoveLoadStoreLeftRight,
|
&RemoveLoadStoreLeftRight,
|
||||||
&OptimizeFPMoves,
|
&OptimizeFPMoves,
|
||||||
@ -288,7 +288,12 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
|
|||||||
// &MergeLoadStore,
|
// &MergeLoadStore,
|
||||||
// &ThreeOpToTwoOp,
|
// &ThreeOpToTwoOp,
|
||||||
};
|
};
|
||||||
if (IRApplyPasses(passes, ARRAY_SIZE(passes), ir, simplified, opts))
|
|
||||||
|
if (opts.optimizeForInterpreter) {
|
||||||
|
// Add special passes here.
|
||||||
|
// passes.push_back(&ReorderLoadStore);
|
||||||
|
}
|
||||||
|
if (IRApplyPasses(passes.data(), passes.size(), ir, simplified, opts))
|
||||||
logBlocks = 1;
|
logBlocks = 1;
|
||||||
code = &simplified;
|
code = &simplified;
|
||||||
//if (ir.GetInstructions().size() >= 24)
|
//if (ir.GetInstructions().size() >= 24)
|
||||||
|
@ -405,6 +405,7 @@ struct IROptions {
|
|||||||
bool unalignedLoadStoreVec4;
|
bool unalignedLoadStoreVec4;
|
||||||
bool preferVec4;
|
bool preferVec4;
|
||||||
bool preferVec4Dot;
|
bool preferVec4Dot;
|
||||||
|
bool optimizeForInterpreter;
|
||||||
};
|
};
|
||||||
|
|
||||||
const IRMeta *GetIRMeta(IROp op);
|
const IRMeta *GetIRMeta(IROp op);
|
||||||
|
@ -48,6 +48,8 @@ IRJit::IRJit(MIPSState *mipsState) : frontend_(mipsState->HasDefaultPrefix()), m
|
|||||||
// blTrampolines_ = kernelMemory.Alloc(size, true, "trampoline");
|
// blTrampolines_ = kernelMemory.Alloc(size, true, "trampoline");
|
||||||
InitIR();
|
InitIR();
|
||||||
|
|
||||||
|
jo.optimizeForInterpreter = true;
|
||||||
|
|
||||||
IROptions opts{};
|
IROptions opts{};
|
||||||
opts.disableFlags = g_Config.uJitDisableFlags;
|
opts.disableFlags = g_Config.uJitDisableFlags;
|
||||||
#if PPSSPP_ARCH(RISCV64)
|
#if PPSSPP_ARCH(RISCV64)
|
||||||
@ -55,7 +57,7 @@ IRJit::IRJit(MIPSState *mipsState) : frontend_(mipsState->HasDefaultPrefix()), m
|
|||||||
opts.unalignedLoadStore = false;
|
opts.unalignedLoadStore = false;
|
||||||
opts.unalignedLoadStoreVec4 = true;
|
opts.unalignedLoadStoreVec4 = true;
|
||||||
opts.preferVec4 = cpu_info.RiscV_V;
|
opts.preferVec4 = cpu_info.RiscV_V;
|
||||||
#elif PPSSPP_ARCH(ARM)
|
#elif PPSSPP_ARCH(ARM) || PPSSPP_ARCH(ARM64)
|
||||||
opts.unalignedLoadStore = (opts.disableFlags & (uint32_t)JitDisable::LSU_UNALIGNED) == 0;
|
opts.unalignedLoadStore = (opts.disableFlags & (uint32_t)JitDisable::LSU_UNALIGNED) == 0;
|
||||||
opts.unalignedLoadStoreVec4 = true;
|
opts.unalignedLoadStoreVec4 = true;
|
||||||
opts.preferVec4 = cpu_info.bASIMD || cpu_info.bNEON;
|
opts.preferVec4 = cpu_info.bASIMD || cpu_info.bNEON;
|
||||||
@ -65,6 +67,7 @@ IRJit::IRJit(MIPSState *mipsState) : frontend_(mipsState->HasDefaultPrefix()), m
|
|||||||
opts.unalignedLoadStoreVec4 = false;
|
opts.unalignedLoadStoreVec4 = false;
|
||||||
opts.preferVec4 = true;
|
opts.preferVec4 = true;
|
||||||
#endif
|
#endif
|
||||||
|
opts.optimizeForInterpreter = jo.optimizeForInterpreter;
|
||||||
frontend_.SetOptions(opts);
|
frontend_.SetOptions(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +146,7 @@ bool IRJit::CompileBlock(u32 em_address, std::vector<IRInst> &instructions, u32
|
|||||||
|
|
||||||
IRBlock *b = blocks_.GetBlock(block_num);
|
IRBlock *b = blocks_.GetBlock(block_num);
|
||||||
b->SetInstructions(instructions);
|
b->SetInstructions(instructions);
|
||||||
b->SetOriginalSize(mipsBytes);
|
b->SetOriginalAddrSize(em_address, mipsBytes);
|
||||||
if (preload) {
|
if (preload) {
|
||||||
// Hash, then only update page stats, don't link yet.
|
// Hash, then only update page stats, don't link yet.
|
||||||
// TODO: Should we always hash? Then we can reuse blocks.
|
// TODO: Should we always hash? Then we can reuse blocks.
|
||||||
|
@ -69,7 +69,8 @@ public:
|
|||||||
bool HasOriginalFirstOp() const;
|
bool HasOriginalFirstOp() const;
|
||||||
bool RestoreOriginalFirstOp(int number);
|
bool RestoreOriginalFirstOp(int number);
|
||||||
bool IsValid() const { return origAddr_ != 0 && origFirstOpcode_.encoding != 0x68FFFFFF; }
|
bool IsValid() const { return origAddr_ != 0 && origFirstOpcode_.encoding != 0x68FFFFFF; }
|
||||||
void SetOriginalSize(u32 size) {
|
void SetOriginalAddrSize(u32 address, u32 size) {
|
||||||
|
origAddr_ = address;
|
||||||
origSize_ = size;
|
origSize_ = size;
|
||||||
}
|
}
|
||||||
void SetTargetOffset(int offset) {
|
void SetTargetOffset(int offset) {
|
||||||
@ -114,25 +115,28 @@ public:
|
|||||||
IRBlockCache() {}
|
IRBlockCache() {}
|
||||||
void Clear();
|
void Clear();
|
||||||
std::vector<int> FindInvalidatedBlockNumbers(u32 address, u32 length);
|
std::vector<int> FindInvalidatedBlockNumbers(u32 address, u32 length);
|
||||||
void FinalizeBlock(int i, bool preload = false);
|
void FinalizeBlock(int blockNum, bool preload = false);
|
||||||
int GetNumBlocks() const override { return (int)blocks_.size(); }
|
int GetNumBlocks() const override { return (int)blocks_.size(); }
|
||||||
int AllocateBlock(int emAddr) {
|
int AllocateBlock(int emAddr) {
|
||||||
blocks_.push_back(IRBlock(emAddr));
|
blocks_.push_back(IRBlock(emAddr));
|
||||||
return (int)blocks_.size() - 1;
|
return (int)blocks_.size() - 1;
|
||||||
}
|
}
|
||||||
IRBlock *GetBlock(int i) {
|
IRBlock *GetBlock(int blockNum) {
|
||||||
if (i >= 0 && i < (int)blocks_.size()) {
|
if (blockNum >= 0 && blockNum < (int)blocks_.size()) {
|
||||||
return &blocks_[i];
|
return &blocks_[blockNum];
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IRBlock *GetBlockUnchecked(int i) {
|
bool IsValidBlock(int blockNum) const override {
|
||||||
return &blocks_[i];
|
return blockNum < (int)blocks_.size() && blocks_[blockNum].IsValid();
|
||||||
}
|
}
|
||||||
const IRBlock *GetBlock(int i) const {
|
IRBlock *GetBlockUnchecked(int blockNum) {
|
||||||
if (i >= 0 && i < (int)blocks_.size()) {
|
return &blocks_[blockNum];
|
||||||
return &blocks_[i];
|
}
|
||||||
|
const IRBlock *GetBlock(int blockNum) const {
|
||||||
|
if (blockNum >= 0 && blockNum < (int)blocks_.size()) {
|
||||||
|
return &blocks_[blockNum];
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -714,6 +714,10 @@ void IRNativeBlockCacheDebugInterface::Init(const IRNativeBackend *backend) {
|
|||||||
backend_ = backend;
|
backend_ = backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IRNativeBlockCacheDebugInterface::IsValidBlock(int blockNum) const {
|
||||||
|
return irBlocks_.IsValidBlock(blockNum);
|
||||||
|
}
|
||||||
|
|
||||||
int IRNativeBlockCacheDebugInterface::GetNumBlocks() const {
|
int IRNativeBlockCacheDebugInterface::GetNumBlocks() const {
|
||||||
return irBlocks_.GetNumBlocks();
|
return irBlocks_.GetNumBlocks();
|
||||||
}
|
}
|
||||||
|
@ -162,10 +162,11 @@ class IRNativeBlockCacheDebugInterface : public JitBlockCacheDebugInterface {
|
|||||||
public:
|
public:
|
||||||
IRNativeBlockCacheDebugInterface(const MIPSComp::IRBlockCache &irBlocks);
|
IRNativeBlockCacheDebugInterface(const MIPSComp::IRBlockCache &irBlocks);
|
||||||
void Init(const IRNativeBackend *backend);
|
void Init(const IRNativeBackend *backend);
|
||||||
int GetNumBlocks() const;
|
int GetNumBlocks() const override;
|
||||||
int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const;
|
int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) const override;
|
||||||
JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const;
|
JitBlockDebugInfo GetBlockDebugInfo(int blockNum) const override;
|
||||||
void ComputeStats(BlockCacheStats &bcStats) const;
|
void ComputeStats(BlockCacheStats &bcStats) const override;
|
||||||
|
bool IsValidBlock(int blockNum) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void GetBlockCodeRange(int blockNum, int *startOffset, int *size) const;
|
void GetBlockCodeRange(int blockNum, int *startOffset, int *size) const;
|
||||||
|
@ -109,6 +109,7 @@ public:
|
|||||||
virtual int GetBlockNumberFromStartAddress(u32 em_address, bool realBlocksOnly = true) 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;
|
||||||
virtual void ComputeStats(BlockCacheStats &bcStats) const = 0;
|
virtual void ComputeStats(BlockCacheStats &bcStats) const = 0;
|
||||||
|
virtual bool IsValidBlock(int blockNum) const = 0;
|
||||||
|
|
||||||
virtual ~JitBlockCacheDebugInterface() {}
|
virtual ~JitBlockCacheDebugInterface() {}
|
||||||
};
|
};
|
||||||
@ -164,6 +165,7 @@ public:
|
|||||||
void RestoreSavedEmuHackOps(const std::vector<u32> &saved);
|
void RestoreSavedEmuHackOps(const std::vector<u32> &saved);
|
||||||
|
|
||||||
int GetNumBlocks() const override { return num_blocks_; }
|
int GetNumBlocks() const override { return num_blocks_; }
|
||||||
|
bool IsValidBlock(int blockNum) const override { return blockNum < num_blocks_ && !blocks_[blockNum].invalid; }
|
||||||
|
|
||||||
static int GetBlockExitSize();
|
static int GetBlockExitSize();
|
||||||
|
|
||||||
|
@ -237,6 +237,8 @@ namespace MIPSComp {
|
|||||||
// ARM64 and RV64
|
// ARM64 and RV64
|
||||||
bool useStaticAlloc;
|
bool useStaticAlloc;
|
||||||
bool enablePointerify;
|
bool enablePointerify;
|
||||||
|
// IR Interpreter
|
||||||
|
bool optimizeForInterpreter;
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
bool enableBlocklink;
|
bool enableBlocklink;
|
||||||
@ -245,6 +247,4 @@ namespace MIPSComp {
|
|||||||
bool continueJumps;
|
bool continueJumps;
|
||||||
int continueMaxInstructions;
|
int continueMaxInstructions;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ RiscVJitBackend::RiscVJitBackend(JitOptions &jitopt, IRBlockCache &blocks)
|
|||||||
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
||||||
jo.enablePointerify = false;
|
jo.enablePointerify = false;
|
||||||
}
|
}
|
||||||
|
jo.optimizeForInterpreter = false;
|
||||||
|
|
||||||
// Since we store the offset, this is as big as it can be.
|
// Since we store the offset, this is as big as it can be.
|
||||||
// We could shift off one bit to double it, would need to change RiscVAsm.
|
// We could shift off one bit to double it, would need to change RiscVAsm.
|
||||||
|
@ -41,6 +41,7 @@ X64JitBackend::X64JitBackend(JitOptions &jitopt, IRBlockCache &blocks)
|
|||||||
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
if (((intptr_t)Memory::base & 0x00000000FFFFFFFFUL) != 0) {
|
||||||
jo.enablePointerify = false;
|
jo.enablePointerify = false;
|
||||||
}
|
}
|
||||||
|
jo.optimizeForInterpreter = false;
|
||||||
|
|
||||||
// Since we store the offset, this is as big as it can be.
|
// Since we store the offset, this is as big as it can be.
|
||||||
AllocCodeSpace(1024 * 1024 * 16);
|
AllocCodeSpace(1024 * 1024 * 16);
|
||||||
|
@ -1060,6 +1060,9 @@ void JitCompareScreen::UpdateDisasm() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
|
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
|
||||||
|
if (!blockCacheDebug->IsValidBlock(currentBlock_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
char temp[256];
|
char temp[256];
|
||||||
snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks());
|
snprintf(temp, sizeof(temp), "%i/%i", currentBlock_, blockCacheDebug->GetNumBlocks());
|
||||||
@ -1205,7 +1208,13 @@ UI::EventReturn JitCompareScreen::OnRandomBlock(UI::EventParams &e) {
|
|||||||
|
|
||||||
int numBlocks = blockCache->GetNumBlocks();
|
int numBlocks = blockCache->GetNumBlocks();
|
||||||
if (numBlocks > 0) {
|
if (numBlocks > 0) {
|
||||||
currentBlock_ = rand() % numBlocks;
|
int tries = 100;
|
||||||
|
while (tries-- > 0) {
|
||||||
|
currentBlock_ = rand() % numBlocks;
|
||||||
|
if (blockCache->IsValidBlock(currentBlock_)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
UpdateDisasm();
|
UpdateDisasm();
|
||||||
return UI::EVENT_DONE;
|
return UI::EVENT_DONE;
|
||||||
|
Loading…
Reference in New Issue
Block a user