Skip to content

Commit 5dec3ca

Browse files
authored
Merge pull request #19265 from hrydgard/ir-lwr
More minor IR optimizations
2 parents ef91fa8 + 5bfc025 commit 5dec3ca

File tree

5 files changed

+68
-7
lines changed

5 files changed

+68
-7
lines changed

Core/MIPS/IR/IRCompALU.cpp

+14-3
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,20 @@ void IRFrontend::Comp_Special3(MIPSOpcode op) {
248248
{
249249
u32 sourcemask = mask >> pos;
250250
u32 destmask = ~(sourcemask << pos);
251-
ir.Write(IROp::AndConst, IRTEMP_0, rs, ir.AddConstant(sourcemask));
252-
if (pos != 0) {
253-
ir.Write(IROp::ShlImm, IRTEMP_0, IRTEMP_0, pos);
251+
252+
if (size != 32) {
253+
// Need to use the sourcemask.
254+
ir.Write(IROp::AndConst, IRTEMP_0, rs, ir.AddConstant(sourcemask));
255+
if (pos != 0) {
256+
ir.Write(IROp::ShlImm, IRTEMP_0, IRTEMP_0, pos);
257+
}
258+
} else {
259+
// If the shl takes care of the sourcemask, don't need to and.
260+
if (pos != 0) {
261+
ir.Write(IROp::ShlImm, IRTEMP_0, rs, pos);
262+
} else {
263+
ir.Write(IROp::Mov, IRTEMP_0, rs);
264+
}
254265
}
255266
ir.Write(IROp::AndConst, rt, rt, ir.AddConstant(destmask));
256267
ir.Write(IROp::Or, rt, rt, IRTEMP_0);

Core/MIPS/IR/IRInst.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ static const IRMeta irMeta[] = {
121121
{ IROp::FMovFromGPR, "FMovFromGPR", "FG" },
122122
{ IROp::FMovToGPR, "FMovToGPR", "GF" },
123123
{ IROp::OptFMovToGPRShr8, "OptFMovToGPRShr8", "GF" },
124+
{ IROp::OptFCvtSWFromGPR, "OptFCvtSWFromGPR", "FG" },
124125
{ IROp::FpCondFromReg, "FpCondFromReg", "_G" },
125126
{ IROp::FpCondToReg, "FpCondToReg", "G" },
126127
{ IROp::FpCtrlFromReg, "FpCtrlFromReg", "_G" },

Core/MIPS/IR/IRInst.h

+1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ enum class IROp : uint8_t {
138138
FCvtScaledSW,
139139

140140
FMovFromGPR,
141+
OptFCvtSWFromGPR,
141142
FMovToGPR,
142143
OptFMovToGPRShr8,
143144

Core/MIPS/IR/IRInterpreter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,9 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
997997
case IROp::FMovFromGPR:
998998
memcpy(&mips->f[inst->dest], &mips->r[inst->src1], 4);
999999
break;
1000+
case IROp::OptFCvtSWFromGPR:
1001+
mips->f[inst->dest] = (float)(int)mips->r[inst->src1];
1002+
break;
10001003
case IROp::FMovToGPR:
10011004
memcpy(&mips->r[inst->dest], &mips->f[inst->src1], 4);
10021005
break;
@@ -1007,6 +1010,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
10071010
mips->r[inst->dest] = temp >> 8;
10081011
break;
10091012
}
1013+
10101014
case IROp::ExitToConst:
10111015
return inst->constant;
10121016

Core/MIPS/IR/IRPassSimplify.cpp

+48-4
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,15 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
229229
CONDITIONAL_DISABLE;
230230

231231
bool logBlocks = false;
232+
233+
bool letThroughHalves = false;
234+
if (opts.optimizeForInterpreter) {
235+
// If we're using the interpreter, which can handle these instructions directly,
236+
// don't break "half" instructions up.
237+
// Of course, we still want to combine if possible.
238+
letThroughHalves = true;
239+
}
240+
232241
for (int i = 0, n = (int)in.GetInstructions().size(); i < n; ++i) {
233242
const IRInst &inst = in.GetInstructions()[i];
234243

@@ -305,6 +314,11 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
305314
switch (inst.op) {
306315
case IROp::Load32Left:
307316
if (!combineOpposite(IROp::Load32Right, -3, IROp::Load32, -3)) {
317+
if (letThroughHalves) {
318+
out.Write(inst);
319+
break;
320+
}
321+
308322
addCommonProlog();
309323
// dest &= (0x00ffffff >> shift)
310324
// Alternatively, could shift to a wall and back (but would require two shifts each way.)
@@ -339,6 +353,10 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
339353

340354
case IROp::Load32Right:
341355
if (!combineOpposite(IROp::Load32Left, 3, IROp::Load32, 0)) {
356+
if (letThroughHalves) {
357+
out.Write(inst);
358+
break;
359+
}
342360
addCommonProlog();
343361
// IRTEMP_LR_VALUE >>= shift
344362
out.Write(IROp::Shr, IRTEMP_LR_VALUE, IRTEMP_LR_VALUE, IRTEMP_LR_SHIFT);
@@ -382,6 +400,10 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
382400

383401
case IROp::Store32Left:
384402
if (!combineOpposite(IROp::Store32Right, -3, IROp::Store32, -3)) {
403+
if (letThroughHalves) {
404+
out.Write(inst);
405+
break;
406+
}
385407
addCommonProlog();
386408
// IRTEMP_LR_VALUE &= 0xffffff00 << shift
387409
out.WriteSetConstant(IRTEMP_LR_MASK, 0xffffff00);
@@ -399,6 +421,10 @@ bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions
399421

400422
case IROp::Store32Right:
401423
if (!combineOpposite(IROp::Store32Left, 3, IROp::Store32, 0)) {
424+
if (letThroughHalves) {
425+
out.Write(inst);
426+
break;
427+
}
402428
addCommonProlog();
403429
// IRTEMP_LR_VALUE &= 0x00ffffff << (24 - shift)
404430
out.WriteSetConstant(IRTEMP_LR_MASK, 0x00ffffff);
@@ -2174,13 +2200,23 @@ bool OptimizeLoadsAfterStores(const IRWriter &in, IRWriter &out, const IROptions
21742200
case IROp::Store32:
21752201
if (next.op == IROp::Load32 &&
21762202
next.constant == inst.constant &&
2177-
next.dest == inst.src3 &&
2203+
next.dest == inst.dest &&
21782204
next.src1 == inst.src1) {
21792205
// The upcoming load is completely redundant.
21802206
// Skip it.
21812207
i++;
21822208
}
21832209
break;
2210+
case IROp::StoreVec4:
2211+
if (next.op == IROp::LoadVec4 &&
2212+
next.constant == inst.constant &&
2213+
next.dest == inst.dest &&
2214+
next.src1 == inst.src1) {
2215+
// The upcoming load is completely redundant. These are common in Wipeout.
2216+
// Skip it. NOTE: It looks like vector load/stores uses different register assignments, but there's a union between dest and src3.
2217+
i++;
2218+
}
2219+
break;
21842220
default:
21852221
break;
21862222
}
@@ -2243,10 +2279,18 @@ bool OptimizeForInterpreter(const IRWriter &in, IRWriter &out, const IROptions &
22432279
inst.op = IROp::OptFMovToGPRShr8;
22442280
i++; // Skip the next instruction.
22452281
}
2246-
out.Write(inst);
2247-
} else {
2248-
out.Write(inst);
22492282
}
2283+
out.Write(inst);
2284+
break;
2285+
case IROp::FMovFromGPR:
2286+
if (!last) {
2287+
IRInst next = in.GetInstructions()[i + 1];
2288+
if (next.op == IROp::FCvtSW && next.src1 == inst.dest && next.dest == inst.dest) {
2289+
inst.op = IROp::OptFCvtSWFromGPR;
2290+
i++; // Skip the next
2291+
}
2292+
}
2293+
out.Write(inst);
22502294
break;
22512295
default:
22522296
out.Write(inst);

0 commit comments

Comments
 (0)