}
/* 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) {
} 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;
# 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), \