re PR target/79282 ([7 Regresion] FAIL: gcc.target/arm/neon-for-64bits-1.c scan-assembler-times vshr 0)
2017-02-14 Vladimir Makarov <vmakarov@redhat.com> PR target/79282 * lra-int.h (struct lra_operand_data, struct lra_insn_reg): Add member early_clobber_alts. * lra-lives.c (reg_early_clobber_p): New. (process_bb_lives): Use it. * lra.c (new_insn_reg): New arg early_clobber_alts. Use it. (debug_operand_data): Initialize early_clobber_alts. (setup_operand_alternative): Set up early_clobber_alts. (collect_non_operand_hard_regs): Ditto. Pass early clobber alternatives to new_insn_reg. (add_regs_to_insn_regno_info): Add arg early_clobber_alts. Use it. (lra_update_insn_regno_info): Pass the new arg. From-SVN: r245459
This commit is contained in:
parent
2932fe90d5
commit
584898ee80
@ -1,3 +1,19 @@
|
||||
2017-02-14 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR target/79282
|
||||
* lra-int.h (struct lra_operand_data, struct lra_insn_reg): Add
|
||||
member early_clobber_alts.
|
||||
* lra-lives.c (reg_early_clobber_p): New.
|
||||
(process_bb_lives): Use it.
|
||||
* lra.c (new_insn_reg): New arg early_clobber_alts. Use it.
|
||||
(debug_operand_data): Initialize early_clobber_alts.
|
||||
(setup_operand_alternative): Set up early_clobber_alts.
|
||||
(collect_non_operand_hard_regs): Ditto. Pass early clobber
|
||||
alternatives to new_insn_reg.
|
||||
(add_regs_to_insn_regno_info): Add arg early_clobber_alts. Use
|
||||
it.
|
||||
(lra_update_insn_regno_info): Pass the new arg.
|
||||
|
||||
2017-02-14 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR middle-end/79505
|
||||
|
@ -130,6 +130,8 @@ struct lra_operand_data
|
||||
{
|
||||
/* The machine description constraint string of the operand. */
|
||||
const char *constraint;
|
||||
/* Alternatives for which early_clobber can be true. */
|
||||
alternative_mask early_clobber_alts;
|
||||
/* It is taken only from machine description (which is different
|
||||
from recog_data.operand_mode) and can be of VOIDmode. */
|
||||
ENUM_BITFIELD(machine_mode) mode : 16;
|
||||
@ -150,6 +152,8 @@ struct lra_operand_data
|
||||
/* Info about register occurrence in an insn. */
|
||||
struct lra_insn_reg
|
||||
{
|
||||
/* Alternatives for which early_clobber can be true. */
|
||||
alternative_mask early_clobber_alts;
|
||||
/* The biggest mode through which the insn refers to the register
|
||||
occurrence (remember the register can be accessed through a
|
||||
subreg in the insn). */
|
||||
|
@ -586,6 +586,16 @@ check_pseudos_live_through_calls (int regno,
|
||||
SET_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs);
|
||||
}
|
||||
|
||||
/* Return true if insn REG is an early clobber operand in alternative
|
||||
NALT. Negative NALT means that we don't know the current insn
|
||||
alternative. So assume the worst. */
|
||||
static inline bool
|
||||
reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt)
|
||||
{
|
||||
return (reg->early_clobber
|
||||
&& (n_alt < 0 || TEST_BIT (reg->early_clobber_alts, n_alt)));
|
||||
}
|
||||
|
||||
/* Process insns of the basic block BB to update pseudo live ranges,
|
||||
pseudo hard register conflicts, and insn notes. We do it on
|
||||
backward scan of BB insns. CURR_POINT is the program point where
|
||||
@ -638,7 +648,7 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
|
||||
FOR_BB_INSNS_REVERSE_SAFE (bb, curr_insn, next)
|
||||
{
|
||||
bool call_p;
|
||||
int dst_regno, src_regno;
|
||||
int n_alt, dst_regno, src_regno;
|
||||
rtx set;
|
||||
struct lra_insn_reg *reg;
|
||||
|
||||
@ -647,9 +657,10 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
|
||||
|
||||
curr_id = lra_get_insn_recog_data (curr_insn);
|
||||
curr_static_id = curr_id->insn_static_data;
|
||||
n_alt = curr_id->used_insn_alternative;
|
||||
if (lra_dump_file != NULL)
|
||||
fprintf (lra_dump_file, " Insn %u: point = %d\n",
|
||||
INSN_UID (curr_insn), curr_point);
|
||||
fprintf (lra_dump_file, " Insn %u: point = %d, n_alt = %d\n",
|
||||
INSN_UID (curr_insn), curr_point, n_alt);
|
||||
|
||||
set = single_set (curr_insn);
|
||||
|
||||
@ -818,13 +829,15 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
|
||||
|
||||
/* See which defined values die here. */
|
||||
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
|
||||
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
|
||||
if (reg->type == OP_OUT
|
||||
&& ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
|
||||
need_curr_point_incr
|
||||
|= mark_regno_dead (reg->regno, reg->biggest_mode,
|
||||
curr_point);
|
||||
|
||||
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
|
||||
if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p)
|
||||
if (reg->type == OP_OUT
|
||||
&& ! reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
|
||||
make_hard_regno_dead (reg->regno);
|
||||
|
||||
if (curr_id->arg_hard_regs != NULL)
|
||||
@ -901,13 +914,15 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p)
|
||||
|
||||
/* Mark early clobber outputs dead. */
|
||||
for (reg = curr_id->regs; reg != NULL; reg = reg->next)
|
||||
if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
|
||||
if (reg->type == OP_OUT
|
||||
&& reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
|
||||
need_curr_point_incr
|
||||
|= mark_regno_dead (reg->regno, reg->biggest_mode,
|
||||
curr_point);
|
||||
|
||||
for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next)
|
||||
if (reg->type == OP_OUT && reg->early_clobber && ! reg->subreg_p)
|
||||
if (reg->type == OP_OUT
|
||||
&& reg_early_clobber_p (reg, n_alt) && ! reg->subreg_p)
|
||||
make_hard_regno_dead (reg->regno);
|
||||
|
||||
if (need_curr_point_incr)
|
||||
|
67
gcc/lra.c
67
gcc/lra.c
@ -529,15 +529,19 @@ lra_update_dups (lra_insn_recog_data_t id, signed char *nops)
|
||||
/* Pools for insn reg info. */
|
||||
object_allocator<lra_insn_reg> lra_insn_reg_pool ("insn regs");
|
||||
|
||||
/* Create LRA insn related info about a reference to REGNO in INSN with
|
||||
TYPE (in/out/inout), biggest reference mode MODE, flag that it is
|
||||
reference through subreg (SUBREG_P), flag that is early clobbered
|
||||
in the insn (EARLY_CLOBBER), and reference to the next insn reg
|
||||
info (NEXT). */
|
||||
/* Create LRA insn related info about a reference to REGNO in INSN
|
||||
with TYPE (in/out/inout), biggest reference mode MODE, flag that it
|
||||
is reference through subreg (SUBREG_P), flag that is early
|
||||
clobbered in the insn (EARLY_CLOBBER), and reference to the next
|
||||
insn reg info (NEXT). If REGNO can be early clobbered,
|
||||
alternatives in which it can be early clobbered are given by
|
||||
EARLY_CLOBBER_ALTS. */
|
||||
static struct lra_insn_reg *
|
||||
new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
|
||||
machine_mode mode,
|
||||
bool subreg_p, bool early_clobber, struct lra_insn_reg *next)
|
||||
bool subreg_p, bool early_clobber,
|
||||
alternative_mask early_clobber_alts,
|
||||
struct lra_insn_reg *next)
|
||||
{
|
||||
lra_insn_reg *ir = lra_insn_reg_pool.allocate ();
|
||||
ir->type = type;
|
||||
@ -547,6 +551,7 @@ new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
|
||||
lra_reg_info[regno].biggest_mode = mode;
|
||||
ir->subreg_p = subreg_p;
|
||||
ir->early_clobber = early_clobber;
|
||||
ir->early_clobber_alts = early_clobber_alts;
|
||||
ir->regno = regno;
|
||||
ir->next = next;
|
||||
return ir;
|
||||
@ -590,6 +595,7 @@ struct lra_static_insn_data *insn_code_data[NUM_INSN_CODES];
|
||||
static struct lra_operand_data debug_operand_data =
|
||||
{
|
||||
NULL, /* alternative */
|
||||
0, /* early_clobber_alts */
|
||||
VOIDmode, /* We are not interesting in the operand mode. */
|
||||
OP_IN,
|
||||
0, 0, 0, 0
|
||||
@ -771,6 +777,7 @@ setup_operand_alternative (lra_insn_recog_data_t data,
|
||||
static_data->operand_alternative = op_alt;
|
||||
for (i = 0; i < nop; i++)
|
||||
{
|
||||
static_data->operand[i].early_clobber_alts = 0;
|
||||
static_data->operand[i].early_clobber = false;
|
||||
static_data->operand[i].is_address = false;
|
||||
if (static_data->operand[i].constraint[0] == '%')
|
||||
@ -788,6 +795,8 @@ setup_operand_alternative (lra_insn_recog_data_t data,
|
||||
for (i = 0; i < nop; i++, op_alt++)
|
||||
{
|
||||
static_data->operand[i].early_clobber |= op_alt->earlyclobber;
|
||||
if (op_alt->earlyclobber)
|
||||
static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
|
||||
static_data->operand[i].is_address |= op_alt->is_address;
|
||||
}
|
||||
}
|
||||
@ -847,8 +856,11 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
|
||||
{
|
||||
if (curr->type != type)
|
||||
curr->type = OP_INOUT;
|
||||
if (curr->early_clobber != early_clobber)
|
||||
curr->early_clobber = true;
|
||||
if (early_clobber)
|
||||
{
|
||||
curr->early_clobber = true;
|
||||
curr->early_clobber_alts = ALL_ALTERNATIVES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (curr == NULL)
|
||||
@ -864,7 +876,8 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
|
||||
&& regno <= LAST_STACK_REG));
|
||||
#endif
|
||||
list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
|
||||
early_clobber, list);
|
||||
early_clobber,
|
||||
early_clobber ? ALL_ALTERNATIVES : 0, list);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
@ -1395,10 +1408,13 @@ lra_get_copy (int n)
|
||||
|
||||
/* Process X of insn UID 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. */
|
||||
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,
|
||||
enum op_type type, bool early_clobber)
|
||||
enum op_type type, bool early_clobber,
|
||||
alternative_mask early_clobber_alts)
|
||||
{
|
||||
int i, j, regno;
|
||||
bool subreg_p;
|
||||
@ -1430,7 +1446,8 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
|
||||
if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
|
||||
{
|
||||
data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
|
||||
early_clobber, data->regs);
|
||||
early_clobber, early_clobber_alts,
|
||||
data->regs);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -1443,13 +1460,14 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
|
||||
structure. */
|
||||
data->regs = new_insn_reg (data->insn, regno, type, mode,
|
||||
subreg_p, early_clobber,
|
||||
data->regs);
|
||||
early_clobber_alts, data->regs);
|
||||
else
|
||||
{
|
||||
if (curr->type != type)
|
||||
curr->type = OP_INOUT;
|
||||
if (curr->early_clobber != early_clobber)
|
||||
curr->early_clobber = true;
|
||||
curr->early_clobber_alts |= early_clobber_alts;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1460,20 +1478,20 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
|
||||
switch (code)
|
||||
{
|
||||
case SET:
|
||||
add_regs_to_insn_regno_info (data, SET_DEST (x), uid, OP_OUT, false);
|
||||
add_regs_to_insn_regno_info (data, SET_SRC (x), uid, OP_IN, false);
|
||||
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);
|
||||
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);
|
||||
add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, OP_OUT, true, ALL_ALTERNATIVES);
|
||||
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);
|
||||
add_regs_to_insn_regno_info (data, XEXP (x, 0), uid, 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);
|
||||
add_regs_to_insn_regno_info (data, XEXP (x, 1), uid, OP_IN, false);
|
||||
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);
|
||||
break;
|
||||
default:
|
||||
if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
|
||||
@ -1494,12 +1512,12 @@ 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--)
|
||||
{
|
||||
if (fmt[i] == 'e')
|
||||
add_regs_to_insn_regno_info (data, XEXP (x, i), uid, type, false);
|
||||
add_regs_to_insn_regno_info (data, XEXP (x, i), uid, 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,
|
||||
type, false);
|
||||
type, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1590,10 +1608,11 @@ lra_update_insn_regno_info (rtx_insn *insn)
|
||||
for (i = static_data->n_operands - 1; i >= 0; i--)
|
||||
add_regs_to_insn_regno_info (data, *data->operand_loc[i], uid,
|
||||
static_data->operand[i].type,
|
||||
static_data->operand[i].early_clobber);
|
||||
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,
|
||||
code == USE ? OP_IN : OP_OUT, false);
|
||||
code == USE ? OP_IN : OP_OUT, false, 0);
|
||||
if (CALL_P (insn))
|
||||
/* On some targets call insns can refer to pseudos in memory in
|
||||
CALL_INSN_FUNCTION_USAGE list. Process them in order to
|
||||
@ -1605,7 +1624,7 @@ lra_update_insn_regno_info (rtx_insn *insn)
|
||||
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,
|
||||
code == USE ? OP_IN : OP_OUT, false);
|
||||
code == USE ? OP_IN : OP_OUT, false, 0);
|
||||
if (NONDEBUG_INSN_P (insn))
|
||||
setup_insn_reg_info (data, freq);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user