Commit e7393c89 by Jakub Jelinek Committed by Jakub Jelinek

tree.h (OMP_CLAUSE__CONDTEMP__ITER): Define.

	* tree.h (OMP_CLAUSE__CONDTEMP__ITER): Define.
	* gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional
	on OMP_SIMD if not nested inside of worksharing loop that also has
	lastprivate conditional clause for the same decl.
	(gimplify_omp_for): Add _condtemp_ clauses to OMP_SIMD if needed.
	* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE__CONDTEMP_ also
	on simd.
	(lower_rec_input_clauses): Likewise.  Handle lastprivate conditional
	on simd construct.
	(lower_lastprivate_conditional_clauses): Handle lastprivate conditional
	on simd construct.
	(lower_lastprivate_clauses): Likewise.
	(lower_omp_sections): Call lower_lastprivate_conditional_clauses before
	calling lower_rec_input_clauses.
	(lower_omp_for): Likewise.
	(lower_omp_1): Use first rather than second OMP_CLAUSE__CONDTEMP_
	clause on simd construct.
	* omp-expand.c (expand_omp_simd): Initialize cond_var if
	OMP_CLAUSE__CONDTEMP_ clause is present.

	* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
	a sorry on lastprivate conditional on simd construct.
	* gcc.dg/vect/vect-simd-6.c: New test.
	* gcc.dg/vect/vect-simd-7.c: New test.

