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. */
{
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. */
timevar_pop (TV_TREE_CLEANUP_CFG);
if (changed && current_loops)
- current_loops->state |= LOOPS_NEED_FIXUP;
+ loops_state_set (LOOPS_NEED_FIXUP);
return changed;
}
/* 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);
#endif
scev_reset ();
- current_loops->state &= ~LOOPS_NEED_FIXUP;
+ loops_state_clear (LOOPS_NEED_FIXUP);
}
/* Cleanup cfg and repair loop structures. */
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;