On Fri, Nov 29, 2019 at 01:03:13PM +0100, Tobias Burnus wrote:
> --- a/gcc/fortran/trans-openmp.c
> +++ b/gcc/fortran/trans-openmp.c
> @@ -60,7 +60,8 @@ gfc_omp_is_allocatable_or_ptr (const_tree decl)
>  
>  /* True if the argument is an optional argument; except that false is also
>     returned for arguments with the value attribute (nonpointers) and for
> -   assumed-shape variables (decl is a local variable containing arg->data).  
> */
> +   assumed-shape variables (decl is a local variable containing arg->data).
> +   Note that pvoid_type_node is for 'type(c_ptr), value.  */
>  
>  static bool
>  gfc_omp_is_optional_argument (const_tree decl)
> @@ -68,6 +69,7 @@ gfc_omp_is_optional_argument (const_tree decl)
>    return (TREE_CODE (decl) == PARM_DECL
>         && DECL_LANG_SPECIFIC (decl)
>         && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE
> +       && TREE_TYPE (decl) != pvoid_type_node

Is it always pvoid_type_node, or could it be say const qualified version
thereof etc. (C void const *) etc.?  If the latter, then
          && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))
might be better check.  If it is always just pvoid_type_node, the above is
fine sure.

>         && GFC_DECL_OPTIONAL_ARGUMENT (decl));
>  }
>  
> @@ -99,9 +101,12 @@ gfc_omp_check_optional_argument (tree decl, bool 
> for_present_check)
>        || !GFC_DECL_OPTIONAL_ARGUMENT (decl))
>      return NULL_TREE;
>  
> -  /* For VALUE, the scalar variable is passed as is but a hidden argument
> -     denotes the value.  Cf. trans-expr.c.  */
> -  if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
> +   /* Scalars with VALUE attribute which are passed by value use a hidden
> +      argument to denote the present status.  They are passed as nonpointer 
> type
> +      with one exception: 'type(c_ptr), value' as '*void'.  */

void* or void * instead of *void?

> +   /* Cf. trans-expr.c's gfc_conv_expr_present.  */
> +   if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE
> +       || TREE_TYPE (decl) == pvoid_type_node)

And similar question to the above one.

> @@ -12027,14 +12022,12 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, 
> omp_context *ctx)
>                              && omp_is_allocatable_or_ptr (ovar))))
>                     {
>                       var = build_simple_mem_ref (var);
> -                     do_optional_check = true;
>                     }

The above then becomes { single_stmt } and so should be changed to
single_stmt without {}s around it.

> @@ -1,33 +1,47 @@
>  ! Check whether absent optional arguments are properly
>  ! handled with use_device_{addr,ptr}.
>  program main
> + use iso_c_binding, only: c_ptr, c_loc
>   implicit none (type, external)
>   call foo()
>  contains
> -  subroutine foo(v, w, x, y, z)
> +  subroutine foo(v, w, x, y, z, cptr)
>      integer, target, optional, value :: v
>      integer, target, optional :: w
>      integer, target, optional :: x(:)
>      integer, target, optional, allocatable :: y
>      integer, target, optional, allocatable :: z(:)
> +    type(c_ptr), target, optional, value :: cptr
>      integer :: d
>  
> -    !$omp target data map(d) use_device_addr(v, w, x, y, z)
> -      if(present(v)) stop 1
> -      if(present(w)) stop 2
> -      if(present(x)) stop 3
> -      if(present(y)) stop 4
> -      if(present(z)) stop 5
> +    ! Need to map per-VALUE arguments, if present
> +    if (present(v)) then
> +      !$omp target enter data map(to:v)
> +      stop 1  ! – but it shall not be present in this test case.
> +    end if
> +    if (present(cptr)) then
> +      !$omp target enter data map(to:cptr)
> +      stop 2  ! – but it shall not be present in this test case.
> +    end if

Shouln't the stop arguments differ from anything else already in the
testcase?

> +
> +    !$omp target data map(d) use_device_addr(v, w, x, y, z, cptr)
> +      if (present(v)) then; v    = 5; stop 1; endif
> +      if (present(w)) then; w    = 5; stop 2; endif
> +      if (present(x)) then; x(1) = 5; stop 3; endif
> +      if (present(y)) then; y    = 5; stop 4; endif
> +      if (present(z)) then; z(1) = 5; stop 5; endif
> +      if (present(cptr)) then; cptr = c_loc(v); stop 6; endif
>      !$omp end target data
>  
>  ! Using 'v' in use_device_ptr gives an ICE
>  ! TODO: Find out what the OpenMP spec permits for use_device_ptr
>  
> -    !$omp target data map(d) use_device_ptr(w, x, y, z)
> -      if(present(w)) stop 6
> -      if(present(x)) stop 7
> -      if(present(y)) stop 8
> -      if(present(z)) stop 9
> +    !$omp target data map(d) use_device_ptr(w, x, y, z, cptr)
> +      if(present(w)) then; w    = 5; stop 11; endif
> +      if(present(x)) then; x(1) = 5; stop 12; endif
> +      if(present(y)) then; y    = 5; stop 13; endif
> +      if(present(z)) then; z(1) = 5; stop 14; endif
> +      if(present(cptr)) then; cptr = c_loc(x); stop 15; endif
>      !$omp end target data
>    end subroutine foo
>  end program main

Otherwise LGTM.

        Jakub

Reply via email to