Commit 50674e96 by Diego Novillo Committed by Diego Novillo

tree-pretty-print.c (dump_generic_node): Handle OMP_PARALLEL_FN,…

tree-pretty-print.c (dump_generic_node): Handle OMP_PARALLEL_FN, OMP_PARALLEL_DATA_ARG and OMP_RETURN_EXPR.


	* tree-pretty-print.c (dump_generic_node): Handle
	OMP_PARALLEL_FN, OMP_PARALLEL_DATA_ARG and OMP_RETURN_EXPR.
	* cgraph.c (cgraph_expand_queue): Rename from
	cgraph_analyze_queue.
	Update all users.
	* cgraphunit.c (cgraph_assemble_pending_functions): Process
	cgraph_expand_queue.
	(cgraph_expand_all_functions): Likewise.
	(cgraph_finalize_pending_functions): Remove.  Update callers.

	* tree.h (OMP_DIRECTIVE_P): Define.
	(OMP_PARALLEL_FN): Define.
	(OMP_PARALLEL_DATA_ARG): Define.
	(OMP_SECTIONS_SECTIONS): Define.
	* tree-pass.h (pass_expand_omp): Declare.
	* omp-low.c (struct omp_region): Declare.
	(struct omp_context): Remove fields 'parallel_type',
	'parallel_start_ix' and 'parallel_start_additional_args'.
	Update all users.
	(struct omp_for_data): Rename from struct expand_omp_for_data.
	(omp_regions): New static variable.
	(root_omp_region): New static variable.
	(find_omp_clause): Make static.
	(is_in_combined_parallel_ctx): Remove.
	(is_combined_parallel): New.
	(extract_omp_for_data): Move earlier in the file.
	(workshare_safe_to_combine_p): New.
	(get_ws_args_for): New.
	(determine_parallel_type): Move earlier in the file.
	(omp_copy_decl_2): Do not set DECL_CONTEXT of new local to the
	child function.
	(omp_copy_decl): Likewise.
	(create_omp_child_function): Likewise.
	(lookup_omp_region): New.
	(dump_omp_region): New.
	(debug_omp_region): New.
	(debug_all_omp_regions): New.
	(new_omp_region): New.
	(scan_omp_parallel): If parallel_nesting_level > 1, the
	directive is nested within another parallel directive.
	Set OMP_PARALLEL_FN.
	(scan_omp_for): Do not try to handle combined parallel+for
	cases.
	Remove FIXME comment.
	(scan_omp_nested): Remove.
	(scan_omp_1): Do not call scan_omp_nested when
	parallel_nesting_level is > 1.
	Do not change the DECL_CONTEXT of local variables found.
	(lookup_decl_in_outer_ctx): New.
	(lower_rec_input_clauses): Rename from expand_rec_input_clauses.
	(lower_lastprivate_clauses): Rename from expand_lastprivate_clauses.
	(lower_reduction_clauses): Rename from expand_reduction_clauses.
	(lower_copyprivate_clauses): Rename from expand_copyprivate_clauses.
	If CTX is nested, lookup VAR in the outer context when
	building copy assignment.
	(lower_send_clauses): Rename from expand_send_clauses.
	If CTX is nested, lookup VAR in the outer context when
	building copy assignments.
	(lower_send_shared_vars): Rename from expand_send_shared_vars.
	If CTX is nested, lookup VAR in the outer context when
	building copy assignments.
	(expand_parallel_call): Rename from build_parallel_call.
	Handle combined parallel+workshare cases.
	Re-implement to emit code into the CFG.
	(list2chain): New.
	(expand_omp_parallel): Re-implement to emit code into the CFG.
	Call move_sese_region_to_fn to outline the sub-graph
	containing the parallel region.
	(expand_omp_for_1): Remove.
	(expand_omp_for_generic): Re-implement to emit code into the
	CFG.
	(expand_omp_for_static_nochunk): Likewise.
	(expand_omp_for_static_chunk): Likewise.
	(expand_omp_for): Likewise.
	(expand_omp_sections): Likewise.
	(remove_exit_barriers): New.
	(expand_omp_synch): New.
	(expand_omp): New.
	(build_omp_regions_1): New.
	(build_omp_regions): New.
	(execute_expand_omp): New.
	(gate_expand_omp): New.
	(pass_expand_omp): Define.
	(lower_omp_sections): Rename from expand_omp_sections.
	Set OMP_SECTIONS_SECTIONS.
	(lower_omp_single_simple): Rename from expand_omp_single_simple.
	(lower_omp_single_copy): Rename from expand_omp_single_copy.
	(lower_omp_single): Rename from expand_omp_simple.
	(lower_omp_master): Rename from expand_omp_master.
	(lower_omp_ordered): Rename from expand_omp_ordered.
	(lower_omp_critical): Rename from expand_omp_critical.
	(lower_omp_for_lastprivate): Rename from expand_omp_for_lastprivate.
	(lower_omp_for): Re-implement.
	(lower_omp_parallel): Re-implement.
	(lower_regimplify): Rename from expand_regimplify.
	(lower_omp_1): Rename from expand_omp_1.
	If there are syntax errors in the program, replace every
	OpenMP directive with NOP.
	Call lower_omp_* instead of expand_omp_*.
	(lower_omp): Rename from expand_omp.

	* tree-gimple.c (is_gimple_stmt): Handle OMP_RETURN_EXPR.
	* tree-gimple.h (enum omp_parallel_type): Remove.
	(gimple_boolify): Declare extern.
	(find_omp_clause, determine_parallel_type): Remove.

	* gimple-low.c (lower_omp_directive): New.
	(lower_stmt): Call it.
	(record_vars_into): Move from ...
	(record_vars): ... here.
	Call record_vars_into with current_function_decl.

	* gimplify.c (struct gimplify_ctx): Remove fields
	combined_pre_p and combined_ctxp.  Update users.
	(get_formal_tmp_var): Add documentation.
	(gimple_boolify): Make extern.
	(gimplify_expr_in_ctx): Remove.  Update callers.
	(gimplify_omp_parallel): Do not assume that OMP_PARALLEL_BODY
	will always be a BIND_EXPR.
	(gimplify_expr): Handle OMP_RETURN_EXPR.
	* tree.def (BLOCK): Remove documentation about BLOCK_TYPE_TAGS.
	(OMP_PARALLEL): Add 3 operands.
	(OMP_SECTIONS): Add 1 operand.
	(OMP_RETURN_EXPR): Define.

	* tree-inline.c (estimate_num_insns_1): Handle OpenMP directives.
	(copy_tree_r): Restore TREE_CHAIN in OMP_CLAUSE_*.
	* tree-iterator.c (alloc_stmt_list): Assert that we are not
	creating a circular free list.
	(free_stmt_list): Assert that we are not freeing stmt_list_cache.

	* tree-flow.h (move_sese_region_to_fn): Declare.
	(record_vars_into): Declare.
	* tree-cfg.c (make_omp_sections_edges): New.
	(make_exit_edges): Handle OMP_PARALLEL, OMP_FOR, OMP_SINGLE,
	OMP_MASTER, OMP_ORDERED, OMP_CRITICAL, OMP_RETURN_EXPR,
	OMP_SECTIONS and OMP_SECTION.
	(is_ctrl_altering_stmt): Return true for OMP_DIRECTIVE_P.
	(set_bb_for_stmt): Undo change to check currently_expanding_to_rtl.
	(verify_stmt): Do not handle OMP_DIRECTIVE_P.
	(gather_blocks_in_sese_region): New.
	(struct move_stmt_d): Declare.
	(move_stmt_r): New.
	(move_block_to_fn): New.
	(move_sese_region_to_fn): New.

	* passes.c (init_optimization_passes): Schedule
	pass_expand_omp after pass_init_datastructures.

	* tree-ssa-operands.c (get_expr_operands): Handle
	OMP_PARALLEL, OMP_SECTIONS, OMP_FOR, OMP_RETURN_EXPR,
	OMP_SINGLE, OMP_MASTER, OMP_ORDERED, OMP_CRITICAL.


