Commit 561c58b4 by Vladimir Makarov Committed by Vladimir Makarov

re PR rtl-optimization/80818 (LRA clobbers live hard reg clobbered during rematerialization)

2017-11-29  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/80818
	* lra.c (collect_non_operand_hard_regs): New arg insn.  Pass it
	recursively.  Use insn code for clobber.
	(lra_set_insn_recog_data): Pass the new arg to
	collect_non_operand_hard_regs.
	(add_regs_to_insn_regno_info): Pass insn instead of uid.  Use insn
	code for clobber.
	(lra_update_insn_regno_info): Pass insn to
	add_regs_to_insn_regno_info.

From-SVN: r255258
parent 08539f3e
2017-11-29 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/80818
* lra.c (collect_non_operand_hard_regs): New arg insn. Pass it
recursively. Use insn code for clobber.
(lra_set_insn_recog_data): Pass the new arg to
collect_non_operand_hard_regs.
(add_regs_to_insn_regno_info): Pass insn instead of uid. Use insn
code for clobber.
(lra_update_insn_regno_info): Pass insn to
add_regs_to_insn_regno_info.
2017-11-29 Jim Wilson <jimw@sifive.com> 2017-11-29 Jim Wilson <jimw@sifive.com>
Andrew Waterman <andrew@sifive.com> Andrew Waterman <andrew@sifive.com>
...@@ -807,7 +807,8 @@ setup_operand_alternative (lra_insn_recog_data_t data, ...@@ -807,7 +807,8 @@ setup_operand_alternative (lra_insn_recog_data_t data,
to LIST. X is a part of insn given by DATA. Return the result to LIST. X is a part of insn given by DATA. Return the result
list. */ list. */
static struct lra_insn_reg * 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, struct lra_insn_reg *list,
enum op_type type, bool early_clobber) enum op_type type, bool early_clobber)
{ {
...@@ -881,25 +882,28 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data, ...@@ -881,25 +882,28 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
switch (code) switch (code)
{ {
case SET: 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, 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); list, OP_IN, false);
break; break;
case CLOBBER: case CLOBBER:
/* We treat clobber of non-operand hard registers as early {
clobber (the behavior is expected from asm). */ int code = INSN_CODE (insn);
list = collect_non_operand_hard_regs (&XEXP (op, 0), data, /* We treat clobber of non-operand hard registers as early
list, OP_OUT, true); clobber (the behavior is expected from asm). */
break; 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: 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); list, OP_INOUT, false);
break; break;
case PRE_MODIFY: case POST_MODIFY: 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, 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); list, OP_IN, false);
break; break;
default: default:
...@@ -907,12 +911,12 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data, ...@@ -907,12 +911,12 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
if (fmt[i] == 'e') 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); list, OP_IN, false);
else if (fmt[i] == 'E') else if (fmt[i] == 'E')
for (j = XVECLEN (op, i) - 1; j >= 0; j--) for (j = XVECLEN (op, i) - 1; j >= 0; j--)
list = collect_non_operand_hard_regs (&XVECEXP (op, i, j), data, list = collect_non_operand_hard_regs (insn, &XVECEXP (op, i, j),
list, OP_IN, false); data, list, OP_IN, false);
} }
} }
return list; return list;
...@@ -1055,7 +1059,7 @@ lra_set_insn_recog_data (rtx_insn *insn) ...@@ -1055,7 +1059,7 @@ lra_set_insn_recog_data (rtx_insn *insn)
insn_static_data->hard_regs = NULL; insn_static_data->hard_regs = NULL;
else else
insn_static_data->hard_regs 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); NULL, OP_IN, false);
data->arg_hard_regs = NULL; data->arg_hard_regs = NULL;
if (CALL_P (insn)) if (CALL_P (insn))
...@@ -1402,13 +1406,14 @@ lra_get_copy (int n) ...@@ -1402,13 +1406,14 @@ lra_get_copy (int n)
/* This page contains code dealing with info about registers in /* This page contains code dealing with info about registers in
insns. */ 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) 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, 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 alternatives in which it can be early clobbered are given by
EARLY_CLOBBER_ALTS. */ EARLY_CLOBBER_ALTS. */
static void 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, enum op_type type, bool early_clobber,
alternative_mask early_clobber_alts) alternative_mask early_clobber_alts)
{ {
...@@ -1436,7 +1441,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, ...@@ -1436,7 +1441,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
/* Process all regs even unallocatable ones as we need info about /* Process all regs even unallocatable ones as we need info about
all regs for rematerialization pass. */ all regs for rematerialization pass. */
expand_reg_info (); 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, data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
early_clobber, early_clobber_alts, early_clobber, early_clobber_alts,
...@@ -1471,20 +1476,25 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, ...@@ -1471,20 +1476,25 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
switch (code) switch (code)
{ {
case SET: 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_DEST (x), insn, 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_SRC (x), insn, OP_IN, false, 0);
break; break;
case CLOBBER: case CLOBBER:
/* We treat clobber of non-operand hard registers as early {
clobber (the behavior is expected from asm). */ int code = INSN_CODE (insn);
add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true, ALL_ALTERNATIVES);
break; /* 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: 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; break;
case PRE_MODIFY: case POST_MODIFY: 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, 0), insn, 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, 1), insn, OP_IN, false, 0);
break; break;
default: default:
if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT) if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
...@@ -1505,11 +1515,11 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid, ...@@ -1505,11 +1515,11 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
if (fmt[i] == 'e') 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') else if (fmt[i] == 'E')
{ {
for (j = XVECLEN (x, i) - 1; j >= 0; j--) 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); type, false, 0);
} }
} }
...@@ -1585,7 +1595,7 @@ setup_insn_reg_info (lra_insn_recog_data_t data, int freq) ...@@ -1585,7 +1595,7 @@ setup_insn_reg_info (lra_insn_recog_data_t data, int freq)
void void
lra_update_insn_regno_info (rtx_insn *insn) lra_update_insn_regno_info (rtx_insn *insn)
{ {
int i, uid, freq; int i, freq;
lra_insn_recog_data_t data; lra_insn_recog_data_t data;
struct lra_static_insn_data *static_data; struct lra_static_insn_data *static_data;
enum rtx_code code; enum rtx_code code;
...@@ -1597,14 +1607,13 @@ lra_update_insn_regno_info (rtx_insn *insn) ...@@ -1597,14 +1607,13 @@ lra_update_insn_regno_info (rtx_insn *insn)
static_data = data->insn_static_data; static_data = data->insn_static_data;
freq = get_insn_freq (insn); freq = get_insn_freq (insn);
invalidate_insn_data_regno_info (data, insn, freq); invalidate_insn_data_regno_info (data, insn, freq);
uid = INSN_UID (insn);
for (i = static_data->n_operands - 1; i >= 0; i--) 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].type,
static_data->operand[i].early_clobber, static_data->operand[i].early_clobber,
static_data->operand[i].early_clobber_alts); static_data->operand[i].early_clobber_alts);
if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE) 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); code == USE ? OP_IN : OP_OUT, false, 0);
if (CALL_P (insn)) if (CALL_P (insn))
/* On some targets call insns can refer to pseudos in memory in /* On some targets call insns can refer to pseudos in memory in
...@@ -1616,7 +1625,7 @@ lra_update_insn_regno_info (rtx_insn *insn) ...@@ -1616,7 +1625,7 @@ lra_update_insn_regno_info (rtx_insn *insn)
link = XEXP (link, 1)) link = XEXP (link, 1))
if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER) if (((code = GET_CODE (XEXP (link, 0))) == USE || code == CLOBBER)
&& MEM_P (XEXP (XEXP (link, 0), 0))) && 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); code == USE ? OP_IN : OP_OUT, false, 0);
if (NONDEBUG_INSN_P (insn)) if (NONDEBUG_INSN_P (insn))
setup_insn_reg_info (data, freq); setup_insn_reg_info (data, freq);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment