mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/59133 (ICE after r204219 on SPEC2006 435.gromacs.)
2013-11-20 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/59133 * lra.c (expand_reg_data): Add new argument. Set up ALL_REGS for new pseudos. (lra_create_new_reg_with_unique_value): Pass new argument value. (lra_emit_add, lra_emit_move): Ditto. * lra-constraints.c (in_class_p): Add check for move for a new insn. (change_class): Rename to lra_change_class. Move to lra-int.h. (get_reload_reg, narrow_reload_pseudo_class): Adjust calls of change_class. (process_addr_reg, process_addr): Ditto. (curr_insn_transform): Ditto. Add check on old pseudo for optional reload. * lra-int.h (lra_get_regno_hard_regno): Move below. (lra_change_class): Renamed change_class from lra.c. 2013-11-20 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/59133 * gcc.target/i386/pr59133.c: New. From-SVN: r205141
This commit is contained in:
parent
1fef36449e
commit
a2d0d374f6
|
|
@ -1,3 +1,21 @@
|
||||||
|
2013-11-20 Vladimir Makarov <vmakarov@redhat.com>
|
||||||
|
|
||||||
|
PR rtl-optimization/59133
|
||||||
|
* lra.c (expand_reg_data): Add new argument. Set up ALL_REGS for
|
||||||
|
new pseudos.
|
||||||
|
(lra_create_new_reg_with_unique_value): Pass new argument value.
|
||||||
|
(lra_emit_add, lra_emit_move): Ditto.
|
||||||
|
* lra-constraints.c (in_class_p): Add check for move for a new
|
||||||
|
insn.
|
||||||
|
(change_class): Rename to lra_change_class. Move to lra-int.h.
|
||||||
|
(get_reload_reg, narrow_reload_pseudo_class): Adjust calls of
|
||||||
|
change_class.
|
||||||
|
(process_addr_reg, process_addr): Ditto.
|
||||||
|
(curr_insn_transform): Ditto. Add check on old pseudo for
|
||||||
|
optional reload.
|
||||||
|
* lra-int.h (lra_get_regno_hard_regno): Move below.
|
||||||
|
(lra_change_class): Renamed change_class from lra.c.
|
||||||
|
|
||||||
2013-11-20 David Malcolm <dmalcolm@redhat.com>
|
2013-11-20 David Malcolm <dmalcolm@redhat.com>
|
||||||
|
|
||||||
* gdbhooks.py (VecPrinter.children): Don't attempt to iterate
|
* gdbhooks.py (VecPrinter.children): Don't attempt to iterate
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,11 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
|
||||||
typically moves that have many alternatives, and restricting
|
typically moves that have many alternatives, and restricting
|
||||||
reload pseudos for one alternative may lead to situations
|
reload pseudos for one alternative may lead to situations
|
||||||
where other reload pseudos are no longer allocatable. */
|
where other reload pseudos are no longer allocatable. */
|
||||||
|| INSN_UID (curr_insn) >= new_insn_uid_start)
|
|| (INSN_UID (curr_insn) >= new_insn_uid_start
|
||||||
|
&& curr_insn_set != NULL
|
||||||
|
&& (OBJECT_P (SET_SRC (curr_insn_set))
|
||||||
|
|| (GET_CODE (SET_SRC (curr_insn_set)) == SUBREG
|
||||||
|
&& OBJECT_P (SUBREG_REG (SET_SRC (curr_insn_set)))))))
|
||||||
/* When we don't know what class will be used finally for reload
|
/* When we don't know what class will be used finally for reload
|
||||||
pseudos, we use ALL_REGS. */
|
pseudos, we use ALL_REGS. */
|
||||||
return ((regno >= new_regno_start && rclass == ALL_REGS)
|
return ((regno >= new_regno_start && rclass == ALL_REGS)
|
||||||
|
|
@ -381,21 +385,6 @@ init_curr_insn_input_reloads (void)
|
||||||
curr_insn_input_reloads_num = 0;
|
curr_insn_input_reloads_num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change class of pseudo REGNO to NEW_CLASS. Print info about it
|
|
||||||
using TITLE. Output a new line if NL_P. */
|
|
||||||
static void
|
|
||||||
change_class (int regno, enum reg_class new_class,
|
|
||||||
const char *title, bool nl_p)
|
|
||||||
{
|
|
||||||
lra_assert (regno >= FIRST_PSEUDO_REGISTER);
|
|
||||||
if (lra_dump_file != NULL)
|
|
||||||
fprintf (lra_dump_file, "%s to class %s for r%d",
|
|
||||||
title, reg_class_names[new_class], regno);
|
|
||||||
setup_reg_classes (regno, new_class, NO_REGS, new_class);
|
|
||||||
if (lra_dump_file != NULL && nl_p)
|
|
||||||
fprintf (lra_dump_file, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
|
/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
|
||||||
created input reload pseudo (only if TYPE is not OP_OUT). The
|
created input reload pseudo (only if TYPE is not OP_OUT). The
|
||||||
result pseudo is returned through RESULT_REG. Return TRUE if we
|
result pseudo is returned through RESULT_REG. Return TRUE if we
|
||||||
|
|
@ -442,7 +431,7 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
|
||||||
dump_value_slim (lra_dump_file, original, 1);
|
dump_value_slim (lra_dump_file, original, 1);
|
||||||
}
|
}
|
||||||
if (new_class != lra_get_allocno_class (regno))
|
if (new_class != lra_get_allocno_class (regno))
|
||||||
change_class (regno, new_class, ", change", false);
|
lra_change_class (regno, new_class, ", change to", false);
|
||||||
if (lra_dump_file != NULL)
|
if (lra_dump_file != NULL)
|
||||||
fprintf (lra_dump_file, "\n");
|
fprintf (lra_dump_file, "\n");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -667,7 +656,7 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
|
||||||
if (! REG_P (reg) || (int) REGNO (reg) < new_regno_start)
|
if (! REG_P (reg) || (int) REGNO (reg) < new_regno_start)
|
||||||
return;
|
return;
|
||||||
if (in_class_p (reg, cl, &rclass) && rclass != cl)
|
if (in_class_p (reg, cl, &rclass) && rclass != cl)
|
||||||
change_class (REGNO (reg), rclass, " Change", true);
|
lra_change_class (REGNO (reg), rclass, " Change to", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate reloads for matching OUT and INS (array of input operand
|
/* Generate reloads for matching OUT and INS (array of input operand
|
||||||
|
|
@ -1133,7 +1122,7 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl)
|
||||||
}
|
}
|
||||||
else if (new_class != NO_REGS && rclass != new_class)
|
else if (new_class != NO_REGS && rclass != new_class)
|
||||||
{
|
{
|
||||||
change_class (regno, new_class, " Change", true);
|
lra_change_class (regno, new_class, " Change to", true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -2796,7 +2785,7 @@ process_address (int nop, rtx *before, rtx *after)
|
||||||
regno = REGNO (*ad.base_term);
|
regno = REGNO (*ad.base_term);
|
||||||
if (regno >= FIRST_PSEUDO_REGISTER
|
if (regno >= FIRST_PSEUDO_REGISTER
|
||||||
&& cl != lra_get_allocno_class (regno))
|
&& cl != lra_get_allocno_class (regno))
|
||||||
change_class (regno, cl, " Change", true);
|
lra_change_class (regno, cl, " Change to", true);
|
||||||
new_reg = SET_SRC (set);
|
new_reg = SET_SRC (set);
|
||||||
delete_insns_since (PREV_INSN (last_insn));
|
delete_insns_since (PREV_INSN (last_insn));
|
||||||
}
|
}
|
||||||
|
|
@ -3316,7 +3305,7 @@ curr_insn_transform (void)
|
||||||
if (new_class != NO_REGS && get_reg_class (regno) != new_class)
|
if (new_class != NO_REGS && get_reg_class (regno) != new_class)
|
||||||
{
|
{
|
||||||
lra_assert (ok_p);
|
lra_assert (ok_p);
|
||||||
change_class (regno, new_class, " Change", true);
|
lra_change_class (regno, new_class, " Change to", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3395,7 +3384,7 @@ curr_insn_transform (void)
|
||||||
&& lra_former_scratch_operand_p (curr_insn, i))
|
&& lra_former_scratch_operand_p (curr_insn, i))
|
||||||
{
|
{
|
||||||
int regno = REGNO (op);
|
int regno = REGNO (op);
|
||||||
change_class (regno, NO_REGS, " Change", true);
|
lra_change_class (regno, NO_REGS, " Change to", true);
|
||||||
if (lra_get_regno_hard_regno (regno) >= 0)
|
if (lra_get_regno_hard_regno (regno) >= 0)
|
||||||
/* We don't have to mark all insn affected by the
|
/* We don't have to mark all insn affected by the
|
||||||
spilled pseudo as there is only one such insn, the
|
spilled pseudo as there is only one such insn, the
|
||||||
|
|
@ -3410,6 +3399,7 @@ curr_insn_transform (void)
|
||||||
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
|
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
|
||||||
&& goal_alt[i] != NO_REGS && REG_P (op)
|
&& goal_alt[i] != NO_REGS && REG_P (op)
|
||||||
&& (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
|
&& (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
|
||||||
|
&& regno < new_regno_start
|
||||||
&& ! lra_former_scratch_p (regno)
|
&& ! lra_former_scratch_p (regno)
|
||||||
&& reg_renumber[regno] < 0
|
&& reg_renumber[regno] < 0
|
||||||
&& (curr_insn_set == NULL_RTX
|
&& (curr_insn_set == NULL_RTX
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,6 @@ along with GCC; see the file COPYING3. If not see
|
||||||
base and index registers might require a reload too. */
|
base and index registers might require a reload too. */
|
||||||
#define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
|
#define LRA_MAX_INSN_RELOADS (MAX_RECOG_OPERANDS * 3)
|
||||||
|
|
||||||
/* Return the hard register which given pseudo REGNO assigned to.
|
|
||||||
Negative value means that the register got memory or we don't know
|
|
||||||
allocation yet. */
|
|
||||||
static inline int
|
|
||||||
lra_get_regno_hard_regno (int regno)
|
|
||||||
{
|
|
||||||
resize_reg_info ();
|
|
||||||
return reg_renumber[regno];
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct lra_live_range *lra_live_range_t;
|
typedef struct lra_live_range *lra_live_range_t;
|
||||||
|
|
||||||
/* The structure describes program points where a given pseudo lives.
|
/* The structure describes program points where a given pseudo lives.
|
||||||
|
|
@ -394,6 +384,31 @@ extern void lra_eliminate_reg_if_possible (rtx *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the hard register which given pseudo REGNO assigned to.
|
||||||
|
Negative value means that the register got memory or we don't know
|
||||||
|
allocation yet. */
|
||||||
|
static inline int
|
||||||
|
lra_get_regno_hard_regno (int regno)
|
||||||
|
{
|
||||||
|
resize_reg_info ();
|
||||||
|
return reg_renumber[regno];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change class of pseudo REGNO to NEW_CLASS. Print info about it
|
||||||
|
using TITLE. Output a new line if NL_P. */
|
||||||
|
static void inline
|
||||||
|
lra_change_class (int regno, enum reg_class new_class,
|
||||||
|
const char *title, bool nl_p)
|
||||||
|
{
|
||||||
|
lra_assert (regno >= FIRST_PSEUDO_REGISTER);
|
||||||
|
if (lra_dump_file != NULL)
|
||||||
|
fprintf (lra_dump_file, "%s class %s for r%d",
|
||||||
|
title, reg_class_names[new_class], regno);
|
||||||
|
setup_reg_classes (regno, new_class, NO_REGS, new_class);
|
||||||
|
if (lra_dump_file != NULL && nl_p)
|
||||||
|
fprintf (lra_dump_file, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Update insn operands which are duplication of NOP operand. The
|
/* Update insn operands which are duplication of NOP operand. The
|
||||||
insn is represented by its LRA internal representation ID. */
|
insn is represented by its LRA internal representation ID. */
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
||||||
10
gcc/lra.c
10
gcc/lra.c
|
|
@ -130,11 +130,13 @@ static void invalidate_insn_data_regno_info (lra_insn_recog_data_t, rtx, int);
|
||||||
|
|
||||||
/* Expand all regno related info needed for LRA. */
|
/* Expand all regno related info needed for LRA. */
|
||||||
static void
|
static void
|
||||||
expand_reg_data (void)
|
expand_reg_data (int old)
|
||||||
{
|
{
|
||||||
resize_reg_info ();
|
resize_reg_info ();
|
||||||
expand_reg_info ();
|
expand_reg_info ();
|
||||||
ira_expand_reg_equiv ();
|
ira_expand_reg_equiv ();
|
||||||
|
for (int i = (int) max_reg_num () - 1; i >= old; i--)
|
||||||
|
lra_change_class (i, ALL_REGS, " Set", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and return a new reg of ORIGINAL mode. If ORIGINAL is NULL
|
/* Create and return a new reg of ORIGINAL mode. If ORIGINAL is NULL
|
||||||
|
|
@ -178,7 +180,7 @@ lra_create_new_reg_with_unique_value (enum machine_mode md_mode, rtx original,
|
||||||
title, REGNO (new_reg));
|
title, REGNO (new_reg));
|
||||||
fprintf (lra_dump_file, "\n");
|
fprintf (lra_dump_file, "\n");
|
||||||
}
|
}
|
||||||
expand_reg_data ();
|
expand_reg_data (max_reg_num ());
|
||||||
setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
|
setup_reg_classes (REGNO (new_reg), rclass, NO_REGS, rclass);
|
||||||
return new_reg;
|
return new_reg;
|
||||||
}
|
}
|
||||||
|
|
@ -417,7 +419,7 @@ lra_emit_add (rtx x, rtx y, rtx z)
|
||||||
/* Functions emit_... can create pseudos -- so expand the pseudo
|
/* Functions emit_... can create pseudos -- so expand the pseudo
|
||||||
data. */
|
data. */
|
||||||
if (old != max_reg_num ())
|
if (old != max_reg_num ())
|
||||||
expand_reg_data ();
|
expand_reg_data (old);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The number of emitted reload insns so far. */
|
/* The number of emitted reload insns so far. */
|
||||||
|
|
@ -443,7 +445,7 @@ lra_emit_move (rtx x, rtx y)
|
||||||
/* Function emit_move can create pseudos -- so expand the pseudo
|
/* Function emit_move can create pseudos -- so expand the pseudo
|
||||||
data. */
|
data. */
|
||||||
if (old != max_reg_num ())
|
if (old != max_reg_num ())
|
||||||
expand_reg_data ();
|
expand_reg_data (old);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
|
lra_emit_add (x, XEXP (y, 0), XEXP (y, 1));
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2013-11-20 Vladimir Makarov <vmakarov@redhat.com>
|
||||||
|
|
||||||
|
PR rtl-optimization/59133
|
||||||
|
* gcc.target/i386/pr59133.c: New.
|
||||||
|
|
||||||
2013-11-20 Joseph Myers <joseph@codesourcery.com>
|
2013-11-20 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
PR middle-end/21718
|
PR middle-end/21718
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O3 -ffast-math -march=core-avx2" } */
|
||||||
|
|
||||||
|
#define XX 0
|
||||||
|
#define YY 1
|
||||||
|
#define ZZ 2
|
||||||
|
#define DIM 3
|
||||||
|
typedef float matrix[DIM][DIM];
|
||||||
|
typedef float rvec[DIM];
|
||||||
|
extern int det (matrix);
|
||||||
|
extern void foo(matrix);
|
||||||
|
|
||||||
|
void bar1 (int n,int *index,rvec x[],matrix trans)
|
||||||
|
{
|
||||||
|
float xt,yt,zt;
|
||||||
|
int i,ii;
|
||||||
|
|
||||||
|
for(i=0; (i<n); i++) {
|
||||||
|
ii=index ? index[i] : i;
|
||||||
|
xt=x[ii][XX];
|
||||||
|
yt=x[ii][YY];
|
||||||
|
zt=x[ii][ZZ];
|
||||||
|
x[ii][XX]=trans[XX][XX]*xt+trans[XX][YY]*yt+trans[XX][ZZ]*zt;
|
||||||
|
x[ii][YY]=trans[YY][XX]*xt+trans[YY][YY]*yt+trans[YY][ZZ]*zt;
|
||||||
|
x[ii][ZZ]=trans[ZZ][XX]*xt+trans[ZZ][YY]*yt+trans[ZZ][ZZ]*zt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bar2 (int n, rvec x[])
|
||||||
|
{
|
||||||
|
int m;
|
||||||
|
matrix trans;
|
||||||
|
|
||||||
|
foo (trans);
|
||||||
|
|
||||||
|
if (det (trans) < 0) {
|
||||||
|
for(m=0; (m<DIM); m++)
|
||||||
|
trans[ZZ][m] = -trans[ZZ][m];
|
||||||
|
}
|
||||||
|
bar1 (n,(int*) 0,x,trans);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue