df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
authorMichael Matz <matz@suse.de>
Fri, 7 Mar 2003 22:06:16 +0000 (22:06 +0000)
committerMichael Matz <matz@gcc.gnu.org>
Fri, 7 Mar 2003 22:06:16 +0000 (22:06 +0000)
        * df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
        (DF_FOR_REGALLOC): New.
        * df.c (df_ref_record): Set DF_REF_STRIPPED.
        (read_modify_subreg_p): Simplify.
        (df_def_record_1, df_uses_record): Set DF_REF_MODE_CHANGE more often.
        Use DF_FOR_REGALLOC.
        * ra.h (struct web): New member subreg_stripped.
        (invalid_mode_change_regs): Declare.
        * ra.c (invalid_mode_change_regs): New.
        (init_ra): Initialize it.
        * ra-build.c (init_one_web_common, remember_web_was_spilled): Use it.
        Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
        (reinit_one_web, parts_to_web_1): Deal with subreg_stripped.
        * ra-colorize.c (colorize_one_web): Use invalid_mode_change_regs.
        Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.

From-SVN: r63952

gcc/ChangeLog
gcc/df.c
gcc/df.h
gcc/ra-build.c
gcc/ra-colorize.c
gcc/ra.c
gcc/ra.h

index 4d90245bf0d3d29dfd498d7908687590c882076a..1debc6929a16991e6de322d717cd5d49e3f707bc 100644 (file)
@@ -1,3 +1,21 @@
+2003-03-07  Michael Matz  <matz@suse.de>
+
+       * df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
+       (DF_FOR_REGALLOC): New.
+       * df.c (df_ref_record): Set DF_REF_STRIPPED.
+       (read_modify_subreg_p): Simplify.
+       (df_def_record_1, df_uses_record): Set DF_REF_MODE_CHANGE more often.
+       Use DF_FOR_REGALLOC.
+       * ra.h (struct web): New member subreg_stripped.
+       (invalid_mode_change_regs): Declare.
+       * ra.c (invalid_mode_change_regs): New.
+       (init_ra): Initialize it.
+       * ra-build.c (init_one_web_common, remember_web_was_spilled): Use it.
+       Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
+       (reinit_one_web, parts_to_web_1): Deal with subreg_stripped.
+       * ra-colorize.c (colorize_one_web): Use invalid_mode_change_regs.
+       Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
+
 2003-03-07  Richard Earnshaw  <rearnsha@arm.com>
 
        * arm.md (addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, negsf2)
index c151249a197ccf620ce70a07e0241a69be9b2d89..740f2ccad1c336ebd07ea7d26c40b02ababc3b5c 100644 (file)
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -849,6 +849,7 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
     {
       loc = &SUBREG_REG (reg);
       reg = *loc;
+      ref_flags |= DF_REF_STRIPPED;
     }
 
   regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
@@ -893,13 +894,8 @@ read_modify_subreg_p (x)
     return false;
   isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
   osize = GET_MODE_SIZE (GET_MODE (x));
-  if (isize <= osize)
-    return true;
-  if (isize <= UNITS_PER_WORD)
-    return false;
-  if (osize > UNITS_PER_WORD)
-    return false;
-  return true;
+  /* Paradoxical subreg writes don't leave a trace of the old content.  */
+  return (isize > osize && isize > UNITS_PER_WORD);
 }
 
 
@@ -927,9 +923,7 @@ df_def_record_1 (df, x, bb, insn)
     }
 
 #ifdef CLASS_CANNOT_CHANGE_MODE
-  if (GET_CODE (dst) == SUBREG
-      && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
-                                    GET_MODE (dst)))
+  if (GET_CODE (dst) == SUBREG)
     flags |= DF_REF_MODE_CHANGE;
 #endif
 
@@ -938,7 +932,8 @@ df_def_record_1 (df, x, bb, insn)
   while (GET_CODE (dst) == STRICT_LOW_PART
         || GET_CODE (dst) == ZERO_EXTRACT
         || GET_CODE (dst) == SIGN_EXTRACT
-        || read_modify_subreg_p (dst))
+        || ((df->flags & DF_FOR_REGALLOC) == 0
+             && read_modify_subreg_p (dst)))
     {
       /* Strict low part always contains SUBREG, but we do not want to make
         it appear outside, as whole register is always considered.  */
@@ -948,9 +943,7 @@ df_def_record_1 (df, x, bb, insn)
          dst = *loc;
        }
 #ifdef CLASS_CANNOT_CHANGE_MODE
-      if (GET_CODE (dst) == SUBREG
-         && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
-                                        GET_MODE (dst)))
+      if (GET_CODE (dst) == SUBREG)
         flags |= DF_REF_MODE_CHANGE;
 #endif
       loc = &XEXP (dst, 0);
