mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-15 02:29:51 +01:00
Fix IRTEMP clash bug. Add more cases to the constant propagation pass.
This commit is contained in:
1 parent
aae32bd929
commit
14df39d7c9
9 files changed
+94
-29
No files matched your search
@@ -26,6 +26,12 @@ u32 Evaluate(u32 a, u32 b, IROp op) {
|
||||
case IROp::And: case IROp::AndConst: return a & b;
|
||||
case IROp::Or: case IROp::OrConst: return a | b;
|
||||
case IROp::Xor: case IROp::XorConst: return a ^ b;
|
||||
case IROp::Shr: case IROp::ShrImm: return a >> b;
|
||||
case IROp::Sar: case IROp::SarImm: return (s32)a >> b;
|
||||
case IROp::Ror: case IROp::RorImm: return (a >> b) | (a << (32 - b));
|
||||
case IROp::Shl: case IROp::ShlImm: return a << b;
|
||||
case IROp::Slt: case IROp::SltConst: return ((s32)a < (s32)b);
|
||||
case IROp::SltU: case IROp::SltUConst: return (a < b);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -38,16 +44,19 @@ IROp ArithToArithConst(IROp op) {
|
||||
case IROp::And: return IROp::AndConst;
|
||||
case IROp::Or: return IROp::OrConst;
|
||||
case IROp::Xor: return IROp::XorConst;
|
||||
case IROp::Slt: return IROp::SltConst;
|
||||
case IROp::SltU: return IROp::SltUConst;
|
||||
default:
|
||||
return (IROp)-1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
bool PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
IRRegCache gpr(&out);
|
||||
|
||||
const u32 *constants = in.GetConstants().data();
|
||||
bool logBlocks = false;
|
||||
for (int i = 0; i < (int)in.GetInstructions().size(); i++) {
|
||||
IRInst inst = in.GetInstructions()[i];
|
||||
bool symmetric = true;
|
||||
@@ -57,6 +66,8 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
break;
|
||||
|
||||
case IROp::Sub:
|
||||
case IROp::Slt:
|
||||
case IROp::SltU:
|
||||
symmetric = false; // fallthrough
|
||||
case IROp::Add:
|
||||
case IROp::And:
|
||||
@@ -67,7 +78,8 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
} else if (gpr.IsImm(inst.src2) && inst.src1 != inst.src2 && inst.dest != inst.src2) {
|
||||
gpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
if (gpr.GetImm(inst.src2) == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) {
|
||||
out.Write(IROp::Mov, inst.dest, inst.src1);
|
||||
if (inst.dest != inst.src1)
|
||||
out.Write(IROp::Mov, inst.dest, inst.src1);
|
||||
} else {
|
||||
out.Write(ArithToArithConst(inst.op), inst.dest, inst.src1, out.AddConstant(gpr.GetImm(inst.src2)));
|
||||
}
|
||||
@@ -85,6 +97,8 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
case IROp::AndConst:
|
||||
case IROp::OrConst:
|
||||
case IROp::XorConst:
|
||||
case IROp::SltConst:
|
||||
case IROp::SltUConst:
|
||||
if (gpr.IsImm(inst.src1)) {
|
||||
gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), constants[inst.src2], inst.op));
|
||||
} else {
|
||||
@@ -93,6 +107,18 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
}
|
||||
break;
|
||||
|
||||
case IROp::ShlImm:
|
||||
case IROp::ShrImm:
|
||||
case IROp::RorImm:
|
||||
case IROp::SarImm:
|
||||
if (gpr.IsImm(inst.src1)) {
|
||||
gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), inst.src2, inst.op));
|
||||
} else {
|
||||
gpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
goto doDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
case IROp::Mov:
|
||||
if (inst.src1 == inst.src2) {
|
||||
// Nop
|
||||
@@ -107,18 +133,33 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
case IROp::Store8:
|
||||
case IROp::Store16:
|
||||
case IROp::Store32:
|
||||
// Just pass through, no excessive flushing
|
||||
gpr.MapInIn(inst.dest, inst.src1);
|
||||
goto doDefault;
|
||||
if (gpr.IsImm(inst.src1) && inst.src1 != inst.dest) {
|
||||
gpr.MapIn(inst.dest);
|
||||
out.Write(inst.op, inst.dest, 0, out.AddConstant(gpr.GetImm(inst.src1) + constants[inst.src2]));
|
||||
} else {
|
||||
// Just pass through, no excessive flushing
|
||||
gpr.MapInIn(inst.dest, inst.src1);
|
||||
goto doDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
case IROp::Load8:
|
||||
case IROp::Load8Ext:
|
||||
case IROp::Load16:
|
||||
case IROp::Load16Ext:
|
||||
case IROp::Load32:
|
||||
gpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
goto doDefault;
|
||||
if (gpr.IsImm(inst.src1) && inst.src1 != inst.dest && inst.src2 != inst.dest) {
|
||||
gpr.MapDirty(inst.dest);
|
||||
out.Write(inst.op, inst.dest, 0, out.AddConstant(gpr.GetImm(inst.src1) + constants[inst.src2]));
|
||||
logBlocks = true;
|
||||
} else {
|
||||
gpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
goto doDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
case IROp::Syscall:
|
||||
case IROp::Interpret:
|
||||
case IROp::ExitToConst:
|
||||
case IROp::ExitToReg:
|
||||
case IROp::ExitToConstIfEq:
|
||||
@@ -155,4 +196,5 @@ void PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return logBlocks;
|
||||
}
|
||||
Reference in new issue
Block a user