Message ID | 5696CFC1.9060004@codesourcery.com |
---|---|
State | New |
Headers | show |
On Wed, Jan 13, 2016 at 02:29:21PM -0800, Cesar Philippidis wrote: > --- a/gcc/gimplify.c > +++ b/gcc/gimplify.c > @@ -5994,6 +5994,11 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) > { > const char *rkind; > bool on_device = false; > + tree type = TREE_TYPE (decl); > + > + if (TREE_CODE (type) == REFERENCE_TYPE > + || POINTER_TYPE_P (type)) I think this should be just POINTER_TYPE_P--this macro checks for REFERENCE_TYPE as well. Marek
On Wed, Jan 13, 2016 at 11:35:08PM +0100, Marek Polacek wrote: > On Wed, Jan 13, 2016 at 02:29:21PM -0800, Cesar Philippidis wrote: > > --- a/gcc/gimplify.c > > +++ b/gcc/gimplify.c > > @@ -5994,6 +5994,11 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) > > { > > const char *rkind; > > bool on_device = false; > > + tree type = TREE_TYPE (decl); > > + > > + if (TREE_CODE (type) == REFERENCE_TYPE > > + || POINTER_TYPE_P (type)) > > I think this should be just POINTER_TYPE_P--this macro checks for > REFERENCE_TYPE as well. Unless the spec says that for all pointers you should consider what it points to, this really looks weird to me. Say for OpenMP, I usually use lang_hooks.decls.omp_privatize_by_reference (decl) hook for similar purposes where the FEs have the possibility to say if you are interested in the pointer/reference itself or what it points to, which is just always false for C, for C++ REFERENCE_TYPE vars and invisiref stuff, and for Fortran various. So I'd expect to see instead tree type = TREE_TYPE (decl); if (lang_hooks.decls.omp_privatize_by_reference (decl)) type = TREE_TYPE (type); or so. Just looking at TREE_TYPE of arbitrary POINTER_TYPE_P has also the disadvantage that the pointer can be void *, or pointer to incomplete type, ... Jakub
On 01/13/16 17:44, Jakub Jelinek wrote: > On Wed, Jan 13, 2016 at 11:35:08PM +0100, Marek Polacek wrote: >> On Wed, Jan 13, 2016 at 02:29:21PM -0800, Cesar Philippidis wrote: >>> --- a/gcc/gimplify.c >>> +++ b/gcc/gimplify.c >>> @@ -5994,6 +5994,11 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) >>> { >>> const char *rkind; >>> bool on_device = false; >>> + tree type = TREE_TYPE (decl); >>> + >>> + if (TREE_CODE (type) == REFERENCE_TYPE >>> + || POINTER_TYPE_P (type)) >> >> I think this should be just POINTER_TYPE_P--this macro checks for >> REFERENCE_TYPE as well. > > Unless the spec says that for all pointers you should consider what it > points to, this really looks weird to me. I think the spec is silent. I remember looking at this before and thinking looking through pointers was strange. IMHO it should behave in a manner as similar as possible to OpenMP (which I presume is precise about whether one should look through arbitrary pointer types). Is this a case of the Fortran FE OpenACC bits not annotating some artificial object correctly? nathan
2016-01-13 Cesar Philippidis <cesar@codesourcery.com> gcc/ * gimplify.c (oacc_default_clause): Decode reference and pointer types for both kernels and parallel regions. libgomp/ * testsuite/libgomp.oacc-fortran/kernels-data.f90: New test. diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 17144d1..bc0715b 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5994,6 +5994,11 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) { const char *rkind; bool on_device = false; + tree type = TREE_TYPE (decl); + + if (TREE_CODE (type) == REFERENCE_TYPE + || POINTER_TYPE_P (type)) + type = TREE_TYPE (type); if ((ctx->region_type & (ORT_ACC_PARALLEL | ORT_ACC_KERNELS)) != 0 && is_global_var (decl) @@ -6012,7 +6017,7 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) /* Scalars are default 'copy' under kernels, non-scalars are default 'present_or_copy'. */ flags |= GOVD_MAP; - if (!AGGREGATE_TYPE_P (TREE_TYPE (decl))) + if (!AGGREGATE_TYPE_P (type)) flags |= GOVD_MAP_FORCE; rkind = "kernels"; @@ -6020,12 +6025,6 @@ oacc_default_clause (struct gimplify_omp_ctx *ctx, tree decl, unsigned flags) case ORT_ACC_PARALLEL: { - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == REFERENCE_TYPE - || POINTER_TYPE_P (type)) - type = TREE_TYPE (type); - if (on_device || AGGREGATE_TYPE_P (type)) /* Aggregates default to 'present_or_copy'. */ flags |= GOVD_MAP; diff --git a/libgomp/testsuite/libgomp.oacc-fortran/kernels-data.f90 b/libgomp/testsuite/libgomp.oacc-fortran/kernels-data.f90 new file mode 100644 index 0000000..bf812b6 --- /dev/null +++ b/libgomp/testsuite/libgomp.oacc-fortran/kernels-data.f90 @@ -0,0 +1,30 @@ +! Ensure that a non-scalar dummy argument which is implicitly used in a +! kernels regions is properly mapped using present_or_copy. + +! { dg-do run } + +program main + implicit none + + integer, parameter :: n = 100 + integer :: array(n), i + + !$acc data copy(array) + call data(array, n) + !$acc end data + + do i = 1, n + if (array(i) .ne. i) call abort + end do +end program main + +subroutine data (array, n) + integer, dimension (n) :: array + integer :: n, i + + !$acc kernels + do i = 1, n + array(i) = i + end do + !$acc end kernels +end subroutine data