From: Ivo Raisr Date: Wed, 6 Sep 2017 06:10:36 +0000 (+0200) Subject: Reorder allocatable registers for AMD64, X86, and PPC so that the callee saved are... X-Git-Tag: VALGRIND_3_14_0~261 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=00d4667295a821fef9eb198abcb0c942dffb6045;p=thirdparty%2Fvalgrind.git Reorder allocatable registers for AMD64, X86, and PPC so that the callee saved are listed first. Helper calls always trash all caller saved registers. By listing the callee saved first then VEX register allocator (both v2 and v3) is more likely to pick them and does not need to spill that much before helper calls. --- diff --git a/NEWS b/NEWS index e910b7f669..eccbd199a4 100644 --- a/NEWS +++ b/NEWS @@ -54,6 +54,7 @@ where XXXXXX is the bug number as listed below. 383275 massif valgrind: m_xarray.c:162 (ensureSpaceXA): Assertion '!xa->arr' failed 384096 Mention AddrCheck at Memcheck's command line option --undef-value-errors=no 384526 reduce number of spill instructions generated by VEX register allocator v3 +384584 Callee saved registers listed first for AMD64, X86, and PPC architectures Release 3.13.0 (15 June 2017) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/VEX/priv/host_amd64_defs.c b/VEX/priv/host_amd64_defs.c index ebe2b0013b..d9949d4fd7 100644 --- a/VEX/priv/host_amd64_defs.c +++ b/VEX/priv/host_amd64_defs.c @@ -64,15 +64,15 @@ const RRegUniverse* getRRegUniverse_AMD64 ( void ) those available for allocation by reg-alloc, and those that follow are not available for allocation. */ ru->allocable_start[HRcInt64] = ru->size; - ru->regs[ru->size++] = hregAMD64_RSI(); - ru->regs[ru->size++] = hregAMD64_RDI(); - ru->regs[ru->size++] = hregAMD64_R8(); - ru->regs[ru->size++] = hregAMD64_R9(); ru->regs[ru->size++] = hregAMD64_R12(); ru->regs[ru->size++] = hregAMD64_R13(); ru->regs[ru->size++] = hregAMD64_R14(); ru->regs[ru->size++] = hregAMD64_R15(); ru->regs[ru->size++] = hregAMD64_RBX(); + ru->regs[ru->size++] = hregAMD64_RSI(); + ru->regs[ru->size++] = hregAMD64_RDI(); + ru->regs[ru->size++] = hregAMD64_R8(); + ru->regs[ru->size++] = hregAMD64_R9(); ru->regs[ru->size++] = hregAMD64_R10(); ru->allocable_end[HRcInt64] = ru->size - 1; @@ -1460,18 +1460,16 @@ void getRegUsage_AMD64Instr ( HRegUsage* u, const AMD64Instr* i, Bool mode64 ) /* This is a bit subtle. */ /* First off, claim it trashes all the caller-saved regs which fall within the register allocator's jurisdiction. - These I believe to be: rax rcx rdx rsi rdi r8 r9 r10 r11 - and all the xmm registers. - */ + These I believe to be: rax rcx rdx rdi rsi r8 r9 r10 + and all the xmm registers. */ addHRegUse(u, HRmWrite, hregAMD64_RAX()); addHRegUse(u, HRmWrite, hregAMD64_RCX()); addHRegUse(u, HRmWrite, hregAMD64_RDX()); - addHRegUse(u, HRmWrite, hregAMD64_RSI()); addHRegUse(u, HRmWrite, hregAMD64_RDI()); + addHRegUse(u, HRmWrite, hregAMD64_RSI()); addHRegUse(u, HRmWrite, hregAMD64_R8()); addHRegUse(u, HRmWrite, hregAMD64_R9()); addHRegUse(u, HRmWrite, hregAMD64_R10()); - addHRegUse(u, HRmWrite, hregAMD64_R11()); addHRegUse(u, HRmWrite, hregAMD64_XMM0()); addHRegUse(u, HRmWrite, hregAMD64_XMM1()); addHRegUse(u, HRmWrite, hregAMD64_XMM3()); diff --git a/VEX/priv/host_amd64_defs.h b/VEX/priv/host_amd64_defs.h index 8a3eea8817..92730fa13a 100644 --- a/VEX/priv/host_amd64_defs.h +++ b/VEX/priv/host_amd64_defs.h @@ -47,15 +47,15 @@ */ #define ST_IN static inline -ST_IN HReg hregAMD64_RSI ( void ) { return mkHReg(False, HRcInt64, 6, 0); } -ST_IN HReg hregAMD64_RDI ( void ) { return mkHReg(False, HRcInt64, 7, 1); } -ST_IN HReg hregAMD64_R8 ( void ) { return mkHReg(False, HRcInt64, 8, 2); } -ST_IN HReg hregAMD64_R9 ( void ) { return mkHReg(False, HRcInt64, 9, 3); } -ST_IN HReg hregAMD64_R12 ( void ) { return mkHReg(False, HRcInt64, 12, 4); } -ST_IN HReg hregAMD64_R13 ( void ) { return mkHReg(False, HRcInt64, 13, 5); } -ST_IN HReg hregAMD64_R14 ( void ) { return mkHReg(False, HRcInt64, 14, 6); } -ST_IN HReg hregAMD64_R15 ( void ) { return mkHReg(False, HRcInt64, 15, 7); } -ST_IN HReg hregAMD64_RBX ( void ) { return mkHReg(False, HRcInt64, 3, 8); } +ST_IN HReg hregAMD64_R12 ( void ) { return mkHReg(False, HRcInt64, 12, 0); } +ST_IN HReg hregAMD64_R13 ( void ) { return mkHReg(False, HRcInt64, 13, 1); } +ST_IN HReg hregAMD64_R14 ( void ) { return mkHReg(False, HRcInt64, 14, 2); } +ST_IN HReg hregAMD64_R15 ( void ) { return mkHReg(False, HRcInt64, 15, 3); } +ST_IN HReg hregAMD64_RBX ( void ) { return mkHReg(False, HRcInt64, 3, 4); } +ST_IN HReg hregAMD64_RSI ( void ) { return mkHReg(False, HRcInt64, 6, 5); } +ST_IN HReg hregAMD64_RDI ( void ) { return mkHReg(False, HRcInt64, 7, 6); } +ST_IN HReg hregAMD64_R8 ( void ) { return mkHReg(False, HRcInt64, 8, 7); } +ST_IN HReg hregAMD64_R9 ( void ) { return mkHReg(False, HRcInt64, 9, 8); } ST_IN HReg hregAMD64_R10 ( void ) { return mkHReg(False, HRcInt64, 10, 9); } ST_IN HReg hregAMD64_XMM3 ( void ) { return mkHReg(False, HRcVec128, 3, 10); } diff --git a/VEX/priv/host_ppc_defs.c b/VEX/priv/host_ppc_defs.c index 33ee292a01..1ef9c5c341 100644 --- a/VEX/priv/host_ppc_defs.c +++ b/VEX/priv/host_ppc_defs.c @@ -69,6 +69,24 @@ const RRegUniverse* getRRegUniverse_PPC ( Bool mode64 ) // GPR1 = stack pointer // GPR2 = TOC pointer ru->allocable_start[(mode64) ? HRcInt64 : HRcInt32] = ru->size; + // GPR14 and above are callee save. List them first. + ru->regs[ru->size++] = hregPPC_GPR14(mode64); + ru->regs[ru->size++] = hregPPC_GPR15(mode64); + ru->regs[ru->size++] = hregPPC_GPR16(mode64); + ru->regs[ru->size++] = hregPPC_GPR17(mode64); + ru->regs[ru->size++] = hregPPC_GPR18(mode64); + ru->regs[ru->size++] = hregPPC_GPR19(mode64); + ru->regs[ru->size++] = hregPPC_GPR20(mode64); + ru->regs[ru->size++] = hregPPC_GPR21(mode64); + ru->regs[ru->size++] = hregPPC_GPR22(mode64); + ru->regs[ru->size++] = hregPPC_GPR23(mode64); + ru->regs[ru->size++] = hregPPC_GPR24(mode64); + ru->regs[ru->size++] = hregPPC_GPR25(mode64); + ru->regs[ru->size++] = hregPPC_GPR26(mode64); + ru->regs[ru->size++] = hregPPC_GPR27(mode64); + ru->regs[ru->size++] = hregPPC_GPR28(mode64); + + // Caller save registers now. ru->regs[ru->size++] = hregPPC_GPR3(mode64); ru->regs[ru->size++] = hregPPC_GPR4(mode64); ru->regs[ru->size++] = hregPPC_GPR5(mode64); @@ -85,22 +103,6 @@ const RRegUniverse* getRRegUniverse_PPC ( Bool mode64 ) ru->regs[ru->size++] = hregPPC_GPR12(mode64); } // GPR13 = thread specific pointer - // GPR14 and above are callee save. Yay. - ru->regs[ru->size++] = hregPPC_GPR14(mode64); - ru->regs[ru->size++] = hregPPC_GPR15(mode64); - ru->regs[ru->size++] = hregPPC_GPR16(mode64); - ru->regs[ru->size++] = hregPPC_GPR17(mode64); - ru->regs[ru->size++] = hregPPC_GPR18(mode64); - ru->regs[ru->size++] = hregPPC_GPR19(mode64); - ru->regs[ru->size++] = hregPPC_GPR20(mode64); - ru->regs[ru->size++] = hregPPC_GPR21(mode64); - ru->regs[ru->size++] = hregPPC_GPR22(mode64); - ru->regs[ru->size++] = hregPPC_GPR23(mode64); - ru->regs[ru->size++] = hregPPC_GPR24(mode64); - ru->regs[ru->size++] = hregPPC_GPR25(mode64); - ru->regs[ru->size++] = hregPPC_GPR26(mode64); - ru->regs[ru->size++] = hregPPC_GPR27(mode64); - ru->regs[ru->size++] = hregPPC_GPR28(mode64); ru->allocable_end[(mode64) ? HRcInt64 : HRcInt32] = ru->size - 1; // GPR29 is reserved for the dispatcher // GPR30 is reserved as AltiVec spill reg temporary diff --git a/VEX/priv/host_ppc_defs.h b/VEX/priv/host_ppc_defs.h index 6b7fcc8cb3..8ee789a51b 100644 --- a/VEX/priv/host_ppc_defs.h +++ b/VEX/priv/host_ppc_defs.h @@ -57,35 +57,35 @@ mkHReg(False, HRcVec128, \ (_enc), (_mode64) ? (_ix64) : (_ix32)) -ST_IN HReg hregPPC_GPR3 ( Bool mode64 ) { return GPR(mode64, 3, 0, 0); } -ST_IN HReg hregPPC_GPR4 ( Bool mode64 ) { return GPR(mode64, 4, 1, 1); } -ST_IN HReg hregPPC_GPR5 ( Bool mode64 ) { return GPR(mode64, 5, 2, 2); } -ST_IN HReg hregPPC_GPR6 ( Bool mode64 ) { return GPR(mode64, 6, 3, 3); } -ST_IN HReg hregPPC_GPR7 ( Bool mode64 ) { return GPR(mode64, 7, 4, 4); } -ST_IN HReg hregPPC_GPR8 ( Bool mode64 ) { return GPR(mode64, 8, 5, 5); } -ST_IN HReg hregPPC_GPR9 ( Bool mode64 ) { return GPR(mode64, 9, 6, 6); } -ST_IN HReg hregPPC_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 7, 7); } +ST_IN HReg hregPPC_GPR14 ( Bool mode64 ) { return GPR(mode64, 14, 0, 0); } +ST_IN HReg hregPPC_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 1, 1); } +ST_IN HReg hregPPC_GPR16 ( Bool mode64 ) { return GPR(mode64, 16, 2, 2); } +ST_IN HReg hregPPC_GPR17 ( Bool mode64 ) { return GPR(mode64, 17, 3, 3); } +ST_IN HReg hregPPC_GPR18 ( Bool mode64 ) { return GPR(mode64, 18, 4, 4); } +ST_IN HReg hregPPC_GPR19 ( Bool mode64 ) { return GPR(mode64, 19, 5, 5); } +ST_IN HReg hregPPC_GPR20 ( Bool mode64 ) { return GPR(mode64, 20, 6, 6); } +ST_IN HReg hregPPC_GPR21 ( Bool mode64 ) { return GPR(mode64, 21, 7, 7); } +ST_IN HReg hregPPC_GPR22 ( Bool mode64 ) { return GPR(mode64, 22, 8, 8); } +ST_IN HReg hregPPC_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 9, 9); } +ST_IN HReg hregPPC_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 10, 10); } +ST_IN HReg hregPPC_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 11, 11); } +ST_IN HReg hregPPC_GPR26 ( Bool mode64 ) { return GPR(mode64, 26, 12, 12); } +ST_IN HReg hregPPC_GPR27 ( Bool mode64 ) { return GPR(mode64, 27, 13, 13); } +ST_IN HReg hregPPC_GPR28 ( Bool mode64 ) { return GPR(mode64, 28, 14, 44); } + +ST_IN HReg hregPPC_GPR3 ( Bool mode64 ) { return GPR(mode64, 3, 15, 15); } +ST_IN HReg hregPPC_GPR4 ( Bool mode64 ) { return GPR(mode64, 4, 16, 16); } +ST_IN HReg hregPPC_GPR5 ( Bool mode64 ) { return GPR(mode64, 5, 17, 17); } +ST_IN HReg hregPPC_GPR6 ( Bool mode64 ) { return GPR(mode64, 6, 18, 18); } +ST_IN HReg hregPPC_GPR7 ( Bool mode64 ) { return GPR(mode64, 7, 19, 19); } +ST_IN HReg hregPPC_GPR8 ( Bool mode64 ) { return GPR(mode64, 8, 20, 20); } +ST_IN HReg hregPPC_GPR9 ( Bool mode64 ) { return GPR(mode64, 9, 21, 21); } +ST_IN HReg hregPPC_GPR10 ( Bool mode64 ) { return GPR(mode64, 10, 22, 22); } // r11 and r12 are only allocatable in 32-bit mode. Hence the 64-bit // index numbering doesn't advance for these two. -ST_IN HReg hregPPC_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 0, 8); } -ST_IN HReg hregPPC_GPR12 ( Bool mode64 ) { return GPR(mode64, 12, 0, 9); } - -ST_IN HReg hregPPC_GPR14 ( Bool mode64 ) { return GPR(mode64, 14, 8, 10); } -ST_IN HReg hregPPC_GPR15 ( Bool mode64 ) { return GPR(mode64, 15, 9, 11); } -ST_IN HReg hregPPC_GPR16 ( Bool mode64 ) { return GPR(mode64, 16, 10, 12); } -ST_IN HReg hregPPC_GPR17 ( Bool mode64 ) { return GPR(mode64, 17, 11, 13); } -ST_IN HReg hregPPC_GPR18 ( Bool mode64 ) { return GPR(mode64, 18, 12, 14); } -ST_IN HReg hregPPC_GPR19 ( Bool mode64 ) { return GPR(mode64, 19, 13, 15); } -ST_IN HReg hregPPC_GPR20 ( Bool mode64 ) { return GPR(mode64, 20, 14, 16); } -ST_IN HReg hregPPC_GPR21 ( Bool mode64 ) { return GPR(mode64, 21, 15, 17); } -ST_IN HReg hregPPC_GPR22 ( Bool mode64 ) { return GPR(mode64, 22, 16, 18); } -ST_IN HReg hregPPC_GPR23 ( Bool mode64 ) { return GPR(mode64, 23, 17, 19); } -ST_IN HReg hregPPC_GPR24 ( Bool mode64 ) { return GPR(mode64, 24, 18, 20); } -ST_IN HReg hregPPC_GPR25 ( Bool mode64 ) { return GPR(mode64, 25, 19, 21); } -ST_IN HReg hregPPC_GPR26 ( Bool mode64 ) { return GPR(mode64, 26, 20, 22); } -ST_IN HReg hregPPC_GPR27 ( Bool mode64 ) { return GPR(mode64, 27, 21, 23); } -ST_IN HReg hregPPC_GPR28 ( Bool mode64 ) { return GPR(mode64, 28, 22, 24); } +ST_IN HReg hregPPC_GPR11 ( Bool mode64 ) { return GPR(mode64, 11, 22, 23); } +ST_IN HReg hregPPC_GPR12 ( Bool mode64 ) { return GPR(mode64, 12, 22, 24); } ST_IN HReg hregPPC_FPR14 ( Bool mode64 ) { return FPR(mode64, 14, 23, 25); } ST_IN HReg hregPPC_FPR15 ( Bool mode64 ) { return FPR(mode64, 15, 24, 26); } diff --git a/VEX/priv/host_x86_defs.c b/VEX/priv/host_x86_defs.c index 2e5c044669..2457cc19f4 100644 --- a/VEX/priv/host_x86_defs.c +++ b/VEX/priv/host_x86_defs.c @@ -64,12 +64,12 @@ const RRegUniverse* getRRegUniverse_X86 ( void ) those available for allocation by reg-alloc, and those that follow are not available for allocation. */ ru->allocable_start[HRcInt32] = ru->size; - ru->regs[ru->size++] = hregX86_EAX(); ru->regs[ru->size++] = hregX86_EBX(); - ru->regs[ru->size++] = hregX86_ECX(); - ru->regs[ru->size++] = hregX86_EDX(); ru->regs[ru->size++] = hregX86_ESI(); ru->regs[ru->size++] = hregX86_EDI(); + ru->regs[ru->size++] = hregX86_EAX(); + ru->regs[ru->size++] = hregX86_ECX(); + ru->regs[ru->size++] = hregX86_EDX(); ru->allocable_end[HRcInt32] = ru->size - 1; ru->allocable_start[HRcFlt64] = ru->size; diff --git a/VEX/priv/host_x86_defs.h b/VEX/priv/host_x86_defs.h index 614b7512c6..e1a57671cb 100644 --- a/VEX/priv/host_x86_defs.h +++ b/VEX/priv/host_x86_defs.h @@ -47,12 +47,12 @@ */ #define ST_IN static inline -ST_IN HReg hregX86_EAX ( void ) { return mkHReg(False, HRcInt32, 0, 0); } -ST_IN HReg hregX86_EBX ( void ) { return mkHReg(False, HRcInt32, 3, 1); } -ST_IN HReg hregX86_ECX ( void ) { return mkHReg(False, HRcInt32, 1, 2); } -ST_IN HReg hregX86_EDX ( void ) { return mkHReg(False, HRcInt32, 2, 3); } -ST_IN HReg hregX86_ESI ( void ) { return mkHReg(False, HRcInt32, 6, 4); } -ST_IN HReg hregX86_EDI ( void ) { return mkHReg(False, HRcInt32, 7, 5); } +ST_IN HReg hregX86_EBX ( void ) { return mkHReg(False, HRcInt32, 3, 0); } +ST_IN HReg hregX86_ESI ( void ) { return mkHReg(False, HRcInt32, 6, 1); } +ST_IN HReg hregX86_EDI ( void ) { return mkHReg(False, HRcInt32, 7, 2); } +ST_IN HReg hregX86_EAX ( void ) { return mkHReg(False, HRcInt32, 0, 3); } +ST_IN HReg hregX86_ECX ( void ) { return mkHReg(False, HRcInt32, 1, 4); } +ST_IN HReg hregX86_EDX ( void ) { return mkHReg(False, HRcInt32, 2, 5); } ST_IN HReg hregX86_FAKE0 ( void ) { return mkHReg(False, HRcFlt64, 0, 6); } ST_IN HReg hregX86_FAKE1 ( void ) { return mkHReg(False, HRcFlt64, 1, 7); }