From-SVN: r271825
parent 1ce8fc63
2019-05-31 Jakub Jelinek <jakub@redhat.com>
* tree.h (OMP_CLAUSE__CONDTEMP__ITER): Define.
* gimplify.c (gimplify_scan_omp_clauses): Allow lastprivate conditional
on OMP_SIMD if not nested inside of worksharing loop that also has
lastprivate conditional clause for the same decl.
(gimplify_omp_for): Add _condtemp_ clauses to OMP_SIMD if needed.
* omp-low.c (scan_sharing_clauses): Handle OMP_CLAUSE__CONDTEMP_ also
on simd.
(lower_rec_input_clauses): Likewise. Handle lastprivate conditional
on simd construct.
(lower_lastprivate_conditional_clauses): Handle lastprivate conditional
on simd construct.
(lower_lastprivate_clauses): Likewise.
(lower_omp_sections): Call lower_lastprivate_conditional_clauses before
calling lower_rec_input_clauses.
(lower_omp_for): Likewise.
(lower_omp_1): Use first rather than second OMP_CLAUSE__CONDTEMP_
clause on simd construct.
* omp-expand.c (expand_omp_simd): Initialize cond_var if
OMP_CLAUSE__CONDTEMP_ clause is present.
* omp-low.c (lower_rec_simd_input_clauses): Set TREE_THIS_NOTRAP on
ivar and lvar.
......
......@@ -8146,17 +8146,29 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
}
if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
if (code == OMP_FOR
|| code == OMP_SECTIONS
|| region_type == ORT_COMBINED_PARALLEL)
flags |= GOVD_LASTPRIVATE_CONDITIONAL;
else
splay_tree_node n = NULL;
if (code == OMP_SIMD
&& outer_ctx
&& outer_ctx->region_type == ORT_WORKSHARE)
{
n = splay_tree_lookup (outer_ctx->variables,
(splay_tree_key) decl);
if (n == NULL
&& outer_ctx->outer_context
&& (outer_ctx->outer_context->region_type
== ORT_COMBINED_PARALLEL))
n = splay_tree_lookup (outer_ctx->outer_context->variables,
(splay_tree_key) decl);
}
if (n && (n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
{
sorry_at (OMP_CLAUSE_LOCATION (c),
"%<conditional%> modifier on %<lastprivate%> "
"clause not supported yet");
OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 0;
}
else
flags |= GOVD_LASTPRIVATE_CONDITIONAL;
}
if (outer_ctx
&& (outer_ctx->region_type == ORT_COMBINED_PARALLEL
......@@ -11559,6 +11571,28 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
omp_add_variable (ctx, var, GOVD_CONDTEMP | GOVD_SEEN);
}
}
else if (TREE_CODE (orig_for_stmt) == OMP_SIMD)
{
unsigned lastprivate_conditional = 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 = unsigned_type_for (fd.iter_type);
while (lastprivate_conditional--)
{
tree c = build_omp_clause (UNKNOWN_LOCATION,
OMP_CLAUSE__CONDTEMP_);
OMP_CLAUSE_DECL (c) = create_tmp_var (type);
OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (gfor);
gimple_omp_for_set_clauses (gfor, c);
}
}
}
if (ret != GS_ALL_DONE)
return GS_ERROR;
......
......@@ -4908,7 +4908,10 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
OMP_CLAUSE_IF);
tree simdlen = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
OMP_CLAUSE_SIMDLEN);
tree condtemp = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
OMP_CLAUSE__CONDTEMP_);
tree n1, n2;
tree cond_var = condtemp ? OMP_CLAUSE_DECL (condtemp) : NULL_TREE;
if (safelen)
{
......@@ -5038,6 +5041,18 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
expand_omp_build_assign (&gsi, fd->loops[i].v, t);
}
}
if (cond_var)
{
if (POINTER_TYPE_P (type)
|| TREE_CODE (n1) != INTEGER_CST
|| fd->loop.cond_code != LT_EXPR
|| tree_int_cst_sgn (n1) != 1)
expand_omp_build_assign (&gsi, cond_var,
build_one_cst (TREE_TYPE (cond_var)));
else
expand_omp_build_assign (&gsi, cond_var,
fold_convert (TREE_TYPE (cond_var), n1));
}
/* Remove the GIMPLE_OMP_FOR statement. */
gsi_remove (&gsi, true);
......@@ -5103,6 +5118,19 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
expand_omp_build_assign (&gsi, fd->loops[i].v, t);
}
}
if (cond_var)
{
if (POINTER_TYPE_P (type)
|| TREE_CODE (n1) != INTEGER_CST
|| fd->loop.cond_code != LT_EXPR
|| tree_int_cst_sgn (n1) != 1)
t = fold_build2 (PLUS_EXPR, TREE_TYPE (cond_var), cond_var,
build_one_cst (TREE_TYPE (cond_var)));
else
t = fold_build2 (PLUS_EXPR, TREE_TYPE (cond_var), cond_var,
fold_convert (TREE_TYPE (cond_var), step));
expand_omp_build_assign (&gsi, cond_var, t);
}
/* Remove GIMPLE_OMP_CONTINUE. */
gsi_remove (&gsi, true);
......
......@@ -1414,12 +1414,16 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
break;
case OMP_CLAUSE__CONDTEMP_:
decl = OMP_CLAUSE_DECL (c);
if (is_parallel_ctx (ctx))
{
decl = OMP_CLAUSE_DECL (c);
install_var_field (decl, false, 3, ctx);
install_var_local (decl, ctx);
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
&& (gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
&& !OMP_CLAUSE__CONDTEMP__ITER (c))
install_var_local (decl, ctx);
break;
case OMP_CLAUSE__CACHE_:
......@@ -3840,6 +3844,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
sctx.max_vf = 1;
break;
case OMP_CLAUSE__CONDTEMP_:
/* FIXME: lastprivate(conditional:) not handled for SIMT yet. */
if (sctx.is_simt)
sctx.max_vf = 1;
break;
default:
continue;
}
......@@ -4054,7 +4063,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
continue;
case OMP_CLAUSE__CONDTEMP_:
if (is_parallel_ctx (ctx))
if (is_parallel_ctx (ctx)
|| (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c)))
break;
continue;
default:
......@@ -4730,6 +4740,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
SET_DECL_VALUE_EXPR (new_var, x);
DECL_HAS_VALUE_EXPR_P (new_var) = 1;
}
else if (is_simd && !OMP_CLAUSE__CONDTEMP__ITER (c))
{
x = build_zero_cst (TREE_TYPE (var));
goto do_private;
}
break;
case OMP_CLAUSE_LASTPRIVATE:
......@@ -4757,15 +4772,52 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
if ((TREE_ADDRESSABLE (new_var) || nx || y
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
&& lower_rec_simd_input_clauses (new_var, ctx, &sctx,
ivar, lvar))
{
if (nx)
x = lang_hooks.decls.omp_clause_default_ctor
(c, unshare_expr (ivar), x);
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
{
x = build2 (MODIFY_EXPR, TREE_TYPE (ivar),
unshare_expr (ivar), x);
nx = x;
}
if (nx && x)
gimplify_and_add (x, &llist[0]);
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
tree v
= *ctx->lastprivate_conditional_map->get (new_var);
tree t = create_tmp_var (TREE_TYPE (v));
tree z = build_zero_cst (TREE_TYPE (v));
tree orig_v
= build_outer_var_ref (var, ctx,
OMP_CLAUSE_LASTPRIVATE);
gimple_seq_add_stmt (dlist,
gimple_build_assign (t, z));
gcc_assert (DECL_HAS_VALUE_EXPR_P (v));
tree civar = DECL_VALUE_EXPR (v);
gcc_assert (TREE_CODE (civar) == ARRAY_REF);
civar = unshare_expr (civar);
TREE_OPERAND (civar, 1) = sctx.idx;
x = build2 (MODIFY_EXPR, TREE_TYPE (t), t,
unshare_expr (civar));
x = build2 (COMPOUND_EXPR, TREE_TYPE (orig_v), x,
build2 (MODIFY_EXPR, TREE_TYPE (orig_v),
orig_v, unshare_expr (ivar)));
tree cond = build2 (LT_EXPR, boolean_type_node, t,
civar);
x = build3 (COND_EXPR, void_type_node, cond, x,
void_node);
gimple_seq tseq = NULL;
gimplify_and_add (x, &tseq);
gimple_seq_add_seq (&llist[1], tseq);
}
if (y)
{
y = lang_hooks.decls.omp_clause_dtor (c, ivar);
......@@ -5222,7 +5274,17 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
if (known_eq (sctx.max_vf, 1U))
sctx.is_simt = false;
{
sctx.is_simt = false;
if (ctx->lastprivate_conditional_map)
{
/* When not vectorized, treat lastprivate(conditional:) like
normal lastprivate, as there will be just one simd lane
writing the privatized variable. */
delete ctx->lastprivate_conditional_map;
ctx->lastprivate_conditional_map = NULL;
}
}
if (nonconst_simd_if)
{
......@@ -5398,10 +5460,39 @@ lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
tree iter_type = NULL_TREE;
tree cond_ptr = NULL_TREE;
tree iter_var = NULL_TREE;
bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
&& gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
tree next = *clauses;
for (tree c = *clauses; c; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
{
if (is_simd)
{
tree cc = omp_find_clause (next, OMP_CLAUSE__CONDTEMP_);
gcc_assert (cc);
if (iter_type == NULL_TREE)
{
iter_type = TREE_TYPE (OMP_CLAUSE_DECL (cc));
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 c3
= build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
OMP_CLAUSE_DECL (c3) = iter_var;
OMP_CLAUSE_CHAIN (c3) = *clauses;
*clauses = c3;
ctx->lastprivate_conditional_map = new hash_map<tree, tree>;
}
next = OMP_CLAUSE_CHAIN (cc);
tree o = lookup_decl (OMP_CLAUSE_DECL (c), ctx);
tree v = lookup_decl (OMP_CLAUSE_DECL (cc), ctx);
ctx->lastprivate_conditional_map->put (o, v);
continue;
}
if (iter_type == NULL)
{
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR)
......@@ -5440,6 +5531,7 @@ lower_lastprivate_conditional_clauses (tree *clauses, omp_context *ctx)
ctx->block_vars = iter_var;
tree c3
= build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__CONDTEMP_);
OMP_CLAUSE__CONDTEMP__ITER (c3) = 1;
OMP_CLAUSE_DECL (c3) = iter_var;
OMP_CLAUSE_CHAIN (c3) = OMP_CLAUSE_CHAIN (c2);
OMP_CLAUSE_CHAIN (c2) = c3;
......@@ -5559,9 +5651,12 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
tree lab2 = NULL_TREE;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
&& OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c)
&& ctx->lastprivate_conditional_map)
{
gcc_assert (body_p && ctx->lastprivate_conditional_map);
gcc_assert (body_p);
if (simduid)
goto next;
if (cond_ptr == NULL_TREE)
{
cond_ptr = omp_find_clause (orig_clauses, OMP_CLAUSE__CONDTEMP_);
......@@ -5701,6 +5796,7 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
gimple_seq_add_stmt (this_stmt_list, gimple_build_label (lab2));
}
next:
c = OMP_CLAUSE_CHAIN (c);
if (c == NULL && !par_clauses)
{
......@@ -6826,15 +6922,15 @@ lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq_add_stmt (&ilist, gimple_build_assign (rtmp, temp));
}
tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
&ilist, &dlist, ctx, NULL);
control = create_tmp_var (unsigned_type_node, ".section");
gimple_omp_sections_set_control (stmt, control);
tree *clauses_ptr = gimple_omp_sections_clauses_ptr (stmt);
lower_lastprivate_conditional_clauses (clauses_ptr, ctx);
new_body = gimple_omp_body (stmt);
gimple_omp_set_body (stmt, NULL);
tgsi = gsi_start (new_body);
......@@ -8486,14 +8582,14 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq_add_stmt (&body, gimple_build_assign (rtmp, temp));
}
lower_lastprivate_conditional_clauses (gimple_omp_for_clauses_ptr (stmt),
ctx);
lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx,
fdp);
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
......@@ -10721,8 +10817,10 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
else
clauses = gimple_omp_sections_clauses (up->stmt);
tree c = omp_find_clause (clauses, OMP_CLAUSE__CONDTEMP_);
c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
OMP_CLAUSE__CONDTEMP_);
if (!OMP_CLAUSE__CONDTEMP__ITER (c))
c = omp_find_clause (OMP_CLAUSE_CHAIN (c),
OMP_CLAUSE__CONDTEMP_);
gcc_assert (OMP_CLAUSE__CONDTEMP__ITER (c));
gimple *g = gimple_build_assign (*v, OMP_CLAUSE_DECL (c));
gsi_insert_after (gsi_p, g, GSI_SAME_STMT);
}
......
2019-05-31 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
a sorry on lastprivate conditional on simd construct.
* gcc.dg/vect/vect-simd-6.c: New test.
* gcc.dg/vect/vect-simd-7.c: New test.
* gcc.dg/vect/vect-simd-5.c: New test.
2019-05-31 Xiong Hu Luo <luoxhu@linux.ibm.com>
......
......@@ -8,7 +8,7 @@ foo (int *p)
for (i = 0; i < 32; i++)
if (p[i])
a = i;
#pragma omp simd lastprivate (conditional: b) /* { dg-message "not supported yet" } */
#pragma omp simd lastprivate (conditional: b)
for (i = 0; i < 32; i++)
if (p[i])
b = i;
......
/* { dg-additional-options "-fopenmp-simd" } */
/* { dg-final { scan-tree-dump-times "vectorized \[12] loops" 2 "vect" { target vect_condition } } } */
#include "tree-vect.h"
int v;
__attribute__((noipa)) int
foo (int *a)
{
int x = 5;
#pragma omp simd lastprivate (conditional: x)
for (int i = 0; i < 128; i++)
if (a[i])
x = a[i];
return x;
}
__attribute__((noipa)) int
bar (int *a, int *b)
{
int x = 0;
#pragma omp simd lastprivate (conditional: x, v)
for (int i = 16; i < 128; ++i)
{
if (a[i])
x = a[i];
if (b[i])
v = b[i] + 10;
}
return x;
}
int
main ()
{
int a[128], b[128], i;
check_vect ();
for (i = 0; i < 128; i++)
{
a[i] = ((i % 11) == 2) ? i + 10 : 0;
asm volatile ("" : "+g" (i));
b[i] = ((i % 13) == 5) ? i * 2 : 0;
}
if (foo (a) != 133)
abort ();
if (bar (b, a) != 244)
abort ();
if (v != 143)
abort ();
return 0;
}
/* { dg-additional-options "-fopenmp-simd" } */
#include "tree-vect.h"
int v;
__attribute__((noipa)) int
foo (int *a)
{
int x = 5;
#pragma omp simd lastprivate (conditional: x) safelen (1)
for (int i = 0; i < 128; i++)
if (a[i])
x = a[i];
return x;
}
__attribute__((noipa)) int
bar (int *a, int *b)
{
int x = 0;
#pragma omp simd lastprivate (conditional: x, v) if (0)
for (int i = 16; i < 128; ++i)
{
if (a[i])
x = a[i];
if (b[i])
v = b[i] + 10;
}
return x;
}
int
main ()
{
int a[128], b[128], i;
check_vect ();
for (i = 0; i < 128; i++)
{
a[i] = ((i % 11) == 2) ? i + 10 : 0;
asm volatile ("" : "+g" (i));
b[i] = ((i % 13) == 5) ? i * 2 : 0;
}
if (foo (a) != 133)
abort ();
if (bar (b, a) != 244)
abort ();
if (v != 143)
abort ();
return 0;
}
......@@ -1752,6 +1752,10 @@ class auto_suppress_location_wrappers
#define OMP_CLAUSE__GRIDDIM__GROUP(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_), 1)
/* _CONDTEMP_ holding temporary with iteration count. */
#define OMP_CLAUSE__CONDTEMP__ITER(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__CONDTEMP_)->base.public_flag)
/* SSA_NAME accessors. */
/* Whether SSA_NAME NODE is a virtual operand. This simply caches the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment