Permalink
Browse files

irjit: Combine lwl/lwr and swl/swr, like before.

Still want to inline the operation, because the backend shouldn't have to
redo it every time, and we want the temps cleaned up if possible.
  • Loading branch information...
unknownbrackets committed Jan 8, 2018
1 parent c6d690e commit b11f00cead9dd5a9686f72d47de94185b5c2ebd6
Showing with 64 additions and 0 deletions.
  1. +1 −0 Core/MIPS/IR/IRFrontend.cpp
  2. +62 −0 Core/MIPS/IR/IRPassSimplify.cpp
  3. +1 −0 Core/MIPS/IR/IRPassSimplify.h
@@ -252,6 +252,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
IRWriter *code = &ir;
if (!js.hadBreakpoints) {
static const IRPassFunc passes[] = {
&RemoveLoadStoreLeftRight,
&OptimizeFPMoves,
&PropagateConstants,
&PurgeTemps,
@@ -199,6 +199,68 @@ bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts) {
return logBlocks;
}
bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions &opts) {
IRInst dummy{ IROp::Nop };
bool logBlocks = false;
for (int i = 0, n = (int)in.GetInstructions().size(); i < n; ++i) {
const IRInst &inst = in.GetInstructions()[i];
const IRInst &next = i + 1 < n ? in.GetInstructions()[i + 1] : dummy;
// TODO: Reorder or look ahead to combine?
auto combineOpposite = [&](IROp matchOp, int matchOff, IROp replaceOp, int replaceOff) {
if (!opts.unalignedLoadStore)
return false;
if (next.op != matchOp || next.dest != inst.dest || next.src1 != inst.src1)
return false;
if (inst.constant + matchOff != next.constant)
return false;
// Write out one unaligned op.
out.Write(replaceOp, inst.dest, inst.src1, out.AddConstant(inst.constant + replaceOff));
// Skip the next one, replaced.
i++;
return true;
};
switch (inst.op) {
case IROp::Load32Left:
if (!combineOpposite(IROp::Load32Right, -3, IROp::Load32, -3)) {
// TODO: Flatten.
out.Write(inst);
}
break;
case IROp::Load32Right:
if (!combineOpposite(IROp::Load32Left, 3, IROp::Load32, 0)) {
// TODO: Flatten.
out.Write(inst);
}
break;
case IROp::Store32Left:
if (!combineOpposite(IROp::Store32Right, -3, IROp::Store32, -3)) {
// TODO: Flatten.
out.Write(inst);
}
break;
case IROp::Store32Right:
if (!combineOpposite(IROp::Store32Left, 3, IROp::Store32, 0)) {
// TODO: Flatten.
out.Write(inst);
}
break;
default:
out.Write(inst);
break;
}
}
return logBlocks;
}
bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts) {
IRRegCache gpr(&out);
@@ -6,6 +6,7 @@ typedef bool (*IRPassFunc)(const IRWriter &in, IRWriter &out, const IROptions &o
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out, const IROptions &opts);
// Block optimizer passes of varying usefulness.
bool RemoveLoadStoreLeftRight(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool ReduceLoads(const IRWriter &in, IRWriter &out, const IROptions &opts);

0 comments on commit b11f00c

Please sign in to comment.