]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: [multiple changes]
authorUlrich Weigand <ulrich.weigand@linaro.org>
Mon, 2 May 2011 14:06:48 +0000 (14:06 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Mon, 2 May 2011 14:06:48 +0000 (14:06 +0000)
2011-05-02  Ulrich Weigand  <ulrich.weigand@linaro.org>

PR middle-end/43085
Backport from mainline:

2010-04-29  Bernd Schmidt  <bernds@codesourcery.com>

From Dominique d'Humieres <dominiq@lps.ens.fr>
PR bootstrap/43858
* ifcvt.c (dead_or_predicable): Use df_simulate_find_defs to compute
test_set.

2010-04-26  Bernd Schmidt  <bernds@codesourcery.com>

* df-problems.c (df_simulate_initialize_forwards): Set, don't clear,
bits for artificial defs at the top of the block.
* fwprop.c (single_def_use_enter_block): Don't call it.

2010-04-22  Bernd Schmidt  <bernds@codesourcery.com>

* ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and
df_simulate_find_noclobber_defs as appropriate.  Keep track of an
extra set merge_set_noclobber, and use it to relax the final test
slightly.
* df.h (df_simulate_find_noclobber_defs): Declare.
* df-problems.c (df_simulate_find_defs): Don't ignore partial or
conditional defs.
(df_simulate_find_noclobber_defs): New function.

From-SVN: r173252

gcc/ChangeLog
gcc/df-problems.c
gcc/df.h
gcc/fwprop.c
gcc/ifcvt.c

index 94ccb22622a1c095856f16f104150bc3cde556f4..434c4ca1dcf5d9d8e7ce641bceeb71718081c19c 100644 (file)
@@ -1,3 +1,32 @@
+2011-05-02  Ulrich Weigand  <ulrich.weigand@linaro.org>
+
+       PR middle-end/43085
+       Backport from mainline:
+
+       2010-04-29  Bernd Schmidt  <bernds@codesourcery.com>
+
+       From Dominique d'Humieres <dominiq@lps.ens.fr>
+       PR bootstrap/43858
+       * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs to compute
+       test_set.
+
+       2010-04-26  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * df-problems.c (df_simulate_initialize_forwards): Set, don't clear,
+       bits for artificial defs at the top of the block.
+       * fwprop.c (single_def_use_enter_block): Don't call it.
+
+       2010-04-22  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and
+       df_simulate_find_noclobber_defs as appropriate.  Keep track of an
+       extra set merge_set_noclobber, and use it to relax the final test
+       slightly.
+       * df.h (df_simulate_find_noclobber_defs): Declare.
+       * df-problems.c (df_simulate_find_defs): Don't ignore partial or
+       conditional defs.
+       (df_simulate_find_noclobber_defs): New function.
+
 2011-04-29  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR target/48288
index 0ec650bad09eb5451f0fb04325a81aeacb00e9d6..1fa80ea3abb13edea84216332ceec45f47f941d5 100644 (file)
@@ -3748,9 +3748,22 @@ df_simulate_find_defs (rtx insn, bitmap defs)
   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
     {
       df_ref def = *def_rec;
-      /* If the def is to only part of the reg, it does
-        not kill the other defs that reach here.  */
-      if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+      bitmap_set_bit (defs, DF_REF_REGNO (def));
+    }
+}
+
+/* Find the set of real DEFs, which are not clobbers, for INSN.  */
+
+void
+df_simulate_find_noclobber_defs (rtx insn, bitmap defs)
+{
+  df_ref *def_rec;
+  unsigned int uid = INSN_UID (insn);
+
+  for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+    {
+      df_ref def = *def_rec;
+      if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
        bitmap_set_bit (defs, DF_REF_REGNO (def));
     }
 }
@@ -3903,13 +3916,9 @@ df_simulate_finalize_backwards (basic_block bb, bitmap live)
    the block, starting with the first one.
    ----------------------------------------------------------------------------*/
 
-/* Apply the artificial uses and defs at the top of BB in a forwards
-   direction.  ??? This is wrong; defs mark the point where a pseudo
-   becomes live when scanning forwards (unless a def is unused).  Since
-   there are no REG_UNUSED notes for artificial defs, passes that
-   require artificial defs probably should not call this function
-   unless (as is the case for fwprop) they are correct when liveness
-   bitmaps are *under*estimated.  */
+/* Initialize the LIVE bitmap, which should be copied from DF_LIVE_IN or
+   DF_LR_IN for basic block BB, for forward scanning by marking artificial
+   defs live.  */
 
 void
 df_simulate_initialize_forwards (basic_block bb, bitmap live)
@@ -3921,7 +3930,7 @@ df_simulate_initialize_forwards (basic_block bb, bitmap live)
     {
       df_ref def = *def_rec;
       if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
-       bitmap_clear_bit (live, DF_REF_REGNO (def));
+       bitmap_set_bit (live, DF_REF_REGNO (def));
     }
 }
 
