OSDN Git Service

* fixed-value.h: New file.
[pf3gnuchains/gcc-fork.git] / gcc / df-scan.c
index 010488e..76f85c1 100644 (file)
@@ -10,7 +10,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -19,10 +19,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
-*/
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -341,6 +339,7 @@ df_scan_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   df->insns_to_delete = BITMAP_ALLOC (&problem_data->insn_bitmaps);
   df->insns_to_rescan = BITMAP_ALLOC (&problem_data->insn_bitmaps);
   df->insns_to_notes_rescan = BITMAP_ALLOC (&problem_data->insn_bitmaps);
+  df_scan->optional_p = false;
 }
 
 
@@ -432,9 +431,10 @@ static struct df_problem problem_SCAN =
   df_scan_start_block,        /* Debugging start block.  */
   NULL,                       /* Debugging end block.  */
   NULL,                       /* Incremental solution verify start.  */
-  NULL,                       /* Incremental solution verfiy end.  */
+  NULL,                       /* Incremental solution verify end.  */
   NULL,                       /* Dependent problem.  */
-  TV_DF_SCAN                  /* Timing variable.  */
+  TV_DF_SCAN,                 /* Timing variable.  */
+  false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
 
 
@@ -2146,8 +2146,8 @@ df_ref_equal_p (struct df_ref *ref1, struct df_ref *ref2)
 static int
 df_ref_compare (const void *r1, const void *r2)
 {
-  const struct df_ref *ref1 = *(struct df_ref **)r1;
-  const struct df_ref *ref2 = *(struct df_ref **)r2;
+  const struct df_ref *const ref1 = *(const struct df_ref *const*)r1;
+  const struct df_ref *const ref2 = *(const struct df_ref *const*)r2;
 
   if (ref1 == ref2)
     return 0;
@@ -2263,8 +2263,8 @@ df_mw_equal_p (struct df_mw_hardreg *mw1, struct df_mw_hardreg *mw2)
 static int
 df_mw_compare (const void *m1, const void *m2)
 {
-  const struct df_mw_hardreg *mw1 = *(struct df_mw_hardreg **)m1;
-  const struct df_mw_hardreg *mw2 = *(struct df_mw_hardreg **)m2;
+  const struct df_mw_hardreg *const mw1 = *(const struct df_mw_hardreg *const*)m1;
+  const struct df_mw_hardreg *const mw2 = *(const struct df_mw_hardreg *const*)m2;
 
   if (mw1 == mw2)
     return 0;
@@ -2625,7 +2625,6 @@ df_ref_record (struct df_collection_rec *collection_rec,
               enum df_ref_type ref_type, 
               enum df_ref_flags ref_flags) 
 {
-  rtx oldreg = reg;
   unsigned int regno;
 
   gcc_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);
@@ -2656,7 +2655,7 @@ df_ref_record (struct df_collection_rec *collection_rec,
        {
          /* Sets to a subreg of a multiword register are partial. 
             Sets to a non-subreg of a multiword register are not.  */
-         if (GET_CODE (oldreg) == SUBREG)
+         if (GET_CODE (reg) == SUBREG)
            ref_flags |= DF_REF_PARTIAL;
          ref_flags |= DF_REF_MW_HARDREG;
 
@@ -2664,7 +2663,6 @@ df_ref_record (struct df_collection_rec *collection_rec,
          hardreg->type = ref_type;
          hardreg->flags = ref_flags;
          hardreg->mw_reg = reg;
-         hardreg->loc = loc;
          hardreg->start_regno = regno;
          hardreg->end_regno = endregno - 1;
          hardreg->mw_order = df->ref_order++;
@@ -2701,7 +2699,8 @@ df_read_modify_subreg_p (rtx x)
     return false;
   isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
   osize = GET_MODE_SIZE (GET_MODE (x));
-  return (isize > osize && isize > UNITS_PER_WORD);
+  return isize > osize
+        && isize > REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x)));
 }
 
 
@@ -2716,7 +2715,6 @@ df_def_record_1 (struct df_collection_rec *collection_rec,
 {
   rtx *loc;
   rtx dst;
-  bool dst_in_strict_lowpart = false;
 
  /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
      construct.  */
@@ -2747,37 +2745,26 @@ df_def_record_1 (struct df_collection_rec *collection_rec,
   /* Maybe, we should flag the use of STRICT_LOW_PART somehow.  It might
      be handy for the reg allocator.  */
   while (GET_CODE (dst) == STRICT_LOW_PART
-        || GET_CODE (dst) == ZERO_EXTRACT
-        || df_read_modify_subreg_p (dst))
+        || GET_CODE (dst) == ZERO_EXTRACT)
     {
-#if 0
-      /* Strict low part always contains SUBREG, but we do not want to make
-        it appear outside, as whole register is always considered.  */
-      if (GET_CODE (dst) == STRICT_LOW_PART)
-       {
-         loc = &XEXP (dst, 0);
-         dst = *loc;
-       }
-#endif
+      flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
       loc = &XEXP (dst, 0);
-      if (GET_CODE (dst) == STRICT_LOW_PART)
-       dst_in_strict_lowpart = true;
       dst = *loc;
-      flags |= DF_REF_READ_WRITE;
-
     }
 
-  /* Sets to a subreg of a single word register are partial sets if
-     they are wrapped in a strict lowpart, and not partial otherwise.
-  */
-  if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))
-      && dst_in_strict_lowpart)
-    flags |= DF_REF_PARTIAL;
-    
+  if (df_read_modify_subreg_p (dst))
+    flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;
+
   if (REG_P (dst)
       || (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst))))
     df_ref_record (collection_rec, 
                    dst, loc, bb, insn, DF_REF_REG_DEF, flags);
