On Thu, Apr 07, 2016 at 09:34:43PM -0700, Cesar Philippidis wrote:
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -5802,7 +5802,8 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree 
> decl, unsigned int flags)
>      flags |= GOVD_SEEN;
>  
>    n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
> -  if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
> +  if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0
> +      && ctx->region_type != ORT_ACC_PARALLEL)
>      {
>        /* We shouldn't be re-adding the decl with the same data
>        sharing class.  */

Why?

> @@ -6557,6 +6558,24 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
> *pre_p,
>       break;
>        }
>  
> +/* OpenACC parallel reductions need a present_or_copy clause to ensure
> +   that the original variable used in the reduction gets updated on
> +   the host.  Scan the list of clauses for reduction so that any existing
> +   data clause can be adjusted if necessary.  */
> +  if (region_type == ORT_ACC_PARALLEL)
> +    {
> +      for (c = *list_p; c; c = OMP_CLAUSE_CHAIN (c))
> +     {
> +       tree decl = NULL_TREE;
> +
> +       if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
> +         continue;
> +
> +       decl = OMP_CLAUSE_DECL (c);
> +       omp_add_variable (ctx, decl, GOVD_REDUCTION);
> +     }
> +    }
> +

And this looks also wrong, why?
If I try under the debugger 3 cases:
void f1 (int sum)
{
  #pragma acc parallel reduction(+:sum) present_or_copy(sum)
    ;
}
void f2 (int sum)
{
  #pragma acc parallel present_or_copy(sum)
    ;
}
void f3 (int sum)
{
  #pragma acc parallel reduction(+:sum)
    ;
}
then I see the loop that starts with the while below doing the right thing
already.  In the first case you end up with
GOVD_SEEN | GOVD_EXPLICIT | GOVD_REDUCTION | GOVD_MAP
in the second with
GOVD_SEEN | GOVD_EXPLICIT | GOVD_MAP
and third one with
GOVD_SEEN | GOVD_EXPLICIT | GOVD_REDUCTION

That is where you IMHO should stop at the gimplify_scan_omp_clauses side,
so don't modify neither omp_add_variable nor gimplify_scan_omp_clauses
at all, and do everything else in gimplify_adjust_omp_clauses.
That function walks the explicit clauses and has all the info gathered
during gimplify_scan_omp_clauses available in the splay tree.
So, you can do all the checking there.  Say on OMP_CLAUSE_REDUCTION
for the ORT_ACC_PARALLEL check the flags if they include GOVD_PRIVATE
or GOVD_FIRSTPRIVATE, if yes, complain.  Also check if GOVD_MAP is included,
if not, add the extra OMP_CLAUSE_MAP tofrom.
And, on OMP_CLAUSE_MAP, check if GOVD_REDUCTION is set on ORT_ACC_PARALLEL,
and if yes, check if it is tofrom and complain otherwise.

>    while ((c = *list_p) != NULL)
>      {
>        bool remove = false;
> @@ -6808,6 +6827,31 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
> *pre_p,
>  
>       case OMP_CLAUSE_MAP:
>         decl = OMP_CLAUSE_DECL (c);
> +       if (region_type == ORT_ACC_PARALLEL)
> +         {
> +           tree t = DECL_P (decl) ? decl : TREE_OPERAND (decl, 0);
> +           splay_tree_node n = NULL;
> +
> +           if (DECL_P (t))
> +             n = splay_tree_lookup (ctx->variables, (splay_tree_key)t);
> +
> +           if (n)
> +             {
> +               int 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 (error_operand_p (decl))
>           remove = true;
>         switch (code)

So the above is also wrong IMNSHO.

        Jakub

Reply via email to