to LIST. X is a part of insn given by DATA. Return the result
list. */
static struct lra_insn_reg *
-collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
+collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
+ lra_insn_recog_data_t data,
struct lra_insn_reg *list,
enum op_type type, bool early_clobber)
{
switch (code)
{
case SET:
- list = collect_non_operand_hard_regs (&SET_DEST (op), data,
+ list = collect_non_operand_hard_regs (insn, &SET_DEST (op), data,
list, OP_OUT, false);
- list = collect_non_operand_hard_regs (&SET_SRC (op), data,
+ list = collect_non_operand_hard_regs (insn, &SET_SRC (op), data,
list, OP_IN, false);
break;
case CLOBBER:
- /* We treat clobber of non-operand hard registers as early
- clobber (the behavior is expected from asm). */
- list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
- list, OP_OUT, true);
- break;
+ {
+ int code = INSN_CODE (insn);
+ /* We treat clobber of non-operand hard registers as early
+ clobber (the behavior is expected from asm). */
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
+ list, OP_OUT, code < 0);
+ break;
+ }
case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
- list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
list, OP_INOUT, false);
break;
case PRE_MODIFY: case POST_MODIFY:
- list = collect_non_operand_hard_regs (&XEXP (op, 0), data,
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 0), data,
list, OP_INOUT, false);
- list = collect_non_operand_hard_regs (&XEXP (op, 1), data,
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, 1), data,
list, OP_IN, false);
break;
default:
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- list = collect_non_operand_hard_regs (&XEXP (op, i), data,
+ list = collect_non_operand_hard_regs (insn, &XEXP (op, i), data,
list, OP_IN, false);
else if (fmt[i] == 'E')
for (j = XVECLEN (op, i) - 1; j >= 0; j--)
- list = collect_non_operand_hard_regs (&XVECEXP (op, i, j), data,
- list, OP_IN, false);
+ list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
+ data, list, OP_IN, false);
}
}
return list;
insn_static_data->hard_regs = NULL;
else
insn_static_data->hard_regs
- = collect_non_operand_hard_regs (&PATTERN (insn), data,
+ = collect_non_operand_hard_regs (insn, &PATTERN (insn), data,
NULL, OP_IN, false);
data->arg_hard_regs = NULL;
if (CALL_P (insn))
/* This page contains code dealing with info about registers in
insns. */
-/* Process X of insn UID recursively and add info (operand type is
+/* Process X of INSN recursively and add info (operand type is
given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
about registers in X to the insn DATA. If X can be early clobbered,
alternatives in which it can be early clobbered are given by
EARLY_CLOBBER_ALTS. */
static void
-add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
+add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
+ rtx_insn *insn,
enum op_type type, bool early_clobber,
alternative_mask early_clobber_alts)
{
/* Process all regs even unallocatable ones as we need info about
all regs for rematerialization pass. */
expand_reg_info ();
- if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
+ if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
{
data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
early_clobber, early_clobber_alts,
switch (code)
{
case SET:
- add_regs_to_insn_regno_info (data, SET_DEST (x), uid, OP_OUT, false, 0);
- add_regs_to_insn_regno_info (data, SET_SRC (x), uid, OP_IN, false, 0);
+ add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0);
+ add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
break;
case CLOBBER:
- /* We treat clobber of non-operand hard registers as early
- clobber (the behavior is expected from asm). */
- add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true, ALL_ALTERNATIVES);
- break;
+ {
+ int code = INSN_CODE (insn);
+
+ /* We treat clobber of non-operand hard registers as early
+ clobber (the behavior is expected from asm). */
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
+ code < 0, code < 0 ? ALL_ALTERNATIVES : 0);
+ break;
+ }
case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
- add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
break;
case PRE_MODIFY: case POST_MODIFY:
- add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_INOUT, false, 0);
- add_regs_to_insn_regno_info (data, XEXP (x, 1), uid, OP_IN, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0);
break;
default:
if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- add_regs_to_insn_regno_info (data, XEXP (x, i), uid, type, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0);
else if (fmt[i] == 'E')
{
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), uid,
+ add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
type, false, 0);
}
}
void
lra_update_insn_regno_info (rtx_insn *insn)
{
- int i, uid, freq;
+ int i, freq;
lra_insn_recog_data_t data;
struct lra_static_insn_data *static_data;
enum rtx_code code;
static_data = data->insn_static_data;
freq = get_insn_freq (insn);
invalidate_insn_data_regno_info (data, insn, freq);
- uid = INSN_UID (insn);
for (i = static_data->n_operands - 1; i >= 0; i--)
- add_regs_to_insn_regno_info (data, *data->operand_loc[i], uid,
+ add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
static_data->operand[i].type,
static_data->operand[i].early_clobber,
static_data->operand[i].early_clobber_alts);
if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
- add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), uid,
+ add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
code == USE ? OP_IN : OP_OUT, false, 0);
if (CALL_P (insn))
/* On some targets call insns can refer to pseudos in memory in
link = XEXP (link, 1))
if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER)
&& MEM_P (XEXP (XEXP (link, 0), 0)))
- add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), uid,
+ add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
code == USE ? OP_IN : OP_OUT, false, 0);
if (NONDEBUG_INSN_P (insn))
setup_insn_reg_info (data, freq);