tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__CONDTEMP_.
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__CONDTEMP_. * tree.h (OMP_CLAUSE_DECL): Use OMP_CLAUSE__CONDTEMP_ instead of OMP_CLAUSE__REDUCTEMP_. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add OMP_CLAUSE__CONDTEMP_. (walk_tree_1): Handle OMP_CLAUSE__CONDTEMP_. * tree-pretty-print.c (dump_omp_clause): Likewise. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Likewise. * gimplify.c (enum gimplify_omp_var_data): Use hexadecimal constants instead of decimal. Add GOVD_LASTPRIVATE_CONDITIONAL. (gimplify_scan_omp_clauses): Don't reject lastprivate conditional on OMP_FOR. (gimplify_omp_for): Warn and disable conditional modifier from lastprivate on loop iterators. * omp-general.h (struct omp_for_data): Add lastprivate_conditional member. * omp-general.c (omp_extract_for_data): Initialize it. * omp-low.c (struct omp_context): Add lastprivate_conditional_map member. (delete_omp_context): Delete it. (lower_lastprivate_conditional_clauses): New function. (lower_lastprivate_clauses): Add BODY_P and CSTMT_LIST arguments, handle lastprivate conditional clauses. (lower_reduction_clauses): Add CLIST argument, emit it into the critical section if any. (lower_omp_sections): Adjust lower_lastprivate_clauses and lower_reduction_clauses callers. (lower_omp_for_lastprivate): Add CLIST argument, pass it through to lower_lastprivate_clauses. (lower_omp_for): Call lower_lastprivate_conditional_clauses, adjust lower_omp_for_lastprivate and lower_reduction_clauses callers, emit clist into a critical section if not emitted there already by lower_reduction_clauses. (lower_omp_taskreg, lower_omp_teams): Adjust lower_reduction_clauses callers. (lower_omp_1): Handle GIMPLE_ASSIGNs storing into lastprivate conditional variables. * omp-expand.c (determine_parallel_type): Punt if OMP_CLAUSE__CONDTEMP_ clause is present. (expand_omp_for_generic, expand_omp_for_static_nochunk, expand_omp_for_static_chunk): Handle lastprivate conditional. (expand_omp_for): Handle fd.lastprivate_conditional like fd.have_reductemp. gcc/testsuite/ * c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect sorry for omp for. * c-c++-common/gomp/lastprivate-conditional-3.c: New test. libgomp/ * testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c: New test. * testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c: New test. From-SVN: r271610
This commit is contained in:
parent
09b4000c7c
commit
6c7ae8c56f
@ -1,3 +1,50 @@
|
||||
2019-05-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* tree-core.h (enum omp_clause_code): Add OMP_CLAUSE__CONDTEMP_.
|
||||
* tree.h (OMP_CLAUSE_DECL): Use OMP_CLAUSE__CONDTEMP_ instead of
|
||||
OMP_CLAUSE__REDUCTEMP_.
|
||||
* tree.c (omp_clause_num_ops, omp_clause_code_name): Add
|
||||
OMP_CLAUSE__CONDTEMP_.
|
||||
(walk_tree_1): Handle OMP_CLAUSE__CONDTEMP_.
|
||||
* tree-pretty-print.c (dump_omp_clause): Likewise.
|
||||
* tree-nested.c (convert_nonlocal_omp_clauses,
|
||||
convert_local_omp_clauses): Likewise.
|
||||
* gimplify.c (enum gimplify_omp_var_data): Use hexadecimal constants
|
||||
instead of decimal. Add GOVD_LASTPRIVATE_CONDITIONAL.
|
||||
(gimplify_scan_omp_clauses): Don't reject lastprivate conditional
|
||||
on OMP_FOR.
|
||||
(gimplify_omp_for): Warn and disable conditional modifier from
|
||||
lastprivate on loop iterators.
|
||||
* omp-general.h (struct omp_for_data): Add lastprivate_conditional
|
||||
member.
|
||||
* omp-general.c (omp_extract_for_data): Initialize it.
|
||||
* omp-low.c (struct omp_context): Add lastprivate_conditional_map
|
||||
member.
|
||||
(delete_omp_context): Delete it.
|
||||
(lower_lastprivate_conditional_clauses): New function.
|
||||
(lower_lastprivate_clauses): Add BODY_P and CSTMT_LIST arguments,
|
||||
handle lastprivate conditional clauses.
|
||||
(lower_reduction_clauses): Add CLIST argument, emit it into
|
||||
the critical section if any.
|
||||
(lower_omp_sections): Adjust lower_lastprivate_clauses and
|
||||
lower_reduction_clauses callers.
|
||||
(lower_omp_for_lastprivate): Add CLIST argument, pass it through
|
||||
to lower_lastprivate_clauses.
|
||||
(lower_omp_for): Call lower_lastprivate_conditional_clauses, adjust
|
||||
lower_omp_for_lastprivate and lower_reduction_clauses callers, emit
|
||||
clist into a critical section if not emitted there already by
|
||||
lower_reduction_clauses.
|
||||
(lower_omp_taskreg, lower_omp_teams): Adjust lower_reduction_clauses
|
||||
callers.
|
||||
(lower_omp_1): Handle GIMPLE_ASSIGNs storing into lastprivate
|
||||
conditional variables.
|
||||
* omp-expand.c (determine_parallel_type): Punt if OMP_CLAUSE__CONDTEMP_
|
||||
clause is present.
|
||||
(expand_omp_for_generic, expand_omp_for_static_nochunk,
|
||||
expand_omp_for_static_chunk): Handle lastprivate conditional.
|
||||
(expand_omp_for): Handle fd.lastprivate_conditional like
|
||||
fd.have_reductemp.
|
||||
|
||||
2019-05-24 Andrew Stubbs <ams@codesourcery.com>
|
||||
|
||||
* config/gcn/gcn-run.c (main): Set a non-zero return value if the
|
||||
|
@ -71,47 +71,50 @@ static hash_set<tree> *asan_poisoned_variables = NULL;
|
||||
|
||||
enum gimplify_omp_var_data
|
||||
{
|
||||
GOVD_SEEN = 1,
|
||||
GOVD_EXPLICIT = 2,
|
||||
GOVD_SHARED = 4,
|
||||
GOVD_PRIVATE = 8,
|
||||
GOVD_FIRSTPRIVATE = 16,
|
||||
GOVD_LASTPRIVATE = 32,
|
||||
GOVD_REDUCTION = 64,
|
||||
GOVD_LOCAL = 128,
|
||||
GOVD_MAP = 256,
|
||||
GOVD_DEBUG_PRIVATE = 512,
|
||||
GOVD_PRIVATE_OUTER_REF = 1024,
|
||||
GOVD_LINEAR = 2048,
|
||||
GOVD_ALIGNED = 4096,
|
||||
GOVD_SEEN = 0x000001,
|
||||
GOVD_EXPLICIT = 0x000002,
|
||||
GOVD_SHARED = 0x000004,
|
||||
GOVD_PRIVATE = 0x000008,
|
||||
GOVD_FIRSTPRIVATE = 0x000010,
|
||||
GOVD_LASTPRIVATE = 0x000020,
|
||||
GOVD_REDUCTION = 0x000040,
|
||||
GOVD_LOCAL = 0x00080,
|
||||
GOVD_MAP = 0x000100,
|
||||
GOVD_DEBUG_PRIVATE = 0x000200,
|
||||
GOVD_PRIVATE_OUTER_REF = 0x000400,
|
||||
GOVD_LINEAR = 0x000800,
|
||||
GOVD_ALIGNED = 0x001000,
|
||||
|
||||
/* Flag for GOVD_MAP: don't copy back. */
|
||||
GOVD_MAP_TO_ONLY = 8192,
|
||||
GOVD_MAP_TO_ONLY = 0x002000,
|
||||
|
||||
/* Flag for GOVD_LINEAR or GOVD_LASTPRIVATE: no outer reference. */
|
||||
GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 16384,
|
||||
GOVD_LINEAR_LASTPRIVATE_NO_OUTER = 0x004000,
|
||||
|
||||
GOVD_MAP_0LEN_ARRAY = 32768,
|
||||
GOVD_MAP_0LEN_ARRAY = 0x008000,
|
||||
|
||||
/* Flag for GOVD_MAP, if it is always, to or always, tofrom mapping. */
|
||||
GOVD_MAP_ALWAYS_TO = 65536,
|
||||
GOVD_MAP_ALWAYS_TO = 0x010000,
|
||||
|
||||
/* Flag for shared vars that are or might be stored to in the region. */
|
||||
GOVD_WRITTEN = 131072,
|
||||
GOVD_WRITTEN = 0x020000,
|
||||
|
||||
/* Flag for GOVD_MAP, if it is a forced mapping. */
|
||||
GOVD_MAP_FORCE = 262144,
|
||||
GOVD_MAP_FORCE = 0x040000,
|
||||
|
||||
/* Flag for GOVD_MAP: must be present already. */
|
||||
GOVD_MAP_FORCE_PRESENT = 524288,
|
||||
GOVD_MAP_FORCE_PRESENT = 0x080000,
|
||||
|
||||
/* Flag for GOVD_MAP: only allocate. */
|
||||
GOVD_MAP_ALLOC_ONLY = 1048576,
|
||||
GOVD_MAP_ALLOC_ONLY = 0x100000,
|
||||
|
||||
/* Flag for GOVD_MAP: only copy back. */
|
||||
GOVD_MAP_FROM_ONLY = 2097152,
|
||||
GOVD_MAP_FROM_ONLY = 0x200000,
|
||||
|
||||
GOVD_NONTEMPORAL = 4194304,
|
||||
GOVD_NONTEMPORAL = 0x400000,
|
||||
|
||||
/* Flag for GOVD_LASTPRIVATE: conditional modifier. */
|
||||
GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
|
||||
|
||||
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
|
||||
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
|
||||
@ -8139,9 +8142,17 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
|
||||
}
|
||||
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
|
||||
sorry_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<conditional%> modifier on %<lastprivate%> clause "
|
||||
"not supported yet");
|
||||
{
|
||||
if (code == OMP_FOR)
|
||||
flags |= GOVD_LASTPRIVATE_CONDITIONAL;
|
||||
else
|
||||
{
|
||||
sorry_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<conditional%> modifier on %<lastprivate%> "
|
||||
"clause not supported yet");
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
|
||||
}
|
||||
}
|
||||
if (outer_ctx
|
||||
&& (outer_ctx->region_type == ORT_COMBINED_PARALLEL
|
||||
|| ((outer_ctx->region_type & ORT_COMBINED_TEAMS)
|
||||
@ -10770,7 +10781,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|
||||
1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
|
||||
!= 1));
|
||||
if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
|
||||
omp_notice_variable (gimplify_omp_ctxp, decl, true);
|
||||
{
|
||||
omp_notice_variable (gimplify_omp_ctxp, decl, true);
|
||||
if (n->value & GOVD_LASTPRIVATE_CONDITIONAL)
|
||||
for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
|
||||
OMP_CLAUSE_LASTPRIVATE);
|
||||
c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
|
||||
OMP_CLAUSE_LASTPRIVATE))
|
||||
if (OMP_CLAUSE_DECL (c3) == decl)
|
||||
{
|
||||
warning_at (OMP_CLAUSE_LOCATION (c3), 0,
|
||||
"conditional %<lastprivate%> on loop "
|
||||
"iterator %qD ignored", decl);
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
|
||||
n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
|
||||
}
|
||||
}
|
||||
else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
|
||||
{
|
||||
c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
|
||||
@ -11005,7 +11031,24 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|
||||
}
|
||||
}
|
||||
else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
|
||||
omp_notice_variable (gimplify_omp_ctxp, decl, true);
|
||||
{
|
||||
omp_notice_variable (gimplify_omp_ctxp, decl, true);
|
||||
splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
|
||||
(splay_tree_key) decl);
|
||||
if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL))
|
||||
for (tree c3 = omp_find_clause (OMP_FOR_CLAUSES (for_stmt),
|
||||
OMP_CLAUSE_LASTPRIVATE);
|
||||
c3; c3 = omp_find_clause (OMP_CLAUSE_CHAIN (c3),
|
||||
OMP_CLAUSE_LASTPRIVATE))
|
||||
if (OMP_CLAUSE_DECL (c3) == decl)
|
||||
{
|
||||
warning_at (OMP_CLAUSE_LOCATION (c3), 0,
|
||||
"conditional %<lastprivate%> on loop "
|
||||
"iterator %qD ignored", decl);
|
||||
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c3) = 0;
|
||||
n->value &= ~GOVD_LASTPRIVATE_CONDITIONAL;
|
||||
}
|
||||
}
|
||||
else
|
||||
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
|
||||
|
||||
|
300
gcc/omp-expand.c
300
gcc/omp-expand.c
@ -345,7 +345,8 @@ determine_parallel_type (struct omp_region *region)
|
||||
|| ((OMP_CLAUSE_SCHEDULE_KIND (c) & OMP_CLAUSE_SCHEDULE_MASK)
|
||||
== OMP_CLAUSE_SCHEDULE_STATIC)
|
||||
|| omp_find_clause (clauses, OMP_CLAUSE_ORDERED)
|
||||
|| omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_))
|
||||
|| omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_)
|
||||
|| omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_))
|
||||
return;
|
||||
}
|
||||
else if (region->inner->type == GIMPLE_OMP_SECTIONS
|
||||
@ -2679,16 +2680,17 @@ expand_omp_for_generic (struct omp_region *region,
|
||||
|
||||
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
|
||||
if (fd->ordered
|
||||
&& omp_find_clause (gimple_omp_for_clauses (gsi_stmt (gsi)),
|
||||
&& omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
|
||||
OMP_CLAUSE_LASTPRIVATE))
|
||||
ordered_lastprivate = false;
|
||||
tree reductions = NULL_TREE;
|
||||
tree mem = NULL_TREE;
|
||||
tree mem = NULL_TREE, cond_var = NULL_TREE, condtemp = NULL_TREE;
|
||||
tree memv = NULL_TREE;
|
||||
if (sched_arg)
|
||||
{
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
tree c = omp_find_clause (gimple_omp_for_clauses (gsi_stmt (gsi)),
|
||||
tree c = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
|
||||
OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (c);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
@ -2703,8 +2705,25 @@ expand_omp_for_generic (struct omp_region *region,
|
||||
}
|
||||
else
|
||||
reductions = null_pointer_node;
|
||||
/* For now. */
|
||||
mem = null_pointer_node;
|
||||
if (fd->lastprivate_conditional)
|
||||
{
|
||||
tree c = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
|
||||
OMP_CLAUSE__CONDTEMP_);
|
||||
condtemp = OMP_CLAUSE_DECL (c);
|
||||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
|
||||
cond_var = OMP_CLAUSE_DECL (c);
|
||||
tree type = TREE_TYPE (condtemp);
|
||||
memv = create_tmp_var (type);
|
||||
TREE_ADDRESSABLE (memv) = 1;
|
||||
unsigned HOST_WIDE_INT sz
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
sz *= fd->lastprivate_conditional;
|
||||
expand_omp_build_assign (&gsi, memv, build_int_cst (type, sz),
|
||||
false);
|
||||
mem = build_fold_addr_expr (memv);
|
||||
}
|
||||
else
|
||||
mem = null_pointer_node;
|
||||
}
|
||||
if (fd->collapse > 1 || fd->ordered)
|
||||
{
|
||||
@ -2959,6 +2978,8 @@ expand_omp_for_generic (struct omp_region *region,
|
||||
gsi_insert_before (&gsi, gimple_build_assign (arr, clobber),
|
||||
GSI_SAME_STMT);
|
||||
}
|
||||
if (fd->lastprivate_conditional)
|
||||
expand_omp_build_assign (&gsi, condtemp, memv, false);
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
gimple *g = gsi_stmt (gsi);
|
||||
@ -3029,6 +3050,35 @@ expand_omp_for_generic (struct omp_region *region,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (startvar, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
if (cond_var)
|
||||
{
|
||||
tree itype = TREE_TYPE (cond_var);
|
||||
/* For lastprivate(conditional:) itervar, we need some iteration
|
||||
counter that starts at unsigned non-zero and increases.
|
||||
Prefer as few IVs as possible, so if we can use startvar
|
||||
itself, use that, or startvar + constant (those would be
|
||||
incremented with step), and as last resort use the s0 + 1
|
||||
incremented by 1. */
|
||||
if ((fd->ordered && fd->collapse == 1)
|
||||
|| bias
|
||||
|| POINTER_TYPE_P (type)
|
||||
|| TREE_CODE (fd->loop.n1) != INTEGER_CST
|
||||
|| fd->loop.cond_code != LT_EXPR)
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, istart0),
|
||||
build_int_cst (itype, 1));
|
||||
else if (tree_int_cst_sgn (fd->loop.n1) == 1)
|
||||
t = fold_convert (itype, t);
|
||||
else
|
||||
{
|
||||
tree c = fold_convert (itype, fd->loop.n1);
|
||||
c = fold_build2 (MINUS_EXPR, itype, build_int_cst (itype, 1), c);
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, t), c);
|
||||
}
|
||||
t = force_gimple_operand_gsi (&gsi, t, false,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (cond_var, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
}
|
||||
|
||||
t = iend0;
|
||||
if (fd->ordered && fd->collapse == 1)
|
||||
@ -3213,6 +3263,25 @@ expand_omp_for_generic (struct omp_region *region,
|
||||
assign_stmt = gimple_build_assign (vback, t);
|
||||
gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
|
||||
|
||||
if (cond_var)
|
||||
{
|
||||
tree itype = TREE_TYPE (cond_var);
|
||||
tree t2;
|
||||
if ((fd->ordered && fd->collapse == 1)
|
||||
|| bias
|
||||
|| POINTER_TYPE_P (type)
|
||||
|| TREE_CODE (fd->loop.n1) != INTEGER_CST
|
||||
|| fd->loop.cond_code != LT_EXPR)
|
||||
t2 = build_int_cst (itype, 1);
|
||||
else
|
||||
t2 = fold_convert (itype, fd->loop.step);
|
||||
t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2);
|
||||
t2 = force_gimple_operand_gsi (&gsi, t2, false,
|
||||
NULL_TREE, true, GSI_SAME_STMT);
|
||||
assign_stmt = gimple_build_assign (cond_var, t2);
|
||||
gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
|
||||
}
|
||||
|
||||
if (fd->ordered && counts[fd->collapse - 1] == NULL_TREE)
|
||||
{
|
||||
tree tem;
|
||||
@ -3465,12 +3534,13 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
|
||||
basic_block body_bb, cont_bb, collapse_bb = NULL;
|
||||
basic_block fin_bb;
|
||||
gimple_stmt_iterator gsi;
|
||||
gimple_stmt_iterator gsi, gsip;
|
||||
edge ep;
|
||||
bool broken_loop = region->cont == NULL;
|
||||
tree *counts = NULL;
|
||||
tree n1, n2, step;
|
||||
tree reductions = NULL_TREE;
|
||||
tree cond_var = NULL_TREE;
|
||||
|
||||
itype = type = TREE_TYPE (fd->loop.v);
|
||||
if (POINTER_TYPE_P (type))
|
||||
@ -3495,6 +3565,8 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
/* Iteration space partitioning goes in ENTRY_BB. */
|
||||
gsi = gsi_last_nondebug_bb (entry_bb);
|
||||
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
|
||||
gsip = gsi;
|
||||
gsi_prev (&gsip);
|
||||
|
||||
if (fd->collapse > 1)
|
||||
{
|
||||
@ -3524,7 +3596,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
gcond *cond_stmt = gimple_build_cond (fd->loop.cond_code, n1, n2,
|
||||
NULL_TREE, NULL_TREE);
|
||||
NULL_TREE, NULL_TREE);
|
||||
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
|
||||
if (walk_tree (gimple_cond_lhs_ptr (cond_stmt),
|
||||
expand_omp_regimplify_p, NULL, NULL)
|
||||
@ -3554,28 +3626,64 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
gsi = gsi_last_bb (entry_bb);
|
||||
}
|
||||
|
||||
if (fd->have_reductemp)
|
||||
if (fd->have_reductemp || fd->lastprivate_conditional)
|
||||
{
|
||||
tree t1 = build_int_cst (long_integer_type_node, 0);
|
||||
tree t2 = build_int_cst (long_integer_type_node, 1);
|
||||
tree t3 = build_int_cstu (long_integer_type_node,
|
||||
(HOST_WIDE_INT_1U << 31) + 1);
|
||||
tree clauses = gimple_omp_for_clauses (fd->for_stmt);
|
||||
clauses = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (clauses);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
gimple *g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (clauses) = reductions;
|
||||
gimple_stmt_iterator gsi2 = gsi_for_stmt (g);
|
||||
gimple_stmt_iterator gsi2 = gsi_none ();
|
||||
gimple *g = NULL;
|
||||
tree mem = null_pointer_node, memv = NULL_TREE;
|
||||
tree condtemp = NULL_TREE;
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (c);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (c) = reductions;
|
||||
gsi2 = gsi_for_stmt (g);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gsi_end_p (gsip))
|
||||
gsi2 = gsi_after_labels (region->entry);
|
||||
else
|
||||
gsi2 = gsip;
|
||||
reductions = null_pointer_node;
|
||||
}
|
||||
if (fd->lastprivate_conditional)
|
||||
{
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
condtemp = OMP_CLAUSE_DECL (c);
|
||||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
|
||||
cond_var = OMP_CLAUSE_DECL (c);
|
||||
tree type = TREE_TYPE (condtemp);
|
||||
memv = create_tmp_var (type);
|
||||
TREE_ADDRESSABLE (memv) = 1;
|
||||
unsigned HOST_WIDE_INT sz
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
sz *= fd->lastprivate_conditional;
|
||||
expand_omp_build_assign (&gsi2, memv, build_int_cst (type, sz),
|
||||
false);
|
||||
mem = build_fold_addr_expr (memv);
|
||||
}
|
||||
tree t
|
||||
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_LOOP_START),
|
||||
9, t1, t2, t2, t3, t1, null_pointer_node,
|
||||
null_pointer_node, reductions, null_pointer_node);
|
||||
null_pointer_node, reductions, mem);
|
||||
force_gimple_operand_gsi (&gsi2, t, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
gsi_remove (&gsi2, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
if (fd->lastprivate_conditional)
|
||||
expand_omp_build_assign (&gsi2, condtemp, memv, false);
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
gsi_remove (&gsi2, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
}
|
||||
}
|
||||
switch (gimple_omp_for_kind (fd->for_stmt))
|
||||
{
|
||||
@ -3735,6 +3843,33 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (startvar, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
if (cond_var)
|
||||
{
|
||||
tree itype = TREE_TYPE (cond_var);
|
||||
/* For lastprivate(conditional:) itervar, we need some iteration
|
||||
counter that starts at unsigned non-zero and increases.
|
||||
Prefer as few IVs as possible, so if we can use startvar
|
||||
itself, use that, or startvar + constant (those would be
|
||||
incremented with step), and as last resort use the s0 + 1
|
||||
incremented by 1. */
|
||||
if (POINTER_TYPE_P (type)
|
||||
|| TREE_CODE (n1) != INTEGER_CST
|
||||
|| fd->loop.cond_code != LT_EXPR)
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, s0),
|
||||
build_int_cst (itype, 1));
|
||||
else if (tree_int_cst_sgn (n1) == 1)
|
||||
t = fold_convert (itype, t);
|
||||
else
|
||||
{
|
||||
tree c = fold_convert (itype, n1);
|
||||
c = fold_build2 (MINUS_EXPR, itype, build_int_cst (itype, 1), c);
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, t), c);
|
||||
}
|
||||
t = force_gimple_operand_gsi (&gsi, t, false,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (cond_var, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
}
|
||||
|
||||
t = fold_convert (itype, e0);
|
||||
t = fold_build2 (MULT_EXPR, itype, t, step);
|
||||
@ -3829,6 +3964,23 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
assign_stmt = gimple_build_assign (vback, t);
|
||||
gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
|
||||
|
||||
if (cond_var)
|
||||
{
|
||||
tree itype = TREE_TYPE (cond_var);
|
||||
tree t2;
|
||||
if (POINTER_TYPE_P (type)
|
||||
|| TREE_CODE (n1) != INTEGER_CST
|
||||
|| fd->loop.cond_code != LT_EXPR)
|
||||
t2 = build_int_cst (itype, 1);
|
||||
else
|
||||
t2 = fold_convert (itype, step);
|
||||
t2 = fold_build2 (PLUS_EXPR, itype, cond_var, t2);
|
||||
t2 = force_gimple_operand_gsi (&gsi, t2, false,
|
||||
NULL_TREE, true, GSI_SAME_STMT);
|
||||
assign_stmt = gimple_build_assign (cond_var, t2);
|
||||
gsi_insert_before (&gsi, assign_stmt, GSI_SAME_STMT);
|
||||
}
|
||||
|
||||
t = build2 (fd->loop.cond_code, boolean_type_node,
|
||||
DECL_P (vback) && TREE_ADDRESSABLE (vback)
|
||||
? t : vback, e);
|
||||
@ -3847,7 +3999,7 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
|
||||
{
|
||||
t = gimple_omp_return_lhs (gsi_stmt (gsi));
|
||||
if (fd->have_reductemp)
|
||||
if (fd->have_reductemp || fd->lastprivate_conditional)
|
||||
{
|
||||
tree fn;
|
||||
if (t)
|
||||
@ -3858,9 +4010,10 @@ expand_omp_for_static_nochunk (struct omp_region *region,
|
||||
if (t)
|
||||
{
|
||||
gimple_call_set_lhs (g, t);
|
||||
gsi_insert_after (&gsi, gimple_build_assign (reductions,
|
||||
NOP_EXPR, t),
|
||||
GSI_SAME_STMT);
|
||||
if (fd->have_reductemp)
|
||||
gsi_insert_after (&gsi, gimple_build_assign (reductions,
|
||||
NOP_EXPR, t),
|
||||
GSI_SAME_STMT);
|
||||
}
|
||||
gsi_insert_after (&gsi, g, GSI_SAME_STMT);
|
||||
}
|
||||
@ -3997,12 +4150,13 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
tree type, itype, vmain, vback, vextra;
|
||||
basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
|
||||
basic_block trip_update_bb = NULL, cont_bb, collapse_bb = NULL, fin_bb;
|
||||
gimple_stmt_iterator gsi;
|
||||
gimple_stmt_iterator gsi, gsip;
|
||||
edge se;
|
||||
bool broken_loop = region->cont == NULL;
|
||||
tree *counts = NULL;
|
||||
tree n1, n2, step;
|
||||
tree reductions = NULL_TREE;
|
||||
tree cond_var = NULL_TREE;
|
||||
|
||||
itype = type = TREE_TYPE (fd->loop.v);
|
||||
if (POINTER_TYPE_P (type))
|
||||
@ -4031,6 +4185,8 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
/* Trip and adjustment setup goes in ENTRY_BB. */
|
||||
gsi = gsi_last_nondebug_bb (entry_bb);
|
||||
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
|
||||
gsip = gsi;
|
||||
gsi_prev (&gsip);
|
||||
|
||||
if (fd->collapse > 1)
|
||||
{
|
||||
@ -4090,28 +4246,64 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
gsi = gsi_last_bb (entry_bb);
|
||||
}
|
||||
|
||||
if (fd->have_reductemp)
|
||||
if (fd->have_reductemp || fd->lastprivate_conditional)
|
||||
{
|
||||
tree t1 = build_int_cst (long_integer_type_node, 0);
|
||||
tree t2 = build_int_cst (long_integer_type_node, 1);
|
||||
tree t3 = build_int_cstu (long_integer_type_node,
|
||||
(HOST_WIDE_INT_1U << 31) + 1);
|
||||
tree clauses = gimple_omp_for_clauses (fd->for_stmt);
|
||||
clauses = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (clauses);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
gimple *g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (clauses) = reductions;
|
||||
gimple_stmt_iterator gsi2 = gsi_for_stmt (g);
|
||||
gimple_stmt_iterator gsi2 = gsi_none ();
|
||||
gimple *g = NULL;
|
||||
tree mem = null_pointer_node, memv = NULL_TREE;
|
||||
tree condtemp = NULL_TREE;
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_);
|
||||
reductions = OMP_CLAUSE_DECL (c);
|
||||
gcc_assert (TREE_CODE (reductions) == SSA_NAME);
|
||||
g = SSA_NAME_DEF_STMT (reductions);
|
||||
reductions = gimple_assign_rhs1 (g);
|
||||
OMP_CLAUSE_DECL (c) = reductions;
|
||||
gsi2 = gsi_for_stmt (g);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gsi_end_p (gsip))
|
||||
gsi2 = gsi_after_labels (region->entry);
|
||||
else
|
||||
gsi2 = gsip;
|
||||
reductions = null_pointer_node;
|
||||
}
|
||||
if (fd->lastprivate_conditional)
|
||||
{
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
condtemp = OMP_CLAUSE_DECL (c);
|
||||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
|
||||
cond_var = OMP_CLAUSE_DECL (c);
|
||||
tree type = TREE_TYPE (condtemp);
|
||||
memv = create_tmp_var (type);
|
||||
TREE_ADDRESSABLE (memv) = 1;
|
||||
unsigned HOST_WIDE_INT sz
|
||||
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type)));
|
||||
sz *= fd->lastprivate_conditional;
|
||||
expand_omp_build_assign (&gsi2, memv, build_int_cst (type, sz),
|
||||
false);
|
||||
mem = build_fold_addr_expr (memv);
|
||||
}
|
||||
tree t
|
||||
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_LOOP_START),
|
||||
9, t1, t2, t2, t3, t1, null_pointer_node,
|
||||
null_pointer_node, reductions, null_pointer_node);
|
||||
null_pointer_node, reductions, mem);
|
||||
force_gimple_operand_gsi (&gsi2, t, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
gsi_remove (&gsi2, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
if (fd->lastprivate_conditional)
|
||||
expand_omp_build_assign (&gsi2, condtemp, memv, false);
|
||||
if (fd->have_reductemp)
|
||||
{
|
||||
gsi_remove (&gsi2, true);
|
||||
release_ssa_name (gimple_assign_lhs (g));
|
||||
}
|
||||
}
|
||||
switch (gimple_omp_for_kind (fd->for_stmt))
|
||||
{
|
||||
@ -4286,6 +4478,33 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (startvar, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
if (cond_var)
|
||||
{
|
||||
tree itype = TREE_TYPE (cond_var);
|
||||
/* For lastprivate(conditional:) itervar, we need some iteration
|
||||
counter that starts at unsigned non-zero and increases.
|
||||
Prefer as few IVs as possible, so if we can use startvar
|
||||
itself, use that, or startvar + constant (those would be
|
||||
incremented with step), and as last resort use the s0 + 1
|
||||
incremented by 1. */
|
||||
if (POINTER_TYPE_P (type)
|
||||
|| TREE_CODE (n1) != INTEGER_CST
|
||||
|| fd->loop.cond_code != LT_EXPR)
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, s0),
|
||||
build_int_cst (itype, 1));
|
||||
else if (tree_int_cst_sgn (n1) == 1)
|
||||
t = fold_convert (itype, t);
|
||||
else
|
||||
{
|
||||
tree c = fold_convert (itype, n1);
|
||||
c = fold_build2 (MINUS_EXPR, itype, build_int_cst (itype, 1), c);
|
||||
t = fold_build2 (PLUS_EXPR, itype, fold_convert (itype, t), c);
|
||||
}
|
||||
t = force_gimple_operand_gsi (&gsi, t, false,
|
||||
NULL_TREE, false, GSI_CONTINUE_LINKING);
|
||||
assign_stmt = gimple_build_assign (cond_var, t);
|
||||
gsi_insert_after (&gsi, assign_stmt, GSI_CONTINUE_LINKING);
|
||||
}
|
||||
|
||||
t = fold_convert (itype, e0);
|
||||
t = fold_build2 (MULT_EXPR, itype, t, step);
|
||||
@ -4416,7 +4635,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
|
||||
{
|
||||
t = gimple_omp_return_lhs (gsi_stmt (gsi));
|
||||
if (fd->have_reductemp)
|
||||
if (fd->have_reductemp || fd->lastprivate_conditional)
|
||||
{
|
||||
tree fn;
|
||||
if (t)
|
||||
@ -4427,9 +4646,10 @@ expand_omp_for_static_chunk (struct omp_region *region,
|
||||
if (t)
|
||||
{
|
||||
gimple_call_set_lhs (g, t);
|
||||
gsi_insert_after (&gsi, gimple_build_assign (reductions,
|
||||
NOP_EXPR, t),
|
||||
GSI_SAME_STMT);
|
||||
if (fd->have_reductemp)
|
||||
gsi_insert_after (&gsi, gimple_build_assign (reductions,
|
||||
NOP_EXPR, t),
|
||||
GSI_SAME_STMT);
|
||||
}
|
||||
gsi_insert_after (&gsi, g, GSI_SAME_STMT);
|
||||
}
|
||||
@ -6043,7 +6263,7 @@ expand_omp_for (struct omp_region *region, gimple *inner_stmt)
|
||||
else
|
||||
start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
|
||||
next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
|
||||
if (fd.have_reductemp)
|
||||
if (fd.have_reductemp || fd.lastprivate_conditional)
|
||||
{
|
||||
if (fd.ordered)
|
||||
start_ix = (int)BUILT_IN_GOMP_LOOP_DOACROSS_START;
|
||||
|
@ -168,6 +168,7 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
||||
fd->have_nowait = distribute || simd;
|
||||
fd->have_ordered = false;
|
||||
fd->have_reductemp = false;
|
||||
fd->lastprivate_conditional = 0;
|
||||
fd->tiling = NULL_TREE;
|
||||
fd->collapse = 1;
|
||||
fd->ordered = 0;
|
||||
@ -220,6 +221,11 @@ omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
|
||||
break;
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
fd->have_reductemp = true;
|
||||
break;
|
||||
case OMP_CLAUSE_LASTPRIVATE:
|
||||
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (t))
|
||||
fd->lastprivate_conditional++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ struct omp_for_data
|
||||
int collapse; /* Collapsed loops, 1 for a non-collapsed loop. */
|
||||
int ordered;
|
||||
bool have_nowait, have_ordered, simd_schedule, have_reductemp;
|
||||
int lastprivate_conditional;
|
||||
unsigned char sched_modifiers;
|
||||
enum omp_clause_schedule_kind sched_kind;
|
||||
struct omp_for_data_loop *loops;
|
||||
|
188
gcc/omp-low.c
188
gcc/omp-low.c
@ -119,10 +119,14 @@ struct omp_context
|
||||
and then offsets (if constant, otherwise NULL) for each entry. */
|
||||
vec<tree> task_reductions;
|
||||
|
||||
/* And a hash map from the reduction clauses to the registered array
|
||||
/* A hash map from the reduction clauses to the registered array
|
||||
elts. */
|
||||
hash_map<tree, unsigned> *task_reduction_map;
|
||||
|
||||
/* And a hash map from the lastprivate(conditional:) variables to their
|
||||
corresponding tracking loop iteration variables. */
|
||||
hash_map<tree, tree> *lastprivate_conditional_map;
|
||||
|
||||
/* Nesting depth of this context. Used to beautify error messages re
|
||||
invalid gotos. The outermost ctx is depth 1, with depth 0 being
|
||||
reserved for the main body of the function. */
|
||||
@ -955,6 +959,8 @@ delete_omp_context (splay_tree_value value)
|
||||
delete ctx->task_reduction_map;
|
||||
}
|
||||
|
||||
delete ctx->lastprivate_conditional_map;
|
||||
|
||||
XDELETE (ctx);
|
||||
}
|
||||
|
||||
@ -5358,18 +5364,72 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
|
||||
}
|
||||
}
|
||||
|
||||
/* Create temporary variables for lastprivate(conditional:) implementation
|
||||
in context CTX with CLAUSES. */
|
||||
|
||||
static void
|
||||
lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
|
||||
{
|
||||
struct omp_for_data fd;
|
||||
tree iter_type = NULL_TREE;
|
||||
tree cond_ptr = NULL_TREE;
|
||||
tree iter_var = NULL_TREE;
|
||||
for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|
||||
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
|
||||
{
|
||||
if (iter_type == NULL)
|
||||
{
|
||||
omp_extract_for_data (as_a <gomp_for *> (ctx->stmt), &fd, NULL);
|
||||
iter_type = unsigned_type_for (fd.iter_type);
|
||||
cond_ptr = create_tmp_var_raw (build_pointer_type (iter_type));
|
||||
DECL_CONTEXT (cond_ptr) = current_function_decl;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (cond_ptr) = 1;
|
||||
DECL_CHAIN (cond_ptr) = ctx->block_vars;
|
||||
ctx->block_vars = cond_ptr;
|
||||
iter_var = create_tmp_var_raw (iter_type);
|
||||
DECL_CONTEXT (iter_var) = current_function_decl;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (iter_var) = 1;
|
||||
DECL_CHAIN (iter_var) = ctx->block_vars;
|
||||
ctx->block_vars = iter_var;
|
||||
tree c2
|
||||
= build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
|
||||
tree c3
|
||||
= build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
|
||||
OMP_CLAUSE_DECL (c2) = cond_ptr;
|
||||
OMP_CLAUSE_DECL (c3) = iter_var;
|
||||
OMP_CLAUSE_CHAIN (c2) = c3;
|
||||
OMP_CLAUSE_CHAIN (c3) = *clauses;
|
||||
*clauses = c2;
|
||||
ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
|
||||
}
|
||||
tree v = create_tmp_var_raw (iter_type);
|
||||
DECL_CONTEXT (v) = current_function_decl;
|
||||
DECL_SEEN_IN_BIND_EXPR_P (v) = 1;
|
||||
DECL_CHAIN (v) = ctx->block_vars;
|
||||
ctx->block_vars = v;
|
||||
tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
|
||||
ctx->lastprivate_conditional_map->put (o, v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Generate code to implement the LASTPRIVATE clauses. This is used for
|
||||
both parallel and workshare constructs. PREDICATE may be NULL if it's
|
||||
always true. */
|
||||
always true. BODY_P is the sequence to insert early initialization
|
||||
if needed, STMT_LIST is where the non-conditional lastprivate handling
|
||||
goes into and CSTMT_LIST is a sequence that needs to be run in a critical
|
||||
section. */
|
||||
|
||||
static void
|
||||
lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
|
||||
gimple_seq *stmt_list, gimple_seq *cstmt_list,
|
||||
omp_context *ctx)
|
||||
{
|
||||
tree x, c, label = NULL, orig_clauses = clauses;
|
||||
bool par_clauses = false;
|
||||
tree simduid = NULL, lastlane = NULL, simtcond = NULL, simtlast = NULL;
|
||||
unsigned HOST_WIDE_INT conditional_off = 0;
|
||||
|
||||
/* Early exit if there are no lastprivate or linear clauses. */
|
||||
for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
|
||||
@ -5448,10 +5508,43 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
|
||||
}
|
||||
|
||||
tree cond_ptr = NULL_TREE;
|
||||
for (c = clauses; c ;)
|
||||
{
|
||||
tree var, new_var;
|
||||
location_t clause_loc = OMP_CLAUSE_LOCATION (c);
|
||||
gimple_seq *this_stmt_list = stmt_list;
|
||||
tree lab2 = NULL_TREE;
|
||||
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|
||||
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
|
||||
{
|
||||
gcc_assert (body_p && ctx->lastprivate_conditional_map);
|
||||
if (cond_ptr == NULL_TREE)
|
||||
{
|
||||
cond_ptr = omp_find_clause (orig_clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
cond_ptr = OMP_CLAUSE_DECL (cond_ptr);
|
||||
}
|
||||
tree type = TREE_TYPE (TREE_TYPE (cond_ptr));
|
||||
tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
|
||||
tree v = *ctx->lastprivate_conditional_map->get (o);
|
||||
gimplify_assign (v, build_zero_cst (type), body_p);
|
||||
this_stmt_list = cstmt_list;
|
||||
tree mem = build2 (MEM_REF, type, cond_ptr,
|
||||
build_int_cst (TREE_TYPE (cond_ptr),
|
||||
conditional_off));
|
||||
tree mem2 = copy_node (mem);
|
||||
conditional_off += tree_to_uhwi (TYPE_SIZE_UNIT (type));
|
||||
gimple_seq seq = NULL;
|
||||
mem = force_gimple_operand (mem, &seq, true, NULL_TREE);
|
||||
gimple_seq_add_seq (this_stmt_list, seq);
|
||||
tree lab1 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
lab2 = create_artificial_label (UNKNOWN_LOCATION);
|
||||
gimple *g = gimple_build_cond (GT_EXPR, v, mem, lab1, lab2);
|
||||
gimple_seq_add_stmt (this_stmt_list, g);
|
||||
gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab1));
|
||||
gimplify_assign (mem2, v, this_stmt_list);
|
||||
}
|
||||
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|
||||
|| (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
|
||||
@ -5493,7 +5586,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
2, simduid,
|
||||
TREE_OPERAND (val, 1));
|
||||
gimple_call_set_lhs (g, lastlane);
|
||||
gimple_seq_add_stmt (stmt_list, g);
|
||||
gimple_seq_add_stmt (this_stmt_list, g);
|
||||
}
|
||||
new_var = build4 (ARRAY_REF, TREE_TYPE (val),
|
||||
TREE_OPERAND (val, 0), lastlane,
|
||||
@ -5511,13 +5604,13 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
gcall *g = gimple_build_call_internal
|
||||
(IFN_GOMP_SIMT_LAST_LANE, 1, simtcond);
|
||||
gimple_call_set_lhs (g, simtlast);
|
||||
gimple_seq_add_stmt (stmt_list, g);
|
||||
gimple_seq_add_stmt (this_stmt_list, g);
|
||||
}
|
||||
x = build_call_expr_internal_loc
|
||||
(UNKNOWN_LOCATION, IFN_GOMP_SIMT_XCHG_IDX,
|
||||
TREE_TYPE (val), 2, val, simtlast);
|
||||
new_var = unshare_expr (new_var);
|
||||
gimplify_assign (new_var, x, stmt_list);
|
||||
gimplify_assign (new_var, x, this_stmt_list);
|
||||
new_var = unshare_expr (new_var);
|
||||
}
|
||||
|
||||
@ -5525,7 +5618,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
&& OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
|
||||
{
|
||||
lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
|
||||
gimple_seq_add_seq (stmt_list,
|
||||
gimple_seq_add_seq (this_stmt_list,
|
||||
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
|
||||
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
|
||||
}
|
||||
@ -5533,7 +5626,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
&& OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
|
||||
{
|
||||
lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
|
||||
gimple_seq_add_seq (stmt_list,
|
||||
gimple_seq_add_seq (this_stmt_list,
|
||||
OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
|
||||
OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
|
||||
}
|
||||
@ -5553,8 +5646,12 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
|
||||
if (omp_is_reference (var))
|
||||
new_var = build_simple_mem_ref_loc (clause_loc, new_var);
|
||||
x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
|
||||
gimplify_and_add (x, stmt_list);
|
||||
gimplify_and_add (x, this_stmt_list);
|
||||
|
||||
if (lab2)
|
||||
gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab2));
|
||||
}
|
||||
|
||||
c = OMP_CLAUSE_CHAIN (c);
|
||||
if (c == NULL && !par_clauses)
|
||||
{
|
||||
@ -5802,10 +5899,15 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner,
|
||||
gimple_seq_add_seq (join_seq, after_join);
|
||||
}
|
||||
|
||||
/* Generate code to implement the REDUCTION clauses. */
|
||||
/* Generate code to implement the REDUCTION clauses, append it
|
||||
to STMT_SEQP. CLIST if non-NULL is a pointer to a sequence
|
||||
that should be emitted also inside of the critical section,
|
||||
in that case clear *CLIST afterwards, otherwise leave it as is
|
||||
and let the caller emit it itself. */
|
||||
|
||||
static void
|
||||
lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
|
||||
lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp,
|
||||
gimple_seq *clist, omp_context *ctx)
|
||||
{
|
||||
gimple_seq sub_seq = NULL;
|
||||
gimple *stmt;
|
||||
@ -6047,6 +6149,12 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
|
||||
|
||||
gimple_seq_add_seq (stmt_seqp, sub_seq);
|
||||
|
||||
if (clist)
|
||||
{
|
||||
gimple_seq_add_seq (stmt_seqp, *clist);
|
||||
*clist = NULL;
|
||||
}
|
||||
|
||||
stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
|
||||
0);
|
||||
gimple_seq_add_stmt (stmt_seqp, stmt);
|
||||
@ -6684,7 +6792,7 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
{
|
||||
gimple_seq l = NULL;
|
||||
lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
|
||||
&l, ctx);
|
||||
NULL, &l, NULL, ctx);
|
||||
gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
|
||||
gimple_omp_section_set_last (sec_start);
|
||||
}
|
||||
@ -6697,7 +6805,8 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
bind = gimple_build_bind (NULL, new_body, block);
|
||||
|
||||
olist = NULL;
|
||||
lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
|
||||
lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist,
|
||||
NULL, ctx);
|
||||
|
||||
block = make_node (BLOCK);
|
||||
new_stmt = gimple_build_bind (NULL, NULL, block);
|
||||
@ -8074,11 +8183,13 @@ lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
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 *DLIST, iterator initialization is appended to
|
||||
*BODY_P. */
|
||||
*BODY_P. *CLIST is for lastprivate(conditional:) code that needs
|
||||
to be emitted in a critical section. */
|
||||
|
||||
static void
|
||||
lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
|
||||
gimple_seq *dlist, struct omp_context *ctx)
|
||||
gimple_seq *dlist, gimple_seq *clist,
|
||||
struct omp_context *ctx)
|
||||
{
|
||||
tree clauses, cond, vinit;
|
||||
enum tree_code cond_code;
|
||||
@ -8158,7 +8269,7 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
|
||||
|
||||
clauses = gimple_omp_for_clauses (fd->for_stmt);
|
||||
stmts = NULL;
|
||||
lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
|
||||
lower_lastprivate_clauses (clauses, cond, body_p, &stmts, clist, ctx);
|
||||
if (!gimple_seq_empty_p (stmts))
|
||||
{
|
||||
gimple_seq_add_seq (&stmts, *dlist);
|
||||
@ -8190,7 +8301,7 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
gomp_for *stmt = as_a <gomp_for *> (gsi_stmt (*gsi_p));
|
||||
gbind *new_stmt;
|
||||
gimple_seq omp_for_body, body, dlist, tred_ilist = NULL, tred_dlist = NULL;
|
||||
gimple_seq cnt_list = NULL;
|
||||
gimple_seq cnt_list = NULL, clist = NULL;
|
||||
gimple_seq oacc_head = NULL, oacc_tail = NULL;
|
||||
size_t i;
|
||||
|
||||
@ -8308,6 +8419,9 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
gimple_seq_add_seq (rclauses ? &tred_ilist : &body,
|
||||
gimple_omp_for_pre_body (stmt));
|
||||
|
||||
lower_lastprivate_conditional_clauses (gimple_omp_for_clauses_ptr (stmt),
|
||||
ctx);
|
||||
|
||||
lower_omp (gimple_omp_body_ptr (stmt), ctx);
|
||||
|
||||
/* Lower the header expressions. At this point, we can assume that
|
||||
@ -8353,7 +8467,7 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
if (oacc_head)
|
||||
gimple_seq_add_seq (&body, oacc_head);
|
||||
|
||||
lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
|
||||
lower_omp_for_lastprivate (&fd, &body, &dlist, &clist, ctx);
|
||||
|
||||
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
|
||||
for (tree c = gimple_omp_for_clauses (stmt); c; c = OMP_CLAUSE_CHAIN (c))
|
||||
@ -8378,7 +8492,18 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
fd.loop.v));
|
||||
|
||||
/* After the loop, add exit clauses. */
|
||||
lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
|
||||
lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, &clist, ctx);
|
||||
|
||||
if (clist)
|
||||
{
|
||||
tree fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
|
||||
gcall *g = gimple_build_call (fndecl, 0);
|
||||
gimple_seq_add_stmt (&body, g);
|
||||
gimple_seq_add_seq (&body, clist);
|
||||
fndecl = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
|
||||
g = gimple_build_call (fndecl, 0);
|
||||
gimple_seq_add_stmt (&body, g);
|
||||
}
|
||||
|
||||
if (ctx->cancellable)
|
||||
gimple_seq_add_stmt (&body, gimple_build_label (ctx->cancel_label));
|
||||
@ -9000,7 +9125,7 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx, NULL);
|
||||
lower_omp (&par_body, ctx);
|
||||
if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
|
||||
lower_reduction_clauses (clauses, &par_rlist, ctx);
|
||||
lower_reduction_clauses (clauses, &par_rlist, NULL, ctx);
|
||||
|
||||
/* Declare all the variables created by mapping and the variables
|
||||
declared in the scope of the parallel body. */
|
||||
@ -10189,7 +10314,8 @@ lower_omp_teams (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt),
|
||||
&bind_body, &dlist, ctx, NULL);
|
||||
lower_omp (gimple_omp_body_ptr (teams_stmt), ctx);
|
||||
lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist, ctx);
|
||||
lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt), &olist,
|
||||
NULL, ctx);
|
||||
if (!gimple_omp_teams_grid_phony (teams_stmt))
|
||||
{
|
||||
gimple_seq_add_stmt (&bind_body, teams_stmt);
|
||||
@ -10498,8 +10624,28 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
goto regimplify;
|
||||
|
||||
case GIMPLE_ASSIGN:
|
||||
if (ctx && ctx->lastprivate_conditional_map)
|
||||
{
|
||||
tree lhs = get_base_address (gimple_assign_lhs (stmt));
|
||||
if (DECL_P (lhs))
|
||||
if (tree *v = ctx->lastprivate_conditional_map->get (lhs))
|
||||
{
|
||||
tree clauses
|
||||
= gimple_omp_for_clauses (as_a <gomp_for *> (ctx->stmt));
|
||||
tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
|
||||
c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
|
||||
OMP_CLAUSE__CONDTEMP_);
|
||||
gimple *g = gimple_build_assign (*v, OMP_CLAUSE_DECL (c));
|
||||
gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
|
||||
}
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
||||
default:
|
||||
regimplify:
|
||||
if ((ctx || task_shared_vars)
|
||||
&& walk_gimple_op (stmt, lower_omp_regimplify_p,
|
||||
ctx ? NULL : &wi))
|
||||
|
@ -1,3 +1,9 @@
|
||||
2019-05-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
|
||||
sorry for omp for.
|
||||
* c-c++-common/gomp/lastprivate-conditional-3.c: New test.
|
||||
|
||||
2019-05-24 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR testsuite/90607
|
||||
|
@ -4,7 +4,7 @@ foo (int *p)
|
||||
int a = -1, b = -1, c = -1, d = -1, e = -1, f = -1, g = -1, h = -1;
|
||||
int i;
|
||||
#pragma omp parallel
|
||||
#pragma omp for lastprivate (conditional: a) /* { dg-message "not supported yet" } */
|
||||
#pragma omp for lastprivate (conditional: a)
|
||||
for (i = 0; i < 32; i++)
|
||||
if (p[i])
|
||||
a = i;
|
||||
|
26
gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c
Normal file
26
gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c
Normal file
@ -0,0 +1,26 @@
|
||||
void
|
||||
foo (int *p)
|
||||
{
|
||||
int i, j, k;
|
||||
#pragma omp parallel
|
||||
{
|
||||
#pragma omp for lastprivate (conditional: i) /* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
|
||||
for (i = 0; i < 32; i++)
|
||||
;
|
||||
#pragma omp for collapse (3) lastprivate (conditional: i) /* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
|
||||
for (i = 0; i < 32; i++)
|
||||
for (j = 0; j < 32; ++j)
|
||||
for (k = 0; k < 2; ++k)
|
||||
;
|
||||
#pragma omp for collapse (3) lastprivate (conditional: j) /* { dg-warning "conditional 'lastprivate' on loop iterator 'j' ignored" } */
|
||||
for (i = 0; i < 32; i++)
|
||||
for (j = 0; j < 32; ++j)
|
||||
for (k = 0; k < 2; ++k)
|
||||
;
|
||||
#pragma omp for collapse (3) lastprivate (conditional: k) /* { dg-warning "conditional 'lastprivate' on loop iterator 'k' ignored" } */
|
||||
for (i = 0; i < 32; i++)
|
||||
for (j = 0; j < 32; ++j)
|
||||
for (k = 0; k < 2; ++k)
|
||||
;
|
||||
}
|
||||
}
|
@ -343,6 +343,9 @@ enum omp_clause_code {
|
||||
/* Internal clause: temporary for task reductions. */
|
||||
OMP_CLAUSE__REDUCTEMP_,
|
||||
|
||||
/* Internal clause: temporary for lastprivate(conditional:). */
|
||||
OMP_CLAUSE__CONDTEMP_,
|
||||
|
||||
/* OpenACC/OpenMP clause: if (scalar-expression). */
|
||||
OMP_CLAUSE_IF,
|
||||
|
||||
|
@ -1369,6 +1369,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
|
||||
function decomposition happens before that. */
|
||||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SIMDUID_:
|
||||
case OMP_CLAUSE__GRIDDIM_:
|
||||
case OMP_CLAUSE__SIMT_:
|
||||
@ -2096,6 +2097,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
|
||||
function decomposition happens before that. */
|
||||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SIMDUID_:
|
||||
case OMP_CLAUSE__GRIDDIM_:
|
||||
case OMP_CLAUSE__SIMT_:
|
||||
|
@ -466,6 +466,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
name = "_reductemp_";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
name = "_condtemp_";
|
||||
goto print_remap;
|
||||
case OMP_CLAUSE_TO_DECLARE:
|
||||
name = "to";
|
||||
goto print_remap;
|
||||
|
@ -308,6 +308,7 @@ unsigned const char omp_clause_num_ops[] =
|
||||
0, /* OMP_CLAUSE_SEQ */
|
||||
1, /* OMP_CLAUSE__LOOPTEMP_ */
|
||||
1, /* OMP_CLAUSE__REDUCTEMP_ */
|
||||
1, /* OMP_CLAUSE__CONDTEMP_ */
|
||||
1, /* OMP_CLAUSE_IF */
|
||||
1, /* OMP_CLAUSE_NUM_THREADS */
|
||||
1, /* OMP_CLAUSE_SCHEDULE */
|
||||
@ -385,6 +386,7 @@ const char * const omp_clause_code_name[] =
|
||||
"seq",
|
||||
"_looptemp_",
|
||||
"_reductemp_",
|
||||
"_condtemp_",
|
||||
"if",
|
||||
"num_threads",
|
||||
"schedule",
|
||||
@ -12304,6 +12306,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
|
||||
case OMP_CLAUSE_IS_DEVICE_PTR:
|
||||
case OMP_CLAUSE__LOOPTEMP_:
|
||||
case OMP_CLAUSE__REDUCTEMP_:
|
||||
case OMP_CLAUSE__CONDTEMP_:
|
||||
case OMP_CLAUSE__SIMDUID_:
|
||||
WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
|
||||
/* FALLTHRU */
|
||||
|
@ -1439,7 +1439,7 @@ class auto_suppress_location_wrappers
|
||||
#define OMP_CLAUSE_DECL(NODE) \
|
||||
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
|
||||
OMP_CLAUSE_PRIVATE, \
|
||||
OMP_CLAUSE__REDUCTEMP_), 0)
|
||||
OMP_CLAUSE__CONDTEMP_), 0)
|
||||
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
|
||||
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
|
||||
!= UNKNOWN_LOCATION)
|
||||
|
@ -1,5 +1,8 @@
|
||||
2019-05-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* testsuite/libgomp.c-c++-common/lastprivate-conditional-1.c: New test.
|
||||
* testsuite/libgomp.c-c++-common/lastprivate-conditional-2.c: New test.
|
||||
|
||||
PR libgomp/90585
|
||||
* plugin/plugin-hsa.c: Include gstdint.h. Include inttypes.h only if
|
||||
HAVE_INTTYPES_H is defined.
|
||||
|
@ -0,0 +1,144 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target tls_runtime } */
|
||||
/* { dg-additional-options "-std=gnu99" {target c } } */
|
||||
|
||||
#include <omp.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3;
|
||||
long long w, w2, w3, p, p2, p3;
|
||||
int *x, *x2, *x3;
|
||||
short y, y2, y3;
|
||||
int z;
|
||||
int thr1, thr2;
|
||||
#pragma omp threadprivate (thr1, thr2)
|
||||
|
||||
void
|
||||
foo (int *a, long long int b, long long int c)
|
||||
{
|
||||
int i;
|
||||
long long j;
|
||||
#pragma omp for lastprivate (conditional: u, x) nowait
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
if ((a[i] % 5) == 3)
|
||||
u = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x = &a[i];
|
||||
}
|
||||
#pragma omp for nowait lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v = i;
|
||||
else
|
||||
++r;
|
||||
}
|
||||
#pragma omp for schedule (monotonic: static) lastprivate (conditional: w) nowait
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
if ((a[j] % 13) == 5)
|
||||
w = j * 2;
|
||||
#pragma omp for schedule (auto) lastprivate (conditional: p) collapse(3)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p = i * 10000 + j * 100 + k;
|
||||
|
||||
#pragma omp for schedule (nonmonotonic: static, 2) nowait lastprivate (conditional: u2, x2)
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
if ((a[i] % 5) == 3)
|
||||
u2 = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x2 = &a[i];
|
||||
}
|
||||
#pragma omp for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s2;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v2 = i;
|
||||
else
|
||||
++r2;
|
||||
}
|
||||
#pragma omp for lastprivate (conditional: w2) schedule (static, 1) nowait
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
if ((a[j] % 13) == 5)
|
||||
w2 = j * 2;
|
||||
#pragma omp for schedule (static, 3) collapse (3) lastprivate (conditional: p2)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p2 = i * 10000 + j * 100 + k;
|
||||
|
||||
#pragma omp for lastprivate (conditional: u3, x3) nowait schedule (runtime)
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
if ((a[i] % 5) == 3)
|
||||
u3 = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x3 = &a[i];
|
||||
}
|
||||
#pragma omp for nowait lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s3;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v3 = i;
|
||||
else
|
||||
++r3;
|
||||
}
|
||||
#pragma omp for schedule (monotonic: guided, 3) lastprivate (conditional: w3) nowait
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
if ((a[j] % 13) == 5)
|
||||
w3 = j * 2;
|
||||
#pragma omp for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p3 = i * 10000 + j * 100 + k;
|
||||
|
||||
/* Nasty testcase, verify that even a no-op assignment is accounted
|
||||
for in lastprivate(conditional:). */
|
||||
#pragma omp for schedule (monotonic: static, 2) firstprivate (z) \
|
||||
lastprivate (conditional: z)
|
||||
for (int k = -2000; k < 8000; ++k)
|
||||
{
|
||||
if (k < 3000 && (k & 3) == 1)
|
||||
{
|
||||
z = k;
|
||||
thr1 = k;
|
||||
}
|
||||
else if (k == 7931)
|
||||
{
|
||||
z = z;
|
||||
thr2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (thr2 && z != thr1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int a[128], i;
|
||||
volatile int j = 0;
|
||||
for (i = 0; i < 128; i++)
|
||||
a[i] = i;
|
||||
w = 1234;
|
||||
#pragma omp parallel
|
||||
foo (a, j, j + 1);
|
||||
if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
|
||||
abort ();
|
||||
if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
|
||||
abort ();
|
||||
if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-require-effective-target tls_runtime } */
|
||||
/* { dg-additional-options "-std=gnu99" {target c } } */
|
||||
|
||||
#include <omp.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3, t;
|
||||
long long w, w2, w3, p, p2, p3;
|
||||
int *x, *x2, *x3;
|
||||
short y, y2, y3;
|
||||
int z;
|
||||
int thr1, thr2;
|
||||
#pragma omp threadprivate (thr1, thr2)
|
||||
|
||||
void
|
||||
foo (int *a, long long int b, long long int c)
|
||||
{
|
||||
int i;
|
||||
long long j;
|
||||
#pragma omp for lastprivate (conditional: u, x) reduction (task, +: t)
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
++t;
|
||||
if ((a[i] % 5) == 3)
|
||||
u = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x = &a[i];
|
||||
}
|
||||
#pragma omp for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static) reduction (task, +: t)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s;
|
||||
++t;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v = i;
|
||||
else
|
||||
++r;
|
||||
}
|
||||
#pragma omp for schedule (monotonic: static) lastprivate (conditional: w) reduction (task, +: t)
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
{
|
||||
if ((a[j] % 13) == 5)
|
||||
w = j * 2;
|
||||
++t;
|
||||
}
|
||||
#pragma omp for schedule (auto) lastprivate (conditional: p) collapse(3) reduction (task, +: t)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
{
|
||||
++t;
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p = i * 10000 + j * 100 + k;
|
||||
}
|
||||
|
||||
#pragma omp for schedule (nonmonotonic: static, 2) reduction (task, +: t) lastprivate (conditional: u2, x2)
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
if ((a[i] % 5) == 3)
|
||||
u2 = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x2 = &a[i];
|
||||
t++;
|
||||
}
|
||||
#pragma omp for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2) reduction (task, +: t)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s2;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v2 = i;
|
||||
else
|
||||
++r2;
|
||||
t++;
|
||||
}
|
||||
#pragma omp for lastprivate (conditional: w2) schedule (static, 1) reduction (task, +: t)
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
{
|
||||
if ((a[j] % 13) == 5)
|
||||
w2 = j * 2;
|
||||
t += 1;
|
||||
}
|
||||
#pragma omp for schedule (static, 3) collapse (3) reduction (task, +: t) lastprivate (conditional: p2)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
{
|
||||
++t;
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p2 = i * 10000 + j * 100 + k;
|
||||
}
|
||||
|
||||
#pragma omp for lastprivate (conditional: u3, x3) reduction (task, +: t) schedule (runtime)
|
||||
for (i = 15; i < 64; i++)
|
||||
{
|
||||
t = t + 1;
|
||||
if ((a[i] % 5) == 3)
|
||||
u3 = i;
|
||||
if ((a[i] % 7) == 2)
|
||||
x3 = &a[i];
|
||||
}
|
||||
#pragma omp for reduction (task, +: t) lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
|
||||
for (i = -3; i < 119; i += 2)
|
||||
{
|
||||
++s3;
|
||||
if ((a[i + 4] % 11) == 9)
|
||||
v3 = i;
|
||||
else
|
||||
++r3;
|
||||
++t;
|
||||
}
|
||||
#pragma omp for schedule (monotonic: guided, 3) lastprivate (conditional: w3) reduction (task, +: t)
|
||||
for (j = b; j < b + 115 * c; j += (b & 3) + 7)
|
||||
{
|
||||
if ((a[j] % 13) == 5)
|
||||
w3 = j * 2;
|
||||
t++;
|
||||
}
|
||||
#pragma omp for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3) reduction (task, +: t)
|
||||
for (i = -5; i < (int) (b + 5); i += 2)
|
||||
for (j = b + 12 + c; j > b; --j)
|
||||
for (int k = 0; k < 5; k += c)
|
||||
{
|
||||
++t;
|
||||
if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
|
||||
p3 = i * 10000 + j * 100 + k;
|
||||
}
|
||||
|
||||
/* Nasty testcase, verify that even a no-op assignment is accounted
|
||||
for in lastprivate(conditional:). */
|
||||
#pragma omp for schedule (monotonic: static, 2) firstprivate (z) \
|
||||
lastprivate (conditional: z) reduction (task, +: t)
|
||||
for (int k = -2000; k < 8000; ++k)
|
||||
{
|
||||
t++;
|
||||
if (k < 3000 && (k & 3) == 1)
|
||||
{
|
||||
z = k;
|
||||
thr1 = k;
|
||||
}
|
||||
else if (k == 7931)
|
||||
{
|
||||
z = z;
|
||||
thr2 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (thr2 && z != thr1)
|
||||
abort ();
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int a[128], i;
|
||||
volatile int j = 0;
|
||||
for (i = 0; i < 128; i++)
|
||||
a[i] = i;
|
||||
w = 1234;
|
||||
#pragma omp parallel
|
||||
foo (a, j, j + 1);
|
||||
if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
|
||||
abort ();
|
||||
if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
|
||||
abort ();
|
||||
if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
|
||||
abort ();
|
||||
if (t != 11356)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user