diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-09 17:02:11 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-01-09 17:02:11 +0000 |
commit | aa3ce8ba15edba2ad4ceff1d2dd731ce5bc0761f (patch) | |
tree | 4dc6d2190928cecfc3a5fdb3cae0d0ea9df303f1 /gcc/lra-constraints.c | |
parent | 889d67a8e4cb4bf7c881ea755751330fea4879c3 (diff) | |
download | gcc-aa3ce8ba15edba2ad4ceff1d2dd731ce5bc0761f.tar.gz |
2013-01-09 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/pr55829
* lra-constraints.c (match_reload): Add code for absent output.
(curr_insn_transform): Add code for reloads of matched inputs
without output.
2013-01-09 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/pr55829
* gcc.target/i386/pr55829.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195057 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index f6c6c89b858..fcece429704 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -658,8 +658,9 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl) /* Generate reloads for matching OUT and INS (array of input operand numbers with end marker -1) with reg class GOAL_CLASS. Add input - and output reloads correspondingly to the lists *BEFORE and - *AFTER. */ + and output reloads correspondingly to the lists *BEFORE and *AFTER. + OUT might be negative. In this case we generate input reloads for + matched input operands INS. */ static void match_reload (signed char out, signed char *ins, enum reg_class goal_class, rtx *before, rtx *after) @@ -668,10 +669,10 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class, rtx new_in_reg, new_out_reg, reg, clobber; enum machine_mode inmode, outmode; rtx in_rtx = *curr_id->operand_loc[ins[0]]; - rtx out_rtx = *curr_id->operand_loc[out]; + rtx out_rtx = out < 0 ? in_rtx : *curr_id->operand_loc[out]; - outmode = curr_operand_mode[out]; inmode = curr_operand_mode[ins[0]]; + outmode = out < 0 ? inmode : curr_operand_mode[out]; push_to_sequence (*before); if (inmode != outmode) { @@ -746,14 +747,13 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class, = lra_create_new_reg_with_unique_value (outmode, out_rtx, goal_class, ""); } - /* In and out operand can be got from transformations before - processing insn constraints. One example of such transformations - is subreg reloading (see function simplify_operand_subreg). The - new pseudos created by the transformations might have inaccurate + /* In operand can be got from transformations before processing insn + constraints. One example of such transformations is subreg + reloading (see function simplify_operand_subreg). The new + pseudos created by the transformations might have inaccurate class (ALL_REGS) and we should make their classes more accurate. */ narrow_reload_pseudo_class (in_rtx, goal_class); - narrow_reload_pseudo_class (out_rtx, goal_class); lra_emit_move (copy_rtx (new_in_reg), in_rtx); *before = get_insns (); end_sequence (); @@ -765,6 +765,10 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class, *curr_id->operand_loc[in] = new_in_reg; } lra_update_dups (curr_id, ins); + if (out < 0) + return; + /* See a comment for the input operand above. */ + narrow_reload_pseudo_class (out_rtx, goal_class); if (find_reg_note (curr_insn, REG_UNUSED, out_rtx) == NULL_RTX) { start_sequence (); @@ -2597,6 +2601,7 @@ curr_insn_transform (void) int n_alternatives; int commutative; signed char goal_alt_matched[MAX_RECOG_OPERANDS][MAX_RECOG_OPERANDS]; + signed char match_inputs[MAX_RECOG_OPERANDS + 1]; rtx before, after; bool alt_p = false; /* Flag that the insn has been changed through a transformation. */ @@ -3052,17 +3057,28 @@ curr_insn_transform (void) && (curr_static_id->operand[goal_alt_matched[i][0]].type == OP_OUT)) { - signed char arr[2]; - - arr[0] = i; - arr[1] = -1; - match_reload (goal_alt_matched[i][0], arr, + /* generate reloads for input and matched outputs. */ + match_inputs[0] = i; + match_inputs[1] = -1; + match_reload (goal_alt_matched[i][0], match_inputs, goal_alt[i], &before, &after); } else if (curr_static_id->operand[i].type == OP_OUT && (curr_static_id->operand[goal_alt_matched[i][0]].type == OP_IN)) + /* Generate reloads for output and matched inputs. */ match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after); + else if (curr_static_id->operand[i].type == OP_IN + && (curr_static_id->operand[goal_alt_matched[i][0]].type + == OP_IN)) + { + /* Generate reloads for matched inputs. */ + match_inputs[0] = i; + for (j = 0; (k = goal_alt_matched[i][j]) >= 0; j++) + match_inputs[j + 1] = k; + match_inputs[j + 1] = -1; + match_reload (-1, match_inputs, goal_alt[i], &before, &after); + } else /* We must generate code in any case when function process_alt_operands decides that it is possible. */ |