@@ -1050,9 +1043,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
          return;
        }
 #ifdef CLASS_CANNOT_CHANGE_MODE
-      if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
-                                     GET_MODE (SUBREG_REG (x))))
-        flags |= DF_REF_MODE_CHANGE;
+      flags |= DF_REF_MODE_CHANGE;
 #endif
 
       /* ... Fall through ...  */
@@ -1072,13 +1063,12 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
          {
            enum df_ref_flags use_flags;
            case SUBREG:
-             if (read_modify_subreg_p (dst))
+             if ((df->flags & DF_FOR_REGALLOC) == 0
+                  && read_modify_subreg_p (dst))
                {
                  use_flags = DF_REF_READ_WRITE;
 #ifdef CLASS_CANNOT_CHANGE_MODE
-                 if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
-                                                 GET_MODE (SUBREG_REG (dst))))
-                   use_flags |= DF_REF_MODE_CHANGE;
+                 use_flags |= DF_REF_MODE_CHANGE;
 #endif
                  df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
                                  insn, use_flags);
@@ -1102,9 +1092,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
                abort ();
              use_flags = DF_REF_READ_WRITE;
 #ifdef CLASS_CANNOT_CHANGE_MODE
-             if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
-                                             GET_MODE (SUBREG_REG (dst))))
-               use_flags |= DF_REF_MODE_CHANGE;
+             use_flags |= DF_REF_MODE_CHANGE;
 #endif
              df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
                             insn, use_flags);
index d20d298cf7a5884f6b65075dbac87e8c3a78e9f6..a294843c6cb7a3c09b0d91f87e75ee59f50c89aa 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define DF_ALL        255
 #define DF_HARD_REGS  1024     /* Mark hard registers.  */
 #define DF_EQUIV_NOTES 2048    /* Mark uses present in EQUIV/EQUAL notes.  */
+#define DF_FOR_REGALLOC 4096    /* If called for the register allocator.  */
 
 enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
                  DF_REF_REG_MEM_STORE};
@@ -52,13 +53,17 @@ enum df_ref_flags
     DF_REF_READ_WRITE = 1,
     
     /* This flag is set on register references inside a subreg on
-       machines which have CLASS_CANNOT_CHANGE_MODE and where the mode
-       change of that subreg expression is invalid for this class.
+       machines which have CANNOT_CHANGE_MODE_CLASS.
        Note, that this flag can also be set on df_refs representing
        the REG itself (i.e., one might not see the subreg anyore).
        Also note, that this flag is set also for hardreg refs, i.e.,
        you must check yourself if it's a pseudo.  */
-    DF_REF_MODE_CHANGE = 2
+    DF_REF_MODE_CHANGE = 2,
+
+    /* This flag is set, if we stripped the subreg from the reference.
+       In this case we must make conservative guesses, at what the
+       outer mode was.  */
+    DF_REF_STRIPPED = 4
   };
 
 
index 4448065de0d3eed6bc6e2e209d652ee218fbf247..37ca30c79948bad36fe04ef95c7373f89e3922fe 100644 (file)
@@ -1305,10 +1305,9 @@ init_one_web_common (web, reg)
       AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
       prune_hardregs_for_mode (&web->usable_regs,
                               PSEUDO_REGNO_MODE (web->regno));
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
       if (web->mode_changed)
-        AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[
-                                 (int) CLASS_CANNOT_CHANGE_MODE]);
+        AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
 #endif
       web->num_freedom = hard_regs_count (web->usable_regs);
       web->num_freedom -= web->add_hardregs;
@@ -1351,6 +1350,7 @@ reinit_one_web (web, reg)
   web->artificial = 0;
   web->live_over_abnormal = 0;
   web->mode_changed = 0;
+  web->subreg_stripped = 0;
   web->move_related = 0;
   web->in_load = 0;
   web->target_of_spilled_move = 0;
@@ -1912,6 +1912,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
          if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
              && web->regno >= FIRST_PSEUDO_REGISTER)
            web->mode_changed = 1;
+         if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
+             && web->regno >= FIRST_PSEUDO_REGISTER)
+           web->subreg_stripped = 1;
          if (i >= def_id
              && TEST_BIT (live_over_abnormal, ref_id))
            web->live_over_abnormal = 1;
@@ -1961,6 +1964,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
       if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
          && web->regno >= FIRST_PSEUDO_REGISTER)
        web->mode_changed = 1;
+      if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
+         && web->regno >= FIRST_PSEUDO_REGISTER)
+       web->subreg_stripped = 1;
 
       /* Setup def2web, or use2web, and increment num_defs or num_uses.  */
       if (i < def_id)
