mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-17 16:30:30 +02:00
jit-ir: Expand unused regs to regular GPRs.
This commit is contained in:
1 parent
99468c6fc1
commit
d06c6c080c
3 files changed
+40
-17
No files matched your search
+13
-13
@@ -33,8 +33,8 @@ static const IRMeta irMeta[] = {
|
||||
{ IROp::SltU, "SltU", "GGG" },
|
||||
{ IROp::SltUConst, "SltUConst", "GGC" },
|
||||
{ IROp::Clz, "Clz", "GG" },
|
||||
{ IROp::MovZ, "MovZ", "GGG" },
|
||||
{ IROp::MovNZ, "MovNZ", "GGG" },
|
||||
{ IROp::MovZ, "MovZ", "GGG", IRFLAG_SRC3DST },
|
||||
{ IROp::MovNZ, "MovNZ", "GGG", IRFLAG_SRC3DST },
|
||||
{ IROp::Max, "Max", "GGG" },
|
||||
{ IROp::Min, "Min", "GGG" },
|
||||
{ IROp::BSwap16, "BSwap16", "GG" },
|
||||
@@ -112,19 +112,19 @@ static const IRMeta irMeta[] = {
|
||||
|
||||
{ IROp::Interpret, "Interpret", "_C" },
|
||||
{ IROp::Downcount, "Downcount", "_II" },
|
||||
{ IROp::ExitToConst, "Exit", "C" },
|
||||
{ IROp::ExitToConstIfEq, "ExitIfEq", "CGG" },
|
||||
{ IROp::ExitToConstIfNeq, "ExitIfNeq", "CGG" },
|
||||
{ IROp::ExitToConstIfGtZ, "ExitIfGtZ", "CG" },
|
||||
{ IROp::ExitToConstIfGeZ, "ExitIfGeZ", "CG" },
|
||||
{ IROp::ExitToConstIfLeZ, "ExitIfLeZ", "CG" },
|
||||
{ IROp::ExitToConstIfLtZ, "ExitIfLtZ", "CG" },
|
||||
{ IROp::ExitToReg, "ExitToReg", "G" },
|
||||
{ IROp::Syscall, "Syscall", "_C" },
|
||||
{ IROp::Break, "Break", ""},
|
||||
{ IROp::ExitToConst, "Exit", "C", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfEq, "ExitIfEq", "CGG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfNeq, "ExitIfNeq", "CGG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfGtZ, "ExitIfGtZ", "CG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfGeZ, "ExitIfGeZ", "CG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfLeZ, "ExitIfLeZ", "CG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToConstIfLtZ, "ExitIfLtZ", "CG", IRFLAG_EXIT },
|
||||
{ IROp::ExitToReg, "ExitToReg", "G", IRFLAG_EXIT | IRFLAG_SRC3 },
|
||||
{ IROp::Syscall, "Syscall", "_C", IRFLAG_EXIT },
|
||||
{ IROp::Break, "Break", "", IRFLAG_EXIT},
|
||||
{ IROp::SetPC, "SetPC", "_G" },
|
||||
{ IROp::SetPCConst, "SetPC", "_C" },
|
||||
{ IROp::CallReplacement, "CallRepl", "_C"},
|
||||
{ IROp::CallReplacement, "CallRepl", "_C" },
|
||||
};
|
||||
|
||||
const IRMeta *metaIndex[256];
|
||||
|
||||
@@ -282,7 +282,12 @@ enum {
|
||||
};
|
||||
|
||||
enum IRFlags {
|
||||
IRFLAG_SRC3 = 1,
|
||||
// Uses src3, not dest.
|
||||
IRFLAG_SRC3 = 0x0001,
|
||||
// Uses src3 AND dest (i.e. mutates dest.)
|
||||
IRFLAG_SRC3DST = 0x0002,
|
||||
// Exit instruction (maybe conditional.)
|
||||
IRFLAG_EXIT = 0x0004,
|
||||
};
|
||||
|
||||
struct IRMeta {
|
||||
|
||||
@@ -443,10 +443,10 @@ bool IRReadsFromGPR(const IRInst &inst, int reg) {
|
||||
if (m->types[2] == 'G' && inst.src2 == reg) {
|
||||
return true;
|
||||
}
|
||||
if ((m->flags & IRFLAG_SRC3) != 0 && m->types[0] == 'G' && inst.src3 == reg) {
|
||||
if ((m->flags & (IRFLAG_SRC3 | IRFLAG_SRC3DST)) != 0 && m->types[0] == 'G' && inst.src3 == reg) {
|
||||
return true;
|
||||
}
|
||||
if (inst.op == IROp::Interpret) {
|
||||
if (inst.op == IROp::Interpret || inst.op == IROp::CallReplacement) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -474,6 +474,7 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out) {
|
||||
|
||||
int dest = IRDestGPR(inst);
|
||||
bool read = true;
|
||||
bool readByExit = true;
|
||||
switch (dest) {
|
||||
case IRTEMP_0:
|
||||
case IRTEMP_1:
|
||||
@@ -482,21 +483,38 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out) {
|
||||
// Unlike other ops, these don't need to persist between blocks.
|
||||
// So we consider them not read unless proven read.
|
||||
read = false;
|
||||
readByExit = false;
|
||||
// Intentional fall-through.
|
||||
|
||||
default:
|
||||
if (dest > IRTEMP_RHS) {
|
||||
// These might sometimes be implicitly read/written by other instructions.
|
||||
break;
|
||||
}
|
||||
for (int j = i + 1; j < n; j++) {
|
||||
const IRInst &laterInst = in.GetInstructions()[j];
|
||||
const IRMeta *m = GetIRMeta(laterInst.op);
|
||||
if (IRReadsFromGPR(laterInst, dest)) {
|
||||
// Read from, so we can't optimize out.
|
||||
read = true;
|
||||
break;
|
||||
}
|
||||
if (readByExit && (m->flags & IRFLAG_EXIT) != 0) {
|
||||
read = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IRDestGPR(laterInst) == dest) {
|
||||
// Clobbered, we can optimize out.
|
||||
// This happens sometimes with temporaries used for constant addresses.
|
||||
read = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Not a GPR output.
|
||||
case -1:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user