diff options
author | Cesar Philippidis <cesar@codesourcery.com> | 2016-04-08 14:09:47 -0700 |
---|---|---|
committer | Cesar Philippidis <cesar@gcc.gnu.org> | 2016-04-08 14:09:47 -0700 |
commit | c42cfb5ca3b02756705485e013fa9107aaf28acd (patch) | |
tree | 354e1cd54c889228c92a0a83560a5bf53a7aab00 /gcc | |
parent | 51a4b0f18711b23f2f696a4f546ccce5b1653cf5 (diff) | |
download | gcc-c42cfb5ca3b02756705485e013fa9107aaf28acd.zip gcc-c42cfb5ca3b02756705485e013fa9107aaf28acd.tar.gz gcc-c42cfb5ca3b02756705485e013fa9107aaf28acd.tar.bz2 |
re PR lto/70289 ([openacc] ICE in input_varpool_node)
gcc/
PR lto/70289
PR ipa/70348
PR tree-optimization/70373
PR middle-end/70533
PR middle-end/70534
PR middle-end/70535
* gimplify.c (gimplify_adjust_omp_clauses): Add or adjust data
clauses for acc parallel reductions as necessary. Error on those
that are private.
* omp-low.c (scan_sharing_clauses): Don't install variables which
are used in acc parallel reductions.
(lower_rec_input_clauses): Remove dead code.
(lower_oacc_reductions): Add support for reference reductions.
(lower_reduction_clauses): Remove dead code.
(lower_omp_target): Don't remap variables appearing in acc parallel
reductions.
* tree.h (OMP_CLAUSE_MAP_IN_REDUCTION): New macro.
gcc/testsuite/
* c-c++-common/goacc/reduction-5.c: New test.
* c-c++-common/goacc/reduction-promotions.c: New test.
* gfortran.dg/goacc/reduction-3.f95: New test.
* gfortran.dg/goacc/reduction-promotions.f90: New test.
libgomp/
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gang-np-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gw-np-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gwv-np-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gwv-np-2.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gwv-np-3.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-gwv-np-4.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-vector-p-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-vector-p-2.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-worker-p-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-wv-p-1.c: New test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-wv-p-2.c: New test.
* testsuite/libgomp.oacc-c-c++-common/loop-reduction-wv-p-3.c: New test.
* testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-1.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-2.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-3.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/par-loop-comb-reduction-4.c: New
test.
* testsuite/libgomp.oacc-c-c++-common/par-reduction-1.c: Add test
coverage.
* testsuite/libgomp.oacc-c-c++-common/par-reduction-2.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/parallel-dims.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/parallel-reduction.c: New test.
* testsuite/libgomp.oacc-c-c++-common/pr70289.c: New test.
* testsuite/libgomp.oacc-c-c++-common/pr70373.c: New test.
* testsuite/libgomp.oacc-c-c++-common/reduction-1.c: Add test
coverage.
* testsuite/libgomp.oacc-c-c++-common/reduction-2.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/reduction-3.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/reduction-4.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/reduction-5.c: Likewise.
* testsuite/libgomp.oacc-c-c++-common/reduction-6.c: New test.
* testsuite/libgomp.oacc-c-c++-common/reduction.h: New test.
* testsuite/libgomp.oacc-fortran/parallel-reduction.f90: New test.
* testsuite/libgomp.oacc-fortran/pr70289.f90: New test.
* testsuite/libgomp.oacc-fortran/reduction-1.f90: Add test coverage.
* testsuite/libgomp.oacc-fortran/reduction-2.f90: Likewise.
* testsuite/libgomp.oacc-fortran/reduction-3.f90: Likewise.
* testsuite/libgomp.oacc-fortran/reduction-4.f90: Likewise.
* testsuite/libgomp.oacc-fortran/reduction-5.f90: Likewise.
* testsuite/libgomp.oacc-fortran/reduction-6.f90: Likewise.
* testsuite/libgomp.oacc-fortran/reduction-7.f90: New test.
From-SVN: r234840
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/gimplify.c | 55 | ||||
-rw-r--r-- | gcc/omp-low.c | 82 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/goacc/reduction-5.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/goacc/reduction-promotions.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/goacc/reduction-3.f95 | 10 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90 | 46 | ||||
-rw-r--r-- | gcc/tree.h | 3 |
9 files changed, 260 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe18079..da9cfd8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2016-04-08 Cesar Philippidis <cesar@codesourcery.com> + + PR lto/70289 + PR ipa/70348 + PR tree-optimization/70373 + PR middle-end/70533 + PR middle-end/70534 + PR middle-end/70535 + * gimplify.c (gimplify_adjust_omp_clauses): Add or adjust data + clauses for acc parallel reductions as necessary. Error on those + that are private. + * omp-low.c (scan_sharing_clauses): Don't install variables which + are used in acc parallel reductions. + (lower_rec_input_clauses): Remove dead code. + (lower_oacc_reductions): Add support for reference reductions. + (lower_reduction_clauses): Remove dead code. + (lower_omp_target): Don't remap variables appearing in acc parallel + reductions. + * tree.h (OMP_CLAUSE_MAP_IN_REDUCTION): New macro. + 2016-04-08 Jakub Jelinek <jakub@redhat.com> PR middle-end/70593 diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 9c0119e..e49bdaa 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -7987,6 +7987,34 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, break; } decl = OMP_CLAUSE_DECL (c); + /* Data clasues associated with acc parallel reductions must be + compatible with present_or_copy. Warn and adjust the clause + if that is not the case. */ + if (ctx->region_type == ORT_ACC_PARALLEL) + { + tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0); + n = NULL; + + if (DECL_P (t)) + n = splay_tree_lookup (ctx->variables, (splay_tree_key) t); + + if (n && (n->value & GOVD_REDUCTION)) + { + enum gomp_map_kind kind = OMP_CLAUSE_MAP_KIND (c); + + OMP_CLAUSE_MAP_IN_REDUCTION (c) = 1; + if ((kind & GOMP_MAP_TOFROM) != GOMP_MAP_TOFROM + && kind != GOMP_MAP_FORCE_PRESENT + && kind != GOMP_MAP_POINTER) + { + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "incompatible data clause with reduction " + "on %qE; promoting to present_or_copy", + DECL_NAME (t)); + OMP_CLAUSE_SET_MAP_KIND (c, GOMP_MAP_TOFROM); + } + } + } if (!DECL_P (decl)) { if ((ctx->region_type & ORT_TARGET) != 0 @@ -8118,6 +8146,33 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p, case OMP_CLAUSE_REDUCTION: decl = OMP_CLAUSE_DECL (c); + /* OpenACC reductions need a present_or_copy data clause. + Add one if necessary. Error is the reduction is private. */ + if (ctx->region_type == ORT_ACC_PARALLEL) + { + n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl); + if (n->value & (GOVD_PRIVATE | GOVD_FIRSTPRIVATE)) + error_at (OMP_CLAUSE_LOCATION (c), "invalid private " + "reduction on %qE", DECL_NAME (decl)); + else if ((n->value & GOVD_MAP) == 0) + { + tree next = OMP_CLAUSE_CHAIN (c); + tree nc = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_MAP); + OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_TOFROM); + OMP_CLAUSE_DECL (nc) = decl; + OMP_CLAUSE_CHAIN (c) = nc; + lang_hooks.decls.omp_finish_clause (nc, pre_p); + while (1) + { + OMP_CLAUSE_MAP_IN_REDUCTION (nc) = 1; + if (OMP_CLAUSE_CHAIN (nc) == NULL) + break; + nc = OMP_CLAUSE_CHAIN (nc); + } + OMP_CLAUSE_CHAIN (nc) = next; + n->value |= GOVD_MAP; + } + } if (DECL_P (decl) && omp_shared_to_firstprivate_optimizable_decl_p (decl)) omp_mark_stores (gimplify_omp_ctxp->outer_context, decl); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 7105194..d25c51f 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -2122,7 +2122,8 @@ scan_sharing_clauses (tree clauses, omp_context *ctx, else install_var_field (decl, true, 3, ctx, base_pointers_restrict); - if (is_gimple_omp_offloaded (ctx->stmt)) + if (is_gimple_omp_offloaded (ctx->stmt) + && !OMP_CLAUSE_MAP_IN_REDUCTION (c)) install_var_local (decl, ctx); } } @@ -4839,7 +4840,7 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, gimplify_assign (ptr, x, ilist); } } - else if (is_reference (var) && !is_oacc_parallel (ctx)) + else if (is_reference (var)) { /* For references that are being privatized for Fortran, allocate new backing storage for the new pointer @@ -5575,7 +5576,8 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner, tree orig = OMP_CLAUSE_DECL (c); tree var = maybe_lookup_decl (orig, ctx); tree ref_to_res = NULL_TREE; - tree incoming, outgoing; + tree incoming, outgoing, v1, v2, v3; + bool is_private = false; enum tree_code rcode = OMP_CLAUSE_REDUCTION_CODE (c); if (rcode == MINUS_EXPR) @@ -5588,7 +5590,6 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner, if (!var) var = orig; - gcc_assert (!is_reference (var)); incoming = outgoing = var; @@ -5624,22 +5625,38 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner, for (; cls; cls = OMP_CLAUSE_CHAIN (cls)) if (OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_REDUCTION && orig == OMP_CLAUSE_DECL (cls)) - goto has_outer_reduction; + { + incoming = outgoing = lookup_decl (orig, probe); + goto has_outer_reduction; + } + else if ((OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_FIRSTPRIVATE + || OMP_CLAUSE_CODE (cls) == OMP_CLAUSE_PRIVATE) + && orig == OMP_CLAUSE_DECL (cls)) + { + is_private = true; + goto do_lookup; + } } do_lookup: /* This is the outermost construct with this reduction, see if there's a mapping for it. */ if (gimple_code (outer->stmt) == GIMPLE_OMP_TARGET - && maybe_lookup_field (orig, outer)) + && maybe_lookup_field (orig, outer) && !is_private) { ref_to_res = build_receiver_ref (orig, false, outer); if (is_reference (orig)) ref_to_res = build_simple_mem_ref (ref_to_res); + tree type = TREE_TYPE (var); + if (POINTER_TYPE_P (type)) + type = TREE_TYPE (type); + outgoing = var; - incoming = omp_reduction_init_op (loc, rcode, TREE_TYPE (var)); + incoming = omp_reduction_init_op (loc, rcode, type); } + else if (ctx->outer) + incoming = outgoing = lookup_decl (orig, ctx->outer); else incoming = outgoing = orig; @@ -5649,6 +5666,37 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner, if (!ref_to_res) ref_to_res = integer_zero_node; + if (is_reference (orig)) + { + tree type = TREE_TYPE (var); + const char *id = IDENTIFIER_POINTER (DECL_NAME (var)); + + if (!inner) + { + tree x = create_tmp_var (TREE_TYPE (type), id); + gimplify_assign (var, build_fold_addr_expr (x), fork_seq); + } + + v1 = create_tmp_var (type, id); + v2 = create_tmp_var (type, id); + v3 = create_tmp_var (type, id); + + gimplify_assign (v1, var, fork_seq); + gimplify_assign (v2, var, fork_seq); + gimplify_assign (v3, var, fork_seq); + + var = build_simple_mem_ref (var); + v1 = build_simple_mem_ref (v1); + v2 = build_simple_mem_ref (v2); + v3 = build_simple_mem_ref (v3); + outgoing = build_simple_mem_ref (outgoing); + + if (TREE_CODE (incoming) != INTEGER_CST) + incoming = build_simple_mem_ref (incoming); + } + else + v1 = v2 = v3 = var; + /* Determine position in reduction buffer, which may be used by target. */ enum machine_mode mode = TYPE_MODE (TREE_TYPE (var)); @@ -5678,20 +5726,20 @@ lower_oacc_reductions (location_t loc, tree clauses, tree level, bool inner, = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION, TREE_TYPE (var), 6, init_code, unshare_expr (ref_to_res), - var, level, op, off); + v1, level, op, off); tree fini_call = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION, TREE_TYPE (var), 6, fini_code, unshare_expr (ref_to_res), - var, level, op, off); + v2, level, op, off); tree teardown_call = build_call_expr_internal_loc (loc, IFN_GOACC_REDUCTION, TREE_TYPE (var), 6, teardown_code, - ref_to_res, var, level, op, off); + ref_to_res, v3, level, op, off); - gimplify_assign (var, setup_call, &before_fork); - gimplify_assign (var, init_call, &after_fork); - gimplify_assign (var, fini_call, &before_join); + gimplify_assign (v1, setup_call, &before_fork); + gimplify_assign (v2, init_call, &after_fork); + gimplify_assign (v3, fini_call, &before_join); gimplify_assign (outgoing, teardown_call, &after_join); } @@ -5933,9 +5981,6 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx) } } - if (is_gimple_omp_oacc (ctx->stmt)) - return; - stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START), 0); gimple_seq_add_stmt (stmt_seqp, stmt); @@ -15829,7 +15874,10 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) if (!maybe_lookup_field (var, ctx)) continue; - if (offloaded) + /* Don't remap oacc parallel reduction variables, because the + intermediate result must be local to each gang. */ + if (offloaded && !(OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && OMP_CLAUSE_MAP_IN_REDUCTION (c))) { x = build_receiver_ref (var, true, ctx); tree new_var = lookup_decl (var, ctx); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 72f93e0..055f5dc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2016-04-08 Cesar Philippidis <cesar@codesourcery.com> + + PR lto/70289 + PR ipa/70348 + PR tree-optimization/70373 + PR middle-end/70533 + PR middle-end/70534 + PR middle-end/70535 + * c-c++-common/goacc/reduction-5.c: New test. + * c-c++-common/goacc/reduction-promotions.c: New test. + * gfortran.dg/goacc/reduction-3.f95: New test. + * gfortran.dg/goacc/reduction-promotions.f90: New test. + 2016-04-08 Patrick Palka <ppalka@gcc.gnu.org> PR c++/70590 diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-5.c b/gcc/testsuite/c-c++-common/goacc/reduction-5.c new file mode 100644 index 0000000..74daad3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/goacc/reduction-5.c @@ -0,0 +1,16 @@ +/* Integer reductions. */ + +#define n 1000 + +int +main(void) +{ + int v1; + +#pragma acc parallel reduction(+:v1) private(v1) /* { dg-error "appears more than once in data clauses" } */ + ; +#pragma acc parallel reduction(+:v1) firstprivate(v1) /* { dg-error "appears more than once in data clauses" } */ + ; + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c b/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c new file mode 100644 index 0000000..4cc09da --- /dev/null +++ b/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c @@ -0,0 +1,32 @@ +/* Integer reductions. */ + +#define n 1000 + +int +main(void) +{ + int v1, v2; + +#pragma acc parallel reduction(+:v1,v2) + ; +#pragma acc parallel reduction(+:v1,v2) copy(v1,v2) + ; +#pragma acc parallel reduction(+:v1,v2) pcopy(v1,v2) + ; +#pragma acc parallel reduction(+:v1,v2) present(v1,v2) + ; +#pragma acc parallel reduction(+:v1,v2) copyin(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; +#pragma acc parallel reduction(+:v1,v2) pcopyin(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; +#pragma acc parallel reduction(+:v1,v2) copyout(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; +#pragma acc parallel reduction(+:v1,v2) pcopyout(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; +#pragma acc parallel reduction(+:v1,v2) create(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; +#pragma acc parallel reduction(+:v1,v2) pcreate(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */ + ; + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95 b/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95 new file mode 100644 index 0000000..72f0eb9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95 @@ -0,0 +1,10 @@ +! { dg-do compile } + +subroutine foo (ia1) +integer :: i1, i2 + +!$acc parallel reduction (+:i1) private(i1) ! { dg-error "invalid private reduction on .i1." } +!$acc end parallel +!$acc parallel reduction (+:i2) firstprivate(i2) ! { dg-error "invalid private reduction on .i2." } +!$acc end parallel +end subroutine foo diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90 b/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90 new file mode 100644 index 0000000..6ff913a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90 @@ -0,0 +1,46 @@ +! Ensure that each parallel reduction variable as a copy or pcopy +! data clause. + +! { dg-additional-options "-fdump-tree-gimple" } + +program test + implicit none + integer :: v1, v2 + + !$acc parallel reduction(+:v1,v2) + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) copy(v1,v2) + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) pcopy(v1,v2) + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) present(v1,v2) + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) copyin(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) pcopyin(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) copyout(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) pcopyout(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) create(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel + + !$acc parallel reduction(+:v1,v2) pcreate(v1,v2) ! { dg-warning "incompatible data clause" } + !$acc end parallel +end program test + +! { dg-final { scan-tree-dump-times "map.tofrom:v1" 8 "gimple" } } +! { dg-final { scan-tree-dump-times "map.tofrom:v2" 8 "gimple" } } +! { dg-final { scan-tree-dump-times "map.force_tofrom:v1" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "map.force_tofrom:v2" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "map.force_present:v1" 1 "gimple" } } +! { dg-final { scan-tree-dump-times "map.force_present:v2" 1 "gimple" } } @@ -1536,6 +1536,9 @@ extern void protected_set_expr_location (tree, location_t); treatment if OMP_CLAUSE_SIZE is zero. */ #define OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION(NODE) \ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)) +/* Nonzero if this map clause is for an ACC parallel reduction variable. */ +#define OMP_CLAUSE_MAP_IN_REDUCTION(NODE) \ + TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)) #define OMP_CLAUSE_PROC_BIND_KIND(NODE) \ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind) |