@@ -3942,7 +3951,7 @@ df_simulate_one_insn_forwards (basic_block bb, rtx insn, bitmap live)
      while here the scan is performed forwards!  So, first assume that the
      def is live, and if this is not true REG_UNUSED notes will rectify the
      situation.  */
-  df_simulate_find_defs (insn, live);
+  df_simulate_find_noclobber_defs (insn, live);
 
   /* Clear all of the registers that go dead.  */
   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
index 194cbcf26393c73d266f5a237666d63f9e2161be..c73f00fe6cebb9481173b9b803d0651dbae0f42a 100644 (file)
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -978,6 +978,7 @@ extern void df_note_add_problem (void);
 extern void df_md_add_problem (void);
 extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap);
 extern void df_md_simulate_one_insn (basic_block, rtx, bitmap);
+extern void df_simulate_find_noclobber_defs (rtx, bitmap);
 extern void df_simulate_find_defs (rtx, bitmap);
 extern void df_simulate_defs (rtx, bitmap);
 extern void df_simulate_uses (rtx, bitmap);
index 7ac64aa5e001ee28096f3065de340bd512ecc07a..6e65093859db8b232291ca3d6ec75ce14165ba42 100644 (file)
@@ -228,7 +228,10 @@ single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
   process_uses (df_get_artificial_uses (bb_index), DF_REF_AT_TOP);
   process_defs (df_get_artificial_defs (bb_index), DF_REF_AT_TOP);
-  df_simulate_initialize_forwards (bb, local_lr);
+
+  /* We don't call df_simulate_initialize_forwards, as it may overestimate
+     the live registers if there are unused artificial defs.  We prefer
+     liveness to be underestimated.  */
 
   FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
index c1e86bf6b0ac3a102c3e092768b87bf4765c8310..061e7dfc5eb6e72025b3b16f68d3cf9fd67c5d82 100644 (file)
@@ -3818,7 +3818,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
                    basic_block other_bb, basic_block new_dest, int reversep)
 {
   rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
-  bitmap merge_set = NULL;
+  bitmap merge_set = NULL, merge_set_noclobber = NULL;
   /* Number of pending changes.  */
   int n_validated_changes = 0;
 
@@ -3951,11 +3951,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
 
       /* Collect:
           MERGE_SET = set of registers set in MERGE_BB
+          MERGE_SET_NOCLOBBER = like MERGE_SET, but only includes registers
+            that are really set, not just clobbered.
           TEST_LIVE = set of registers live at EARLIEST
-          TEST_SET  = set of registers set between EARLIEST and the
-                      end of the block.  */
+          TEST_SET = set of registers set between EARLIEST and the
+            end of the block.  */
 
       merge_set = BITMAP_ALLOC (&reg_obstack);
+      merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
 
       /* If we allocated new pseudos (e.g. in the conditional move
         expander called from noce_emit_cmove), we must resize the
@@ -3967,13 +3970,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
        {
          if (NONDEBUG_INSN_P (insn))
            {
-             unsigned int uid = INSN_UID (insn);
-             df_ref *def_rec;
-             for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
-               {
-                 df_ref def = *def_rec;
-                 bitmap_set_bit (merge_set, DF_REF_REGNO (def));
-               }
+             df_simulate_find_defs (insn, merge_set);
+             df_simulate_find_noclobber_defs (insn, merge_set_noclobber);
            }
        }
 
@@ -3984,7 +3982,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
          unsigned i;
          bitmap_iterator bi;
 
-          EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
+          EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
            {
              if (i < FIRST_PSEUDO_REGISTER
                  && ! fixed_regs[i]
@@ -4015,12 +4013,14 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
        }
 
       /* We can perform the transformation if
-          MERGE_SET & (TEST_SET | TEST_LIVE)
+          MERGE_SET_NOCLOBBER & TEST_SET
+        and
+          MERGE_SET & TEST_LIVE
         and
           TEST_SET & DF_LIVE_IN (merge_bb)
         are empty.  */
 
-      if (bitmap_intersect_p (merge_set, test_set)
+      if (bitmap_intersect_p (merge_set_noclobber, test_set)
          || bitmap_intersect_p (merge_set, test_live)
          || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
        intersect = true;
@@ -4104,10 +4104,11 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
          unsigned i;
          bitmap_iterator bi;
 
-         EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
+         EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
            remove_reg_equal_equiv_notes_for_regno (i);
 
          BITMAP_FREE (merge_set);
+         BITMAP_FREE (merge_set_noclobber);
        }
 
       reorder_insns (head, end, PREV_INSN (earliest));
@@ -4128,7 +4129,10 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
   cancel_changes (0);
  fail:
   if (merge_set)
-    BITMAP_FREE (merge_set);
+    {
+      BITMAP_FREE (merge_set);
+      BITMAP_FREE (merge_set_noclobber);
+    }
   return FALSE;
 }
 \f