irjit: Add options for compile/optimize steps.

This way the backend can set flags for the type of IR it wants.  It's
seems too complex to combine certain things like lwl/lwr in a pass.
This commit is contained in:
Unknown W. Brackets 2017-12-31 17:14:34 -08:00
parent 671be24105
commit b37ba9e599
6 changed files with 40 additions and 31 deletions

View File

@ -32,8 +32,6 @@
namespace MIPSComp {
IRFrontend::IRFrontend(bool startDefaultPrefix) {
logBlocks = 0;
dontLogBlocks = 0;
js.startDefaultPrefix = true;
js.hasSetRounding = false;
// js.currentRoundingFunc = convertS0ToSCRATCH1[0];
@ -267,7 +265,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, std::v
// &MergeLoadStore,
// &ThreeOpToTwoOp,
};
if (IRApplyPasses(passes, ARRAY_SIZE(passes), ir, simplified))
if (IRApplyPasses(passes, ARRAY_SIZE(passes), ir, simplified, opts))
logBlocks = 1;
code = &simplified;
//if (ir.GetInstructions().size() >= 24)

View File

@ -94,6 +94,10 @@ public:
js.EatPrefix();
}
void SetOptions(const IROptions &o) {
opts = o;
}
private:
void RestoreRoundingMode(bool force = false);
void ApplyRoundingMode(bool force = false);
@ -134,9 +138,10 @@ private:
// State
JitState js;
IRWriter ir;
IROptions opts{};
int dontLogBlocks;
int logBlocks;
int dontLogBlocks = 0;
int logBlocks = 0;
};
} // namespace

View File

@ -363,6 +363,10 @@ private:
std::vector<u32> constPool_;
};
struct IROptions {
bool unalignedLoadStore;
};
const IRMeta *GetIRMeta(IROp op);
void DisassembleIR(char *buf, size_t bufsize, IRInst inst, const u32 *constPool);
void InitIR();

View File

@ -41,6 +41,10 @@ IRJit::IRJit(MIPSState *mips) : frontend_(mips->HasDefaultPrefix()), mips_(mips)
u32 size = 128 * 1024;
// blTrampolines_ = kernelMemory.Alloc(size, true, "trampoline");
InitIR();
IROptions opts{};
opts.unalignedLoadStore = true;
frontend_.SetOptions(opts);
}
IRJit::~IRJit() {

View File

@ -110,9 +110,9 @@ IROp ShiftToShiftImm(IROp op) {
}
}
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out) {
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out, const IROptions &opts) {
if (c == 1) {
return passes[0](in, out);
return passes[0](in, out, opts);
}
bool logBlocks = false;
@ -121,7 +121,7 @@ bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWri
const IRWriter *nextIn = &in;
IRWriter *nextOut = &temp[1];
for (size_t i = 0; i < c - 1; ++i) {
if (passes[i](*nextIn, *nextOut)) {
if (passes[i](*nextIn, *nextOut, opts)) {
logBlocks = true;
}
@ -129,14 +129,14 @@ bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWri
nextIn = &temp[0];
}
if (passes[c - 1](*nextIn, out)) {
if (passes[c - 1](*nextIn, out, opts)) {
logBlocks = true;
}
return logBlocks;
}
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out) {
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts) {
const u32 *constants = !in.GetConstants().empty() ? &in.GetConstants()[0] : nullptr;
bool logBlocks = false;
IRInst prev;
@ -191,7 +191,7 @@ bool OptimizeFPMoves(const IRWriter &in, IRWriter &out) {
}
// Might be useful later on x86.
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out) {
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts) {
bool logBlocks = false;
for (int i = 0; i < (int)in.GetInstructions().size(); i++) {
IRInst inst = in.GetInstructions()[i];
@ -245,7 +245,7 @@ bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out) {
return logBlocks;
}
bool PropagateConstants(const IRWriter &in, IRWriter &out) {
bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts) {
IRRegCache gpr(&out);
const u32 *constants = !in.GetConstants().empty() ? &in.GetConstants()[0] : nullptr;
@ -619,7 +619,7 @@ int IRDestGPR(const IRInst &inst) {
return -1;
}
bool PurgeTemps(const IRWriter &in, IRWriter &out) {
bool PurgeTemps(const IRWriter &in, IRWriter &out, const IROptions &opts) {
std::vector<IRInst> insts;
insts.reserve(in.GetInstructions().size());
@ -710,7 +710,7 @@ bool PurgeTemps(const IRWriter &in, IRWriter &out) {
return logBlocks;
}
bool ReduceLoads(const IRWriter &in, IRWriter &out) {
bool ReduceLoads(const IRWriter &in, IRWriter &out, const IROptions &opts) {
for (u32 value : in.GetConstants()) {
out.AddConstant(value);
}
@ -846,7 +846,7 @@ static std::vector<IRInst> ReorderLoadStoreOps(std::vector<IRInst> &ops, const u
return ops;
}
bool ReorderLoadStore(const IRWriter &in, IRWriter &out) {
bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts) {
bool logBlocks = false;
enum class RegState : u8 {
@ -1042,7 +1042,7 @@ bool ReorderLoadStore(const IRWriter &in, IRWriter &out) {
return logBlocks;
}
bool MergeLoadStore(const IRWriter &in, IRWriter &out) {
bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts) {
bool logBlocks = false;
auto opsCompatible = [&](const IRInst &a, const IRInst &b, int dist) {
@ -1076,16 +1076,15 @@ bool MergeLoadStore(const IRWriter &in, IRWriter &out) {
break;
}
}
// Warning: this may generate unaligned stores.
if (c == 2 || c == 3) {
if ((c == 2 || c == 3) && opts.unalignedLoadStore) {
inst.op = IROp::Store16;
out.Write(inst);
prev = inst;
// Skip the next one.
// Skip the next one (the 3rd will be separate.)
++i;
continue;
}
if (c == 4) {
if (c == 4 && opts.unalignedLoadStore) {
inst.op = IROp::Store32;
out.Write(inst);
prev = inst;
@ -1108,8 +1107,7 @@ bool MergeLoadStore(const IRWriter &in, IRWriter &out) {
break;
}
}
// Warning: this may generate unaligned stores.
if (c == 2) {
if (c == 2 && opts.unalignedLoadStore) {
inst.op = IROp::Store32;
out.Write(inst);
prev = inst;

View File

@ -2,14 +2,14 @@
#include "Core/MIPS/IR/IRInst.h"
typedef bool (*IRPassFunc)(const IRWriter &in, IRWriter &out);
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out);
typedef bool (*IRPassFunc)(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool IRApplyPasses(const IRPassFunc *passes, size_t c, const IRWriter &in, IRWriter &out, const IROptions &opts);
// Block optimizer passes of varying usefulness.
bool PropagateConstants(const IRWriter &in, IRWriter &out);
bool PurgeTemps(const IRWriter &in, IRWriter &out);
bool ReduceLoads(const IRWriter &in, IRWriter &out);
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out);
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out);
bool ReorderLoadStore(const IRWriter &in, IRWriter &out);
bool MergeLoadStore(const IRWriter &in, IRWriter &out);
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);
bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);