* gimplify.c (enum gimplify_omp_var_data): Add GOVD_CONDTEMP.
(gimplify_adjust_omp_clauses_1): Handle GOVD_CONDTEMP.
(gimplify_omp_for): If worksharing loop with lastprivate conditional
is nested inside of parallel region, add _condtemp_ clause to both.
* tree-nested.c (convert_nonlocal_omp_clauses,
convert_local_omp_clauses): Ignore OMP_CLAUSE__CONDTEMP_ instead of
assertion failure.
* omp-general.h (struct omp_for_data): Add have_pointer_condtemp
member.
* omp-general.c (omp_extract_for_data): Compute it.
* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE__CONDTEMP_.
(lower_rec_input_clauses): Likewise.
(lower_lastprivate_conditional_clauses): If OMP_CLAUSE__CONDTEMP_
clause is already present, just add one further one after it.
(lower_lastprivate_clauses): Handle cond_ptr with array type.
(lower_send_shared_vars): Clear _condtemp_ vars.
(lower_omp_1) <case GIMPLE_ASSIGN>: Handle target data like critical
or section or taskgroup.
* omp-expand.c (determine_parallel_type): Disallow combining only if
first OMP_CLAUSE__CONDTEMP_ has pointer type. Disallow combining
of parallel sections if OMP_CLAUSE__CONDTEMP_ is present.
(expand_omp_for_generic, expand_omp_for_static_nochunk,
expand_omp_for_static_chunk, expand_omp_for): Use
fd->have_pointer_condtemp instead of fd->lastprivate_conditional to
determine if a special set of API routines are needed and if condtemp
needs to be initialized, while always initialize cond_var if
fd->lastprivate_conditional is non-zero.
From-SVN: r271791
+2019-05-30 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (enum gimplify_omp_var_data): Add GOVD_CONDTEMP.
+ (gimplify_adjust_omp_clauses_1): Handle GOVD_CONDTEMP.
+ (gimplify_omp_for): If worksharing loop with lastprivate conditional
+ is nested inside of parallel region, add _condtemp_ clause to both.
+ * tree-nested.c (convert_nonlocal_omp_clauses,
+ convert_local_omp_clauses): Ignore OMP_CLAUSE__CONDTEMP_ instead of
+ assertion failure.
+ * omp-general.h (struct omp_for_data): Add have_pointer_condtemp
+ member.
+ * omp-general.c (omp_extract_for_data): Compute it.
+ * omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE__CONDTEMP_.
+ (lower_rec_input_clauses): Likewise.
+ (lower_lastprivate_conditional_clauses): If OMP_CLAUSE__CONDTEMP_
+ clause is already present, just add one further one after it.
+ (lower_lastprivate_clauses): Handle cond_ptr with array type.
+ (lower_send_shared_vars): Clear _condtemp_ vars.
+ (lower_omp_1) <case GIMPLE_ASSIGN>: Handle target data like critical
+ or section or taskgroup.
+ * omp-expand.c (determine_parallel_type): Disallow combining only if
+ first OMP_CLAUSE__CONDTEMP_ has pointer type. Disallow combining
+ of parallel sections if OMP_CLAUSE__CONDTEMP_ is present.
+ (expand_omp_for_generic, expand_omp_for_static_nochunk,
+ expand_omp_for_static_chunk, expand_omp_for): Use
+ fd->have_pointer_condtemp instead of fd->lastprivate_conditional to
+ determine if a special set of API routines are needed and if condtemp
+ needs to be initialized, while always initialize cond_var if
+ fd->lastprivate_conditional is non-zero.
+
2019-05-30 Bill Schmidt <wschmidt@linux.ibm.com>
Michael Meissner <meissner@linux.ibm.com>
/* Flag for GOVD_LASTPRIVATE: conditional modifier. */
GOVD_LASTPRIVATE_CONDITIONAL = 0x800000,
+ GOVD_CONDTEMP = 0x1000000,
+
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
| GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
| GOVD_LOCAL)
code = OMP_CLAUSE_LASTPRIVATE;
else if (flags & (GOVD_ALIGNED | GOVD_NONTEMPORAL))
return 0;
+ else if (flags & GOVD_CONDTEMP)
+ {
+ code = OMP_CLAUSE__CONDTEMP_;
+ gimple_add_tmp_var (decl);
+ }
else
gcc_unreachable ();
}
else
gimplify_seq_add_stmt (pre_p, gfor);
+
+ if (TREE_CODE (orig_for_stmt) == OMP_FOR)
+ {
+ struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+ unsigned lastprivate_conditional = 0;
+ while (ctx
+ && (ctx->region_type == ORT_TARGET_DATA
+ || ctx->region_type == ORT_TASKGROUP))
+ ctx = ctx->outer_context;
+ if (ctx && (ctx->region_type & ORT_PARALLEL) != 0)
+ for (tree c = gimple_omp_for_clauses (gfor);
+ c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
+ ++lastprivate_conditional;
+ if (lastprivate_conditional)
+ {
+ struct omp_for_data fd;
+ omp_extract_for_data (gfor, &fd, NULL);
+ tree type = build_array_type_nelts (unsigned_type_for (fd.iter_type),
+ lastprivate_conditional);
+ tree var = create_tmp_var_raw (type);
+ tree c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
+ OMP_CLAUSE_DECL (c) = var;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
+ gimple_omp_for_set_clauses (gfor, c);
+ omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
+ }
+ }
+
if (ret != GS_ALL_DONE)
return GS_ERROR;
*expr_p = NULL_TREE;
== OMP_CLAUSE_SCHEDULE_STATIC)
|| omp_find_clause (clauses, OMP_CLAUSE_ORDERED)
|| omp_find_clause (clauses, OMP_CLAUSE__REDUCTEMP_)
- || omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_))
+ || ((c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_))
+ && POINTER_TYPE_P (TREE_TYPE (OMP_CLAUSE_DECL (c)))))
return;
}
else if (region->inner->type == GIMPLE_OMP_SECTIONS
- && omp_find_clause (gimple_omp_sections_clauses (ws_stmt),
- OMP_CLAUSE__REDUCTEMP_))
+ && (omp_find_clause (gimple_omp_sections_clauses (ws_stmt),
+ OMP_CLAUSE__REDUCTEMP_)
+ || omp_find_clause (gimple_omp_sections_clauses (ws_stmt),
+ OMP_CLAUSE__CONDTEMP_)))
return;
region->is_combined_parallel = true;
tree reductions = NULL_TREE;
tree mem = NULL_TREE, cond_var = NULL_TREE, condtemp = NULL_TREE;
tree memv = NULL_TREE;
+ if (fd->lastprivate_conditional)
+ {
+ tree c = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
+ OMP_CLAUSE__CONDTEMP_);
+ if (fd->have_pointer_condtemp)
+ condtemp = OMP_CLAUSE_DECL (c);
+ c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
+ cond_var = OMP_CLAUSE_DECL (c);
+ }
if (sched_arg)
{
if (fd->have_reductemp)
}
else
reductions = null_pointer_node;
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
{
- 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;
gsi_insert_before (&gsi, gimple_build_assign (arr, clobber),
GSI_SAME_STMT);
}
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
expand_omp_build_assign (&gsi, condtemp, memv, false);
if (fd->have_reductemp)
{
tree *counts = NULL;
tree n1, n2, step;
tree reductions = NULL_TREE;
- tree cond_var = NULL_TREE;
+ tree cond_var = NULL_TREE, condtemp = NULL_TREE;
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
gsi = gsi_last_bb (entry_bb);
}
- if (fd->have_reductemp || fd->lastprivate_conditional)
+ if (fd->lastprivate_conditional)
+ {
+ tree clauses = gimple_omp_for_clauses (fd->for_stmt);
+ tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
+ if (fd->have_pointer_condtemp)
+ condtemp = OMP_CLAUSE_DECL (c);
+ c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
+ cond_var = OMP_CLAUSE_DECL (c);
+ }
+ if (fd->have_reductemp || fd->have_pointer_condtemp)
{
tree t1 = build_int_cst (long_integer_type_node, 0);
tree t2 = build_int_cst (long_integer_type_node, 1);
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_);
gsi2 = gsip;
reductions = null_pointer_node;
}
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
{
- 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;
null_pointer_node, reductions, mem);
force_gimple_operand_gsi (&gsi2, t, true, NULL_TREE,
true, GSI_SAME_STMT);
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
expand_omp_build_assign (&gsi2, condtemp, memv, false);
if (fd->have_reductemp)
{
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
{
t = gimple_omp_return_lhs (gsi_stmt (gsi));
- if (fd->have_reductemp || fd->lastprivate_conditional)
+ if (fd->have_reductemp || fd->have_pointer_condtemp)
{
tree fn;
if (t)
tree *counts = NULL;
tree n1, n2, step;
tree reductions = NULL_TREE;
- tree cond_var = NULL_TREE;
+ tree cond_var = NULL_TREE, condtemp = NULL_TREE;
itype = type = TREE_TYPE (fd->loop.v);
if (POINTER_TYPE_P (type))
gsi = gsi_last_bb (entry_bb);
}
- if (fd->have_reductemp || fd->lastprivate_conditional)
+ if (fd->lastprivate_conditional)
+ {
+ tree clauses = gimple_omp_for_clauses (fd->for_stmt);
+ tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
+ if (fd->have_pointer_condtemp)
+ condtemp = OMP_CLAUSE_DECL (c);
+ c = omp_find_clause (OMP_CLAUSE_CHAIN (c), OMP_CLAUSE__CONDTEMP_);
+ cond_var = OMP_CLAUSE_DECL (c);
+ }
+ if (fd->have_reductemp || fd->have_pointer_condtemp)
{
tree t1 = build_int_cst (long_integer_type_node, 0);
tree t2 = build_int_cst (long_integer_type_node, 1);
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_);
gsi2 = gsip;
reductions = null_pointer_node;
}
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
{
- 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;
null_pointer_node, reductions, mem);
force_gimple_operand_gsi (&gsi2, t, true, NULL_TREE,
true, GSI_SAME_STMT);
- if (fd->lastprivate_conditional)
+ if (fd->have_pointer_condtemp)
expand_omp_build_assign (&gsi2, condtemp, memv, false);
if (fd->have_reductemp)
{
if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
{
t = gimple_omp_return_lhs (gsi_stmt (gsi));
- if (fd->have_reductemp || fd->lastprivate_conditional)
+ if (fd->have_reductemp || fd->have_pointer_condtemp)
{
tree fn;
if (t)
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 || fd.lastprivate_conditional)
+ if (fd.have_reductemp || fd.have_pointer_condtemp)
{
if (fd.ordered)
start_ix = (int)BUILT_IN_GOMP_LOOP_DOACROSS_START;
fd->have_nowait = distribute || simd;
fd->have_ordered = false;
fd->have_reductemp = false;
+ fd->have_pointer_condtemp = false;
fd->lastprivate_conditional = 0;
fd->tiling = NULL_TREE;
fd->collapse = 1;
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (t))
fd->lastprivate_conditional++;
break;
+ case OMP_CLAUSE__CONDTEMP_:
+ if (POINTER_TYPE_P (TREE_TYPE (OMP_CLAUSE_DECL (t))))
+ fd->have_pointer_condtemp = true;
+ break;
default:
break;
}
int collapse; /* Collapsed loops, 1 for a non-collapsed loop. */
int ordered;
bool have_nowait, have_ordered, simd_schedule, have_reductemp;
+ bool have_pointer_condtemp;
int lastprivate_conditional;
unsigned char sched_modifiers;
enum omp_clause_schedule_kind sched_kind;
install_var_local (decl, ctx);
break;
+ case OMP_CLAUSE__CONDTEMP_:
+ if (is_parallel_ctx (ctx))
+ {
+ decl = OMP_CLAUSE_DECL (c);
+ install_var_field (decl, false, 3, ctx);
+ install_var_local (decl, ctx);
+ }
+ break;
+
case OMP_CLAUSE__CACHE_:
default:
gcc_unreachable ();
case OMP_CLAUSE__SIMT_:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE__CONDTEMP_:
break;
case OMP_CLAUSE__CACHE_:
DECL_HAS_VALUE_EXPR_P (new_var) = 1;
}
continue;
+ case OMP_CLAUSE__CONDTEMP_:
+ if (is_parallel_ctx (ctx))
+ break;
+ continue;
default:
continue;
}
TREE_NO_WARNING (var) = 1;
break;
+ case OMP_CLAUSE__CONDTEMP_:
+ if (is_parallel_ctx (ctx))
+ {
+ x = build_receiver_ref (var, false, ctx);
+ SET_DECL_VALUE_EXPR (new_var, x);
+ DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+ }
+ break;
+
case OMP_CLAUSE_LASTPRIVATE:
if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
break;
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
iter_type = unsigned_type_node;
- 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;
+ tree c2 = omp_find_clause (*clauses, OMP_CLAUSE__CONDTEMP_);
+ if (c2)
+ {
+ cond_ptr
+ = lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c2), ctx);
+ OMP_CLAUSE_DECL (c2) = cond_ptr;
+ }
+ else
+ {
+ 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;
+ c2 = build_omp_clause (UNKNOWN_LOCATION,
+ OMP_CLAUSE__CONDTEMP_);
+ OMP_CLAUSE_DECL (c2) = cond_ptr;
+ OMP_CLAUSE_CHAIN (c2) = *clauses;
+ *clauses = c2;
+ }
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 (c3) = OMP_CLAUSE_CHAIN (c2);
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);
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 mem;
+ if (POINTER_TYPE_P (TREE_TYPE (cond_ptr)))
+ {
+ mem = build2 (MEM_REF, type, cond_ptr,
+ build_int_cst (TREE_TYPE (cond_ptr),
+ conditional_off));
+ conditional_off += tree_to_uhwi (TYPE_SIZE_UNIT (type));
+ }
+ else
+ mem = build4 (ARRAY_REF, type, cond_ptr,
+ size_int (conditional_off++), NULL_TREE, NULL_TREE);
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);
if (use_pointer_for_field (ovar, ctx))
{
x = build_sender_ref (ovar, ctx);
- var = build_fold_addr_expr (var);
+ if (TREE_CODE (TREE_TYPE (f)) == ARRAY_TYPE
+ && TREE_TYPE (f) == TREE_TYPE (ovar))
+ {
+ gcc_assert (is_parallel_ctx (ctx)
+ && DECL_ARTIFICIAL (ovar));
+ /* _condtemp_ clause. */
+ var = build_constructor (TREE_TYPE (x), NULL);
+ }
+ else
+ var = build_fold_addr_expr (var);
gimplify_assign (x, var, ilist);
}
else
if (gimple_code (up->stmt) == GIMPLE_OMP_ORDERED
|| gimple_code (up->stmt) == GIMPLE_OMP_CRITICAL
|| gimple_code (up->stmt) == GIMPLE_OMP_TASKGROUP
- || gimple_code (up->stmt) == GIMPLE_OMP_SECTION)
+ || gimple_code (up->stmt) == GIMPLE_OMP_SECTION
+ || (gimple_code (up->stmt) == GIMPLE_OMP_TARGET
+ && (gimple_omp_target_kind (up->stmt)
+ == GF_OMP_TARGET_KIND_DATA)))
continue;
else if (!up->lastprivate_conditional_map)
break;
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE__CONDTEMP_:
break;
/* The following clause belongs to the OpenACC cache directive, which
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_:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_IF_PRESENT:
case OMP_CLAUSE_FINALIZE:
+ case OMP_CLAUSE__CONDTEMP_:
break;
/* The following clause belongs to the OpenACC cache directive, which
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_: