OSDN Git Service

gcc:
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
index e5a8835..b34aee2 100644 (file)
@@ -1,5 +1,6 @@
 /* If-conversion support.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010,
+   2011
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -102,7 +103,6 @@ static int noce_find_if_block (basic_block, edge, edge, int);
 static int cond_exec_find_if_block (ce_if_block_t *);
 static int find_if_case_1 (basic_block, edge, edge);
 static int find_if_case_2 (basic_block, edge, edge);
-static int find_memory (rtx *, void *);
 static int dead_or_predicable (basic_block, basic_block, basic_block,
                               basic_block, int);
 static void noce_emit_move_insn (rtx, rtx);
@@ -305,6 +305,10 @@ cond_exec_process_insns (ce_if_block_t *ce_info ATTRIBUTE_UNUSED,
 
   for (insn = start; ; insn = NEXT_INSN (insn))
     {
+      /* dwarf2out can't cope with conditional prologues.  */
+      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
+       return FALSE;
+
       if (NOTE_P (insn) || DEBUG_INSN_P (insn))
        goto insn_done;
 
@@ -477,7 +481,8 @@ cond_exec_process_if_block (ce_if_block_t * ce_info,
       /* Look for matching sequences at the head and tail of the two blocks,
         and limit the range of insns to be converted if possible.  */
       n_matching = flow_find_cross_jump (then_bb, else_bb,
-                                        &then_first_tail, &else_first_tail);
+                                        &then_first_tail, &else_first_tail,
+                                        NULL);
       if (then_first_tail == BB_HEAD (then_bb))
        then_start = then_end = NULL_RTX;
       if (else_first_tail == BB_HEAD (else_bb))
@@ -3975,15 +3980,6 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
   return TRUE;
 }
 
-/* A subroutine of dead_or_predicable called through for_each_rtx.
-   Return 1 if a memory is found.  */
-
-static int
-find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
-{
-  return MEM_P (*px);
-}
-
 /* Used by the code above to perform the actual rtl transformations.
    Return TRUE if successful.
 
@@ -3997,7 +3993,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;
+  bitmap merge_set = NULL;
   /* Number of pending changes.  */
   int n_validated_changes = 0;
 
@@ -4087,129 +4083,46 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
     }
 #endif
 
+  /* If we allocated new pseudos (e.g. in the conditional move
+     expander called from noce_emit_cmove), we must resize the
+     array first.  */
+  if (max_regno < max_reg_num ())
+    max_regno = max_reg_num ();
+
   /* Try the NCE path if the CE path did not result in any changes.  */
   if (n_validated_changes == 0)
     {
+      rtx cond, insn;
+      regset live;
+      bool success;
+
       /* In the non-conditional execution case, we have to verify that there
         are no trapping operations, no calls, no references to memory, and
         that any registers modified are dead at the branch site.  */
 
-      rtx insn, cond, prev;
-      bitmap test_live, test_set;
-      bool intersect = false;
-
-      /* Check for no calls or trapping operations.  */
-      for (insn = head; ; insn = NEXT_INSN (insn))
-       {
-         if (CALL_P (insn))
-           return FALSE;
-         if (NONDEBUG_INSN_P (insn))
-           {
-             if (may_trap_p (PATTERN (insn)))
-               return FALSE;
-
-             /* ??? Even non-trapping memories such as stack frame
-                references must be avoided.  For stores, we collect
-                no lifetime info; for reads, we'd have to assert
-                true_dependence false against every store in the
-                TEST range.  */
-             if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
-               return FALSE;
-           }
-         if (insn == end)
-           break;
-       }
-
-      if (! any_condjump_p (jump))
+      if (!any_condjump_p (jump))
        return FALSE;
 
       /* Find the extent of the conditional.  */
       cond = noce_get_condition (jump, &earliest, false);
-      if (! cond)
+      if (!cond)
        return FALSE;
 
-      /* 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.  */
+      live = BITMAP_ALLOC (&reg_obstack);
+      simulate_backwards_to_point (merge_bb, live, end);
+      success = can_move_insns_across (head, end, earliest, jump,
+                                      merge_bb, live,
+                                      df_get_live_in (other_bb), NULL);
+      BITMAP_FREE (live);
+      if (!success)
+       return FALSE;
 
+      /* Collect the set of registers set in MERGE_BB.  */
       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
-        array first.  */
-      if (max_regno < max_reg_num ())
-       max_regno = max_reg_num ();
 
       FOR_BB_INSNS (merge_bb, insn)
-       {
-         if (NONDEBUG_INSN_P (insn))
-           {
-             df_simulate_find_defs (insn, merge_set);
-             df_simulate_find_noclobber_defs (insn, merge_set_noclobber);
-           }
-       }
-
-      /* For small register class machines, don't lengthen lifetimes of
-        hard registers before reload.  */
-      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])
-               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. */
-      bitmap_copy (test_live, df_get_live_in (other_bb));
-      df_simulate_initialize_backwards (test_bb, test_live);
-      for (insn = jump; ; insn = prev)
-       {
-         if (INSN_P (insn))
-           {
-             df_simulate_find_defs (insn, test_set);
-             df_simulate_one_insn_backwards (test_bb, insn, test_live);
-           }
-         prev = PREV_INSN (insn);
-         if (insn == earliest)
-           break;
-       }
-
-      /* We can perform the transformation if
-          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_noclobber, test_set)
-         || bitmap_intersect_p (merge_set, test_live)
-         || bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
-       intersect = true;
-
-      BITMAP_FREE (test_live);
-      BITMAP_FREE (test_set);
-
-      if (intersect)
-       goto fail;
+       if (NONDEBUG_INSN_P (insn))
+         df_simulate_find_defs (insn, merge_set);
     }
 
  no_body:
@@ -4288,7 +4201,6 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
            remove_reg_equal_equiv_notes_for_regno (i);
 
          BITMAP_FREE (merge_set);
-         BITMAP_FREE (merge_set_noclobber);
        }
 
       reorder_insns (head, end, PREV_INSN (earliest));
@@ -4307,12 +4219,10 @@ 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);
-    }
+    BITMAP_FREE (merge_set);
+
   return FALSE;
 }
 \f