[new-regalloc] Bootstrap dammit

Michael Matz matz@suse.de
Fri Feb 21 00:43:00 GMT 2003


Hi,

the below patch makes the branch bootstrap again most languages (Ada not
tested).  Now I've finally a better base for ensuring that the merge of my
other things don't introduce too much breakage.


Ciao,
Michael.
-- 

        * df.h (DF_REF_ALREADY_SPILLED, DF_REF_COMPARE_RELATED,
        DF_REF_EARLYCLOBBER): New.
        * df.c (df_ref_search_cached): Ignore some flags for equality.
        (read_modify_subreg_p): Return false.
        (df_uses_record): Mark compare related refs.

        * ra-build.c (copy_insn_p): If there are stack pseudos, it's no
        copy insn.
        (detect_remat_webs): Don't rematerialize trapping expressions.
        (class_ok_for_mode): New.
        (web_class): Use it.

        * ra-colorize.c (proper_hard_reg_subset_p): New.
        (colorize_one_web): Use it.

        * ra-rewrite.c (delete_useless_defs): Don't delete throwing insns.
        (assign_stack_slots_1): Ditto.

Index: df.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.c,v
retrieving revision 1.1.2.19
diff -u -p -r1.1.2.19 df.c
--- df.c	20 Nov 2002 22:43:10 -0000	1.1.2.19
+++ df.c	21 Feb 2003 00:10:55 -0000
@@ -799,7 +799,9 @@ df_ref_search_cached (df, reg, loc, insn
 	  && DF_REF_LOC (this_ref) == loc
 	  && DF_REF_INSN (this_ref) == insn
 	  && DF_REF_TYPE (this_ref) == ref_type
-          && (DF_REF_FLAGS (this_ref) & ~DF_REF_DELETED) == ref_flags)
+          && (DF_REF_FLAGS (this_ref)
+	      & (DF_REF_READ_WRITE | DF_REF_MODE_CHANGE
+		 | DF_REF_COMPARE_RELATED)) == ref_flags)
 	{
 	  DF_REF_FLAGS (this_ref) &= ~DF_REF_DELETED;
 	  return this_ref;
@@ -939,23 +941,29 @@ df_ref_record (df, reg, loc, insn, ref_t
     }
 }

-/* Writes to paradoxical subregs, or subregs which are too narrow
-   are read-modify-write.  */
+/* Writes to subregs which are too narrow are read-modify-write.  */

 static inline bool
 read_modify_subreg_p (x)
      rtx x;
 {
   unsigned int isize, osize;
+  /* Hmm, with exact subreg tracking _no_ writes to subregs are
+     read-mod-write in any way.  Inside a STRICT_LOW_PART they are,
+     but not otherwise.  Narrow subregs at least clobber the whole word
+     they belong to, wider subregs a whole number of words.
+     Paradoxical subreg writes don't leave a trace of the old content.  */
+  return false;
   if (GET_CODE (x) != SUBREG)
     return false;
   isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
   osize = GET_MODE_SIZE (GET_MODE (x));
+  /* Paradoxical subreg writes don't leave a trace of the old content.  */
   if (isize <= osize)
-    return true;
-  if (isize <= UNITS_PER_WORD)
     return false;
-  if (osize >= UNITS_PER_WORD)
+  if (osize >= GET_MODE_SIZE (SImode))
+    return false;
+  if (isize <= UNITS_PER_WORD)
     return false;
   return true;
 }
@@ -1225,6 +1233,10 @@ df_uses_record (df, loc, ref_type, bb, i
       /* ... Fall through to handle uses ...  */

     default:
+      /* Mark registers used in comparisons, because we might want to adjust
+         their spill cost in the graph coloring register allocator.  */
+      if (GET_RTX_CLASS (code) == '<')
+	flags |= DF_REF_COMPARE_RELATED;
       break;
     }

Index: df.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/df.h,v
retrieving revision 1.1.2.11
diff -u -p -r1.1.2.11 df.h
--- df.h	20 Nov 2002 22:43:09 -0000	1.1.2.11
+++ df.h	21 Feb 2003 00:10:55 -0000
@@ -61,7 +61,10 @@ enum df_ref_flags
        I.e. you must check yourself if it's a pseudo.  */
     DF_REF_MODE_CHANGE = 2,
     DF_REF_DELETED = 4,
-    DF_REF_MEM_OK = 8
+    DF_REF_MEM_OK = 8,
+    DF_REF_ALREADY_SPILLED = 16,
+    DF_REF_COMPARE_RELATED = 32,
+    DF_REF_EARLYCLOBBER = 64
   };

 /* Define a register reference structure.  */
Index: ra-build.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ra-build.c,v
retrieving revision 1.1.2.9
diff -u -p -r1.1.2.9 ra-build.c
--- ra-build.c	1 Feb 2003 17:27:08 -0000	1.1.2.9
+++ ra-build.c	21 Feb 2003 00:10:55 -0000
@@ -279,8 +279,8 @@ copy_insn_p (insn, source, target)
   /* Copies between hardregs are useless for us, as not coalesable anyway. */
   if ((s_regno < FIRST_PSEUDO_REGISTER
        && d_regno < FIRST_PSEUDO_REGISTER)
-      /*|| SPILL_SLOT_P (s_regno)
-      || SPILL_SLOT_P (d_regno)*/)
+      || SPILL_SLOT_P (s_regno)
+      || SPILL_SLOT_P (d_regno))
     return 0;

   if (source)
@@ -2599,6 +2599,8 @@ rematerializable_stack_arg_p (insn, src)
   return 0;
 }

