diff options
author | Jakub Jelinek <jakub@redhat.com> | 2019-07-20 13:21:42 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2019-07-20 13:21:42 +0200 |
commit | 554a530ff81870098572832eed8ca00b3593bb41 (patch) | |
tree | 7d7930d120a4adebe92eebe4c63a801388f5a6a5 /gcc/omp-low.c | |
parent | b6339213ff68ac5a87b7fdda878f26b52d801b76 (diff) | |
download | gcc-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.c | 92 |
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)) |