aboutsummaryrefslogtreecommitdiff
path: root/gcc/omp-low.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-07-20 13:21:42 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2019-07-20 13:21:42 +0200
commit554a530ff81870098572832eed8ca00b3593bb41 (patch)
tree7d7930d120a4adebe92eebe4c63a801388f5a6a5 /gcc/omp-low.c
parentb6339213ff68ac5a87b7fdda878f26b52d801b76 (diff)
downloadgcc-554a530ff81870098572832eed8ca00b3593bb41.zip
gcc-554a530ff81870098572832eed8ca00b3593bb41.tar.gz
gcc-554a530ff81870098572832eed8ca00b3593bb41.tar.bz2
tree.def (OMP_LOOP): New tree code.
* tree.def (OMP_LOOP): New tree code. * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_BIND. (enum omp_clause_bind_kind): New enum. (struct tree_omp_clause): Add subcode.bind_kind. * tree.h (OMP_LOOP_CHECK): Rename to ... (OMP_LOOPING_CHECK): ... this. (OMP_FOR_BODY, OMP_FOR_CLAUSES, OMP_FOR_INIT, OMP_FOR_COND, OMP_FOR_INCR, OMP_FOR_PRE_BODY, OMP_FOR_ORIG_DECLS): Use OMP_LOOPING_CHECK instead of OMP_LOOP_CHECK. (OMP_CLAUSE_BIND_KIND): Define. * tree.c (omp_clause_num_ops, omp_clause_code_name): Add bind clause entries. (walk_tree_1): Handle OMP_CLAUSE_BIND. * tree-pretty-print.c (dump_omp_clause): Likewise. (dump_generic_node): Handle OMP_LOOP. * gimplify.c (enum omp_region_type): Add ORT_IMPLICIT_TARGET. (in_omp_construct): New variable. (is_gimple_stmt): Handle OMP_LOOP. (gimplify_scan_omp_clauses): For lastprivate don't set check_non_private if code == OMP_LOOP. For reduction clause on OMP_LOOP combined with parallel or teams propagate as shared on the combined construct. Handle OMP_CLAUSE_BIND. (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_BIND. (gimplify_omp_for): Pass OMP_LOOP instead of OMP_{FOR,DISTRIBUTE} for constructs from a loop construct to gimplify_scan_omp_clauses. Don't predetermine iterator linear on OMP_SIMD from loop construct. (replace_reduction_placeholders, gimplify_omp_loop): New functions. (gimplify_omp_workshare): Use ORT_IMPLICIT_TARGET instead of trying to match the implicit ORT_TARGET construct around whole body. Temporarily clear in_omp_construct when processing body. (gimplify_expr): Handle OMP_LOOP. For OMP_MASTER, OMP_TASKGROUP etc. temporarily set in_omp_construct when processing body. (gimplify_body): Create ORT_IMPLICIT_TARGET instead of ORT_TARGET. * omp-low.c (struct omp_context): Add loop_p. (build_outer_var_ref): Treat ctx->loop_p similarly to simd construct in that the original var might be private. (scan_sharing_clauses): Handle OMP_CLAUSE_BIND. (check_omp_nesting_restrictions): Adjust nesting restrictions for addition of loop construct. (scan_omp_1_stmt): Allow setjmp inside of loop construct. gcc/c-family/ * c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_LOOP. (enum pragma_omp_clause): Add PRAGMA_OMP_CLAUSE_BIND. * c-pragma.c (omp_pragmas_simd): Add PRAGMA_OMP_LOOP entry. * c-common.h (enum c_omp_clause_split): Add C_OMP_CLAUSE_SPLIT_LOOP. * c-omp.c (c_omp_split_clauses): Add support for 4 new combined constructs with the loop construct. gcc/c/ * c-parser.c (c_parser_omp_clause_name): Handle bind clause. (c_parser_omp_clause_bind): New function. (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND. (OMP_LOOP_CLAUSE_MASK): Define. (c_parser_omp_loop): New function. (c_parser_omp_parallel, c_parser_omp_teams): Handle parsing of loop combined with parallel or teams. (c_parser_omp_construct): Handle PRAGMA_OMP_LOOP. * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_BIND. gcc/cp/ * cp-tree.h (OMP_FOR_GIMPLIFYING_P): Use OMP_LOOPING_CHECK instead of OMP_LOOP_CHECK. * parser.c (cp_parser_omp_clause_name): Handle bind clause. (cp_parser_omp_clause_bind): New function. (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_BIND. (OMP_LOOP_CLAUSE_MASK): Define. (cp_parser_omp_loop): New function. (cp_parser_omp_parallel, cp_parser_omp_teams): Handle parsing of loop combined with parallel or teams. (cp_parser_omp_construct): Handle PRAGMA_OMP_LOOP. (cp_parser_pragma): Likewise. * pt.c (tsubst_expr): Handle OMP_LOOP. * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_BIND. gcc/testsuite/ * c-c++-common/gomp/cancel-1.c: Adjust expected diagnostic wording. * c-c++-common/gomp/clauses-1.c (foo, baz, bar): Add order(concurrent) clause where allowed. Add combined constructs with loop with all possible clauses. (qux): New function. * c-c++-common/gomp/loop-1.c: New test. * c-c++-common/gomp/loop-2.c: New test. * c-c++-common/gomp/loop-3.c: New test. * c-c++-common/gomp/loop-4.c: New test. * c-c++-common/gomp/loop-5.c: New test. * c-c++-common/gomp/order-3.c: Adjust expected diagnostic wording. * c-c++-common/gomp/simd-setjmp-1.c: New test. * c-c++-common/gomp/teams-2.c: Adjust expected diagnostic wording. libgomp/ * testsuite/libgomp.c-c++-common/loop-1.c: New test. From-SVN: r273621
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r--gcc/omp-low.c92
1 files changed, 59 insertions, 33 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 03df07b..d8756c0 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -153,6 +153,9 @@ struct omp_context
/* True if there is order(concurrent) clause on the construct. */
bool order_concurrent;
+
+ /* True if there is bind clause on the construct (i.e. a loop construct). */
+ bool loop_p;
};
static splay_tree all_contexts;
@@ -581,6 +584,7 @@ build_outer_var_ref (tree var, omp_context *ctx,
}
else if ((gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
&& gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ || ctx->loop_p
|| (code == OMP_CLAUSE_PRIVATE
&& (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
|| gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS
@@ -1397,6 +1401,10 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
ctx->order_concurrent = true;
break;
+ case OMP_CLAUSE_BIND:
+ ctx->loop_p = true;
+ break;
+
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_ORDERED:
case OMP_CLAUSE_COLLAPSE:
@@ -1603,6 +1611,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_NOGROUP:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_USE_DEVICE_PTR:
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_ASYNC:
@@ -2675,7 +2684,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
&& gimple_code (ctx->outer->stmt) == GIMPLE_OMP_FOR)
ctx = ctx->outer;
if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
- && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
+ && !ctx->loop_p)
{
c = NULL_TREE;
if (ctx->order_concurrent
@@ -2684,8 +2694,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|| gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE))
{
error_at (gimple_location (stmt),
- "OpenMP constructs other than %<parallel%> or"
- " %<simd%> may not be nested inside a region with"
+ "OpenMP constructs other than %<parallel%>, %<loop%>"
+ " or %<simd%> may not be nested inside a region with"
" the %<order(concurrent)%> clause");
return false;
}
@@ -2714,23 +2724,28 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|| gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE
|| gimple_code (stmt) == GIMPLE_OMP_SCAN)
return true;
+ else if (gimple_code (stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ return true;
error_at (gimple_location (stmt),
- "OpenMP constructs other than %<#pragma omp ordered simd%>"
- " or %<#pragma omp atomic%> may not be nested inside"
- " %<simd%> region");
+ "OpenMP constructs other than "
+ "%<ordered simd%>, %<simd%>, %<loop%> or %<atomic%> may "
+ "not be nested inside %<simd%> region");
return false;
}
else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
{
if ((gimple_code (stmt) != GIMPLE_OMP_FOR
- || ((gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE)
- && (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_GRID_LOOP)))
+ || (gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_DISTRIBUTE
+ && gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_GRID_LOOP
+ && omp_find_clause (gimple_omp_for_clauses (stmt),
+ OMP_CLAUSE_BIND) == NULL_TREE))
&& gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
{
error_at (gimple_location (stmt),
- "only %<distribute%> or %<parallel%> regions are "
- "allowed to be strictly nested inside %<teams%> "
- "region");
+ "only %<distribute%>, %<parallel%> or %<loop%> "
+ "regions are allowed to be strictly nested inside "
+ "%<teams%> region");
return false;
}
}
@@ -2740,10 +2755,15 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
|| gimple_omp_for_kind (stmt) != GF_OMP_FOR_KIND_SIMD)
&& gimple_code (stmt) != GIMPLE_OMP_SCAN)
{
- error_at (gimple_location (stmt),
- "OpenMP constructs other than %<parallel%> or"
- " %<simd%> may not be nested inside a region with"
- " the %<order(concurrent)%> clause");
+ if (ctx->loop_p)
+ error_at (gimple_location (stmt),
+ "OpenMP constructs other than %<parallel%>, %<loop%> or "
+ "%<simd%> may not be nested inside a %<loop%> region");
+ else
+ error_at (gimple_location (stmt),
+ "OpenMP constructs other than %<parallel%>, %<loop%> or "
+ "%<simd%> may not be nested inside a region with "
+ "the %<order(concurrent)%> clause");
return false;
}
}
@@ -2766,6 +2786,11 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
/* We split taskloop into task and nested taskloop in it. */
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_TASKLOOP)
return true;
+ /* For now, hope this will change and loop bind(parallel) will not
+ be allowed in lots of contexts. */
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR
+ && omp_find_clause (gimple_omp_for_clauses (stmt), OMP_CLAUSE_BIND))
+ return true;
if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
{
bool ok = false;
@@ -2816,8 +2841,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
const char *construct
= (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL)
- ? "#pragma omp cancel"
- : "#pragma omp cancellation point";
+ ? "cancel"
+ : "cancellation point";
if (ctx == NULL)
{
error_at (gimple_location (stmt), "orphaned %qs construct",
@@ -2830,7 +2855,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
{
case 1:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
- bad = "#pragma omp parallel";
+ bad = "parallel";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2840,7 +2865,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case 2:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
|| gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
- bad = "#pragma omp for";
+ bad = "for";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2849,12 +2874,12 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel for%> inside "
+ "%<cancel for%> inside "
"%<nowait%> for construct");
if (omp_find_clause (gimple_omp_for_clauses (ctx->stmt),
OMP_CLAUSE_ORDERED))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel for%> inside "
+ "%<cancel for%> inside "
"%<ordered%> for construct");
}
kind = "for";
@@ -2862,7 +2887,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case 4:
if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
&& gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
- bad = "#pragma omp sections";
+ bad = "sections";
else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
== BUILT_IN_GOMP_CANCEL
&& !integer_zerop (gimple_call_arg (stmt, 1)))
@@ -2874,7 +2899,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
(ctx->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel sections%> inside "
+ "%<cancel sections%> inside "
"%<nowait%> sections construct");
}
else
@@ -2887,7 +2912,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
(ctx->outer->stmt),
OMP_CLAUSE_NOWAIT))
warning_at (gimple_location (stmt), 0,
- "%<#pragma omp cancel sections%> inside "
+ "%<cancel sections%> inside "
"%<nowait%> sections construct");
}
}
@@ -2898,7 +2923,7 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
&& (!is_taskloop_ctx (ctx)
|| ctx->outer == NULL
|| !is_task_ctx (ctx->outer)))
- bad = "#pragma omp task";
+ bad = "task";
else
{
for (omp_context *octx = ctx->outer;
@@ -2976,14 +3001,14 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
return true;
error_at (gimple_location (stmt),
"barrier region may not be closely nested inside "
- "of work-sharing, %<critical%>, %<ordered%>, "
- "%<master%>, explicit %<task%> or %<taskloop%> "
- "region");
+ "of work-sharing, %<loop%>, %<critical%>, "
+ "%<ordered%>, %<master%>, explicit %<task%> or "
+ "%<taskloop%> region");
return false;
}
error_at (gimple_location (stmt),
"work-sharing region may not be closely nested inside "
- "of work-sharing, %<critical%>, %<ordered%>, "
+ "of work-sharing, %<loop%>, %<critical%>, %<ordered%>, "
"%<master%>, explicit %<task%> or %<taskloop%> region");
return false;
case GIMPLE_OMP_PARALLEL:
@@ -3012,8 +3037,8 @@ check_omp_nesting_restrictions (gimple *stmt, omp_context *ctx)
case GIMPLE_OMP_TASK:
error_at (gimple_location (stmt),
"%<master%> region may not be closely nested inside "
- "of work-sharing, explicit %<task%> or %<taskloop%> "
- "region");
+ "of work-sharing, %<loop%>, explicit %<task%> or "
+ "%<taskloop%> region");
return false;
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TEAMS:
@@ -3497,11 +3522,12 @@ scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
if (ctx
&& gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
&& gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD
- && setjmp_or_longjmp_p (fndecl))
+ && setjmp_or_longjmp_p (fndecl)
+ && !ctx->loop_p)
{
remove = true;
error_at (gimple_location (stmt),
- "setjmp/longjmp inside simd construct");
+ "setjmp/longjmp inside %<simd%> construct");
}
else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (fndecl))