summaryrefslogtreecommitdiff
path: root/gcc/tree-cfgcleanup.c
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-01 11:50:39 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-01 11:50:39 +0000
commitac6e3339fccf89d6b4b36cdb254390f05de9201b (patch)
treeff781d81e1c759d85b9e39299b57bf35bf7747a4 /gcc/tree-cfgcleanup.c
parent6e70769979fc9cbf18f7997d0ee0c513dd6e5a34 (diff)
downloadgcc-ac6e3339fccf89d6b4b36cdb254390f05de9201b.tar.gz
* tree-pretty-print.c (dump_generic_node): Dump OMP_SECTIONS_SWITCH.
Display new operands of OMP_SECTIONS and OMP_CONTINUE. * tree.h (OMP_SECTIONS_CONTROL): New macro. (OMP_DIRECTIVE_P): Add OMP_SECTIONS_SWITCH. * omp-low.c (get_ws_args_for, determine_parallel_type, expand_omp_for_generic, expand_omp_for_static_nochunk, expand_omp_for_static_chunk, expand_omp_for, expand_omp_sections): Work with more precise CFG. (build_omp_regions_1): Handle OMP_SECTIONS_SWITCH. (lower_omp_sections): Emit OMP_SECTIONS_SWITCH. Add arguments to OMP_CONTINUE. * tree-gimple.c (is_gimple_stmt): Handle OMP_SECTIONS_SWITCH. * gimple-low.c (lower_stmt): Ditto. * tree-inline.c (estimate_num_insns_1): Ditto. * tree.def (OMP_SECTIONS, OMP_CONTINUE): Added new operands. (OMP_SECTIONS_SWITCH): New. * tree-cfgcleanup.c (cleanup_omp_return): New. (cleanup_tree_cfg_bb): Call cleanup_omp_return. * tree-cfg.c (make_edges): Create back edges for OMP_CONTINUE and exit edge for OMP_FOR. Handle OMP_SECTIONS_SWITCH. (tree_redirect_edge_and_branch): Handle omp constructs. * fortran/trans-openmp.c (gfc_trans_omp_sections): Build OMP_SECTIONS with three arguments. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127121 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r--gcc/tree-cfgcleanup.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index c35001c33e7..bd2523bf7e6 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -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. */