#undef LANG_HOOKS_TYPE_FOR_SIZE
#undef LANG_HOOKS_INIT_TS
#undef LANG_HOOKS_OMP_ARRAY_DATA
+#undef LANG_HOOKS_OMP_ARRAY_DATA_PRIVATIZE
#undef LANG_HOOKS_OMP_ARRAY_SIZE
#undef LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR
#undef LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT
#define LANG_HOOKS_TYPE_FOR_SIZE gfc_type_for_size
#define LANG_HOOKS_INIT_TS gfc_init_ts
#define LANG_HOOKS_OMP_ARRAY_DATA gfc_omp_array_data
+#define LANG_HOOKS_OMP_ARRAY_DATA_PRIVATIZE gfc_omp_array_data_privatize
#define LANG_HOOKS_OMP_ARRAY_SIZE gfc_omp_array_size
#define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR gfc_omp_is_allocatable_or_ptr
#define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT gfc_omp_check_optional_argument
return decl;
}
+/* Returns true if DECL is an array for which the actual array data has to be
+ privatized; the caller must ensure that DECL is an array descriptor,
+ i.e. 'omp_array_data' returns true. */
+
+bool
+gfc_omp_array_data_privatize (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+
+ if (POINTER_TYPE_P (type))
+ type = TREE_TYPE (type);
+
+ gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+
+ return (GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_POINTER
+ && GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_POINTER_CONT);
+}
+
/* Return the byte-size of the passed array descriptor. */
tree
bool gfc_omp_is_allocatable_or_ptr (const_tree);
tree gfc_omp_check_optional_argument (tree, bool);
tree gfc_omp_array_data (tree, bool);
+bool gfc_omp_array_data_privatize (tree);
tree gfc_omp_array_size (tree, gimple_seq *);
bool gfc_omp_privatize_by_reference (const_tree);
enum omp_clause_default_kind gfc_omp_predetermined_sharing (tree);
#define LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS NULL
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
#define LANG_HOOKS_OMP_ARRAY_DATA hook_tree_tree_bool_null
+#define LANG_HOOKS_OMP_ARRAY_DATA_PRIVATIZE hook_bool_tree_false
#define LANG_HOOKS_OMP_ARRAY_SIZE lhd_omp_array_size
#define LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR hook_bool_const_tree_false
#define LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT hook_tree_tree_bool_null
LANG_HOOKS_POST_COMPILATION_PARSING_CLEANUPS, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
LANG_HOOKS_OMP_ARRAY_DATA, \
- LANG_HOOKS_OMP_ARRAY_SIZE, \
+ LANG_HOOKS_OMP_ARRAY_DATA_PRIVATIZE, \
+ LANG_HOOKS_OMP_ARRAY_SIZE, \
LANG_HOOKS_OMP_IS_ALLOCATABLE_OR_PTR, \
LANG_HOOKS_OMP_CHECK_OPTIONAL_ARGUMENT, \
LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
is true, only the TREE_TYPE is returned without generating a new tree. */
tree (*omp_array_data) (tree, bool);
+ /* Return true if the actual array data of the passed array descriptor decl
+ shall be privatized as well, otherwise only the array descriptor is to
+ be privatized. The argument must be a decl for an array descriptor,
+ i.e. it may only be called for a decl for which omp_array_data returns
+ a non-NULL_TREE. */
+ bool (*omp_array_data_privatize) (tree);
+
/* Return a tree for the actual data of an array descriptor - or NULL_TREE
if original tree is not an array descriptor. If the second argument
is true, only the TREE_TYPE is returned without generating a new tree. */
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
&& is_gimple_omp_offloaded (ctx->stmt)
&& !is_gimple_omp_oacc (ctx->stmt)
- && lang_hooks.decls.omp_array_data (decl, true))
+ && lang_hooks.decls.omp_array_data (decl, true)
+ && lang_hooks.decls.omp_array_data_privatize (decl))
{
install_var_field (decl, false, 16 | 3, ctx);
install_var_field (decl, true, 8 | 3, ctx);
}
/* Fortran array descriptors: firstprivate of data + attach. */
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
- && lang_hooks.decls.omp_array_data (var, true))
+ && lang_hooks.decls.omp_array_data (var, true)
+ && lang_hooks.decls.omp_array_data_privatize (var))
map_cnt += 2;
do_dtor:
build_int_cstu (tkind_type, tkind));
/* Fortran array descriptors: firstprivate of data + attach. */
if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_HAS_DEVICE_ADDR
- && lang_hooks.decls.omp_array_data (ovar, true))
+ && lang_hooks.decls.omp_array_data (ovar, true)
+ && lang_hooks.decls.omp_array_data_privatize (ovar))
{
tree not_null_lb, null_lb, after_lb;
tree var1, var2, size1, size2;
--- /dev/null
+! { dg-do run }
+
+program main
+ implicit none
+
+ !$omp requires self_maps
+
+ integer :: i
+ INTEGER, POINTER :: fptr(:)
+ INTEGER, ALLOCATABLE :: alloc_array(:)
+ integer, parameter :: N = 5
+
+ ALLOCATE(fptr(N))
+ fptr = 7
+ alloc_array = [1,2,3,4,5,6]
+
+ !$omp target firstprivate(fptr, alloc_array)
+ DO i=1, N
+ fptr(i) = 5*i + fptr(i)
+ END DO
+ fptr => null() ! ptr must be privatized, pointer target not
+ if (any (alloc_array /= [1,2,3,4,5,6])) stop 1
+ alloc_array = alloc_array * 21
+ !$omp end target
+
+ ! pointer array: values shall be updated
+ if (any (fptr /= 7 + 5*[1,2,3,4,5])) stop 2
+ ! allocatables: shall not be updated
+ if (any (alloc_array /= [1,2,3,4,5,6])) stop 3
+
+ ! Check data-sharing constructs as well:
+ !$omp parallel firstprivate(fptr, alloc_array)
+ !$omp masked
+ fptr = fptr * 10
+ fptr => null()
+ if (any (alloc_array /= [1,2,3,4,5,6])) stop 4
+ alloc_array = alloc_array * 21
+ !$omp end masked
+ !$omp end parallel
+
+ if (any (fptr /= (7 + 5*[1,2,3,4,5])*10)) stop 5
+ if (any (alloc_array /= [1,2,3,4,5,6])) stop 6
+
+ call assumed_shape(alloc_array, N)
+
+ DEALLOCATE(fptr, alloc_array)
+
+contains
+ subroutine assumed_shape(x, m)
+ integer, value :: m
+ integer :: x(:)
+ integer :: y(m)
+ integer, save :: z(5)
+
+ y = [11,22,33,44,55]
+ z = [111,222,333,444,555]
+ !$omp target firstprivate(x,y,z)
+ if (any (x /= [1,2,3,4,5,6])) stop 7
+ if (any (y /= [11,22,33,44,55])) stop 8
+ if (any (z /= [111,222,333,444,555])) stop 9
+ x = 31 * x
+ y = 47 * y
+ z = 53 * z
+ !$omp end target
+
+ if (any (x /= [1,2,3,4,5,6])) stop 10
+ if (any (y /= [11,22,33,44,55])) stop 11
+ if (any (z /= [111,222,333,444,555])) stop 12
+
+ !$omp parallel firstprivate(x,y,z) if(.false.)
+ if (any (x /= [1,2,3,4,5,6])) stop 13
+ if (any (y /= [11,22,33,44,55])) stop 14
+ if (any (z /= [111,222,333,444,555])) stop 15
+ x = 31 * x
+ y = 47 * y
+ z = 53 * z
+ !$omp end parallel
+
+ if (any (x /= [1,2,3,4,5,6])) stop 16
+ if (any (y /= [11,22,33,44,55])) stop 17
+ if (any (z /= [111,222,333,444,555])) stop 18
+ end subroutine
+
+end program