OSDN Git Service

* obj-c++.dg/comp-types-10.mm: XFAIL for ICE.
[pf3gnuchains/gcc-fork.git] / gcc / cfgrtl.c
index b5a432e..994fb16 100644 (file)
@@ -1,6 +1,6 @@
 /* Control flow graph manipulation code for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -427,8 +427,10 @@ free_bb_for_insn (void)
   return 0;
 }
 
-struct tree_opt_pass pass_free_cfg =
+struct rtl_opt_pass pass_free_cfg =
 {
+ {
+  RTL_PASS,
   NULL,                                 /* name */
   NULL,                                 /* gate */
   free_bb_for_insn,                     /* execute */
@@ -441,7 +443,7 @@ struct tree_opt_pass pass_free_cfg =
   PROP_cfg,                             /* properties_destroyed */
   0,                                    /* todo_flags_start */
   0,                                    /* todo_flags_finish */
-  0                                     /* letter */
+ }
 };
 
 /* Return RTX to emit after when we want to emit code on the entry of function.  */
@@ -465,24 +467,31 @@ emit_insn_at_entry (rtx insn)
   commit_edge_insertions ();
 }
 
-/* Update insns block within BB.  */
+/* Update BLOCK_FOR_INSN of insns between BEGIN and END
+   (or BARRIER if found) and notify df of the bb change. 
+   The insn chain range is inclusive
+   (i.e. both BEGIN and END will be updated. */
 
-void
-update_bb_for_insn (basic_block bb)
+static void
+update_bb_for_insn_chain (rtx begin, rtx end, basic_block bb)
 {
   rtx insn;
 
-  for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
-    {
-      if (!BARRIER_P (insn))
-       {
-         set_block_for_insn (insn, bb);
-         df_insn_change_bb (insn);
-       }
-      if (insn == BB_END (bb))
-       break;
-    }
+  end = NEXT_INSN (end);
+  for (insn = begin; insn != end; insn = NEXT_INSN (insn))
+    if (!BARRIER_P (insn))
+      df_insn_change_bb (insn, bb);
+}
+
+/* Update BLOCK_FOR_INSN of insns in BB to BB,
+   and notify df of the change.  */
+
+void
+update_bb_for_insn (basic_block bb)
+{
+  update_bb_for_insn_chain (BB_HEAD (bb), BB_END (bb), bb);
 }
+
 \f
 /* Return the INSN immediately following the NOTE_INSN_BASIC_BLOCK
    note associated with the BLOCK.  */
@@ -629,16 +638,7 @@ rtl_merge_blocks (basic_block a, basic_block b)
   /* Reassociate the insns of B with A.  */
   if (!b_empty)
     {
-      rtx x;
-
-      for (x = a_end; x != b_end; x = NEXT_INSN (x))
-       {
-         set_block_for_insn (x, a);
-         df_insn_change_bb (x);
-       }
-
-      set_block_for_insn (b_end, a);
-      df_insn_change_bb (b_end);
+      update_bb_for_insn_chain (a_end, b_end, a);
 
       a_end = b_end;
     }
@@ -843,14 +843,9 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
                 which originally were or were created before jump table are
                 inside the basic block.  */
              rtx new_insn = BB_END (src);
-             rtx tmp;
 
-             for (tmp = NEXT_INSN (BB_END (src)); tmp != barrier;
-                  tmp = NEXT_INSN (tmp))
-               {
-                 set_block_for_insn (tmp, src);
-                 df_insn_change_bb (tmp);
-               }
+             update_bb_for_insn_chain (NEXT_INSN (BB_END (src)),
+                                       PREV_INSN (barrier), src);
 
              NEXT_INSN (PREV_INSN (new_insn)) = NEXT_INSN (new_insn);
              PREV_INSN (NEXT_INSN (new_insn)) = PREV_INSN (new_insn);
@@ -1656,10 +1651,10 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first)
       free (in_bb_p);
     }
 
-  if (current_function_epilogue_delay_list != 0)
+  if (crtl->epilogue_delay_list != 0)
     {
       fprintf (outf, "\n;; Insns in epilogue delay list:\n\n");
-      for (tmp_rtx = current_function_epilogue_delay_list; tmp_rtx != 0;
+      for (tmp_rtx = crtl->epilogue_delay_list; tmp_rtx != 0;
           tmp_rtx = XEXP (tmp_rtx, 1))
        print_rtl_single (outf, XEXP (tmp_rtx, 0));
     }
@@ -2637,6 +2632,13 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
        first = NEXT_INSN (first);
       gcc_assert (NOTE_INSN_BASIC_BLOCK_P (first));
       BB_HEAD (b) = NULL;
+
+      /* emit_insn_after_noloc doesn't call df_insn_change_bb.
+         We need to explicitly call. */
+      update_bb_for_insn_chain (NEXT_INSN (first),
+                               BB_END (b),
+                               a);
+
       delete_insn (first);
     }
   /* Otherwise just re-associate the instructions.  */
@@ -2644,13 +2646,7 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
     {
       rtx insn;
 
-      for (insn = BB_HEAD (b);
-          insn != NEXT_INSN (BB_END (b));
-          insn = NEXT_INSN (insn))
-       {
-         set_block_for_insn (insn, a);
-         df_insn_change_bb (insn);
-       }
+      update_bb_for_insn_chain (BB_HEAD (b), BB_END (b), a);
 
       insn = BB_HEAD (b);
       /* Skip possible DELETED_LABEL insn.  */
@@ -2749,7 +2745,7 @@ need_fake_edge_p (const_rtx insn)
   if ((CALL_P (insn)
        && !SIBLING_CALL_P (insn)
        && !find_reg_note (insn, REG_NORETURN, NULL)
-       && !CONST_OR_PURE_CALL_P (insn)))
+       && !(RTL_CONST_OR_PURE_CALL_P (insn))))
     return true;
 
   return ((GET_CODE (PATTERN (insn)) == ASM_OPERANDS