marshalling to implement data sharing and copying clauses.
Contributed by Diego Novillo <dnovillo@redhat.com>
- Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
tree copy = build_decl (VAR_DECL, name, type);
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
- DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (var);
+ DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
TREE_USED (copy) = 1;
static void
build_omp_barrier (tree *stmt_list)
{
- tree t;
-
- t = built_in_decls[BUILT_IN_GOMP_BARRIER];
- t = build_function_call_expr (t, NULL);
+ tree t = build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
gimplify_and_add (t, stmt_list);
}
static void
lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
- omp_context *ctx)
+ omp_context *ctx)
{
tree_stmt_iterator diter;
- tree c, dtor, copyin_seq, x, args, ptr;
+ tree c, dtor, copyin_seq, x, ptr;
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
gcc_assert (DECL_P (ptr));
x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
- args = tree_cons (NULL, x, NULL);
- x = built_in_decls[BUILT_IN_ALLOCA];
- x = build_function_call_expr (x, args);
+ x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
x = fold_convert (TREE_TYPE (ptr), x);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, ptr, x);
+ x = build_gimple_modify_stmt (ptr, x);
gimplify_and_add (x, ilist);
}
else if (is_reference (var))
}
else
{
- args = tree_cons (NULL, x, NULL);
- x = built_in_decls[BUILT_IN_ALLOCA];
- x = build_function_call_expr (x, args);
+ x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
x = fold_convert (TREE_TYPE (new_var), x);
}
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, new_var, x);
+ x = build_gimple_modify_stmt (new_var, x);
gimplify_and_add (x, ilist);
new_var = build_fold_indirect_ref (new_var);
{
x = omp_reduction_init (c, TREE_TYPE (new_var));
gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, new_var, x);
+ x = build_gimple_modify_stmt (new_var, x);
gimplify_and_add (x, ilist);
}
break;
but it certainly is to C++ operator=. */
if (copyin_seq)
{
- x = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
x = build2 (NE_EXPR, boolean_type_node, x,
build_int_cst (TREE_TYPE (x), 0));
x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
{
x = build2 (code, TREE_TYPE (ref), ref, new_var);
ref = build_outer_var_ref (var, ctx);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, ref, x);
+ x = build_gimple_modify_stmt (ref, x);
append_to_statement_list (x, &sub_list);
}
}
- x = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
gimplify_and_add (x, stmt_list);
gimplify_and_add (sub_list, stmt_list);
- x = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
gimplify_and_add (x, stmt_list);
}
ref = build_sender_ref (var, ctx);
x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
x = by_ref ? build_fold_addr_expr (x) : x;
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, ref, x);
+ x = build_gimple_modify_stmt (ref, x);
gimplify_and_add (x, slist);
ref = build_receiver_ref (var, by_ref, ctx);
{
ref = build_sender_ref (val, ctx);
x = by_ref ? build_fold_addr_expr (var) : var;
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, ref, x);
+ x = build_gimple_modify_stmt (ref, x);
gimplify_and_add (x, ilist);
}
if (do_out)
{
ref = build_sender_ref (val, ctx);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, var, ref);
+ x = build_gimple_modify_stmt (var, ref);
gimplify_and_add (x, olist);
}
}
{
x = build_sender_ref (ovar, ctx);
var = build_fold_addr_expr (var);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, x, var);
+ x = build_gimple_modify_stmt (x, var);
gimplify_and_add (x, ilist);
}
else
{
x = build_sender_ref (ovar, ctx);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, x, var);
+ x = build_gimple_modify_stmt (x, var);
gimplify_and_add (x, ilist);
x = build_sender_ref (ovar, ctx);
- x = build2 (GIMPLE_MODIFY_STMT, void_type_node, var, x);
+ x = build_gimple_modify_stmt (var, x);
gimplify_and_add (x, olist);
}
}
expand_parallel_call (struct omp_region *region, basic_block bb,
tree entry_stmt, tree ws_args)
{
- tree t, args, val, cond, c, list, clauses;
+ tree t, t1, t2, val, cond, c, list, clauses;
block_stmt_iterator si;
int start_ix;
si = bsi_start (then_bb);
t = build1 (LABEL_EXPR, void_type_node, then_lab);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp, val);
+ t = build_gimple_modify_stmt (tmp, val);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
si = bsi_start (else_bb);
t = build1 (LABEL_EXPR, void_type_node, else_lab);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, tmp,
- build_int_cst (unsigned_type_node, 1));
+ t = build_gimple_modify_stmt (tmp,
+ build_int_cst (unsigned_type_node, 1));
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
}
list = NULL_TREE;
- args = tree_cons (NULL, val, NULL);
t = OMP_PARALLEL_DATA_ARG (entry_stmt);
if (t == NULL)
- t = null_pointer_node;
+ t1 = null_pointer_node;
else
- t = build_fold_addr_expr (t);
- args = tree_cons (NULL, t, args);
- t = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
- args = tree_cons (NULL, t, args);
+ t1 = build_fold_addr_expr (t);
+ t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
if (ws_args)
- args = chainon (args, ws_args);
+ {
+ tree args = tree_cons (NULL, t2,
+ tree_cons (NULL, t1,
+ tree_cons (NULL, val, ws_args)));
+ t = build_function_call_expr (built_in_decls[start_ix], args);
+ }
+ else
+ t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
- t = built_in_decls[start_ix];
- t = build_function_call_expr (t, args);
gimplify_and_add (t, &list);
t = OMP_PARALLEL_DATA_ARG (entry_stmt);
t = null_pointer_node;
else
t = build_fold_addr_expr (t);
- args = tree_cons (NULL, t, NULL);
- t = build_function_call_expr (OMP_PARALLEL_FN (entry_stmt), args);
+ t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
gimplify_and_add (t, &list);
- t = built_in_decls[BUILT_IN_GOMP_PARALLEL_END];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
gimplify_and_add (t, &list);
si = bsi_last (bb);
if (lang_protect_cleanup_actions)
t = lang_protect_cleanup_actions ();
else
- {
- t = built_in_decls[BUILT_IN_TRAP];
- t = build_function_call_expr (t, NULL);
- }
+ t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
EH_FILTER_MUST_NOT_THROW (f) = 1;
gimplify_and_add (t, &EH_FILTER_FAILURE (f));
new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
if (exit_bb)
single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
- cgraph_add_new_function (child_fn);
+ DECL_STRUCT_FUNCTION (child_fn)->curr_properties
+ = cfun->curr_properties;
+ cgraph_add_new_function (child_fn, true);
/* Convert OMP_RETURN into a RETURN_EXPR. */
if (exit_bb)
{
tree l0, l1, l2 = NULL, l3 = NULL;
tree type, istart0, iend0, iend;
- tree t, args, list;
+ tree t, list;
basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
basic_block l2_bb = NULL, l3_bb = NULL;
block_stmt_iterator si;
gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
if (!in_combined_parallel)
{
+ tree t0, t1, t2, t3, t4;
/* If this is not a combined parallel loop, emit a call to
GOMP_loop_foo_start in ENTRY_BB. */
list = alloc_stmt_list ();
- t = build_fold_addr_expr (iend0);
- args = tree_cons (NULL, t, NULL);
- t = build_fold_addr_expr (istart0);
- args = tree_cons (NULL, t, args);
+ t4 = build_fold_addr_expr (iend0);
+ t3 = build_fold_addr_expr (istart0);
+ t2 = fold_convert (long_integer_type_node, fd->step);
+ t1 = fold_convert (long_integer_type_node, fd->n2);
+ t0 = fold_convert (long_integer_type_node, fd->n1);
if (fd->chunk_size)
{
t = fold_convert (long_integer_type_node, fd->chunk_size);
- args = tree_cons (NULL, t, args);
+ t = build_call_expr (built_in_decls[start_fn], 6,
+ t0, t1, t2, t, t3, t4);
}
- t = fold_convert (long_integer_type_node, fd->step);
- args = tree_cons (NULL, t, args);
- t = fold_convert (long_integer_type_node, fd->n2);
- args = tree_cons (NULL, t, args);
- t = fold_convert (long_integer_type_node, fd->n1);
- args = tree_cons (NULL, t, args);
- t = build_function_call_expr (built_in_decls[start_fn], args);
+ else
+ t = build_call_expr (built_in_decls[start_fn], 5,
+ t0, t1, t2, t3, t4);
t = get_formal_tmp_var (t, &list);
if (cont_bb)
{
/* Iteration setup for sequential loop goes in L0_BB. */
list = alloc_stmt_list ();
t = fold_convert (type, istart0);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = fold_convert (type, iend0);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, iend, t);
+ t = build_gimple_modify_stmt (iend, t);
gimplify_and_add (t, &list);
si = bsi_start (l0_bb);
list = alloc_stmt_list ();
t = build2 (PLUS_EXPR, type, fd->v, fd->step);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
/* Emit code to get the next parallel iteration in L2_BB. */
list = alloc_stmt_list ();
- t = build_fold_addr_expr (iend0);
- args = tree_cons (NULL, t, NULL);
- t = build_fold_addr_expr (istart0);
- args = tree_cons (NULL, t, args);
- t = build_function_call_expr (built_in_decls[next_fn], args);
+ t = build_call_expr (built_in_decls[next_fn], 2,
+ build_fold_addr_expr (istart0),
+ build_fold_addr_expr (iend0));
t = get_formal_tmp_var (t, &list);
t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
build_and_jump (&l3));
t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
else
t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (t, 0);
bsi_insert_after (&si, t, BSI_SAME_STMT);
bsi_remove (&si, true);
/* Iteration space partitioning goes in ENTRY_BB. */
list = alloc_stmt_list ();
- t = built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
t = fold_convert (type, t);
nthreads = get_formal_tmp_var (t, &list);
- t = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
t = fold_convert (type, t);
threadid = get_formal_tmp_var (t, &list);
t = fold_convert (type, s0);
t = build2 (MULT_EXPR, type, t, fd->step);
t = build2 (PLUS_EXPR, type, t, fd->n1);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = fold_convert (type, e0);
list = alloc_stmt_list ();
t = build2 (PLUS_EXPR, type, fd->v, fd->step);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
/* Trip and adjustment setup goes in ENTRY_BB. */
list = alloc_stmt_list ();
- t = built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
t = fold_convert (type, t);
nthreads = get_formal_tmp_var (t, &list);
- t = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
t = fold_convert (type, t);
threadid = get_formal_tmp_var (t, &list);
t = fold_convert (type, s0);
t = build2 (MULT_EXPR, type, t, fd->step);
t = build2 (PLUS_EXPR, type, t, fd->n1);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = fold_convert (type, e0);
list = alloc_stmt_list ();
t = build2 (PLUS_EXPR, type, fd->v, fd->step);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, t);
+ t = build_gimple_modify_stmt (fd->v, t);
gimplify_and_add (t, &list);
t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
t = build_int_cst (type, 1);
t = build2 (PLUS_EXPR, type, trip, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, trip, t);
+ t = build_gimple_modify_stmt (trip, t);
gimplify_and_add (t, &list);
si = bsi_start (trip_update_bb);
/* If we are not inside a combined parallel+sections region,
call GOMP_sections_start. */
t = build_int_cst (unsigned_type_node, len);
- t = tree_cons (NULL, t, NULL);
u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
- t = build_function_call_expr (u, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, v, t);
+ t = build_call_expr (u, 1, t);
+ t = build_gimple_modify_stmt (v, t);
bsi_insert_after (&si, t, BSI_SAME_STMT);
}
bsi_remove (&si, true);
make_edge (l0_bb, default_bb, 0);
si = bsi_start (default_bb);
- t = built_in_decls[BUILT_IN_TRAP];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
/* Code to get the next section goes in L1_BB. */
si = bsi_last (l1_bb);
gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
- t = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
- t = build_function_call_expr (t, NULL);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, v, t);
+ t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
+ t = build_gimple_modify_stmt (v, t);
bsi_insert_after (&si, t, BSI_SAME_STMT);
bsi_remove (&si, true);
}
t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
else
t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (t, 0);
bsi_insert_after (&si, t, BSI_SAME_STMT);
bsi_remove (&si, true);
}
{
tree t;
- t = built_in_decls[BUILT_IN_GOMP_SINGLE_START];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
t = build3 (COND_EXPR, void_type_node, t,
OMP_SINGLE_BODY (single_stmt), NULL);
gimplify_and_add (t, pre_p);
static void
lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
{
- tree ptr_type, t, args, l0, l1, l2, copyin_seq;
+ tree ptr_type, t, l0, l1, l2, copyin_seq;
ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
l1 = create_artificial_label ();
l2 = create_artificial_label ();
- t = built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START];
- t = build_function_call_expr (t, NULL);
+ t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
t = fold_convert (ptr_type, t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, ctx->receiver_decl, t);
+ t = build_gimple_modify_stmt (ctx->receiver_decl, t);
gimplify_and_add (t, pre_p);
t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
©in_seq, ctx);
t = build_fold_addr_expr (ctx->sender_decl);
- args = tree_cons (NULL, t, NULL);
- t = built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END];
- t = build_function_call_expr (t, args);
+ t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
gimplify_and_add (t, pre_p);
t = build_and_jump (&l2);
append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
- x = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
gimplify_and_add (x, &BIND_EXPR_BODY (bind));
append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
- x = built_in_decls[BUILT_IN_GOMP_ORDERED_START];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
gimplify_and_add (x, &BIND_EXPR_BODY (bind));
lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
OMP_ORDERED_BODY (stmt) = NULL;
- x = built_in_decls[BUILT_IN_GOMP_ORDERED_END];
- x = build_function_call_expr (x, NULL);
+ x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
gimplify_and_add (x, &BIND_EXPR_BODY (bind));
x = make_node (OMP_RETURN);
name = OMP_CRITICAL_NAME (stmt);
if (name)
{
- tree decl, args;
+ tree decl;
splay_tree_node n;
if (!critical_name_mutexes)
DECL_COMMON (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
- cgraph_varpool_finalize_decl (decl);
+ varpool_finalize_decl (decl);
splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
(splay_tree_value) decl);
else
decl = (tree) n->value;
- args = tree_cons (NULL, build_fold_addr_expr (decl), NULL);
lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
- lock = build_function_call_expr (lock, args);
+ lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
- args = tree_cons (NULL, build_fold_addr_expr (decl), NULL);
unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
- unlock = build_function_call_expr (unlock, args);
+ unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
}
else
{
lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
- lock = build_function_call_expr (lock, NULL);
+ lock = build_call_expr (lock, 0);
unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
- unlock = build_function_call_expr (unlock, NULL);
+ unlock = build_call_expr (unlock, 0);
}
push_gimplify_context ();
/* A subroutine of lower_omp_for. Generate code to emit the predicate
for a lastprivate clause. Given a loop control predicate of (V
cond N2), we gate the clause on (!(V cond N2)). The lowered form
- is appended to *BODY_P. */
+ is appended to *DLIST, iterator initialization is appended to
+ *BODY_P. */
static void
lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
- struct omp_context *ctx)
+ tree *dlist, struct omp_context *ctx)
{
- tree clauses, cond;
+ tree clauses, cond, stmts, vinit, t;
enum tree_code cond_code;
cond_code = fd->cond_code;
cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
clauses = OMP_FOR_CLAUSES (fd->for_stmt);
- lower_lastprivate_clauses (clauses, cond, body_p, ctx);
+ stmts = NULL;
+ lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
+ if (stmts != NULL)
+ {
+ append_to_statement_list (stmts, dlist);
+
+ /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
+ vinit = fd->n1;
+ if (cond_code == EQ_EXPR
+ && host_integerp (fd->n2, 0)
+ && ! integer_zerop (fd->n2))
+ vinit = build_int_cst (TREE_TYPE (fd->v), 0);
+
+ /* Initialize the iterator variable, so that threads that don't execute
+ any iterations don't execute the lastprivate clauses by accident. */
+ t = build_gimple_modify_stmt (fd->v, vinit);
+ gimplify_and_add (t, body_p);
+ }
}
/* Once lowered, extract the bounds and clauses. */
extract_omp_for_data (stmt, &fd);
+ lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
+
append_to_statement_list (stmt, body_p);
append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
append_to_statement_list (t, body_p);
/* After the loop, add exit clauses. */
- lower_omp_for_lastprivate (&fd, &dlist, ctx);
lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
append_to_statement_list (dlist, body_p);
t = build_fold_addr_expr (ctx->sender_decl);
/* fixup_child_record_type might have changed receiver_decl's type. */
t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
- t = build2 (GIMPLE_MODIFY_STMT, void_type_node, ctx->receiver_decl, t);
+ t = build_gimple_modify_stmt (ctx->receiver_decl, t);
append_to_statement_list (t, &new_body);
}
tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
}
+/* Copy EXP into a temporary. Insert the initialization statement before TSI. */
+
+static tree
+init_tmp_var (tree exp, tree_stmt_iterator *tsi)
+{
+ tree t, stmt;
+
+ t = create_tmp_var (TREE_TYPE (exp), NULL);
+ DECL_GIMPLE_REG_P (t) = 1;
+ stmt = build_gimple_modify_stmt (t, exp);
+ SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
+ tsi_link_before (tsi, stmt, TSI_SAME_STMT);
+
+ return t;
+}
+
+/* Similarly, but copy from the temporary and insert the statement
+ after the iterator. */
+
+static tree
+save_tmp_var (tree exp, tree_stmt_iterator *tsi)
+{
+ tree t, stmt;
+
+ t = create_tmp_var (TREE_TYPE (exp), NULL);
+ DECL_GIMPLE_REG_P (t) = 1;
+ stmt = build_gimple_modify_stmt (exp, t);
+ SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
+ tsi_link_after (tsi, stmt, TSI_SAME_STMT);
+
+ return t;
+}
/* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
case VAR_DECL:
if (ctx && DECL_HAS_VALUE_EXPR_P (t))
- lower_regimplify (tp, wi);
+ {
+ lower_regimplify (&t, wi);
+ if (wi->val_only)
+ {
+ if (wi->is_lhs)
+ t = save_tmp_var (t, &wi->tsi);
+ else
+ t = init_tmp_var (t, &wi->tsi);
+ }
+ *tp = t;
+ }
break;
case ADDR_EXPR: