Commit e5c95afe by Zdenek Dvorak Committed by Zdenek Dvorak

tree-pretty-print.c (dump_generic_node): Dump OMP_SECTIONS_SWITCH.

	* 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.

From-SVN: r127121
parent 203bb67e
2007-08-01 Zdenek Dvorak <ook@ucw.cz> 2007-08-01 Zdenek Dvorak <ook@ucw.cz>
* 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.
2007-08-01 Zdenek Dvorak <ook@ucw.cz>
* tree-cfg.c (tree_merge_blocks): Preserve loop exit phi nodes only * tree-cfg.c (tree_merge_blocks): Preserve loop exit phi nodes only
in loop closed ssa. in loop closed ssa.
......
...@@ -1205,7 +1205,7 @@ gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses) ...@@ -1205,7 +1205,7 @@ gfc_trans_omp_sections (gfc_code *code, gfc_omp_clauses *clauses)
} }
stmt = gfc_finish_block (&body); stmt = gfc_finish_block (&body);
stmt = build2_v (OMP_SECTIONS, stmt, omp_clauses); stmt = build3_v (OMP_SECTIONS, stmt, omp_clauses, NULL_TREE);
gfc_add_expr_to_block (&block, stmt); gfc_add_expr_to_block (&block, stmt);
return gfc_finish_block (&block); return gfc_finish_block (&block);
......
...@@ -244,6 +244,7 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data) ...@@ -244,6 +244,7 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
case CHANGE_DYNAMIC_TYPE_EXPR: case CHANGE_DYNAMIC_TYPE_EXPR:
case OMP_FOR: case OMP_FOR:
case OMP_SECTIONS: case OMP_SECTIONS:
case OMP_SECTIONS_SWITCH:
case OMP_SECTION: case OMP_SECTION:
case OMP_SINGLE: case OMP_SINGLE:
case OMP_MASTER: case OMP_MASTER:
......
...@@ -517,6 +517,10 @@ make_edges (void) ...@@ -517,6 +517,10 @@ make_edges (void)
case OMP_SECTIONS: case OMP_SECTIONS:
cur_region = new_omp_region (bb, code, cur_region); cur_region = new_omp_region (bb, code, cur_region);
fallthru = true;
break;
case OMP_SECTIONS_SWITCH:
fallthru = false; fallthru = false;
break; break;
...@@ -533,31 +537,42 @@ make_edges (void) ...@@ -533,31 +537,42 @@ make_edges (void)
switch (cur_region->type) switch (cur_region->type)
{ {
case OMP_FOR: case OMP_FOR:
/* ??? Technically there should be a some sort of loopback /* Make the loopback edge. */
edge here, but it goes to a block that doesn't exist yet, make_edge (bb, single_succ (cur_region->entry), 0);
and without it, updating the ssa form would be a real
bear. Fortunately, we don't yet do ssa before expanding /* Create an edge from OMP_FOR to exit, which corresponds to
these nodes. */ the case that the body of the loop is not executed at
all. */
make_edge (cur_region->entry, bb->next_bb, 0);
fallthru = true;
break; break;
case OMP_SECTIONS: case OMP_SECTIONS:
/* Wire up the edges into and out of the nested sections. */ /* Wire up the edges into and out of the nested sections. */
/* ??? Similarly wrt loopback. */
{ {
basic_block switch_bb = single_succ (cur_region->entry);
struct omp_region *i; struct omp_region *i;
for (i = cur_region->inner; i ; i = i->next) for (i = cur_region->inner; i ; i = i->next)
{ {
gcc_assert (i->type == OMP_SECTION); gcc_assert (i->type == OMP_SECTION);
make_edge (cur_region->entry, i->entry, 0); make_edge (switch_bb, i->entry, 0);
make_edge (i->exit, bb, EDGE_FALLTHRU); make_edge (i->exit, bb, EDGE_FALLTHRU);
} }
/* Make the loopback edge to the block with
OMP_SECTIONS_SWITCH. */
make_edge (bb, switch_bb, 0);
/* Make the edge from the switch to exit. */
make_edge (switch_bb, bb->next_bb, 0);
fallthru = false;
} }
break; break;
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
fallthru = true;
break; break;
default: default:
...@@ -4807,6 +4822,13 @@ tree_redirect_edge_and_branch (edge e, basic_block dest) ...@@ -4807,6 +4822,13 @@ tree_redirect_edge_and_branch (edge e, basic_block dest)
e->flags |= EDGE_FALLTHRU; e->flags |= EDGE_FALLTHRU;
break; break;
case OMP_RETURN:
case OMP_CONTINUE:
case OMP_SECTIONS_SWITCH:
case OMP_FOR:
/* The edges from OMP constructs can be simply redirected. */
break;
default: default:
/* Otherwise it must be a fallthru edge, and we don't need to /* Otherwise it must be a fallthru edge, and we don't need to
do anything besides redirecting it. */ do anything besides redirecting it. */
......
...@@ -507,6 +507,36 @@ split_bbs_on_noreturn_calls (void) ...@@ -507,6 +507,36 @@ split_bbs_on_noreturn_calls (void)
return changed; 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 /* Tries to cleanup cfg in basic block BB. Returns true if anything
changes. */ changes. */
...@@ -515,8 +545,11 @@ cleanup_tree_cfg_bb (basic_block bb) ...@@ -515,8 +545,11 @@ cleanup_tree_cfg_bb (basic_block bb)
{ {
bool retval = false; 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 /* Forwarder blocks can carry line number information which is
useful when debugging, so we only clean them up when useful when debugging, so we only clean them up when
optimizing. */ optimizing. */
......
...@@ -230,6 +230,7 @@ is_gimple_stmt (tree t) ...@@ -230,6 +230,7 @@ is_gimple_stmt (tree t)
case OMP_PARALLEL: case OMP_PARALLEL:
case OMP_FOR: case OMP_FOR:
case OMP_SECTIONS: case OMP_SECTIONS:
case OMP_SECTIONS_SWITCH:
case OMP_SECTION: case OMP_SECTION:
case OMP_SINGLE: case OMP_SINGLE:
case OMP_MASTER: case OMP_MASTER:
......
...@@ -2010,6 +2010,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data) ...@@ -2010,6 +2010,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case OMP_CLAUSE: case OMP_CLAUSE:
case OMP_RETURN: case OMP_RETURN:
case OMP_CONTINUE: case OMP_CONTINUE:
case OMP_SECTIONS_SWITCH:
break; break;
/* We don't account constants for now. Assume that the cost is amortized /* We don't account constants for now. Assume that the cost is amortized
......
...@@ -1851,9 +1851,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, ...@@ -1851,9 +1851,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_SECTIONS: case OMP_SECTIONS:
pp_string (buffer, "#pragma omp sections"); pp_string (buffer, "#pragma omp sections");
if (OMP_SECTIONS_CONTROL (node))
{
pp_string (buffer, " <");
dump_generic_node (buffer, OMP_SECTIONS_CONTROL (node), spc,
flags, false);
pp_string (buffer, ">");
}
dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags); dump_omp_clauses (buffer, OMP_SECTIONS_CLAUSES (node), spc, flags);
goto dump_omp_body; goto dump_omp_body;
case OMP_SECTIONS_SWITCH:
pp_string (buffer, "OMP_SECTIONS_SWITCH");
is_expr = false;
break;
case OMP_SECTION: case OMP_SECTION:
pp_string (buffer, "#pragma omp section"); pp_string (buffer, "#pragma omp section");
goto dump_omp_body; goto dump_omp_body;
...@@ -1901,7 +1913,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, ...@@ -1901,7 +1913,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break; break;
case OMP_CONTINUE: case OMP_CONTINUE:
pp_string (buffer, "OMP_CONTINUE"); pp_string (buffer, "OMP_CONTINUE <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_string (buffer, " <- ");
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
pp_string (buffer, ">");
is_expr = false; is_expr = false;
break; break;
......
...@@ -999,8 +999,14 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6) ...@@ -999,8 +999,14 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
/* OpenMP - #pragma omp sections [clause1 ... clauseN] /* OpenMP - #pragma omp sections [clause1 ... clauseN]
Operand 0: OMP_SECTIONS_BODY: Sections body. Operand 0: OMP_SECTIONS_BODY: Sections body.
Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */ Operand 1: OMP_SECTIONS_CLAUSES: List of clauses.
DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 2) Operand 2: OMP_SECTIONS_CONTROL: The control variable used for deciding
which of the sections to execute. */
DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 3)
/* This tree immediatelly follows OMP_SECTIONS, and represents the switch
used to decide which branch is taken. */
DEFTREECODE (OMP_SECTIONS_SWITCH, "omp_sections_switch", tcc_statement, 0)
/* OpenMP - #pragma omp single /* OpenMP - #pragma omp single
Operand 0: OMP_SINGLE_BODY: Single section body. Operand 0: OMP_SINGLE_BODY: Single section body.
...@@ -1028,8 +1034,9 @@ DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2) ...@@ -1028,8 +1034,9 @@ DEFTREECODE (OMP_CRITICAL, "omp_critical", tcc_statement, 2)
DEFTREECODE (OMP_RETURN, "omp_return", tcc_statement, 0) DEFTREECODE (OMP_RETURN, "omp_return", tcc_statement, 0)
/* OpenMP - An intermediate tree code to mark the location of the /* OpenMP - An intermediate tree code to mark the location of the
loop or sections iteration in the partially lowered code. */ loop or sections iteration in the partially lowered code.
DEFTREECODE (OMP_CONTINUE, "omp_continue", tcc_statement, 0) The arguments are definition and use of the control variable. */
DEFTREECODE (OMP_CONTINUE, "omp_continue", tcc_statement, 2)
/* OpenMP - #pragma omp atomic /* OpenMP - #pragma omp atomic
Operand 0: The address at which the atomic operation is to be performed. Operand 0: The address at which the atomic operation is to be performed.
......
...@@ -187,6 +187,7 @@ extern const enum tree_code_class tree_code_type[]; ...@@ -187,6 +187,7 @@ extern const enum tree_code_class tree_code_type[];
(TREE_CODE (NODE) == OMP_PARALLEL \ (TREE_CODE (NODE) == OMP_PARALLEL \
|| TREE_CODE (NODE) == OMP_FOR \ || TREE_CODE (NODE) == OMP_FOR \
|| TREE_CODE (NODE) == OMP_SECTIONS \ || TREE_CODE (NODE) == OMP_SECTIONS \
|| TREE_CODE (NODE) == OMP_SECTIONS_SWITCH \
|| TREE_CODE (NODE) == OMP_SINGLE \ || TREE_CODE (NODE) == OMP_SINGLE \
|| TREE_CODE (NODE) == OMP_SECTION \ || TREE_CODE (NODE) == OMP_SECTION \
|| TREE_CODE (NODE) == OMP_MASTER \ || TREE_CODE (NODE) == OMP_MASTER \
...@@ -1695,6 +1696,7 @@ struct tree_constructor GTY(()) ...@@ -1695,6 +1696,7 @@ struct tree_constructor GTY(())
#define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0) #define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0)
#define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1) #define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1)
#define OMP_SECTIONS_CONTROL(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 2)
#define OMP_SECTION_BODY(NODE) TREE_OPERAND (OMP_SECTION_CHECK (NODE), 0) #define OMP_SECTION_BODY(NODE) TREE_OPERAND (OMP_SECTION_CHECK (NODE), 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment