mirror of
git://sourceware.org/git/valgrind.git
synced 2026-01-12 00:19:31 +08:00
Cherry pick 074de238d4 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.
This commit is contained in:
1
NEWS
1
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)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -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), \
|
||||
|
||||
Reference in New Issue
Block a user