From: Ivo Raisr Date: Sat, 23 Sep 2017 07:46:40 +0000 (+0200) Subject: Cherry pick 074de238d44c0cdaf394489ea69a67b76916fbce from master. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fjit-hacks-2;p=thirdparty%2Fvalgrind.git Cherry pick 074de238d44c0cdaf394489ea69a67b76916fbce from master. VEX register allocator: allocate caller-save registers for short lived vregs. Allocate caller-saved registers for short lived vregs and callee-save registers for vregs which span accross helper calls. Fixes BZ#384987. --- diff --git a/NEWS b/NEWS index 6b9734ef14..bf6c0c7bc7 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,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 384584 Callee saved registers listed first for AMD64, X86, and PPC architectures +384987 VEX register allocator: allocate caller-save registers for short lived vregs 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 d8e5302df6..7c753820bf 100644 --- a/VEX/priv/host_generic_reg_alloc3.c +++ b/VEX/priv/host_generic_reg_alloc3.c @@ -632,20 +632,25 @@ static inline HReg find_vreg_to_spill( } /* Find a free rreg of the correct class. - Tries to find an rreg whose live range (if any) is as far ahead in the - incoming instruction stream as possible. An ideal rreg candidate is - a callee-save register because it won't be used for parameter passing - around helper function calls. */ + Tries to find an rreg whose hard live range (if any) starts after the vreg's + live range ends. If that is not possible, then at least whose live range + is as far ahead in the incoming instruction stream as possible. + An ideal rreg candidate is a caller-save register for short-lived vregs + and a callee-save register for long-lived vregs because it won't need to + be spilled around helper calls. */ static inline Bool find_free_rreg( const RegAllocChunk* chunk, const RegAllocState* state, - Short ii_chunk_current, HRegClass target_hregclass, + UInt v_idx, Short ii_chunk_current, HRegClass target_hregclass, Bool reserve_phase, const RegAllocControl* con, UInt* r_idx_found) { Bool found = False; Short distance_so_far = 0; /* running max for |live_after - current_ii| */ + const VRegState* vreg = &state->vregs[v_idx]; - for (UInt r_idx = con->univ->allocable_start[target_hregclass]; - r_idx <= con->univ->allocable_end[target_hregclass]; r_idx++) { + /* Assume majority of vregs are short-lived. Start scannig from caller-save + registers first. */ + for (Int r_idx = (Int) con->univ->allocable_end[target_hregclass]; + r_idx >= (Int) con->univ->allocable_start[target_hregclass]; r_idx--) { const RRegState* rreg = &state->rregs[r_idx]; const RRegLRState* rreg_lrs = &chunk->rreg_lr_state[r_idx]; if (rreg->disp == Free) { @@ -656,7 +661,12 @@ static inline Bool find_free_rreg( } else { const RRegLR* lr = rreg_lrs->lr_current; if (lr->live_after > ii_chunk_current) { - /* Not live, yet. */ + /* RReg's hard live range is not live, yet. */ + if (vreg->effective_dead_before <= lr->live_after) { + found = True; + *r_idx_found = r_idx; + break; /* VReg is short-lived; it fits in. */ + } if ((lr->live_after - ii_chunk_current) > distance_so_far) { distance_so_far = lr->live_after - ii_chunk_current; found = True; @@ -1294,9 +1304,9 @@ static void stage5_chunk(RegAllocChunk* chunk, RegAllocState* state, # define FIND_OR_MAKE_FREE_RREG(_v_idx, _reg_class, _reserve_phase) \ ({ \ UInt _r_free_idx; \ - Bool free_rreg_found = find_free_rreg(chunk, state, \ - ii_chunk, (_reg_class), (_reserve_phase), \ - con, &_r_free_idx); \ + Bool free_rreg_found = find_free_rreg(chunk, state, (_v_idx), ii_chunk, \ + (_reg_class), (_reserve_phase), \ + con, &_r_free_idx); \ if (!free_rreg_found) { \ HReg vreg_to_spill = find_vreg_to_spill(chunk, state, \ &chunk->reg_usage[ii_chunk], (_reg_class), \