@@ -2364,10 +2370,9 @@ remember_web_was_spilled (web)
                       reg_class_contents[(int) GENERAL_REGS]);
   AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
   prune_hardregs_for_mode (&web->usable_regs, PSEUDO_REGNO_MODE (web->regno));
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
   if (web->mode_changed)
-    AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[
-                             (int) CLASS_CANNOT_CHANGE_MODE]);
+    AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
 #endif
   web->num_freedom = hard_regs_count (web->usable_regs);
   if (!web->num_freedom)
index 359dfd86126524477b5a9632ca1d6488f00dc8ef..6c514df1c4ee84cdcf113099c0a1fba7d05729e9 100644 (file)
@@ -1370,10 +1370,9 @@ colorize_one_web (web, hard)
       else
        COPY_HARD_REG_SET (colors,
                           usable_regs[reg_preferred_class (web->regno)]);
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
       if (web->mode_changed)
-        AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
-                                 (int) CLASS_CANNOT_CHANGE_MODE]);
+        AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
 #endif
       COPY_HARD_REG_SET (call_clobbered, colors);
       AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
@@ -1404,10 +1403,9 @@ colorize_one_web (web, hard)
          else
            IOR_HARD_REG_SET (colors, usable_regs
                              [reg_alternate_class (web->regno)]);
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
          if (web->mode_changed)
-           AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
-                                     (int) CLASS_CANNOT_CHANGE_MODE]);
+           AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
 #endif
          COPY_HARD_REG_SET (call_clobbered, colors);
          AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
index dfd4ef5b519cee3e9f040f377a0a2ea3bc0c108f..45f22ced3bb3293e6eab178d05101dbeb19510b0 100644 (file)
--- a/gcc/ra.c
+++ b/gcc/ra.c
@@ -148,6 +148,7 @@ HARD_REG_SET never_use_colors;
 HARD_REG_SET usable_regs[N_REG_CLASSES];
 unsigned int num_free_regs[N_REG_CLASSES];
 HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
+HARD_REG_SET invalid_mode_change_regs;
 unsigned char byte2bitcount[256];
 
 unsigned int debug_new_regalloc = -1;
@@ -555,6 +556,23 @@ init_ra ()
       COPY_HARD_REG_SET (hardregs_for_mode[i], rs);
     }
 
+  CLEAR_HARD_REG_SET (invalid_mode_change_regs);
+#ifdef CANNOT_CHANGE_MODE_CLASS
+  if (0)
+  for (i = 0; i < NUM_MACHINE_MODES; i++)
+    {
+      enum machine_mode from = (enum machine_mode) i;
+      enum machine_mode to;
+      for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
+       {
+         int r;
+         for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+           if (REG_CANNOT_CHANGE_MODE_P (from, to, r))
+             SET_HARD_REG_BIT (invalid_mode_change_regs, r);
+       }
+    }
+#endif
+
   for (an_unusable_color = 0; an_unusable_color < FIRST_PSEUDO_REGISTER;
        an_unusable_color++)
     if (TEST_HARD_REG_BIT (never_use_colors, an_unusable_color))
@@ -755,7 +773,7 @@ reg_alloc ()
         chains per insn, and per regno.  In later passes only update
          that info from the new and modified insns.  */
       df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
-                 DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN);
+                 DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN | DF_FOR_REGALLOC);
 
       if ((debug_new_regalloc & DUMP_DF) != 0)
        {
index 522b77a758647f3718e2ba1430302aa1f296548e..f324d362ad3bbd1e44078e76695f193bd394d4f1 100644 (file)
--- a/gcc/ra.h
+++ b/gcc/ra.h
@@ -168,6 +168,11 @@ struct web
      was illegal for hardregs in CLASS_CANNOT_CHANGE_MODE.  */
   unsigned int mode_changed:1;
 
+  /* Nonzero if some references of this web, where in subreg context,
+     but the actual subreg is already stripped (i.e. we don't know the
+     outer mode of the actual reference).  */
+  unsigned int subreg_stripped:1;
+
   /* Nonzero, when this web stems from the last pass of the allocator,
      and all info is still valid (i.e. it wasn't spilled).  */
   unsigned int old_web:1;
@@ -497,6 +502,8 @@ extern unsigned int num_free_regs[N_REG_CLASSES];
    represent the possible resources which could be taken away be a value
    in mode M.  */
 extern HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
+/* The set of hardregs, for which _any_ mode change is invalid.  */
+extern HARD_REG_SET invalid_mode_change_regs;
 /* For 0 <= I <= 255, the number of bits set in I.  Used to calculate
    the number of set bits in a HARD_REG_SET.  */
 extern unsigned char byte2bitcount[256];