testsuite/

	* testsuite/gcc.dg/gomp/for-13.c: Use -fdump-tree-ompexp.
	* testsuite/gcc.dg/gomp/critical-1.c: Likewise.
	* testsuite/gcc.dg/gomp/critical-3.c: Likewise.
	* testsuite/gcc.dg/gomp/empty.c: Likewise.
	* testsuite/gcc.dg/gomp/ordered-1.c: Likewise.
	* testsuite/gcc.dg/gomp/for-4.c: Likewise.
	* testsuite/gcc.dg/gomp/for-6.c: Likewise.
	* testsuite/gcc.dg/gomp/master-3.c: Likewise.
	* testsuite/gcc.dg/gomp/for-8.c: Likewise.
	* testsuite/gcc.dg/gomp/for-10.c: Likewise.
	* testsuite/gcc.dg/gomp/for-18.c: Likewise.
	* testsuite/gcc.dg/gomp/for-5.c: Likewise.
	* testsuite/gcc.dg/gomp/for-7.c: Likewise.
	* testsuite/gcc.dg/gomp/for-9.c: Likewise.

From-SVN: r109969
parent 307d19fe
2006-01-19 Diego Novillo <dnovillo@redhat.com>
* tree-pretty-print.c (dump_generic_node): Handle
OMP_PARALLEL_FN, OMP_PARALLEL_DATA_ARG and OMP_RETURN_EXPR.
* cgraph.c (cgraph_expand_queue): Rename from
cgraph_analyze_queue. Update all users.
* cgraphunit.c (cgraph_assemble_pending_functions): Process
cgraph_expand_queue.
(cgraph_expand_all_functions): Likewise.
(cgraph_finalize_pending_functions): Remove. Update callers.
* tree.h (OMP_DIRECTIVE_P): Define.
(OMP_PARALLEL_FN): Define.
(OMP_PARALLEL_DATA_ARG): Define.
(OMP_SECTIONS_SECTIONS): Define.
* tree-pass.h (pass_expand_omp): Declare.
* omp-low.c (struct omp_region): Declare.
(struct omp_context): Remove fields 'parallel_type',
'parallel_start_ix' and 'parallel_start_additional_args'.
Update all users.
(struct omp_for_data): Rename from struct expand_omp_for_data.
(omp_regions): New static variable.
(root_omp_region): New static variable.
(find_omp_clause): Make static.
(is_in_combined_parallel_ctx): Remove.
(is_combined_parallel): New.
(extract_omp_for_data): Move earlier in the file.
(workshare_safe_to_combine_p): New.
(get_ws_args_for): New.
(determine_parallel_type): Move earlier in the file.
(omp_copy_decl_2): Do not set DECL_CONTEXT of new local to the
child function.
(omp_copy_decl): Likewise.
(create_omp_child_function): Likewise.
(lookup_omp_region): New.
(dump_omp_region): New.
(debug_omp_region): New.
(debug_all_omp_regions): New.
(new_omp_region): New.
(scan_omp_parallel): If parallel_nesting_level > 1, the
directive is nested within another parallel directive.
Set OMP_PARALLEL_FN.
(scan_omp_for): Do not try to handle combined parallel+for
cases.
Remove FIXME comment.
(scan_omp_nested): Remove.
(scan_omp_1): Do not call scan_omp_nested when
parallel_nesting_level is > 1.
Do not change the DECL_CONTEXT of local variables found.
(lookup_decl_in_outer_ctx): New.
(lower_rec_input_clauses): Rename from expand_rec_input_clauses.
(lower_lastprivate_clauses): Rename from expand_lastprivate_clauses.
(lower_reduction_clauses): Rename from expand_reduction_clauses.
(lower_copyprivate_clauses): Rename from expand_copyprivate_clauses.
If CTX is nested, lookup VAR in the outer context when
building copy assignment.
(lower_send_clauses): Rename from expand_send_clauses.
If CTX is nested, lookup VAR in the outer context when
building copy assignments.
(lower_send_shared_vars): Rename from expand_send_shared_vars.
If CTX is nested, lookup VAR in the outer context when
building copy assignments.
(expand_parallel_call): Rename from build_parallel_call.
Handle combined parallel+workshare cases.
Re-implement to emit code into the CFG.
(list2chain): New.
(expand_omp_parallel): Re-implement to emit code into the CFG.
Call move_sese_region_to_fn to outline the sub-graph
containing the parallel region.
(expand_omp_for_1): Remove.
(expand_omp_for_generic): Re-implement to emit code into the
CFG.
(expand_omp_for_static_nochunk): Likewise.
(expand_omp_for_static_chunk): Likewise.
(expand_omp_for): Likewise.
(expand_omp_sections): Likewise.
(remove_exit_barriers): New.
(expand_omp_synch): New.
(expand_omp): New.
(build_omp_regions_1): New.
(build_omp_regions): New.
(execute_expand_omp): New.
(gate_expand_omp): New.
(pass_expand_omp): Define.
(lower_omp_sections): Rename from expand_omp_sections.
Set OMP_SECTIONS_SECTIONS.
(lower_omp_single_simple): Rename from expand_omp_single_simple.
(lower_omp_single_copy): Rename from expand_omp_single_copy.
(lower_omp_single): Rename from expand_omp_simple.
(lower_omp_master): Rename from expand_omp_master.
(lower_omp_ordered): Rename from expand_omp_ordered.
(lower_omp_critical): Rename from expand_omp_critical.
(lower_omp_for_lastprivate): Rename from expand_omp_for_lastprivate.
(lower_omp_for): Re-implement.
(lower_omp_parallel): Re-implement.
(lower_regimplify): Rename from expand_regimplify.
(lower_omp_1): Rename from expand_omp_1.
If there are syntax errors in the program, replace every
OpenMP directive with NOP.
Call lower_omp_* instead of expand_omp_*.
(lower_omp): Rename from expand_omp.
* tree-gimple.c (is_gimple_stmt): Handle OMP_RETURN_EXPR.
* tree-gimple.h (enum omp_parallel_type): Remove.
(gimple_boolify): Declare extern.
(find_omp_clause, determine_parallel_type): Remove.
* gimple-low.c (lower_omp_directive): New.
(lower_stmt): Call it.
(record_vars_into): Move from ...
(record_vars): ... here.
Call record_vars_into with current_function_decl.
* gimplify.c (struct gimplify_ctx): Remove fields
combined_pre_p and combined_ctxp. Update users.
(get_formal_tmp_var): Add documentation.
(gimple_boolify): Make extern.
(gimplify_expr_in_ctx): Remove. Update callers.
(gimplify_omp_parallel): Do not assume that OMP_PARALLEL_BODY
will always be a BIND_EXPR.
(gimplify_expr): Handle OMP_RETURN_EXPR.
* tree.def (BLOCK): Remove documentation about BLOCK_TYPE_TAGS.
(OMP_PARALLEL): Add 3 operands.
(OMP_SECTIONS): Add 1 operand.
(OMP_RETURN_EXPR): Define.
* tree-inline.c (estimate_num_insns_1): Handle OpenMP directives.
(copy_tree_r): Restore TREE_CHAIN in OMP_CLAUSE_*.
* tree-iterator.c (alloc_stmt_list): Assert that we are not
creating a circular free list.
(free_stmt_list): Assert that we are not freeing stmt_list_cache.
* tree-flow.h (move_sese_region_to_fn): Declare.
(record_vars_into): Declare.
* tree-cfg.c (make_omp_sections_edges): New.
(make_exit_edges): Handle OMP_PARALLEL, OMP_FOR, OMP_SINGLE,
OMP_MASTER, OMP_ORDERED, OMP_CRITICAL, OMP_RETURN_EXPR,
OMP_SECTIONS and OMP_SECTION.
(is_ctrl_altering_stmt): Return true for OMP_DIRECTIVE_P.
(set_bb_for_stmt): Undo change to check currently_expanding_to_rtl.
(verify_stmt): Do not handle OMP_DIRECTIVE_P.
(gather_blocks_in_sese_region): New.
(struct move_stmt_d): Declare.
(move_stmt_r): New.
(move_block_to_fn): New.
(move_sese_region_to_fn): New.
* passes.c (init_optimization_passes): Schedule
pass_expand_omp after pass_init_datastructures.
* tree-ssa-operands.c (get_expr_operands): Handle
OMP_PARALLEL, OMP_SECTIONS, OMP_FOR, OMP_RETURN_EXPR,
OMP_SINGLE, OMP_MASTER, OMP_ORDERED, OMP_CRITICAL.
2006-01-19 Jeff Law <law@redhat.com>
* tree-vrp.c (extract_range_from_assert): Refine the result range
......
......@@ -113,8 +113,10 @@ struct cgraph_node *cgraph_nodes;
/* Queue of cgraph nodes scheduled to be lowered. */
struct cgraph_node *cgraph_nodes_queue;
/* Queue of cgraph nodes scheduled to be analyzed. */
struct cgraph_node *cgraph_analyze_queue;
/* Queue of cgraph nodes scheduled to be expanded. This is a
secondary queue used during optimization to accomodate passes that
may generate new functions that need to be optimized and expanded. */
struct cgraph_node *cgraph_expand_queue;
/* Number of nodes in existence. */
int cgraph_n_nodes;
......@@ -1095,19 +1097,23 @@ cgraph_variable_initializer_availability (struct cgraph_varpool_node *node)
}
/* Add the function FNDECL to the call graph. This assumes that the
body of FNDECL is in GENERIC form and ready to be processed by
cgraph_finalize_function. */
/* Add the function FNDECL to the call graph. FNDECL is assumed to be
in low GIMPLE form and ready to be processed by cgraph_finalize_function.
When operating in unit-at-a-time, a new callgraph node is added to
CGRAPH_EXPAND_QUEUE, which is processed after all the original
functions in the call graph .
When not in unit-at-a-time, the new callgraph node is added to
CGRAPH_NODES_QUEUE for cgraph_assemble_pending_functions to
process. */
void
cgraph_add_new_function (tree fndecl)
{
/* We're called while lowering another function. We can't do anything
at this time without recursing. Which would cause a GC at an
inappropriate time. */
struct cgraph_node *n = cgraph_node (fndecl);
n->next_needed = cgraph_analyze_queue;
cgraph_analyze_queue = n;
n->next_needed = cgraph_expand_queue;
cgraph_expand_queue = n;
}
#include "gt-cgraph.h"
......@@ -152,7 +152,7 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
/* Set when function is reachable by call from other function
that is either reachable or needed. */
bool reachable;
/* Set once the function is lowered (ie it's CFG is built). */
/* Set once the function is lowered (i.e. its CFG is built). */
bool lowered;
/* Set once the function has been instantiated and its callee
lists created. */
......@@ -239,7 +239,7 @@ extern GTY(()) int cgraph_max_uid;
extern bool cgraph_global_info_ready;
extern bool cgraph_function_flags_ready;
extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
extern GTY(()) struct cgraph_node *cgraph_analyze_queue;
extern GTY(()) struct cgraph_node *cgraph_expand_queue;
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
......
......@@ -353,8 +353,22 @@ cgraph_assemble_pending_functions (void)
}
}
/* Process CGRAPH_EXPAND_QUEUE, these are functions created during
the expansion process. Note that this queue may grow as its
being processed, as the new functions may generate new ones. */
while (cgraph_expand_queue)
{
struct cgraph_node *n = cgraph_expand_queue;
cgraph_expand_queue = cgraph_expand_queue->next_needed;
n->next_needed = NULL;
cgraph_finalize_function (n->decl, false);
output = true;
}
return output;
}
/* As an GCC extension we allow redefinition of the function. The
semantics when both copies of bodies differ is not well defined.
We replace the old body with new body so in unit at a time mode
......@@ -418,20 +432,6 @@ cgraph_lower_function (struct cgraph_node *node)
node->lowered = true;
}
static void
cgraph_finalize_pending_functions (void)
{
struct cgraph_node *next, *node = cgraph_analyze_queue;
cgraph_analyze_queue = NULL;
for (; node ; node = next)
{
next = node->next_needed;
node->next_needed = NULL;
cgraph_finalize_function (node->decl, true);
}
}
/* DECL has been parsed. Take it, queue it, compile it at the whim of the
logic in effect. If NESTED is true, then our caller cannot stand to have
the garbage collector run at the moment. We would need to either create
......@@ -458,7 +458,6 @@ cgraph_finalize_function (tree decl, bool nested)
if (!flag_unit_at_a_time)
{
cgraph_analyze_function (node);
cgraph_finalize_pending_functions ();
cgraph_decide_inlining_incrementally (node, false);
}
......@@ -982,7 +981,6 @@ cgraph_finalize_compilation_unit (void)
gcc_assert (DECL_SAVED_TREE (decl));
cgraph_analyze_function (node);
cgraph_finalize_pending_functions ();
for (edge = node->callees; edge; edge = edge->next_callee)
if (!edge->callee->reachable)
......@@ -1166,7 +1164,21 @@ cgraph_expand_all_functions (void)
cgraph_expand_function (node);
}
}
free (order);
/* Process CGRAPH_EXPAND_QUEUE, these are functions created during
the expansion process. Note that this queue may grow as its
being processed, as the new functions may generate new ones. */
while (cgraph_expand_queue)
{
node = cgraph_expand_queue;
cgraph_expand_queue = cgraph_expand_queue->next_needed;
node->next_needed = NULL;
node->output = 0;
node->lowered = DECL_STRUCT_FUNCTION (node->decl)->cfg != NULL;
cgraph_expand_function (node);
}
}
/* This is used to sort the node types by the cgraph order number. */
......
......@@ -151,6 +151,32 @@ lower_stmt_body (tree expr, struct lower_data *data)
lower_stmt (&tsi, data);
}
/* Lower the OpenMP directive statement pointed by TSI. DATA is
passed through the recursion. */
static void
lower_omp_directive (tree_stmt_iterator *tsi, struct lower_data *data)
{
tree clause, stmt;
stmt = tsi_stmt (*tsi);
clause = (TREE_CODE (stmt) >= OMP_PARALLEL && TREE_CODE (stmt) <= OMP_SINGLE)
? OMP_CLAUSES (stmt)
: NULL_TREE;
for (; clause; clause = OMP_CLAUSE_CHAIN (clause))
TREE_BLOCK (clause) = TREE_BLOCK (stmt);
lower_stmt_body (OMP_BODY (stmt), data);
tsi_link_before (tsi, stmt, TSI_SAME_STMT);
tsi_link_before (tsi, OMP_BODY (stmt), TSI_SAME_STMT);
OMP_BODY (stmt) = NULL_TREE;
tsi_delink (tsi);
}
/* Lowers statement TSI. DATA is passed through the recursion. */
static void
......@@ -192,8 +218,20 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
case GOTO_EXPR:
case LABEL_EXPR:
case SWITCH_EXPR:
case OMP_RETURN_EXPR:
break;
case OMP_PARALLEL:
case OMP_FOR:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
lower_omp_directive (tsi, data);
return;
default:
gcc_unreachable ();
}
......@@ -503,11 +541,16 @@ lower_return_expr (tree_stmt_iterator *tsi, struct lower_data *data)
}
/* Record the variables in VARS. */
/* Record the variables in VARS into function FN. */
void
record_vars (tree vars)
record_vars_into (tree vars, tree fn)
{
struct function *saved_cfun = cfun;
if (fn != current_function_decl)
cfun = DECL_STRUCT_FUNCTION (fn);
for (; vars; vars = TREE_CHAIN (vars))
{
tree var = vars;
......@@ -516,6 +559,7 @@ record_vars (tree vars)
we don't need to care about. */
if (TREE_CODE (var) != VAR_DECL)
continue;
/* Nothing to do in this case. */
if (DECL_EXTERNAL (var))
continue;
......@@ -524,6 +568,18 @@ record_vars (tree vars)
cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
cfun->unexpanded_var_list);
}
if (fn != current_function_decl)
cfun = saved_cfun;
}
/* Record the variables in VARS into current_function_decl. */
void
record_vars (tree vars)
{
record_vars_into (vars, current_function_decl);
}
......
......@@ -92,16 +92,6 @@ struct gimplify_ctx
int conditions;
bool save_stack;
bool into_ssa;
/* When gimplifying combined omp parallel directives (omp parallel
loop and omp parallel sections), any prefix code needed to setup
the associated worksharing construct needs to be emitted in the
pre-queue of its parent parallel, otherwise the lowering process
will move that code to the child function. Similarly, we need to
move up to the gimplification context of the parent parallel
directive so temporaries are declared in the right context. */
tree *combined_pre_p;
struct gimplify_ctx *combined_ctxp;
};
static struct gimplify_ctx *gimplify_ctxp;
......@@ -634,6 +624,10 @@ internal_get_tmp_var (tree val, tree *pre_p, tree *post_p, bool is_formal)
return t;
}
/* Returns a formal temporary variable initialized with VAL. PRE_P
points to a statement list where side-effects needed to compute VAL
should be stored. */
tree
get_formal_tmp_var (tree val, tree *pre_p)
{
......@@ -2297,7 +2291,7 @@ shortcut_cond_expr (tree expr)
/* EXPR is used in a boolean context; make sure it has BOOLEAN_TYPE. */
static tree
tree
gimple_boolify (tree expr)
{
tree type = TREE_TYPE (expr);
......@@ -4131,29 +4125,6 @@ gimplify_to_stmt_list (tree *stmt_p)
}
}
/* Gimplify *EXPR_P as if it had been used inside the gimplification
context CTX_P. The other arguments are as in gimplify_expr. */
static enum gimplify_status
gimplify_expr_in_ctx (tree *expr_p, tree *pre_p, tree *post_p,
bool (* gimple_test_f) (tree), fallback_t fallback,
struct gimplify_ctx *ctx_p,
struct gimplify_omp_ctx *omp_ctx_p)
{
enum gimplify_status ret;
struct gimplify_ctx *prev_ctxp;
struct gimplify_omp_ctx *prev_omp_ctxp;
prev_ctxp = gimplify_ctxp;
gimplify_ctxp = ctx_p;
prev_omp_ctxp = gimplify_omp_ctxp;
gimplify_omp_ctxp = omp_ctx_p;
ret = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fallback);
gimplify_ctxp = prev_ctxp;
gimplify_omp_ctxp = prev_omp_ctxp;
return ret;
}
/* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
to CTX. If entries already exist, force them to be some flavor of private.
......@@ -4531,19 +4502,6 @@ gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
break;
case OMP_CLAUSE_SCHEDULE:
if (gimplify_ctxp->combined_pre_p)
{
gcc_assert (gimplify_omp_ctxp == outer_ctx);
gs = gimplify_expr_in_ctx (&OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c),
gimplify_ctxp->combined_pre_p, NULL,
is_gimple_val, fb_rvalue,
gimplify_ctxp->combined_ctxp,
outer_ctx->outer_context);
if (gs == GS_ERROR)
remove = true;
break;
}
/* FALLTHRU */
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
gs = gimplify_expr (&TREE_OPERAND (c, 0), pre_p, NULL,
......@@ -4708,17 +4666,12 @@ gimplify_omp_parallel (tree *expr_p, tree *pre_p)
push_gimplify_context ();
if (determine_parallel_type (expr) == IS_COMBINED_PARALLEL)
{
gimplify_ctxp->combined_pre_p = pre_p;
gimplify_ctxp->combined_ctxp = gimplify_ctxp->prev_context;
}
gimplify_stmt (&OMP_PARALLEL_BODY (expr));
pop_gimplify_context (OMP_PARALLEL_BODY (expr));
gimplify_ctxp->combined_pre_p = NULL;
gimplify_ctxp->combined_ctxp = NULL;
if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
pop_gimplify_context (OMP_PARALLEL_BODY (expr));
else
pop_gimplify_context (NULL_TREE);
gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
......@@ -4732,13 +4685,9 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
{
tree for_stmt, decl, t;
enum gimplify_status ret = 0;
struct gimplify_omp_ctx *outer_combined_omp_ctxp = NULL;
for_stmt = *expr_p;
if (gimplify_ctxp->combined_pre_p)
outer_combined_omp_ctxp = gimplify_omp_ctxp->outer_context;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false);
t = OMP_FOR_INIT (for_stmt);
......@@ -4754,33 +4703,15 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
/* Gimplify inside our parent's context if this is part of a combined
parallel+workshare directive. */
if (gimplify_ctxp->combined_pre_p)
ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
gimplify_ctxp->combined_pre_p, NULL,
is_gimple_val, fb_rvalue,
gimplify_ctxp->combined_ctxp,
outer_combined_omp_ctxp);
else
ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
t = OMP_FOR_COND (for_stmt);
gcc_assert (COMPARISON_CLASS_P (t));
gcc_assert (TREE_OPERAND (t, 0) == decl);
/* Gimplify inside our parent's context if this is part of a combined
parallel+workshare directive. */
if (gimplify_ctxp->combined_pre_p)
ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
gimplify_ctxp->combined_pre_p, NULL,
is_gimple_val, fb_rvalue,
gimplify_ctxp->combined_ctxp,
outer_combined_omp_ctxp);
else
ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
t = OMP_FOR_INCR (for_stmt);
switch (TREE_CODE (t))
......@@ -4818,18 +4749,8 @@ gimplify_omp_for (tree *expr_p, tree *pre_p)
gcc_unreachable ();
}
/* Gimplify inside our parent's context if this is part of a
combined parallel+workshare directive. */
if (gimplify_ctxp->combined_pre_p)
ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
gimplify_ctxp->combined_pre_p, NULL,
is_gimple_val, fb_rvalue,
gimplify_ctxp->combined_ctxp,
outer_combined_omp_ctxp);
else
ret |= gimplify_expr (&TREE_OPERAND (t, 1),
&OMP_FOR_PRE_BODY (for_stmt), NULL,
is_gimple_val, fb_rvalue);
ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
NULL, is_gimple_val, fb_rvalue);
break;
default:
......@@ -5622,6 +5543,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
ret = gimplify_omp_atomic (expr_p, pre_p);
break;
case OMP_RETURN_EXPR:
ret = GS_ALL_DONE;
break;
default:
switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
{
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -481,6 +481,7 @@ init_optimization_passes (void)
p = &all_passes;
NEXT_PASS (pass_fixup_cfg);
NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_expand_omp);
NEXT_PASS (pass_all_optimizations);
NEXT_PASS (pass_warn_function_noreturn);
NEXT_PASS (pass_mudflap_2);
......
2006-01-19 Diego Novillo <dnovillo@redhat.com>
* testsuite/gcc.dg/gomp/for-13.c: Use -fdump-tree-ompexp.
* testsuite/gcc.dg/gomp/critical-1.c: Likewise.
* testsuite/gcc.dg/gomp/critical-3.c: Likewise.
* testsuite/gcc.dg/gomp/empty.c: Likewise.
* testsuite/gcc.dg/gomp/ordered-1.c: Likewise.
* testsuite/gcc.dg/gomp/for-4.c: Likewise.
* testsuite/gcc.dg/gomp/for-6.c: Likewise.
* testsuite/gcc.dg/gomp/master-3.c: Likewise.
* testsuite/gcc.dg/gomp/for-8.c: Likewise.
* testsuite/gcc.dg/gomp/for-10.c: Likewise.
* testsuite/gcc.dg/gomp/for-18.c: Likewise.
* testsuite/gcc.dg/gomp/for-5.c: Likewise.
* testsuite/gcc.dg/gomp/for-7.c: Likewise.
* testsuite/gcc.dg/gomp/for-9.c: Likewise.
2006-01-18 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/vrp25.c: New test.
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-omplower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -21,8 +21,8 @@ void foo (void)
bar(3);
}
/* { dg-final { scan-tree-dump-times "GOMP_critical_start" 2 "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_end" 2 "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_name_start" 2 "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_name_end" 2 "omplower" } } */
/* { dg-final { cleanup-tree-dump "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_start" 2 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_end" 2 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_name_start" 2 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_critical_name_end" 2 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
// { dg-do compile }
// { dg-options "-fopenmp -fdump-tree-omplower" }
// { dg-options "-fopenmp -fdump-tree-ompexp" }
void bar(void);
void foo(void)
......@@ -8,4 +8,4 @@ void foo(void)
bar();
}
// { dg-final { scan-tree-dump-times "\\&\\.gomp_critical_user_xyzzy" 2 "omplower" } }
// { dg-final { scan-tree-dump-times "\\&\\.gomp_critical_user_xyzzy" 2 "ompexp" } }
/* { dg-do compile } */
/* { dg-options "-O -fopenmp -fdump-tree-omplower" } */
/* { dg-options "-O -fopenmp -fdump-tree-ompexp" } */
main()
{
......@@ -8,5 +8,5 @@ main()
}
/* There should not be a GOMP_parallel_start call. */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_start" 0 "omplower"} } */
/* { dg-final { cleanup-tree-dump "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_start" 0 "ompexp"} } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_runtime_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_runtime_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_runtime_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_runtime_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
......@@ -2,7 +2,7 @@
// for iteration variable as private.
// { dg-do compile }
// { dg-options "-fopenmp -fdump-tree-lower" }
// { dg-options "-fopenmp -fdump-tree-ompexp" }
extern void bar(int);
void foo(void)
......@@ -14,5 +14,5 @@ void foo(void)
bar(i);
}
// { dg-final { scan-tree-dump-times "omp_data_o" 0 "lower" } }
// { dg-final { cleanup-tree-dump "lower" } }
// { dg-final { scan-tree-dump-times "omp_data_o" 0 "ompexp" } }
// { dg-final { cleanup-tree-dump "ompexp" } }
/* { dg-do compile } */
/* { dg-options "-O -fopenmp -fdump-tree-omplower" } */
/* { dg-options "-O -fopenmp -fdump-tree-ompexp" } */
void
foo (int *a, int i)
......@@ -37,6 +37,6 @@ bar (int *a, int i)
a[j] = 4;
}
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_dynamic_start" 4 "omplower" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_guided_start" 4 "omplower" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_dynamic_start" 4 "ompexp" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "GOMP_parallel_loop_guided_start" 4 "ompexp" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_dynamic_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_dynamic_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_dynamic_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_dynamic_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_guided_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_guided_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_guided_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_guided_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_runtime_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_static_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_static_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_static_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_static_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_dynamic_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_dynamic_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_dynamic_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_dynamic_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-lower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -12,6 +12,6 @@ void foo (int n)
bar(i);
}
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_guided_start" 1 "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_guided_next" 1 "lower" } } */
/* { dg-final { cleanup-tree-dump "lower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_guided_start" 1 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_loop_ordered_guided_next" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-omplower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -9,5 +9,5 @@ void foo (void)
bar(0);
}
/* { dg-final { scan-tree-dump-times "omp_get_thread_num" 1 "omplower" } } */
/* { dg-final { cleanup-tree-dump "omplower" } } */
/* { dg-final { scan-tree-dump-times "omp_get_thread_num" 1 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
/* { dg-do compile } */
/* { dg-options "-fopenmp -fdump-tree-omplower" } */
/* { dg-options "-fopenmp -fdump-tree-ompexp" } */
extern void bar(int);
......@@ -15,6 +15,6 @@ void foo (void)
}
}
/* { dg-final { scan-tree-dump-times "GOMP_ordered_start" 2 "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_ordered_end" 2 "omplower" } } */
/* { dg-final { cleanup-tree-dump "omplower" } } */
/* { dg-final { scan-tree-dump-times "GOMP_ordered_start" 2 "ompexp" } } */
/* { dg-final { scan-tree-dump-times "GOMP_ordered_end" 2 "ompexp" } } */
/* { dg-final { cleanup-tree-dump "ompexp" } } */
......@@ -540,6 +540,8 @@ extern void fold_cond_expr_cond (void);
extern void replace_uses_by (tree, tree);
extern void start_recording_case_labels (void);
extern void end_recording_case_labels (void);
extern basic_block move_sese_region_to_fn (struct function *, basic_block,
basic_block);
/* In tree-cfgcleanup.c */
extern bool cleanup_tree_cfg (void);
......@@ -580,8 +582,9 @@ extern void remove_phi_node (tree, tree);
extern tree phi_reverse (tree);
/* In gimple-low.c */
extern void record_vars_into (tree, tree);
extern void record_vars (tree);
extern bool block_may_fallthru (tree block);
extern bool block_may_fallthru (tree);
/* In tree-ssa-alias.c */
extern void dump_may_aliases_for (FILE *, tree);
......@@ -886,6 +889,7 @@ tree create_mem_ref (block_stmt_iterator *, tree,
rtx addr_for_mem_ref (struct mem_address *, bool);
void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree);
/* This structure is simply used during pushing fields onto the fieldstack
to track the offset of the field, since bitpos_of_field gives it relative
to its immediate containing type, and we want it relative to the ultimate
......
......@@ -224,6 +224,7 @@ is_gimple_stmt (tree t)
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_RETURN_EXPR:
/* These are always void. */
return true;
......
......@@ -109,21 +109,6 @@ enum gimplify_status {
GS_ALL_DONE = 1 /* The expression is fully gimplified. */
};
/* Type of parallel constructs. Used to decide what runtime function
to use for launching children threads and the gimplification
strategy. */
enum omp_parallel_type {
IS_NOT_PARALLEL = 0,
/* Regular omp parallel */
IS_PARALLEL,
/* Combined parallel + workshare (parallel loop and parallel
sections). */
IS_COMBINED_PARALLEL
};
extern enum gimplify_status gimplify_expr (tree *, tree *, tree *,
bool (*) (tree), fallback_t);
extern void gimplify_type_sizes (tree, tree *);
......@@ -147,12 +132,11 @@ extern tree force_labels_r (tree *, int *, void *);
extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
struct gimplify_omp_ctx;
extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
extern tree gimple_boolify (tree);
/* In omp-low.c. */
extern tree find_omp_clause (tree, enum tree_code);
extern void diagnose_omp_structured_block_errors (tree);
extern tree omp_reduction_init (tree, tree);
enum omp_parallel_type determine_parallel_type (tree stmt);
/* In tree-nested.c. */
extern void lower_nested_functions (tree);
......
......@@ -1598,6 +1598,29 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
case LOOP_EXPR:
case PHI_NODE:
case WITH_SIZE_EXPR:
case OMP_PARALLEL:
case OMP_FOR:
case OMP_SECTIONS:
case OMP_SINGLE:
case OMP_SECTION:
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_ATOMIC:
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_LASTPRIVATE:
case OMP_CLAUSE_REDUCTION:
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_COPYPRIVATE:
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_SCHEDULE:
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_DEFAULT:
case OMP_RETURN_EXPR:
break;
/* We don't account constants for now. Assume that the cost is amortized
......@@ -2285,7 +2308,22 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
/* Now, restore the chain, if appropriate. That will cause
walk_tree to walk into the chain as well. */
if (code == PARM_DECL || code == TREE_LIST)
if (code == PARM_DECL
|| code == TREE_LIST
/* OpenMP clauses are linked through TREE_CHAIN. */
|| code == OMP_CLAUSE_PRIVATE
|| code == OMP_CLAUSE_SHARED
|| code == OMP_CLAUSE_FIRSTPRIVATE
|| code == OMP_CLAUSE_LASTPRIVATE
|| code == OMP_CLAUSE_REDUCTION
|| code == OMP_CLAUSE_COPYIN
|| code == OMP_CLAUSE_COPYPRIVATE
|| code == OMP_CLAUSE_IF
|| code == OMP_CLAUSE_NUM_THREADS
|| code == OMP_CLAUSE_SCHEDULE
|| code == OMP_CLAUSE_NOWAIT
|| code == OMP_CLAUSE_ORDERED
|| code == OMP_CLAUSE_DEFAULT)
TREE_CHAIN (*tp) = chain;
/* For now, we don't update BLOCKs when we make copies. So, we
......
......@@ -40,6 +40,7 @@ alloc_stmt_list (void)
if (list)
{
stmt_list_cache = TREE_CHAIN (list);
gcc_assert (stmt_list_cache != list);
memset (list, 0, sizeof(struct tree_common));
TREE_SET_CODE (list, STATEMENT_LIST);
}
......@@ -54,6 +55,9 @@ free_stmt_list (tree t)
{
gcc_assert (!STATEMENT_LIST_HEAD (t));
gcc_assert (!STATEMENT_LIST_TAIL (t));
/* If this triggers, it's a sign that the same list is being freed
twice. */
gcc_assert (t != stmt_list_cache || stmt_list_cache == NULL);
TREE_CHAIN (t) = stmt_list_cache;
stmt_list_cache = t;
}
......
......@@ -263,6 +263,7 @@ extern struct tree_opt_pass pass_lower_complex;
extern struct tree_opt_pass pass_lower_vector;
extern struct tree_opt_pass pass_lower_vector_ssa;
extern struct tree_opt_pass pass_lower_omp;
extern struct tree_opt_pass pass_expand_omp;
extern struct tree_opt_pass pass_object_sizes;
extern struct tree_opt_pass pass_fold_builtins;
extern struct tree_opt_pass pass_stdarg;
......
......@@ -1702,6 +1702,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_PARALLEL:
pp_string (buffer, "#pragma omp parallel");
dump_omp_clauses (buffer, OMP_PARALLEL_CLAUSES (node), spc, flags);
if (OMP_PARALLEL_FN (node))
{
pp_string (buffer, " [child fn: ");
dump_generic_node (buffer, OMP_PARALLEL_FN (node), spc, flags, false);
pp_string (buffer, " (");
if (OMP_PARALLEL_DATA_ARG (node))
dump_generic_node (buffer, OMP_PARALLEL_DATA_ARG (node), spc, flags,
false);
else
pp_string (buffer, "???");
pp_string (buffer, ")]");
}
dump_omp_body:
if (!(flags & TDF_SLIM) && OMP_BODY (node))
......@@ -1803,6 +1818,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_omp_clauses (buffer, OMP_SINGLE_CLAUSES (node), spc, flags);
goto dump_omp_body;
case OMP_RETURN_EXPR:
pp_string (buffer, "OMP_RETURN");
is_expr = false;
break;
case REDUC_MAX_EXPR:
pp_string (buffer, " REDUC_MAX_EXPR < ");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
......
......@@ -1288,6 +1288,14 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case FILTER_EXPR:
case LABEL_DECL:
case CONST_DECL:
case OMP_PARALLEL:
case OMP_SECTIONS:
case OMP_FOR:
case OMP_RETURN_EXPR:
case OMP_SINGLE:
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
/* Expressions that make no memory references. */
return;
......
......@@ -65,7 +65,6 @@ DEFTREECODE (TREE_VEC, "tree_vec", tcc_exceptional, 0)
For a block which represents the outermost scope of a function, it
points to the FUNCTION_DECL node.
BLOCK_VARS points to a chain of decl nodes.
BLOCK_TYPE_TAGS points to a chain of types which have their own names.
BLOCK_CHAIN points to the next BLOCK at the same level.
BLOCK_ABSTRACT_ORIGIN points to the original (abstract) tree node which
this block is an instance of, or else is NULL to indicate that this
......@@ -957,8 +956,15 @@ DEFTREECODE (TARGET_MEM_REF, "target_mem_ref", tcc_reference, 7)
exposed to TREE_RANGE_CHECK. */
/* OpenMP - #pragma omp parallel [clause1 ... clauseN]
Operand 0: OMP_PARALLEL_BODY: Code to be executed by all threads.
Operand 1: OMP_PARALLEL_CLAUSES: List of clauses. */
DEFTREECODE (OMP_PARALLEL, "omp_parallel", tcc_statement, 2)
Operand 1: OMP_PARALLEL_CLAUSES: List of clauses.
Operand 2: OMP_PARALLEL_FN: FUNCTION_DECL used when outlining the
body of the parallel region. Only valid after
pass_lower_omp.
Operand 3: OMP_PARALLEL_DATA_ARG: Local variable in the parent
function containing data to be shared with the child
function. */
DEFTREECODE (OMP_PARALLEL, "omp_parallel", tcc_statement, 4)
/* OpenMP - #pragma omp for [clause1 ... clauseN]
Operand 0: OMP_FOR_BODY: Loop body.
......@@ -983,8 +989,11 @@ DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
/* OpenMP - #pragma omp sections [clause1 ... clauseN]
Operand 0: OMP_SECTIONS_BODY: Sections body.
Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */
DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 2)
Operand 1: OMP_SECTIONS_CLAUSES: List of clauses.
Operand 2: OMP_SECTIONS_SECTIONS: Vector of the different sections
in the body. Only valid after lowering and destroyed
after the CFG has been built. */
DEFTREECODE (OMP_SECTIONS, "omp_sections", tcc_statement, 3)
/* OpenMP - #pragma omp single
Operand 0: OMP_SINGLE_BODY: Single section body.
......@@ -1063,6 +1072,9 @@ DEFTREECODE (OMP_CLAUSE_ORDERED, "ordered", tcc_expression, 0)
/* OpenMP clause: default. */
DEFTREECODE (OMP_CLAUSE_DEFAULT, "default", tcc_expression, 0)
/* Return from an OpenMP directive. */
DEFTREECODE (OMP_RETURN_EXPR, "omp_return", tcc_statement, 0)
/* Reduction operations.
Operations that take a vector of elements and "reduce" it to a scalar
result (e.g. summing the elements of the vector, finding the minimum over
......
......@@ -166,6 +166,19 @@ extern const enum tree_code_class tree_code_type[];
#define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
/* Returns nonzero iff NODE is an OpenMP directive. */
#define OMP_DIRECTIVE_P(NODE) \
(TREE_CODE (NODE) == OMP_PARALLEL \
|| TREE_CODE (NODE) == OMP_SECTIONS \
|| TREE_CODE (NODE) == OMP_SECTION \
|| TREE_CODE (NODE) == OMP_FOR \
|| TREE_CODE (NODE) == OMP_RETURN_EXPR \
|| TREE_CODE (NODE) == OMP_SINGLE \
|| TREE_CODE (NODE) == OMP_MASTER \
|| TREE_CODE (NODE) == OMP_ORDERED \
|| TREE_CODE (NODE) == OMP_CRITICAL)
/* Number of argument-words in each kind of tree-node. */
extern const unsigned char tree_code_length[];
......@@ -1424,6 +1437,8 @@ struct tree_constructor GTY(())
#define OMP_PARALLEL_BODY(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 0)
#define OMP_PARALLEL_CLAUSES(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 1)
#define OMP_PARALLEL_FN(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 2)
#define OMP_PARALLEL_DATA_ARG(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 3)
#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 0)
#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 1)
......@@ -1434,6 +1449,7 @@ struct tree_constructor GTY(())
#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_SECTIONS(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 2)
#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