summaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 7764f29f477..2c27f1abfe4 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -855,10 +855,11 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
numbers with end marker -1) with reg class GOAL_CLASS. Add input
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. */
+ matched input operands INS. EARLY_CLOBBER_P is a flag that the
+ output operand is early clobbered for chosen alternative. */
static void
match_reload (signed char out, signed char *ins, enum reg_class goal_class,
- rtx_insn **before, rtx_insn **after)
+ rtx_insn **before, rtx_insn **after, bool early_clobber_p)
{
int i, in;
rtx new_in_reg, new_out_reg, reg;
@@ -939,17 +940,19 @@ match_reload (signed char out, signed char *ins, enum reg_class goal_class,
have a situation like "a <- a op b", where the constraints
force the second input operand ("b") to match the output
operand ("a"). "b" must then be copied into a new register
- so that it doesn't clobber the current value of "a". */
+ so that it doesn't clobber the current value of "a".
+
+ We can not use the same value if the output pseudo is
+ early clobbered or the input pseudo is mentioned in the
+ output, e.g. as an address part in memory, because
+ output reload will actually extend the pseudo liveness.
+ We don't care about eliminable hard regs here as we are
+ interesting only in pseudos. */
new_in_reg = new_out_reg
- = (ins[1] < 0 && REG_P (in_rtx)
+ = (! early_clobber_p && ins[1] < 0 && REG_P (in_rtx)
&& (int) REGNO (in_rtx) < lra_new_regno_start
&& find_regno_note (curr_insn, REG_DEAD, REGNO (in_rtx))
- /* We can not use the same value if the pseudo is mentioned
- in the output, e.g. as an address part in memory,
- becuase output reload will actually extend the pseudo
- liveness. We don't care about eliminable hard regs here
- as we are interesting only in pseudos. */
&& (out < 0 || regno_use_in (REGNO (in_rtx), out_rtx) == NULL_RTX)
? lra_create_new_reg (inmode, in_rtx, goal_class, "")
: lra_create_new_reg_with_unique_value (outmode, out_rtx,
@@ -3867,13 +3870,18 @@ curr_insn_transform (bool check_only_p)
match_inputs[0] = i;
match_inputs[1] = -1;
match_reload (goal_alt_matched[i][0], match_inputs,
- goal_alt[i], &before, &after);
+ goal_alt[i], &before, &after,
+ curr_static_id->operand_alternative
+ [goal_alt_number * n_operands + goal_alt_matched[i][0]]
+ .earlyclobber);
}
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);
+ match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after,
+ curr_static_id->operand_alternative
+ [goal_alt_number * n_operands + i].earlyclobber);
else if (curr_static_id->operand[i].type == OP_IN
&& (curr_static_id->operand[goal_alt_matched[i][0]].type
== OP_IN))
@@ -3883,7 +3891,7 @@ curr_insn_transform (bool check_only_p)
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);
+ match_reload (-1, match_inputs, goal_alt[i], &before, &after, false);
}
else
/* We must generate code in any case when function