public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [lra] patch to fix SPEC2000 sixtrack compiler crash
@ 2011-08-03 19:41 Vladimir Makarov
  0 siblings, 0 replies; only message in thread
From: Vladimir Makarov @ 2011-08-03 19:41 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 645 bytes --]

The following patch fixes a new crash on SPEC2000 sixtrack on x86-64.  
LRA failed to find a mode for a constant.  When LRA can not find a mode 
of operand it uses mode from machine description of the insn.  It is not 
enough, in very rare cases the mode can be found only from context.  The 
patch adds such code.

The patch was successfully bootstrapped on x86-64.

2011-08-03  Vladimir Makarov <vmakarov@redhat.com>

         * lra-int.h (lra_get_mode): Remove.

         * lra-constraints.c (find_mode, get_op_mode): New.
         (match_reload, curr_insn_transform, process_alt_operands): Use
         get_op_mode instead of lra_get_mode.


[-- Attachment #2: sixtrack.patch --]
[-- Type: text/plain, Size: 3992 bytes --]

Index: lra-int.h
===================================================================
--- lra-int.h	(revision 176797)
+++ lra-int.h	(working copy)
@@ -225,16 +225,6 @@ struct lra_insn_recog_data
 
 typedef struct lra_insn_recog_data *lra_insn_recog_data_t;
 
-/* Return mode for X which corresponds to machine description operand
-   with mode MD_MODE.  */
-static inline enum machine_mode
-lra_get_mode (enum machine_mode md_mode, rtx x)
-{
-  if (GET_MODE (x) != VOIDmode)
-    return GET_MODE (x);
-  return md_mode;
-}
-
 /* lra.c: */
 
 extern FILE *lra_dump_file;
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 176950)
+++ lra-constraints.c	(working copy)
@@ -786,6 +786,60 @@ bitmap_head lra_dont_inherit_pseudos;
   (reg_class_size [(C)] == 1						\
    || (reg_class_size [(C)] >= 1 && targetm.class_likely_spilled_p (C)))
 
+/* Return mode of WHAT inside of WHERE whose mode of the context is
+   OUTER_MODE.  If WHERE does not contain WHAT, return VOIDmode.  */
+static enum machine_mode
+find_mode (rtx *where, enum machine_mode outer_mode, rtx *what)
+{
+  int i, j;
+  enum machine_mode mode;
+  rtx x;
+  const char *fmt;
+  enum rtx_code code;
+
+  if (where == what)
+    return outer_mode;
+  if (*where == NULL_RTX)
+    return VOIDmode;
+  x = *where;
+  code = GET_CODE (x);
+  outer_mode = GET_MODE (x);
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'e')
+	{
+	  if ((mode = find_mode (&XEXP (x, i), outer_mode, what)) != VOIDmode)
+	    return mode;
+	}
+      else if (fmt[i] == 'E')
+	{
+	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+	  if ((mode = find_mode (&XVECEXP (x, i, j), outer_mode, what))
+	      != VOIDmode)
+	    return mode;
+	}
+    }
+  return VOIDmode;
+}
+
+/* Return mode for operand NOP of the current insn.  */
+static inline enum machine_mode
+get_op_mode (int nop)
+{
+  rtx *loc = curr_id->operand_loc[nop];
+  enum machine_mode mode = GET_MODE (*loc);
+
+  /* Take mode from the operand first.  */
+  if (mode != VOIDmode)
+    return mode;
+  /* Take mode from the machine description second.  */
+  if ((mode = curr_static_id->operand[nop].mode) != VOIDmode)
+    return mode;
+  /* Here is a very rare case.  Take mode from the context.  */
+  return find_mode (&PATTERN (curr_insn), VOIDmode, loc);
+}
+
 /* Generate reloads for matching OUT and IN with reg class GOAL_CLASS.
    Add input and output reloads correspondingly to the lists *BEFORE
    and *AFTER.  */
@@ -798,8 +852,8 @@ match_reload (int out, int in, enum reg_
   rtx in_rtx = *curr_id->operand_loc[in];
   rtx out_rtx = *curr_id->operand_loc[out];
 
-  inmode = lra_get_mode (curr_static_id->operand[in].mode, in_rtx);
-  outmode = lra_get_mode (curr_static_id->operand[out].mode, out_rtx);
+  inmode = get_op_mode (in);
+  outmode = get_op_mode (out);
   if (inmode != outmode)
     {
       /* Don't reuse the pseudos for inheritance -- they will be bound.  */
@@ -1897,8 +1951,7 @@ process_alt_operands (int only_alternati
 		  && ((targetm.preferred_reload_class
 		       (op, this_alternative) == NO_REGS)
 		      || no_input_reloads_p)
-		  && lra_get_mode (curr_static_id->operand[nop].mode,
-				   op) != VOIDmode)
+		  && get_op_mode (nop) != VOIDmode)
 		{
 		  const_to_mem = 1;
 		  if (! no_regs_p)
@@ -2807,8 +2860,7 @@ curr_insn_transform (void)
 	rtx op = *curr_id->operand_loc[i];
 	rtx subreg = NULL_RTX;
 	rtx plus = NULL_RTX;
-	enum machine_mode mode
-	  = lra_get_mode (curr_static_id->operand[i].mode, op);
+	enum machine_mode mode = get_op_mode (i);
 	
 	if (GET_CODE (op) == SUBREG)
 	  {
@@ -2921,7 +2973,7 @@ curr_insn_transform (void)
 	  enum op_type type = curr_static_id->operand[i].type;
 
 	  loc = curr_id->operand_loc[i];
-	  mode = lra_get_mode (curr_static_id->operand[i].mode, *loc);
+	  mode = get_op_mode (i);
 	  if (GET_CODE (*loc) == SUBREG)
 	    {
 	      reg = SUBREG_REG (*loc);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-03 19:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-03 19:41 [lra] patch to fix SPEC2000 sixtrack compiler crash Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).