From: Ivo Raisr Date: Wed, 6 Sep 2017 06:10:36 +0000 (+0200) Subject: Cherry pick 00d4667295a821fef9eb198abcb0c942dffb6045 from master. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cd804792f24b7631748aeb8b6dfceff2af957f66;p=thirdparty%2Fvalgrind.git Cherry pick 00d4667295a821fef9eb198abcb0c942dffb6045 from master. 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 446a7fa2d6..6b9734ef14 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,7 @@ where XXXXXX is the bug number as listed below. 382515 "Assertion 'di->have_dinfo' failed." on wine's dlls/mscoree/tests/mscoree.c 382998 xml-socket doesn't work 383275 massif valgrind: m_xarray.c:162 (ensureSpaceXA): Assertion '!xa->arr' failed +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 57ef1698dc..349e43c74c 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 5cc9a85e92..f8fcbf99be 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 c55059efd8..5f47bdb813 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 ad5b75db89..1f18550886 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); }