OSDN Git Service

2005-06-29 Stuart Hastings <stuart@apple.com>
[pf3gnuchains/gcc-fork.git] / gcc / ifcvt.c
index 9575e62..750ffa9 100644 (file)
@@ -16,8 +16,8 @@
 
    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, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -691,7 +691,11 @@ noce_emit_move_insn (rtx x, rtx y)
       optab ot;
 
       start_sequence ();
-      insn = emit_move_insn (x, y);
+      /* Check that the SET_SRC is reasonable before calling emit_move_insn,
+        otherwise construct a suitable SET pattern ourselves.  */
+      insn = (OBJECT_P (y) || CONSTANT_P (y) || GET_CODE (y) == SUBREG)
+            ? emit_move_insn (x, y)
+            : emit_insn (gen_rtx_SET (VOIDmode, x, y));
       seq = get_insns ();
       end_sequence();
 
@@ -2360,9 +2364,9 @@ merge_if_block (struct ce_if_block * ce_info)
 
   if (then_bb)
     {
-      if (combo_bb->global_live_at_end)
-       COPY_REG_SET (combo_bb->global_live_at_end,
-                     then_bb->global_live_at_end);
+      if (combo_bb->il.rtl->global_live_at_end)
+       COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
+                     then_bb->il.rtl->global_live_at_end);
       merge_blocks (combo_bb, then_bb);
       num_true_changes++;
     }
@@ -2413,9 +2417,9 @@ merge_if_block (struct ce_if_block * ce_info)
           && join_bb != EXIT_BLOCK_PTR)
     {
       /* We can merge the JOIN.  */
-      if (combo_bb->global_live_at_end)
-       COPY_REG_SET (combo_bb->global_live_at_end,
-                     join_bb->global_live_at_end);
+      if (combo_bb->il.rtl->global_live_at_end)
+       COPY_REG_SET (combo_bb->il.rtl->global_live_at_end,
+                     join_bb->il.rtl->global_live_at_end);
 
       merge_blocks (combo_bb, join_bb);
       num_true_changes++;
@@ -3056,9 +3060,9 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
   /* Conversion went ok, including moving the insns and fixing up the
      jump.  Adjust the CFG to match.  */
 
-  bitmap_ior (test_bb->global_live_at_end,
-             else_bb->global_live_at_start,
-             then_bb->global_live_at_end);
+  bitmap_ior (test_bb->il.rtl->global_live_at_end,
+             else_bb->il.rtl->global_live_at_start,
+             then_bb->il.rtl->global_live_at_end);
 
 
   /* We can avoid creating a new basic block if then_bb is immediately
@@ -3174,9 +3178,9 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
   /* Conversion went ok, including moving the insns and fixing up the
      jump.  Adjust the CFG to match.  */
 
-  bitmap_ior (test_bb->global_live_at_end,
-             then_bb->global_live_at_start,
-             else_bb->global_live_at_end);
+  bitmap_ior (test_bb->il.rtl->global_live_at_end,
+             then_bb->il.rtl->global_live_at_start,
+             else_bb->il.rtl->global_live_at_end);
 
   delete_basic_block (else_bb);
 
@@ -3353,7 +3357,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       /* 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.  */
 
-      COPY_REG_SET (test_live, other_bb->global_live_at_start);
+      COPY_REG_SET (test_live, other_bb->il.rtl->global_live_at_start);
       pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
                                       0);
 
@@ -3369,12 +3373,13 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
       /* We can perform the transformation if
           MERGE_SET & (TEST_SET | TEST_LIVE)
         and
-          TEST_SET & merge_bb->global_live_at_start
+          TEST_SET & merge_bb->il.rtl->global_live_at_start
         are empty.  */
 
       if (bitmap_intersect_p (test_set, merge_set)
          || bitmap_intersect_p (test_live, merge_set)
-         || bitmap_intersect_p (test_set, merge_bb->global_live_at_start))
+         || bitmap_intersect_p (test_set,
+                                merge_bb->il.rtl->global_live_at_start))
        fail = 1;
 
       FREE_REG_SET (tmp);
@@ -3426,12 +3431,31 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
   /* Move the insns out of MERGE_BB to before the branch.  */
   if (head != NULL)
     {
+      rtx insn;
+
       if (end == BB_END (merge_bb))
        BB_END (merge_bb) = PREV_INSN (head);
 
       if (squeeze_notes (&head, &end))
        return TRUE;
 
+      /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
+        notes might become invalid.  */
+      insn = head;
+      do
+       {
+         rtx note, set;
+
+         if (! INSN_P (insn))
+           continue;
+         note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+         if (! note)
+           continue;
+         set = single_set (insn);
+         if (!set || !function_invariant_p (SET_SRC (set)))
+           remove_note (insn, note);
+       } while (insn != end && (insn = NEXT_INSN (insn)));
+
       reorder_insns (head, end, PREV_INSN (earliest));
     }