From b8fb83b36d0f96b12af9a1f5596f31b3c6b72ef0 Mon Sep 17 00:00:00 2001
From: Cesar Philippidis <cesar@codesourcery.com>
Date: Mon, 6 Aug 2018 09:19:28 -0700
Subject: [PATCH] [OpenACC] Add support for firstprivate Fortran allocatable
scalars
This patch updates the way that lower_omp_target uses firstprivate
pointers in OpenACC offloaded regions. On host side, when preparing
pointer type firstprivate data mapping, not to be confused with
GOMP_MAP_FIRSTPRIVATE_POINTER, the compiler passes passes the address
of the value being pointed to, not the address of the pointer
itself. Correspondingly, on the device side, the compiler generates to
deference the remapped pointer once and copy the data to a local
buffer.
While this behavior like it would break things, it will not affect C
or C++ data mappings, because those languages transfer pointers via
GOMP_MAP_FIRSTPRIVATE_POINTER. In addition, this will not cause
problems with array types, because the default remapping rules for
OpenACC is to transfer them in via copy. Besides it really doesn't
make sense to allow arrays to be transferred in via firstprivate
because that would use up a lot of memory on the accelerator.
2018-XX-YY Cesar Philippidis <cesar@codesourcery.com>
gcc/
omp-low.c (lower_omp_target): Update OpenACC handling of
pointer variables with GOMP_MAP_FIRSTPRIVATE mappings.
libgomp/
testsuite/libgomp.oacc-fortran/allocatable-scalar.f90: New
test.
---
gcc/omp-low.c | 18 ++++++++----
.../libgomp.oacc-fortran/allocatable-scalar.f90 | 33 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 5 deletions(-)
create mode 100644 libgomp/testsuite/libgomp.oacc-fortran/allocatable-scalar.f90
@@ -7643,15 +7643,21 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
gcc_assert (is_gimple_omp_oacc (ctx->stmt));
- if (omp_is_reference (new_var)
- && TREE_CODE (TREE_TYPE (new_var)) != POINTER_TYPE)
+ if (omp_is_reference (new_var))
{
/* Create a local object to hold the instance
value. */
- tree type = TREE_TYPE (TREE_TYPE (new_var));
+ tree type = TREE_TYPE (new_var);
+ /* Pointer types are mapped onto the device via a
+ single level of indirection. */
+ if (TREE_CODE (type) != POINTER_TYPE)
+ type = TREE_TYPE (type);
const char *id = IDENTIFIER_POINTER (DECL_NAME (new_var));
tree inst = create_tmp_var (type, id);
- gimplify_assign (inst, fold_indirect_ref (x), &fplist);
+ if (TREE_CODE (TREE_TYPE (new_var)) == POINTER_TYPE)
+ gimplify_assign (inst, fold_indirect_ref (x), &fplist);
+ else
+ gimplify_assign (inst, fold_indirect_ref (x), &fplist);
x = build_fold_addr_expr (inst);
}
gimplify_assign (new_var, x, &fplist);
@@ -7879,7 +7885,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
{
gcc_assert (is_gimple_omp_oacc (ctx->stmt));
- if (!omp_is_reference (var))
+ /* Handle Fortran allocatable scalars. */
+ if (!omp_is_reference (var)
+ && TREE_CODE (TREE_TYPE (var)) != POINTER_TYPE)
{
if (is_gimple_reg (var)
&& OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT (c))
new file mode 100644
@@ -0,0 +1,33 @@
+! Test non-declared allocatable scalars in OpenACC data clauses.
+
+! { dg-do run }
+
+program main
+ implicit none
+ integer, parameter :: n = 100
+ integer, allocatable :: a, c
+ integer :: i, b(n)
+
+ allocate (a)
+
+ a = 50
+
+ !$acc parallel loop
+ do i = 1, n;
+ b(i) = a
+ end do
+
+ do i = 1, n
+ if (b(i) /= a) call abort
+ end do
+
+ allocate (c)
+
+ !$acc parallel copyout(c) num_gangs(1)
+ c = a
+ !$acc end parallel
+
+ if (c /= a) call abort
+
+ deallocate (a, c)
+end program main
--
2.7.4