From c9855f2c22456018ad004a5c32cb2643d56cc5dd Mon Sep 17 00:00:00 2001 From: nodchip Date: Mon, 19 Jul 2010 15:07:19 +0000 Subject: [PATCH] JitIL: Implemented linear scan algorithm for register allocation. This is for speed improvement. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5919 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index ec12db09b3..2f1f9b726c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -30,7 +30,7 @@ because it the allocator needs to be able to free unused registers. In addition, this allows eliminating redundant mov instructions in a lot of cases. -The register allocation is just a simple forward greedy allocator. +The register allocation is linear scan allocation. */ #ifdef _MSC_VER @@ -58,6 +58,7 @@ struct RegInfo { IRBuilder* Build; InstLoc FirstI; std::vector IInfo; + std::vector lastUsed; InstLoc regs[16]; InstLoc fregs[16]; unsigned numSpills; @@ -67,7 +68,7 @@ struct RegInfo { unsigned numProfiledLoads; unsigned exitNumber; - RegInfo(JitIL* j, InstLoc f, unsigned insts) : Jit(j), FirstI(f), IInfo(insts) { + RegInfo(JitIL* j, InstLoc f, unsigned insts) : Jit(j), FirstI(f), IInfo(insts), lastUsed(insts) { for (unsigned i = 0; i < 16; i++) { regs[i] = 0; fregs[i] = 0; @@ -87,6 +88,7 @@ static void regMarkUse(RegInfo& R, InstLoc I, InstLoc Op, unsigned OpNum) { unsigned& info = R.IInfo[Op - R.FirstI]; if (info == 0) R.IInfo[I - R.FirstI] |= 1 << (OpNum + 1); if (info < 2) info++; + R.lastUsed[Op - R.FirstI] = max(R.lastUsed[Op - R.FirstI], I); } static unsigned regReadUse(RegInfo& R, InstLoc I) { @@ -178,8 +180,18 @@ static X64Reg regFindFreeReg(RegInfo& RI) { if (RI.regs[RegAllocOrder[i]] == 0) return RegAllocOrder[i]; - static unsigned nextReg = 0; - X64Reg reg = RegAllocOrder[nextReg++ % RegAllocSize]; + int bestIndex = -1; + InstLoc bestEnd = 0; + for (int i = 0; i < RegAllocSize; ++i) { + const InstLoc start = RI.regs[RegAllocOrder[i]]; + const InstLoc end = RI.lastUsed[start - RI.FirstI]; + if (bestEnd < end) { + bestEnd = end; + bestIndex = i; + } + } + + X64Reg reg = RegAllocOrder[bestIndex]; regSpill(RI, reg); return reg; } @@ -188,8 +200,19 @@ static X64Reg fregFindFreeReg(RegInfo& RI) { for (int i = 0; i < FRegAllocSize; i++) if (RI.fregs[FRegAllocOrder[i]] == 0) return FRegAllocOrder[i]; - static unsigned nextReg = 0; - X64Reg reg = FRegAllocOrder[nextReg++ % FRegAllocSize]; + + int bestIndex = -1; + InstLoc bestEnd = 0; + for (int i = 0; i < FRegAllocSize; ++i) { + const InstLoc start = RI.fregs[FRegAllocOrder[i]]; + const InstLoc end = RI.lastUsed[start - RI.FirstI]; + if (bestEnd < end) { + bestEnd = end; + bestIndex = i; + } + } + + X64Reg reg = FRegAllocOrder[bestIndex]; fregSpill(RI, reg); return reg; }