OSDN Git Service

Clarify copyright license agreement.
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
index ff75ed1..e5a8835 100644 (file)
@@ -36,7 +36,6 @@
 #include "output.h"
 #include "optabs.h"
 #include "diagnostic-core.h"
-#include "toplev.h"
 #include "tm_p.h"
 #include "cfgloop.h"
 #include "target.h"
@@ -1333,8 +1332,8 @@ static rtx
 noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
                 rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
 {
-  rtx target;
-  int unsignedp;
+  rtx target ATTRIBUTE_UNUSED;
+  int unsignedp ATTRIBUTE_UNUSED;
 
   /* If earliest == jump, try to build the cmove insn directly.
      This is helpful when combine has created some complex condition
@@ -3998,6 +3997,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, merge_set_noclobber = NULL;
   /* Number of pending changes.  */
   int n_validated_changes = 0;
 
@@ -4086,6 +4086,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       earliest = jump;
     }
 #endif
+
   /* Try the NCE path if the CE path did not result in any changes.  */
   if (n_validated_changes == 0)
     {
@@ -4094,9 +4095,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
         that any registers modified are dead at the branch site.  */
 
       rtx insn, cond, prev;
-      bitmap merge_set, merge_set_noclobber, test_live, test_set;
-      unsigned i, fail = 0;
-      bitmap_iterator bi;
+      bitmap test_live, test_set;
+      bool intersect = false;
 
       /* Check for no calls or trapping operations.  */
       for (insn = head; ; insn = NEXT_INSN (insn))
@@ -4138,12 +4138,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
 
       merge_set = BITMAP_ALLOC (&reg_obstack);
       merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
-      test_live = BITMAP_ALLOC (&reg_obstack);
-      test_set = BITMAP_ALLOC (&reg_obstack);
 
-      /* ??? bb->local_set is only valid during calculate_global_regs_live,
-        so we must recompute usage for MERGE_BB.  Not so bad, I suppose,
-         since we've already asserted that MERGE_BB is small.  */
       /* If we allocated new pseudos (e.g. in the conditional move
         expander called from noce_emit_cmove), we must resize the
         array first.  */
@@ -4164,17 +4159,22 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       if (! reload_completed
          && targetm.small_register_classes_for_mode_p (VOIDmode))
        {
+         unsigned i;
+         bitmap_iterator bi;
+
           EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
            {
              if (i < FIRST_PSEUDO_REGISTER
                  && ! fixed_regs[i]
                  && ! global_regs[i])
-               fail = 1;
+               goto fail;
            }
        }
 
       /* For TEST, we're interested in a range of insns, not a whole block.
         Moreover, we're interested in the insns live from OTHER_BB.  */
+      test_live = BITMAP_ALLOC (&reg_obstack);
+      test_set = BITMAP_ALLOC (&reg_obstack);
 
       /* The loop below takes the set of live registers
          after JUMP, and calculates the live set before EARLIEST. */
@@ -4195,23 +4195,21 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       /* We can perform the transformation if
           MERGE_SET_NOCLOBBER & TEST_SET
         and
-          MERGE_SET & TEST_LIVE)
+          MERGE_SET & TEST_LIVE
         and
           TEST_SET & DF_LIVE_IN (merge_bb)
         are empty.  */
 
-      if (bitmap_intersect_p (test_set, merge_set_noclobber)
-         || bitmap_intersect_p (test_live, merge_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)))
-       fail = 1;
+       intersect = true;
 
-      BITMAP_FREE (merge_set_noclobber);
-      BITMAP_FREE (merge_set);
       BITMAP_FREE (test_live);
       BITMAP_FREE (test_set);
 
-      if (fail)
-       return FALSE;
+      if (intersect)
+       goto fail;
     }
 
  no_body:
@@ -4261,8 +4259,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       if (end == BB_END (merge_bb))
        BB_END (merge_bb) = PREV_INSN (head);
 
-      /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
-        notes might become invalid.  */
+      /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
+        notes being moved might become invalid.  */
       insn = head;
       do
        {
@@ -4279,6 +4277,20 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
            remove_note (insn, note);
        } while (insn != end && (insn = NEXT_INSN (insn)));
 
+      /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
+        notes referring to the registers being set might become invalid.  */
+      if (merge_set)
+       {
+         unsigned i;
+         bitmap_iterator bi;
+
+         EXECUTE_IF_SET_IN_BITMAP (merge_set, 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));
     }
 
@@ -4295,6 +4307,12 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
 
  cancel:
   cancel_changes (0);
+ fail:
+  if (merge_set)
+    {
+      BITMAP_FREE (merge_set);
+      BITMAP_FREE (merge_set_noclobber);
+    }
   return FALSE;
 }
 \f