From b37ba9e5994657bf272ba6c50c758af1897e611f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 31 Dec 2017 17:14:34 -0800 Subject: [PATCH] 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. --- Core/MIPS/IR/IRFrontend.cpp | 4 +--- Core/MIPS/IR/IRFrontend.h | 9 +++++++-- Core/MIPS/IR/IRInst.h | 4 ++++ Core/MIPS/IR/IRJit.cpp | 4 ++++ Core/MIPS/IR/IRPassSimplify.cpp | 32 +++++++++++++++----------------- Core/MIPS/IR/IRPassSimplify.h | 18 +++++++++--------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index bdafffae96..d3da613ca4 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -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 &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) diff --git a/Core/MIPS/IR/IRFrontend.h b/Core/MIPS/IR/IRFrontend.h index e59cf3c70f..600177be20 100644 --- a/Core/MIPS/IR/IRFrontend.h +++ b/Core/MIPS/IR/IRFrontend.h @@ -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 diff --git a/Core/MIPS/IR/IRInst.h b/Core/MIPS/IR/IRInst.h index 1506542177..a54e4cab93 100644 --- a/Core/MIPS/IR/IRInst.h +++ b/Core/MIPS/IR/IRInst.h @@ -363,6 +363,10 @@ private: std::vector constPool_; }; +struct IROptions { + bool unalignedLoadStore; +}; + const IRMeta *GetIRMeta(IROp op); void DisassembleIR(char *buf, size_t bufsize, IRInst inst, const u32 *constPool); void InitIR(); diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 7110ab7ea2..84db03b150 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -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() { diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index c8fdbafbbc..c8e728f45c 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -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 = ∈ 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 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 ReorderLoadStoreOps(std::vector &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; diff --git a/Core/MIPS/IR/IRPassSimplify.h b/Core/MIPS/IR/IRPassSimplify.h index aeb2cff238..118b44128f 100644 --- a/Core/MIPS/IR/IRPassSimplify.h +++ b/Core/MIPS/IR/IRPassSimplify.h @@ -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);