OSDN Git Service

* tree-sra.c (decide_block_copy): Decide if there are groups.
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfgcleanup.c
index c35001c..bcae448 100644 (file)
@@ -507,6 +507,36 @@ split_bbs_on_noreturn_calls (void)
   return changed;
 }
 
+/* If OMP_RETURN in basic block BB is unreachable, remove it.  */
+
+static bool
+cleanup_omp_return (basic_block bb)
+{
+  tree stmt = last_stmt (bb);
+  basic_block control_bb;
+
+  if (stmt == NULL_TREE
+      || TREE_CODE (stmt) != OMP_RETURN
+      || !single_pred_p (bb))
+    return false;
+
+  control_bb = single_pred (bb);
+  stmt = last_stmt (control_bb);
+
+  if (TREE_CODE (stmt) != OMP_SECTIONS_SWITCH)
+    return false;
+
+  /* The block with the control statement normally has two entry edges -- one
+     from entry, one from continue.  If continue is removed, return is
+     unreachable, so we remove it here as well.  */
+  if (EDGE_COUNT (control_bb->preds) == 2)
+    return false;
+
+  gcc_assert (EDGE_COUNT (control_bb->preds) == 1);
+  remove_edge_and_dominated_blocks (single_pred_edge (bb));
+  return true;
+}
+
 /* Tries to cleanup cfg in basic block BB.  Returns true if anything
    changes.  */
 
@@ -515,8 +545,11 @@ cleanup_tree_cfg_bb (basic_block bb)
 {
   bool retval = false;
 
-  retval = cleanup_control_flow_bb (bb);
+  if (cleanup_omp_return (bb))
+    return true;
 
+  retval = cleanup_control_flow_bb (bb);
+  
   /* Forwarder blocks can carry line number information which is
      useful when debugging, so we only clean them up when
      optimizing.  */
@@ -633,7 +666,7 @@ cleanup_tree_cfg_noloop (void)
   timevar_pop (TV_TREE_CLEANUP_CFG);
 
   if (changed && current_loops)
-    current_loops->state |= LOOPS_NEED_FIXUP;
+    loops_state_set (LOOPS_NEED_FIXUP);
 
   return changed;
 }
@@ -649,7 +682,7 @@ repair_loop_structures (void)
   /* This usually does nothing.  But sometimes parts of cfg that originally
      were inside a loop get out of it due to edge removal (since they
      become unreachable by back edges from latch).  */
-  if ((current_loops->state & LOOP_CLOSED_SSA) != 0)
+  if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
     rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
 
   BITMAP_FREE (changed_bbs);
@@ -659,7 +692,7 @@ repair_loop_structures (void)
 #endif
   scev_reset ();
 
-  current_loops->state &= ~LOOPS_NEED_FIXUP;
+  loops_state_clear (LOOPS_NEED_FIXUP);
 }
 
 /* Cleanup cfg and repair loop structures.  */
@@ -670,7 +703,7 @@ cleanup_tree_cfg (void)
   bool changed = cleanup_tree_cfg_noloop ();
 
   if (current_loops != NULL
-      && (current_loops->state & LOOPS_NEED_FIXUP))
+      && loops_state_satisfies_p (LOOPS_NEED_FIXUP))
     repair_loop_structures ();
 
   return changed;