summaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-09 17:02:11 +0000
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-09 17:02:11 +0000
commitaa3ce8ba15edba2ad4ceff1d2dd731ce5bc0761f (patch)
tree4dc6d2190928cecfc3a5fdb3cae0d0ea9df303f1 /gcc/lra-constraints.c
parent889d67a8e4cb4bf7c881ea755751330fea4879c3 (diff)
downloadgcc-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.c44
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. */