OSDN Git Service

2010-04-24 Steven G. Kargl <kargl@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / cfglayout.c
index f718f1e..5e12057 100644 (file)
@@ -1,5 +1,5 @@
 /* Basic block reordering routines for the GNU compiler.
-   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -238,7 +238,7 @@ int epilogue_locator;
 /* Hold current location information and last location information, so the
    datastructures are built lazily only when some instructions in given
    place are needed.  */
-location_t curr_location, last_location;
+static location_t curr_location, last_location;
 static tree curr_block, last_block;
 static int curr_rtl_loc = -1;
 
@@ -290,12 +290,17 @@ set_curr_insn_source_location (location_t location)
      time locators are not initialized.  */
   if (curr_rtl_loc == -1)
     return;
-  if (location == last_location)
-    return;
   curr_location = location;
 }
 
-/* Set current scope block. */
+/* Get current location.  */
+location_t
+get_curr_insn_source_location (void)
+{
+  return curr_location;
+}
+
+/* Set current scope block.  */
 void
 set_curr_insn_block (tree b)
 {
@@ -307,6 +312,13 @@ set_curr_insn_block (tree b)
     curr_block = b;
 }
 
+/* Get current scope block.  */
+tree
+get_curr_insn_block (void)
+{
+  return curr_block;
+}
+
 /* Return current insn locator.  */
 int
 curr_insn_locator (void)
@@ -682,7 +694,7 @@ relink_block_chain (bool stay_in_cfglayout_mode)
   free_original_copy_tables ();
   if (stay_in_cfglayout_mode)
     initialize_original_copy_tables ();
-  
+
   /* Finally, put basic_block_info in the new order.  */
   compact_blocks ();
 }
@@ -775,6 +787,18 @@ fixup_reorder_chain (void)
        {
          if (any_condjump_p (bb_end_insn))
            {
+             /* This might happen if the conditional jump has side
+                effects and could therefore not be optimized away.
+                Make the basic block to end with a barrier in order
+                to prevent rtl_verify_flow_info from complaining.  */
+             if (!e_fall)
+               {
+                 gcc_assert (!onlyjump_p (bb_end_insn)
+                             || returnjump_p (bb_end_insn));
+                 bb->il.rtl->footer = emit_barrier_after (bb_end_insn);
+                 continue;
+               }
+
              /* If the old fallthru is still next, nothing to do.  */
              if (bb->aux == e_fall->dest
                  || e_fall->dest == EXIT_BLOCK_PTR)
@@ -836,6 +860,18 @@ fixup_reorder_chain (void)
                  continue;
                }
            }
+         else if (extract_asm_operands (PATTERN (bb_end_insn)) != NULL)
+           {
+             /* If the old fallthru is still next or if
+                asm goto doesn't have a fallthru (e.g. when followed by
+                __builtin_unreachable ()), nothing to do.  */
+             if (! e_fall
+                 || bb->aux == e_fall->dest
+                 || e_fall->dest == EXIT_BLOCK_PTR)
+               continue;
+
+             /* Otherwise we'll have to use the fallthru fixup below.  */
+           }
          else
            {
              /* Otherwise we have some return, switch or computed
@@ -896,7 +932,7 @@ fixup_reorder_chain (void)
       FOR_EACH_EDGE (e, ei, bb->succs)
        if (e->flags & EDGE_FALLTHRU)
          break;
-      
+
       if (e && !can_fallthru (e->src, e->dest))
        force_nonfallthru (e);
     }
@@ -1120,6 +1156,7 @@ duplicate_insn_chain (rtx from, rtx to)
     {
       switch (GET_CODE (insn))
        {
+       case DEBUG_INSN:
        case INSN:
        case CALL_INSN:
        case JUMP_INSN: