Commit a2d0d374 by Vladimir Makarov Committed by Vladimir Makarov

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
parent 1fef3644
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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 *); ...@@ -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
......
...@@ -130,11 +130,13 @@ static void invalidate_insn_data_regno_info (lra_insn_recog_data_t, rtx, int); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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));
......
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
......
/* { 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);
}
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