+extern int flag_non_call_exceptions;
+
 /* Look at all webs, if they perhaps are rematerializable.
    They are, if all their defs are simple sets to the same value,
    and that value is simple enough, and want_to_remat() holds for it.  */
@@ -2657,6 +2659,8 @@ detect_remat_webs ()
 		   && bitmap_bit_p (emitted_by_spill, INSN_UID (insn))
 		   && memref_is_stack_slot (src))
 	       || rematerializable_stack_arg_p (insn, src))
+	      /* Don't even try to rematerialize trapping things.  */
+	      && !(flag_non_call_exceptions && may_trap_p (src))
 	      /* And we must be able to construct an insn without
 		 side-effects to actually load that value into a reg.  */
 	      && want_to_remat (src))
@@ -3683,6 +3687,23 @@ conflicts_early_clobbered ()
     }
 }

+static int class_ok_for_mode PARAMS ((enum reg_class, enum machine_mode));
+
+/* Returns true if at least one of the hardregs in CLASS is OK
+   for MODE.  */
+static int
+class_ok_for_mode (class, mode)
+     enum reg_class class;
+     enum machine_mode mode;
+{
+  int i;
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+    if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
+	&& HARD_REGNO_MODE_OK (i, mode))
+      return 1;
+  return 0;
+}
+
 /* Select a reg_class for the WEB. Split the WEB if single reg_class
    can't be selected.  */
 static void
@@ -3752,6 +3773,9 @@ web_class (web)
     }
   else
     {
+      /* XXX Ugly hack to suppress repeated spilling tries for such webs.  */
+      if (!class_ok_for_mode (class, PSEUDO_REGNO_MODE (web->regno)))
+	class = GENERAL_REGS;
       web->regclass = class;
       COPY_HARD_REG_SET (web->usable_regs, usable_regs[class]);
     }
Index: ra-colorize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ra-colorize.c,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 ra-colorize.c
--- ra-colorize.c	1 Feb 2003 17:27:08 -0000	1.1.2.8
+++ ra-colorize.c	21 Feb 2003 00:10:55 -0000
@@ -72,6 +72,7 @@ static int get_biased_reg PARAMS ((HARD_
 				   HARD_REG_SET, enum machine_mode));
 static char * hardregset_to_string PARAMS ((HARD_REG_SET));
 static void calculate_dont_begin PARAMS ((struct web *, HARD_REG_SET *));
+static int proper_hard_reg_subset_p PARAMS ((HARD_REG_SET, HARD_REG_SET));
 static void colorize_one_web PARAMS ((struct web *, int));
 static void assign_colors PARAMS ((void));
 static void try_recolor_web PARAMS ((struct web *));
@@ -1293,6 +1294,22 @@ calculate_dont_begin (web, result)
   COPY_HARD_REG_SET (*result, dont_begin);
 }

+/* Returns nonzero if S1 is a proper subset of S2.  */
+
+static int
+proper_hard_reg_subset_p (s1, s2)
+     HARD_REG_SET s1, s2;
+{
+  HARD_REG_SET s;
+  COPY_HARD_REG_SET (s, s2);
+  AND_COMPL_HARD_REG_SET (s, s1);
+  /* If s == s2 - s1 is empty s1 is not a proper subset of s2.  */
+  GO_IF_HARD_REG_SUBSET (s, reg_class_contents[(int) NO_REGS], lose);
+  return 1;
+lose:
+  return 0;
+}
+
 /* Try to assign a color to WEB.  If HARD if nonzero, we try many
    tricks to get it one color, including respilling already colored
    neighbors.
@@ -1619,7 +1636,12 @@ colorize_one_web (web, hard)
 		  /* If in the last iteration no insns were emitted for this
 		     web we also try to spill neighbors which are spill
 		     temps (and not only type 2 spill temps).  */
-		  if (web->changed && !aw->changed && aw->spill_temp)
+		  if (web->changed && aw->spill_temp
+		      && (!aw->changed
+			  /* Similar if the other (spill-temp) web has more
+			     usable regs than us.  */
+			  || proper_hard_reg_subset_p (web->usable_regs,
+						       aw->usable_regs)))
 		    set_cand (8, aw);
 		  if (aw->spill_temp && aw->span_deaths /* && !aw->changed */
 		      && !web->span_deaths
Index: ra-rewrite.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ra-rewrite.c,v
retrieving revision 1.1.2.8
diff -u -p -r1.1.2.8 ra-rewrite.c
--- ra-rewrite.c	1 Feb 2003 17:27:08 -0000	1.1.2.8
+++ ra-rewrite.c	21 Feb 2003 00:10:55 -0000
@@ -1983,7 +1983,8 @@ delete_useless_defs ()
       rtx insn = DF_REF_INSN (df->defs[i]);
       rtx set = single_set (insn);
       struct web *web = find_web_for_subweb (def2web[i]);
-      if (set && web->type == SPILLED && web->stack_slot == NULL)
+      if (set && web->type == SPILLED && web->stack_slot == NULL
+	  && !can_throw_internal (insn))
         {
 	  deleted_def_insns++;
 	  deleted_def_cost += BLOCK_FOR_INSN (insn)->frequency + 1;
@@ -2459,7 +2460,8 @@ assign_stack_slots_1 ()
 	  rtx dead = DF_REF_INSN (web->defs[0]);
 	  struct ra_insn_info *info = &insn_df[INSN_UID (dead)];

-	  if (info->num_defs != 1 || GET_CODE (dead) != INSN)
+	  if (info->num_defs != 1 || GET_CODE (dead) != INSN
+	      || can_throw_internal (dead))
 	    continue;
 	  for (i = 0; i < info->num_uses; ++i)
 	    {



More information about the Gcc-patches mailing list