diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-18 20:01:31 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-18 20:01:31 +0000 |
commit | 49e6b159a6b2225a0198f8e261c6b6f3772fba3f (patch) | |
tree | 7474601b4ae09317bf0a9ed2647974807abfc493 /gcc/lra-constraints.c | |
parent | 2fffb07a72d0755a559b08cfa30eb12d277daec1 (diff) | |
download | gcc-49e6b159a6b2225a0198f8e261c6b6f3772fba3f.tar.gz |
2013-02-18 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 196123 using svnmerge.py
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@196126 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 112 |
1 files changed, 73 insertions, 39 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index af68c3aee4c..d3f4420b6a0 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -421,8 +421,20 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original, if (rtx_equal_p (curr_insn_input_reloads[i].input, original) && in_class_p (curr_insn_input_reloads[i].reg, rclass, &new_class)) { - *result_reg = curr_insn_input_reloads[i].reg; - regno = REGNO (*result_reg); + rtx reg = curr_insn_input_reloads[i].reg; + regno = REGNO (reg); + /* If input is equal to original and both are VOIDmode, + GET_MODE (reg) might be still different from mode. + Ensure we don't return *result_reg with wrong mode. */ + if (GET_MODE (reg) != mode) + { + if (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (mode)) + continue; + reg = lowpart_subreg (mode, reg, GET_MODE (reg)); + if (reg == NULL_RTX || GET_CODE (reg) != SUBREG) + continue; + } + *result_reg = reg; if (lra_dump_file != NULL) { fprintf (lra_dump_file, " Reuse r%d for reload ", regno); @@ -1201,24 +1213,26 @@ simplify_operand_subreg (int nop, enum machine_mode reg_mode) enum reg_class rclass = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS); - new_reg = lra_create_new_reg_with_unique_value (reg_mode, reg, rclass, - "subreg reg"); - bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (new_reg)); - if (type != OP_OUT - || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)) - { - push_to_sequence (before); - lra_emit_move (new_reg, reg); - before = get_insns (); - end_sequence (); - } - if (type != OP_IN) + if (get_reload_reg (curr_static_id->operand[nop].type, reg_mode, reg, + rclass, "subreg reg", &new_reg)) { - start_sequence (); - lra_emit_move (reg, new_reg); - emit_insn (after); - after = get_insns (); - end_sequence (); + bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (new_reg)); + if (type != OP_OUT + || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)) + { + push_to_sequence (before); + lra_emit_move (new_reg, reg); + before = get_insns (); + end_sequence (); + } + if (type != OP_IN) + { + start_sequence (); + lra_emit_move (reg, new_reg); + emit_insn (after); + after = get_insns (); + end_sequence (); + } } SUBREG_REG (operand) = new_reg; lra_process_new_insns (curr_insn, before, after, @@ -1519,8 +1533,8 @@ process_alt_operands (int only_alternative) if (! curr_static_id->operand[m].early_clobber || operand_reg[nop] == NULL_RTX || (find_regno_note (curr_insn, REG_DEAD, - REGNO (operand_reg[nop])) - != NULL_RTX)) + REGNO (op)) + || REGNO (op) == REGNO (operand_reg[m]))) match_p = true; } if (match_p) @@ -2045,6 +2059,7 @@ process_alt_operands (int only_alternative) if ((! curr_alt_win[i] && ! curr_alt_match_win[i]) || hard_regno[i] < 0) continue; + lra_assert (operand_reg[i] != NULL_RTX); clobbered_hard_regno = hard_regno[i]; CLEAR_HARD_REG_SET (temp_set); add_to_hard_reg_set (&temp_set, biggest_mode[i], clobbered_hard_regno); @@ -2059,30 +2074,49 @@ process_alt_operands (int only_alternative) else if ((curr_alt_matches[j] == i && curr_alt_match_win[j]) || (curr_alt_matches[i] == j && curr_alt_match_win[i])) continue; - else if (uses_hard_regs_p (*curr_id->operand_loc[j], temp_set)) + /* If we don't reload j-th operand, check conflicts. */ + else if ((curr_alt_win[j] || curr_alt_match_win[j]) + && uses_hard_regs_p (*curr_id->operand_loc[j], temp_set)) break; if (j >= n_operands) continue; - /* We need to reload early clobbered register. */ - for (j = 0; j < n_operands; j++) - if (curr_alt_matches[j] == i) - { - curr_alt_match_win[j] = false; - losers++; - overall += LRA_LOSER_COST_FACTOR; - } - if (! curr_alt_match_win[i]) - curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i; + /* If earlyclobber operand conflicts with another + non-matching operand which is actually the same register + as the earlyclobber operand, it is better to reload the + another operand as an operand matching the earlyclobber + operand can be also the same. */ + if (operand_reg[j] != NULL_RTX && ! curr_alt_match_win[j] + && REGNO (operand_reg[i]) == REGNO (operand_reg[j])) + { + curr_alt_win[j] = false; + curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = j; + losers++; + overall += LRA_LOSER_COST_FACTOR; + } else { - /* Remember pseudos used for match reloads are never - inherited. */ - lra_assert (curr_alt_matches[i] >= 0); - curr_alt_win[curr_alt_matches[i]] = false; + /* We need to reload early clobbered register and the + matched registers. */ + for (j = 0; j < n_operands; j++) + if (curr_alt_matches[j] == i) + { + curr_alt_match_win[j] = false; + losers++; + overall += LRA_LOSER_COST_FACTOR; + } + if (! curr_alt_match_win[i]) + curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++] = i; + else + { + /* Remember pseudos used for match reloads are never + inherited. */ + lra_assert (curr_alt_matches[i] >= 0); + curr_alt_win[curr_alt_matches[i]] = false; + } + curr_alt_win[i] = curr_alt_match_win[i] = false; + losers++; + overall += LRA_LOSER_COST_FACTOR; } - curr_alt_win[i] = curr_alt_match_win[i] = false; - losers++; - overall += LRA_LOSER_COST_FACTOR; } small_class_operands_num = 0; for (nop = 0; nop < n_operands; nop++) |