From f27940478deeb2ad43ee6ad0ecefbb67e3e00107 Mon Sep 17 00:00:00 2001 From: magumagu Date: Thu, 26 Jun 2014 15:22:37 -0700 Subject: [PATCH] JitIL: Attempt to constant-fold more aggressively. --- Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp | 8 +++++++- Source/Core/Core/PowerPC/JitILCommon/IR.cpp | 22 +++++++++++++++++++-- Source/Core/Core/PowerPC/JitILCommon/IR.h | 8 +++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp index 0bc9e8ec74..0870a0c32d 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/IR_X86.cpp @@ -1684,7 +1684,13 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) { case CInt16: { if (!thisUsed) break; X64Reg reg = regFindFreeReg(RI); - Jit->MOV(32, R(reg), Imm32(ibuild->GetImmValue(I))); + u64 val = ibuild->GetImmValue64(I); + if ((u32)val == val) + Jit->MOV(32, R(reg), Imm32(val)); + else if ((s32)val == val) + Jit->MOV(64, R(reg), Imm32(val)); + else + Jit->MOV(64, R(reg), Imm64(val)); RI.regs[reg] = I; break; } diff --git a/Source/Core/Core/PowerPC/JitILCommon/IR.cpp b/Source/Core/Core/PowerPC/JitILCommon/IR.cpp index 90450ea652..8bb10142d1 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/IR.cpp +++ b/Source/Core/Core/PowerPC/JitILCommon/IR.cpp @@ -362,6 +362,8 @@ InstLoc IRBuilder::FoldUOp(unsigned Opcode, InstLoc Op1, unsigned extra) { return EmitICmpSgt(getOp1(Op1), getOp2(Op1)); if (getOpcode(*Op1) == ICmpCRUnsigned) return EmitICmpUgt(getOp1(Op1), getOp2(Op1)); + if (isImm(*Op1)) + return EmitIntConst((s64)GetImmValue64(Op1) > 0); } if (Opcode == FastCRLTSet) { @@ -369,11 +371,15 @@ InstLoc IRBuilder::FoldUOp(unsigned Opcode, InstLoc Op1, unsigned extra) { return EmitICmpSlt(getOp1(Op1), getOp2(Op1)); if (getOpcode(*Op1) == ICmpCRUnsigned) return EmitICmpUlt(getOp1(Op1), getOp2(Op1)); + if (isImm(*Op1)) + return EmitIntConst(!!(GetImmValue64(Op1) & (1ull << 62))); } if (Opcode == FastCREQSet) { if (getOpcode(*Op1) == ICmpCRSigned || getOpcode(*Op1) == ICmpCRUnsigned) return EmitICmpEq(getOp1(Op1), getOp2(Op1)); + if (isImm(*Op1)) + return EmitIntConst((GetImmValue64(Op1) & 0xFFFFFFFFU) == 0); } return EmitUOp(Opcode, Op1, extra); @@ -982,10 +988,22 @@ InstLoc IRBuilder::FoldICmp(unsigned Opcode, InstLoc Op1, InstLoc Op2) { } InstLoc IRBuilder::FoldICmpCRSigned(InstLoc Op1, InstLoc Op2) { + if (isImm(*Op1)) { + if (isImm(*Op2)) { + s64 diff = (s64)(s32)GetImmValue(Op1) - (s64)(s32)GetImmValue(Op2); + return EmitIntConst64((u64)diff); + } + } return EmitBiOp(ICmpCRSigned, Op1, Op2); } InstLoc IRBuilder::FoldICmpCRUnsigned(InstLoc Op1, InstLoc Op2) { + if (isImm(*Op1)) { + if (isImm(*Op2)) { + u64 diff = (u64)GetImmValue(Op1) - (u64)GetImmValue(Op2); + return EmitIntConst64(diff); + } + } return EmitBiOp(ICmpCRUnsigned, Op1, Op2); } @@ -1045,7 +1063,7 @@ InstLoc IRBuilder::FoldBiOp(unsigned Opcode, InstLoc Op1, InstLoc Op2, unsigned } } -InstLoc IRBuilder::EmitIntConst(unsigned value) { +InstLoc IRBuilder::EmitIntConst64(u64 value) { InstLoc curIndex = InstList.data() + InstList.size(); InstList.push_back(CInt32 | ((unsigned int)ConstList.size() << 8)); MarkUsed.push_back(false); @@ -1053,7 +1071,7 @@ InstLoc IRBuilder::EmitIntConst(unsigned value) { return curIndex; } -unsigned IRBuilder::GetImmValue(InstLoc I) const { +u64 IRBuilder::GetImmValue64(InstLoc I) const { return ConstList[*I >> 8]; } diff --git a/Source/Core/Core/PowerPC/JitILCommon/IR.h b/Source/Core/Core/PowerPC/JitILCommon/IR.h index 37887891e1..58202ffd9b 100644 --- a/Source/Core/Core/PowerPC/JitILCommon/IR.h +++ b/Source/Core/Core/PowerPC/JitILCommon/IR.h @@ -246,7 +246,8 @@ private: unsigned ComputeKnownZeroBits(InstLoc I) const; public: - InstLoc EmitIntConst(unsigned value); + InstLoc EmitIntConst(unsigned value) { return EmitIntConst64(value); } + InstLoc EmitIntConst64(u64 value); InstLoc EmitStoreLink(InstLoc val) { return FoldUOp(StoreLink, val); } @@ -559,7 +560,8 @@ public: InstLoc getFirstInst() { return InstList.data(); } unsigned int getNumInsts() { return (unsigned int)InstList.size(); } unsigned int ReadInst(InstLoc I) { return *I; } - unsigned int GetImmValue(InstLoc I) const; + unsigned int GetImmValue(InstLoc I) const { return (u32)GetImmValue64(I); } + u64 GetImmValue64(InstLoc I) const; void SetMarkUsed(InstLoc I); bool IsMarkUsed(InstLoc I) const; void WriteToFile(u64 codeHash); @@ -598,7 +600,7 @@ private: std::vector InstList; // FIXME: We must ensure this is continuous! std::vector MarkUsed; // Used for IRWriter - std::vector ConstList; + std::vector ConstList; InstLoc curReadPtr; InstLoc GRegCache[32]; InstLoc GRegCacheStore[32];