+
+  /* We want to keep sp alive everywhere - by making all
+     writes to sp also use of sp. */
+  if (REG_P (dst) && REGNO (dst) == STACK_POINTER_REGNUM)
+    df_ref_record (collection_rec,
+               dst, NULL, bb, insn, DF_REF_REG_USE, flags);
 }
 
 
@@ -2982,9 +2969,9 @@ df_uses_record (struct df_collection_rec *collection_rec,
     case PRE_MODIFY:
     case POST_MODIFY:
       /* Catch the def of the register being modified.  */
-      flags |= DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY;
       df_ref_record (collection_rec, XEXP (x, 0), &XEXP (x, 0), bb, insn, 
-                    DF_REF_REG_DEF, flags);
+                    DF_REF_REG_DEF,
+                     flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY);
 
       /* ... Fall through to handle uses ...  */
 
@@ -3079,9 +3066,16 @@ df_get_call_refs (struct df_collection_rec * collection_rec,
                        DF_REF_REG_USE, bb, insn, flags);
       else if (GET_CODE (XEXP (note, 0)) == CLOBBER)
        {
-         unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0));
-         if (!bitmap_bit_p (defs_generated, regno))
-           df_defs_record (collection_rec, XEXP (note, 0), bb, insn, flags);
+         if (REG_P (XEXP (XEXP (note, 0), 0)))
+           {
+             unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0));
+             if (!bitmap_bit_p (defs_generated, regno))
+               df_defs_record (collection_rec, XEXP (note, 0), bb,
+                               insn, flags);
+           }
+         else
+           df_uses_record (collection_rec, &XEXP (note, 0),
+                           DF_REF_REG_USE, bb, insn, flags);
        }
     }
 
@@ -3434,7 +3428,7 @@ df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)
 {
   bitmap_clear (eh_block_artificial_uses);
 
-  /* The following code (down thru the arg_pointer seting APPEARS
+  /* The following code (down thru the arg_pointer setting APPEARS
      to be necessary because there is nothing that actually
      describes what the exception handling code may actually need
      to keep alive.  */
@@ -3587,11 +3581,12 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
      it has to show up in the entry def set.  */
   if (df_need_static_chain_reg (cfun))
     {
-#if !defined (STATIC_CHAIN_INCOMING_REGNUM) \
-      || STATIC_CHAIN_REGNUM == STATIC_CHAIN_INCOMING_REGNUM
-      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_REGNUM);
-#else 
+#ifdef STATIC_CHAIN_INCOMING_REGNUM
       bitmap_set_bit (entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
+#else 
+#ifdef STATIC_CHAIN_REGNUM
+      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_REGNUM);
+#endif
 #endif
     }
 }
@@ -4270,12 +4265,6 @@ df_scan_verify (void)
   if (!df)
     return;
 
-  /* This is a hack, but a necessary one.  If you do not do this,
-     insn_attrtab can never be compiled in a bootstrap.  This
-     verification is just too expensive.  */
-  if (n_basic_blocks > 250)
-    return;
-
   /* Verification is a 4 step process. */
 
   /* (1) All of the refs are marked by going thru the reg chains.  */