[Attaching patch this time.] On 09/01/2015 04:21 PM, Cesar Philippidis wrote: > This patch teaches lower_oacc_reductions not to generate calls to > GOACC_{UN}LOCK if they aren't any reductions. That situation can happen > when there is a fake gang reduction on a private variable. > > I also found a bug where the lower_rec_input_clauses expects there to be > a data mapping for the reduction variable when there isn't, e.g. for > private/local reduction variables. And I made the nvptx backend aware of > the fact that the lhs of a call to REDUCTION_TEARDOWN may be have been > optimized away for worker reductions too. I have a couple of test cases > for these bugs, but I'll include them with my upcoming auto-independent > loop patch. > > This patch has been committed to gomp-4_0-branch. > > Cesar >
2015-09-01 Cesar Philippidis <ce...@codesourcery.com> gcc/ * config/nvptx/nvptx.c (nvptx_goacc_reduction_teardown): Allow lhs to be NULL for worker reductions too. * omp-low.c (lower_rec_input_clauses): Bail out on OpenACC reductions. (lower_oacc_reductions): Use maybe_lookup_decl for private reductions. Don't emit locks for fake private gang reductions. diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index 1b85892..51f2893 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -4229,14 +4229,19 @@ nvptx_goacc_reduction_teardown (gimple call) tree rid = gimple_call_arg (call, 5); gimple_seq seq = NULL; + if (v == NULL) + { + gsi_remove (&gsi, true); + return false; + } + push_gimplify_context (true); switch (loop_dim) { case GOMP_DIM_GANG: case GOMP_DIM_VECTOR: - if (v) - gimplify_assign (v, local_var, &seq); + gimplify_assign (v, local_var, &seq); break; case GOMP_DIM_WORKER: { diff --git a/gcc/omp-low.c b/gcc/omp-low.c index fdca880..bfef298 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3892,7 +3892,14 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, new_var = var = OMP_CLAUSE_DECL (c); if (c_kind != OMP_CLAUSE_COPYIN) - new_var = lookup_decl (var, ctx); + { + /* Not all OpenACC reductions require new mappings. */ + if (is_gimple_omp_oacc (ctx->stmt) + && (new_var = maybe_lookup_decl (var, ctx)) == NULL) + new_var = var; + else + new_var = lookup_decl (var, ctx); + } if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN) { @@ -4724,6 +4731,8 @@ lower_oacc_reductions (enum internal_fn ifn, int loop_dim, tree clauses, tree c, tcode, gwv, rid, lid = build_int_cst (integer_type_node, oacc_lid); int oacc_rid, i; unsigned mask = extract_oacc_loop_mask (ctx); + gimple_seq red_seq = NULL; + int num_reductions = 0; enum tree_code rcode; /* Remove the outer-most level of parallelism from the loop. */ @@ -4753,14 +4762,6 @@ lower_oacc_reductions (enum internal_fn ifn, int loop_dim, tree clauses, gimplify_and_add (call, ilist); } - /* Call GOACC_LOCK. */ - if (ifn == IFN_GOACC_REDUCTION_FINI && write_back) - { - call = build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_GOACC_LOCK, - void_type_node, 2, dim, lid); - gimplify_and_add (call, ilist); - } - for (c = clauses, oacc_rid = 0; c && write_back; c = OMP_CLAUSE_CHAIN (c), oacc_rid++) @@ -4776,7 +4777,9 @@ lower_oacc_reductions (enum internal_fn ifn, int loop_dim, tree clauses, var = OMP_CLAUSE_REDUCTION_PRIVATE_DECL (c); if (var == NULL_TREE) - var = lookup_decl (orig, ctx); + var = maybe_lookup_decl (orig, ctx); + if (var == NULL_TREE) + var = orig; res = build_outer_var_ref (orig, ctx); @@ -4811,16 +4814,32 @@ lower_oacc_reductions (enum internal_fn ifn, int loop_dim, tree clauses, call = build_call_expr_internal_loc (UNKNOWN_LOCATION, ifn, TREE_TYPE (var), 6, ref_to_res, var, gwv, tcode, lid, rid); - gimplify_assign (var, call, ilist); + gimplify_assign (var, call, &red_seq); + num_reductions++; } - /* Call GOACC_UNLOCK. */ - if (ifn == IFN_GOACC_REDUCTION_FINI && write_back) + if (num_reductions) { - dim = build_int_cst (integer_type_node, loop_dim); - call = build_call_expr_internal_loc (UNKNOWN_LOCATION, IFN_GOACC_UNLOCK, - void_type_node, 2, dim, lid); - gimplify_and_add (call, ilist); + /* Call GOACC_LOCK. */ + if (ifn == IFN_GOACC_REDUCTION_FINI && write_back) + { + call = build_call_expr_internal_loc (UNKNOWN_LOCATION, + IFN_GOACC_LOCK, void_type_node, + 2, dim, lid); + gimplify_and_add (call, ilist); + } + + gimple_seq_add_seq (ilist, red_seq); + + /* Call GOACC_UNLOCK. */ + if (ifn == IFN_GOACC_REDUCTION_FINI && write_back) + { + dim = build_int_cst (integer_type_node, loop_dim); + call = build_call_expr_internal_loc (UNKNOWN_LOCATION, + IFN_GOACC_UNLOCK, + void_type_node, 2, dim, lid); + gimplify_and_add (call, ilist); + } } }