You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(4) |
2
(2) |
|
3
(1) |
4
(1) |
5
|
6
|
7
|
8
(1) |
9
(1) |
|
10
(4) |
11
(1) |
12
(2) |
13
(2) |
14
(3) |
15
(2) |
16
(2) |
|
17
|
18
(1) |
19
(5) |
20
|
21
|
22
(8) |
23
(4) |
|
24
(1) |
25
|
26
(3) |
27
(8) |
28
(4) |
29
(4) |
30
(1) |
|
From: Rhys K. <rhy...@so...> - 2017-09-10 15:10:20
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=2e5843802daee5eabb73a8d66c0f2d7964d52963 commit 2e5843802daee5eabb73a8d66c0f2d7964d52963 Author: Rhys Kidd <rhy...@gm...> Date: Sun Sep 10 11:08:20 2017 -0400 Update AUTHORS Diff: --- AUTHORS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AUTHORS b/AUTHORS index da822b9..4c03a66 100644 --- a/AUTHORS +++ b/AUTHORS @@ -82,6 +82,8 @@ liaison. Maran Pakkirisamy implemented support for decimal floating point on s390. +Rhys Kidd updated and maintains the macOS port. + Many, many people sent bug reports, patches, and helpful feedback. Development of Valgrind was supported in part by the Tri-Lab Partners |
|
From: Rhys K. <rhy...@so...> - 2017-09-10 14:51:12
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=128fd6e6a5c94beb6af97ff8146a91422ab50efb commit 128fd6e6a5c94beb6af97ff8146a91422ab50efb Author: Rhys Kidd <rhy...@gm...> Date: Sun Sep 10 01:12:15 2017 -0400 Fix syscall param msg->desc.port.name on macOS 10.12. bz#379373 Based upon patch from Louis Brunner. Diff: --- NEWS | 2 ++ coregrind/m_syswrap/syswrap-darwin.c | 18 +++++++++++++++--- darwin14.supp | 18 ------------------ darwin15.supp | 18 ------------------ darwin16.supp | 18 ------------------ 5 files changed, 17 insertions(+), 57 deletions(-) diff --git a/NEWS b/NEWS index 1b5c80a..e43410a 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,8 @@ To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX where XXXXXX is the bug number as listed below. +379373 Fix syscall param msg->desc.port.name points to uninitialised byte(s) + on macOS 10.12 379748 Fix missing pselect syscall (OS X 10.11) 380397 s390x: __GI_strcspn() replacemenet needed 381162 possible array overrun in VEX register allocator diff --git a/coregrind/m_syswrap/syswrap-darwin.c b/coregrind/m_syswrap/syswrap-darwin.c index 0ae281c..0670824 100644 --- a/coregrind/m_syswrap/syswrap-darwin.c +++ b/coregrind/m_syswrap/syswrap-darwin.c @@ -9580,8 +9580,20 @@ PRE(kernelrpc_mach_port_construct_trap) { UWord a1; UWord a2; ULong a3; UWord a4; munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); - PRINT("kernelrpc_mach_port_construct_trap(FIXME)" - "(%lx,%lx,%llx,%lx)", a1, a2, a3, a4); + PRINT("kernelrpc_mach_port_construct_trap" + "(target: %s, options: %#lx, content: %llx, name: %p)", + name_for_port(a1), a2, a3, *(mach_port_name_t**)a4); + PRE_MEM_WRITE("kernelrpc_mach_port_construct_trap(name)", a4, + sizeof(mach_port_name_t*)); +} +POST(kernelrpc_mach_port_construct_trap) +{ + UWord a1; UWord a2; ULong a3; UWord a4; + munge_wwlw(&a1, &a2, &a3, &a4, ARG1, ARG2, ARG3, ARG4, ARG5); + PRINT("-> name:%p", *(mach_port_name_t**)a4); + if (ML_(safe_to_deref)((mach_port_name_t*)a4, sizeof(mach_port_name_t*))) { + POST_MEM_WRITE(a4, sizeof(mach_port_name_t*)); + } } PRE(kernelrpc_mach_port_destruct_trap) @@ -10597,7 +10609,7 @@ const SyscallTableEntry ML_(mach_trap_table)[] = { # endif # if DARWIN_VERS >= DARWIN_10_9 - MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24), kernelrpc_mach_port_construct_trap), + MACXY(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24), kernelrpc_mach_port_construct_trap), MACX_(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(25), kernelrpc_mach_port_destruct_trap), # else _____(VG_DARWIN_SYSCALL_CONSTRUCT_MACH(24)), diff --git a/darwin14.supp b/darwin14.supp index ba818d5..63fe2b4 100644 --- a/darwin14.supp +++ b/darwin14.supp @@ -665,24 +665,6 @@ obj:*GPUSupport.framework*GPUSupportMercury* } -{ - OSX1010:mach_msg_trap-1 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*libsystem_kernel.dylib* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1010:mach_msg_trap-2 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - # See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's # unavoidable due to BSD setenv() semantics. { diff --git a/darwin15.supp b/darwin15.supp index e745cf0..a383d24 100644 --- a/darwin15.supp +++ b/darwin15.supp @@ -724,24 +724,6 @@ obj:*GPUSupport.framework*GPUSupportMercury* } -{ - OSX1011:mach_msg_trap-1 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*libsystem_kernel.dylib* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1011:mach_msg_trap-2 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - # See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's # unavoidable due to BSD setenv() semantics. { diff --git a/darwin16.supp b/darwin16.supp index b3f9dbd..18dda6a 100644 --- a/darwin16.supp +++ b/darwin16.supp @@ -749,24 +749,6 @@ obj:*GPUSupport.framework*GPUSupportMercury* } -{ - OSX1012:mach_msg_trap-1 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*libsystem_kernel.dylib* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - -{ - OSX1012:mach_msg_trap-2 - Memcheck:Param - msg->desc.port.name - fun:mach_msg_trap - obj:*SystemConfiguration.framework*SystemConfiguration* - obj:*SystemConfiguration.framework*SystemConfiguration* -} - # See https://bugs.kde.org/show_bug.cgi?id=188572 about this; it's # unavoidable due to BSD setenv() semantics. { |
|
From: Ivo R. <ir...@so...> - 2017-09-10 09:47:51
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=6a113f32c270e98db2a179c4d414e9a1cdf87363 commit 6a113f32c270e98db2a179c4d414e9a1cdf87363 Author: Ivo Raisr <iv...@iv...> Date: Sun Sep 10 11:47:01 2017 +0200 Cherry-pick 3117cd9637a843cbab5de302fb30e22153fbfc1c from master. Reduce number of spill instructions generated by VEX register allocator v3. Keeps track whether the bound real register has been reloaded from a virtual register recently and if this real reg is still equal to that spill slot. Avoids unnecessary spilling that vreg later, when this rreg needs to be reserved, usually as a caller save register for a helper call. Diff: --- VEX/priv/host_generic_reg_alloc3.c | 109 +++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 29 deletions(-) diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c index 8c3628e..a13d620 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -141,6 +141,12 @@ typedef /* If .disp == Bound, what vreg is it bound to? */ HReg vreg; + + /* If .disp == Bound, has the associated vreg been reloaded from its spill + slot recently and is this rreg still equal to that spill slot? + Avoids unnecessary spilling that vreg later, when this rreg needs + to be reserved. */ + Bool eq_spill_slot; } RRegState; @@ -309,6 +315,12 @@ static inline void enlarge_rreg_lrs(RRegLRState* rreg_lrs) rreg_lrs->lrs_size = 2 * rreg_lrs->lrs_used; } +#define PRINT_STATE(what) \ + do { \ + print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL, \ + depth, con, what); \ + } while (0) + static inline void print_state(const RegAllocChunk* chunk, const VRegState* vreg_state, UInt n_vregs, const RRegState* rreg_state, Short ii_total_current, UInt depth, const RegAllocControl* con, @@ -374,6 +386,9 @@ static inline void print_state(const RegAllocChunk* chunk, case Bound: vex_printf("bound for "); con->ppReg(rreg->vreg); + if (rreg->eq_spill_slot) { + vex_printf(" (equals to its spill slot)"); + } vex_printf("\n"); break; case Reserved: @@ -400,6 +415,21 @@ static inline void emit_instr(RegAllocChunk* chunk, HInstr* instr, UInt depth, addHInstr(chunk->instrs_out, instr); } +/* Updates register allocator state after vreg has been spilled. */ +static inline void mark_vreg_spilled( + UInt v_idx, VRegState* vreg_state, UInt n_vregs, + RRegState* rreg_state, UInt n_rregs) +{ + HReg rreg = vreg_state[v_idx].rreg; + UInt r_idx = hregIndex(rreg); + + vreg_state[v_idx].disp = Spilled; + vreg_state[v_idx].rreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; +} + /* Spills a vreg assigned to some rreg. The vreg is spilled and the rreg is freed. Returns rreg's index. */ @@ -434,12 +464,7 @@ static inline UInt spill_vreg( emit_instr(chunk, spill2, depth, con, "spill2"); } - /* Update register allocator state. */ - vreg_state[v_idx].disp = Spilled; - vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - + mark_vreg_spilled(v_idx, vreg_state, n_vregs, rreg_state, n_rregs); return r_idx; } @@ -1039,8 +1064,7 @@ static void stage4_chunk(RegAllocChunk* chunk, vex_printf("---- "); con->ppInstr(chunk->instrs_in->insns[ii_vec], con->mode64); vex_printf("\n\n"); - print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL, - depth, con, "Initial Register Allocator state"); + PRINT_STATE("Initial Register Allocator state"); vex_printf("\n"); } @@ -1084,6 +1108,8 @@ static void stage4_chunk(RegAllocChunk* chunk, vassert(IS_VALID_VREGNO(v_idx)); vassert(vreg_state[v_idx].disp == Assigned); vassert(hregIndex(vreg_state[v_idx].rreg) == r_idx); + } else { + vassert(rreg_state[r_idx].eq_spill_slot == False); } } @@ -1133,7 +1159,8 @@ static void stage4_chunk(RegAllocChunk* chunk, UInt r_idx = hregIndex(rreg); vassert(rreg_state[r_idx].disp == Bound); - rreg_state[r_idx].vreg = vregD; + rreg_state[r_idx].vreg = vregD; + rreg_state[r_idx].eq_spill_slot = False; if (DEBUG_REGALLOC) { print_depth(depth); @@ -1152,8 +1179,9 @@ static void stage4_chunk(RegAllocChunk* chunk, if (vreg_state[vd_idx].dead_before <= INSTRNO_TOTAL + 1) { vreg_state[vd_idx].disp = Unallocated; vreg_state[vd_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } /* Move on to the next instruction. We skip the post-instruction @@ -1203,16 +1231,22 @@ static void stage4_chunk(RegAllocChunk* chunk, if ((rreg_lrs->lr_current->live_after <= ii_chunk) && (ii_chunk < rreg_lrs->lr_current->dead_before)) { - if (rreg->disp == Bound) { + switch (rreg->disp) { + case Bound: { /* Yes, there is an associated vreg. We need to deal with it now somehow. */ HReg vreg = rreg->vreg; UInt v_idx = hregIndex(vreg); if (! HRegUsage__contains(reg_usage, vreg)) { - /* Spill the vreg. It is not used by this instruction. */ - spill_vreg(chunk, vreg_state, n_vregs, rreg_state, - vreg, v_idx, INSTRNO_TOTAL, depth, con); + if (rreg->eq_spill_slot) { + mark_vreg_spilled(v_idx, vreg_state, n_vregs, + rreg_state, n_rregs); + } else { + /* Spill the vreg. It is not used by this instruction.*/ + spill_vreg(chunk, vreg_state, n_vregs, rreg_state, + vreg, v_idx, INSTRNO_TOTAL, depth, con); + } } else { /* Find or make a free rreg where to move this vreg to. */ UInt r_free_idx = FIND_OR_MAKE_FREE_RREG( @@ -1229,9 +1263,17 @@ static void stage4_chunk(RegAllocChunk* chunk, vreg_state[v_idx].rreg = con->univ->regs[r_free_idx]; rreg_state[r_free_idx].disp = Bound; rreg_state[r_free_idx].vreg = vreg; - rreg->disp = Free; - rreg->vreg = INVALID_HREG; + rreg_state[r_free_idx].eq_spill_slot = rreg->eq_spill_slot; + rreg->disp = Free; + rreg->vreg = INVALID_HREG; + rreg->eq_spill_slot = False; } + break; + } + case Free: + break; + default: + vassert(0); } /* Finally claim the rreg as reserved. */ @@ -1342,15 +1384,16 @@ static void stage4_chunk(RegAllocChunk* chunk, UInt v_idx = hregIndex(vreg); vassert(IS_VALID_VREGNO(v_idx)); HReg rreg = vreg_state[v_idx].rreg; + UInt r_idx; if (vreg_state[v_idx].disp == Assigned) { - UInt r_idx = hregIndex(rreg); + r_idx = hregIndex(rreg); vassert(rreg_state[r_idx].disp == Bound); addToHRegRemap(&remap, vreg, rreg); } else { vassert(hregIsInvalid(rreg)); /* Find or make a free rreg of the correct class. */ - UInt r_idx = FIND_OR_MAKE_FREE_RREG( + r_idx = FIND_OR_MAKE_FREE_RREG( v_idx, vreg_state[v_idx].reg_class, False); rreg = con->univ->regs[r_idx]; @@ -1373,12 +1416,18 @@ static void stage4_chunk(RegAllocChunk* chunk, } } - rreg_state[r_idx].disp = Bound; - rreg_state[r_idx].vreg = vreg; + rreg_state[r_idx].disp = Bound; + rreg_state[r_idx].vreg = vreg; + rreg_state[r_idx].eq_spill_slot = True; vreg_state[v_idx].disp = Assigned; vreg_state[v_idx].rreg = rreg; addToHRegRemap(&remap, vreg, rreg); } + + /* If this vreg is written or modified, mark it so. */ + if (reg_usage->vMode[j] != HRmRead) { + rreg_state[r_idx].eq_spill_slot = False; + } } con->mapRegs(&remap, instr, con->mode64); @@ -1386,8 +1435,7 @@ static void stage4_chunk(RegAllocChunk* chunk, if (DEBUG_REGALLOC) { print_depth(depth); - print_state(chunk, vreg_state, n_vregs, rreg_state, INSTRNO_TOTAL, - depth, con, "Register Allocator state after dealing with" + PRINT_STATE("Register Allocator state after dealing with" " the current instruction"); vex_printf("\n"); } @@ -1406,8 +1454,9 @@ static void stage4_chunk(RegAllocChunk* chunk, if (rreg_lrs->lrs_used > 0) { /* Consider "dead before" the next instruction. */ if (rreg_lrs->lr_current->dead_before <= ii_chunk + 1) { - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; if (rreg_lrs->lr_current_idx < rreg_lrs->lrs_used - 1) { rreg_lrs->lr_current_idx += 1; rreg_lrs->lr_current @@ -1422,8 +1471,9 @@ static void stage4_chunk(RegAllocChunk* chunk, if (vreg_state[v_idx].dead_before <= INSTRNO_TOTAL + 1) { vreg_state[v_idx].disp = Unallocated; vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } break; } @@ -1515,8 +1565,9 @@ HInstrSB* doRegisterAllocation( every Out-Of-Line leg. */ RRegState* rreg_state = LibVEX_Alloc_inline(n_rregs * sizeof(RRegState)); for (UInt r_idx = 0; r_idx < n_rregs; r_idx++) { - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } /* --- Stage 1. Determine total ordering of instructions and structure |
|
From: Ivo R. <ir...@so...> - 2017-09-10 07:44:33
|
https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=3117cd9637a843cbab5de302fb30e22153fbfc1c commit 3117cd9637a843cbab5de302fb30e22153fbfc1c Author: Ivo Raisr <iv...@iv...> Date: Sat Sep 9 22:08:21 2017 +0200 Reduce number of spill instructions generated by VEX register allocator v3. Keeps track whether the bound real register has been reloaded from a virtual register recently and if this real reg is still equal to that spill slot. Avoids unnecessary spilling that vreg later, when this rreg needs to be reserved, usually as a caller save register for a helper call. Fixes BZ#384526. Diff: --- NEWS | 1 + VEX/priv/host_generic_reg_alloc3.c | 115 +++++++++++++++++++++++++++---------- 2 files changed, 85 insertions(+), 31 deletions(-) diff --git a/NEWS b/NEWS index 835e35f..1b5c80a 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,7 @@ where XXXXXX is the bug number as listed below. 382998 xml-socket doesn't work 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 Release 3.13.0 (15 June 2017) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/VEX/priv/host_generic_reg_alloc3.c b/VEX/priv/host_generic_reg_alloc3.c index f798372..8ee4e48 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -96,6 +96,12 @@ typedef /* If .disp == Bound, what vreg is it bound to? */ HReg vreg; + + /* If .disp == Bound, has the associated vreg been reloaded from its spill + slot recently and is this rreg still equal to that spill slot? + Avoids unnecessary spilling that vreg later, when this rreg needs + to be reserved. */ + Bool eq_spill_slot; } RRegState; @@ -157,6 +163,12 @@ static inline void enlarge_rreg_lrs(RRegLRState* rreg_lrs) rreg_lrs->lrs_size = 2 * rreg_lrs->lrs_used; } +#define PRINT_STATE \ + do { \ + print_state(con, vreg_state, n_vregs, rreg_state, n_rregs, \ + rreg_lr_state, ii); \ + } while (0) + static inline void print_state( const RegAllocControl* con, const VRegState* vreg_state, UInt n_vregs, @@ -217,6 +229,9 @@ static inline void print_state( case Bound: vex_printf("bound for "); con->ppReg(rreg->vreg); + if (rreg->eq_spill_slot) { + vex_printf(" (equals to its spill slot)"); + } vex_printf("\n"); break; case Reserved: @@ -243,6 +258,21 @@ static inline void emit_instr(HInstr* instr, HInstrArray* instrs_out, addHInstr(instrs_out, instr); } +/* Updates register allocator state after vreg has been spilled. */ +static inline void mark_vreg_spilled( + UInt v_idx, VRegState* vreg_state, UInt n_vregs, + RRegState* rreg_state, UInt n_rregs) +{ + HReg rreg = vreg_state[v_idx].rreg; + UInt r_idx = hregIndex(rreg); + + vreg_state[v_idx].disp = Spilled; + vreg_state[v_idx].rreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; +} + /* Spills a vreg assigned to some rreg. The vreg is spilled and the rreg is freed. Returns rreg's index. */ @@ -274,12 +304,7 @@ static inline UInt spill_vreg( emit_instr(spill2, instrs_out, con, "spill2"); } - /* Update register allocator state. */ - vreg_state[v_idx].disp = Spilled; - vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; - + mark_vreg_spilled(v_idx, vreg_state, n_vregs, rreg_state, n_rregs); return r_idx; } @@ -508,8 +533,9 @@ HInstrArray* doRegisterAllocation_v3( } for (UInt r_idx = 0; r_idx < n_rregs; r_idx++) { - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } for (UInt r_idx = 0; r_idx < n_rregs; r_idx++) { @@ -777,8 +803,7 @@ HInstrArray* doRegisterAllocation_v3( vex_printf("---- "); con->ppInstr(instrs_in->arr[ii], con->mode64); vex_printf("\n\nInitial state:\n"); - print_state(con, vreg_state, n_vregs, rreg_state, n_rregs, - rreg_lr_state, ii); + PRINT_STATE; vex_printf("\n"); } @@ -820,6 +845,8 @@ HInstrArray* doRegisterAllocation_v3( vassert(IS_VALID_VREGNO(v_idx)); vassert(vreg_state[v_idx].disp == Assigned); vassert(hregIndex(vreg_state[v_idx].rreg) == r_idx); + } else { + vassert(rreg_state[r_idx].eq_spill_slot == False); } } @@ -869,7 +896,8 @@ HInstrArray* doRegisterAllocation_v3( UInt r_idx = hregIndex(rreg); vassert(rreg_state[r_idx].disp == Bound); - rreg_state[r_idx].vreg = vregD; + rreg_state[r_idx].vreg = vregD; + rreg_state[r_idx].eq_spill_slot = False; if (DEBUG_REGALLOC) { vex_printf("coalesced: "); @@ -887,8 +915,9 @@ HInstrArray* doRegisterAllocation_v3( if (vreg_state[vd_idx].dead_before <= (Short) ii + 1) { vreg_state[vd_idx].disp = Unallocated; vreg_state[vd_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } /* Move on to the next instruction. We skip the post-instruction @@ -938,16 +967,22 @@ HInstrArray* doRegisterAllocation_v3( if ((rreg_lrs->lr_current->live_after <= (Short) ii) && ((Short) ii < rreg_lrs->lr_current->dead_before)) { - if (rreg->disp == Bound) { + switch (rreg->disp) { + case Bound: { /* Yes, there is an associated vreg. We need to deal with it now somehow. */ HReg vreg = rreg->vreg; UInt v_idx = hregIndex(vreg); if (! HRegUsage__contains(®_usage[ii], vreg)) { - /* Spill the vreg. It is not used by this instruction. */ - spill_vreg(vreg, v_idx, ii, vreg_state, n_vregs, - rreg_state, n_rregs, instrs_out, con); + if (rreg->eq_spill_slot) { + mark_vreg_spilled(v_idx, vreg_state, n_vregs, + rreg_state, n_rregs); + } else { + /* Spill the vreg. It is not used by this instruction.*/ + spill_vreg(vreg, v_idx, ii, vreg_state, n_vregs, + rreg_state, n_rregs, instrs_out, con); + } } else { /* Find or make a free rreg where to move this vreg to. */ UInt r_free_idx = FIND_OR_MAKE_FREE_RREG( @@ -962,11 +997,19 @@ HInstrArray* doRegisterAllocation_v3( /* Update the register allocator state. */ vassert(vreg_state[v_idx].disp == Assigned); vreg_state[v_idx].rreg = con->univ->regs[r_free_idx]; - rreg_state[r_free_idx].disp = Bound; - rreg_state[r_free_idx].vreg = vreg; - rreg->disp = Free; - rreg->vreg = INVALID_HREG; + rreg_state[r_free_idx].disp = Bound; + rreg_state[r_free_idx].vreg = vreg; + rreg_state[r_free_idx].eq_spill_slot = rreg->eq_spill_slot; + rreg->disp = Free; + rreg->vreg = INVALID_HREG; + rreg->eq_spill_slot = False; } + break; + } + case Free: + break; + default: + vassert(0); } /* Finally claim the rreg as reserved. */ @@ -1073,15 +1116,16 @@ HInstrArray* doRegisterAllocation_v3( UInt v_idx = hregIndex(vreg); vassert(IS_VALID_VREGNO(v_idx)); HReg rreg = vreg_state[v_idx].rreg; + UInt r_idx; if (vreg_state[v_idx].disp == Assigned) { - UInt r_idx = hregIndex(rreg); + r_idx = hregIndex(rreg); vassert(rreg_state[r_idx].disp == Bound); addToHRegRemap(&remap, vreg, rreg); } else { vassert(hregIsInvalid(rreg)); /* Find or make a free rreg of the correct class. */ - UInt r_idx = FIND_OR_MAKE_FREE_RREG( + r_idx = FIND_OR_MAKE_FREE_RREG( ii, v_idx, vreg_state[v_idx].reg_class, False); rreg = con->univ->regs[r_idx]; @@ -1102,14 +1146,22 @@ HInstrArray* doRegisterAllocation_v3( if (reload2 != NULL) { emit_instr(reload2, instrs_out, con, "reload2"); } + + } - rreg_state[r_idx].disp = Bound; - rreg_state[r_idx].vreg = vreg; + rreg_state[r_idx].disp = Bound; + rreg_state[r_idx].vreg = vreg; + rreg_state[r_idx].eq_spill_slot = True; vreg_state[v_idx].disp = Assigned; vreg_state[v_idx].rreg = rreg; addToHRegRemap(&remap, vreg, rreg); } + + /* If this vreg is written or modified, mark it so. */ + if (reg_usage[ii].vMode[j] != HRmRead) { + rreg_state[r_idx].eq_spill_slot = False; + } } con->mapRegs(&remap, instr, con->mode64); @@ -1117,8 +1169,7 @@ HInstrArray* doRegisterAllocation_v3( if (DEBUG_REGALLOC) { vex_printf("After dealing with current instruction:\n"); - print_state(con, vreg_state, n_vregs, rreg_state, n_rregs, - rreg_lr_state, ii); + PRINT_STATE; vex_printf("\n"); } @@ -1136,8 +1187,9 @@ HInstrArray* doRegisterAllocation_v3( if (rreg_lrs->lrs_used > 0) { /* Consider "dead before" the next instruction. */ if (rreg_lrs->lr_current->dead_before <= (Short) ii + 1) { - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; if (rreg_lrs->lr_current_idx < rreg_lrs->lrs_used - 1) { rreg_lrs->lr_current_idx += 1; rreg_lrs->lr_current @@ -1152,8 +1204,9 @@ HInstrArray* doRegisterAllocation_v3( if (vreg_state[v_idx].dead_before <= (Short) ii + 1) { vreg_state[v_idx].disp = Unallocated; vreg_state[v_idx].rreg = INVALID_HREG; - rreg_state[r_idx].disp = Free; - rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].disp = Free; + rreg_state[r_idx].vreg = INVALID_HREG; + rreg_state[r_idx].eq_spill_slot = False; } break; } |