https://gcc.gnu.org/g:4e14dd9c20db032fb77cc59fa3e5dc9a18ca533f

commit 4e14dd9c20db032fb77cc59fa3e5dc9a18ca533f
Author: Julian Brown <jul...@codesourcery.com>
Date:   Sat Jun 10 07:53:57 2023 +0000

    OpenACC: "declare create" fixes wrt. "allocatable" variables
    
    This patch fixes a case revealed by the previous patch where a synthetic
    "acc data" region created for a "declare create" variable could interact
    strangely with lexical inheritance behaviour.  In fact, it doesn't seem
    right to create the "acc data" region for allocatable variables at all
    -- doing so means that a data region is likely to be created for an
    unallocated variable.
    
    The fix is not to add such variables to the synthetic "acc data" region
    at all, and defer to the code that performs "enter data"/"exit data"
    for them when allocated/deallocated on the host instead. Then, "declare
    create" variables are implicitly turned into "present" clauses on in-scope
    offload regions.
    
    2023-06-16  Julian Brown  <jul...@codesourcery.com>
    
    gcc/fortran/
            * trans-openmp.cc (gfc_omp_finish_clause): Handle "declare create" 
for
            scalar allocatable variables.
            (gfc_trans_omp_clauses): Don't include allocatable vars in synthetic
            "acc data" region created for "declare create" variables.  Mark such
            variables with the "oacc declare create" attribute instead.  Don't
            create ALWAYS_POINTER mapping for target-to-host updates of declare
            create variables.
            (gfc_trans_oacc_declare): Handle empty clause list.
    
    gcc/
            * gimplify.cc (gimplify_adjust_omp_clauses_1): Handle "oacc declare
            create" attribute.
    
    libgomp/
            * testsuite/libgomp.oacc-fortran/declare-create-1.f90: New test.
            * testsuite/libgomp.oacc-fortran/declare-create-2.f90: New test.
            * testsuite/libgomp.oacc-fortran/declare-create-3.f90: New test.

Diff:
---
 gcc/ChangeLog.omp                                  |  5 +++
 gcc/fortran/ChangeLog.omp                          | 11 ++++++
 gcc/fortran/trans-openmp.cc                        | 45 +++++++++++++++++++---
 gcc/gimplify.cc                                    |  8 ++++
 libgomp/ChangeLog.omp                              |  6 +++
 .../libgomp.oacc-fortran/declare-create-1.f90      | 21 ++++++++++
 .../libgomp.oacc-fortran/declare-create-2.f90      | 25 ++++++++++++
 .../libgomp.oacc-fortran/declare-create-3.f90      | 25 ++++++++++++
 8 files changed, 141 insertions(+), 5 deletions(-)

diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp
index ac55142fa48..05120c5266d 100644
--- a/gcc/ChangeLog.omp
+++ b/gcc/ChangeLog.omp
@@ -1,3 +1,8 @@
+2023-06-19  Julian Brown  <jul...@codesourcery.com>
+
+       * gimplify.cc (gimplify_adjust_omp_clauses_1): Handle "oacc declare
+       create" attribute.
+
 2023-06-19  Julian Brown  <jul...@codesourcery.com>
 
        * gimplify.cc (omp_tsort_mark, omp_mapping_group): Move before
diff --git a/gcc/fortran/ChangeLog.omp b/gcc/fortran/ChangeLog.omp
index 04c900a3ee3..e28e1133d69 100644
--- a/gcc/fortran/ChangeLog.omp
+++ b/gcc/fortran/ChangeLog.omp
@@ -1,3 +1,14 @@
+2023-06-19  Julian Brown  <jul...@codesourcery.com>
+
+       * trans-openmp.cc (gfc_omp_finish_clause): Handle "declare create" for
+       scalar allocatable variables.
+       (gfc_trans_omp_clauses): Don't include allocatable vars in synthetic
+       "acc data" region created for "declare create" variables.  Mark such
+       variables with the "oacc declare create" attribute instead.  Don't
+       create ALWAYS_POINTER mapping for target-to-host updates of declare
+       create variables.
+       (gfc_trans_oacc_declare): Handle empty clause list.
+
 2024-06-05  Jakub Jelinek  <ja...@redhat.com>
            Frederik Harwath  <frede...@codesourcery.com>
            Sandra Loosemore  <san...@codesourcery.com>
diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc
index 71a8fff7496..33436bd9c5f 100644
--- a/gcc/fortran/trans-openmp.cc
+++ b/gcc/fortran/trans-openmp.cc
@@ -1628,7 +1628,16 @@ gfc_omp_finish_clause (tree c, gimple_seq *pre_p, bool 
openacc)
       orig_decl = decl;
 
       c4 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
-      OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
+      if (openacc
+         && GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
+         && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_FORCE_PRESENT)
+       /* This allows "declare create" to work for scalar allocatables.  The
+          resulting mapping nodes are:
+            force_present(*var) firstprivate_pointer(var)
+          which is the same as an explicit "present" clause gives.  */
+       OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_FIRSTPRIVATE_POINTER);
+      else
+       OMP_CLAUSE_SET_MAP_KIND (c4, GOMP_MAP_POINTER);
       OMP_CLAUSE_DECL (c4) = decl;
       OMP_CLAUSE_SIZE (c4) = size_int (0);
       decl = build_fold_indirect_ref (decl);
@@ -4579,6 +4588,29 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
              if (!n->sym->attr.referenced)
                continue;
 
+             /* We do not want to include allocatable vars in a synthetic
+                "acc data" region created for "!$acc declare create" vars.
+                Such variables are handled by augmenting allocate/deallocate
+                statements elsewhere (with
+                "acc enter data declare_allocate(...)", etc.).  */
+             if (op == EXEC_OACC_DECLARE
+                 && n->u.map.op == OMP_MAP_ALLOC
+                 && n->sym->attr.allocatable
+                 && n->sym->attr.oacc_declare_create)
+               {
+                 tree tree_var = gfc_get_symbol_decl (n->sym);
+                 if (!lookup_attribute ("oacc declare create",
+                                        DECL_ATTRIBUTES (tree_var)))
+                   DECL_ATTRIBUTES (tree_var)
+                     = tree_cons (get_identifier ("oacc declare create"),
+                                  NULL_TREE, DECL_ATTRIBUTES (tree_var));
+                 /* We might need to turn what would normally be a
+                    "firstprivate" mapping into a "present" mapping.  For the
+                    latter, we need the decl to be addressable.  */
+                 TREE_ADDRESSABLE (tree_var) = 1;
+                 continue;
+               }
+
              bool always_modifier = false;
              tree node = build_omp_clause (input_location, OMP_CLAUSE_MAP);
              tree node2 = NULL_TREE;
@@ -4807,7 +4839,8 @@ gfc_trans_omp_clauses (stmtblock_t *block, 
gfc_omp_clauses *clauses,
                          else if (op == EXEC_OMP_TARGET_EXIT_DATA)
                            gmk = GOMP_MAP_RELEASE;
                          else if (GFC_DECL_GET_SCALAR_ALLOCATABLE (decl)
-                                  && n->sym->attr.oacc_declare_create)
+                                  && n->sym->attr.oacc_declare_create
+                                  && n->u.map.op != OMP_MAP_FORCE_FROM)
                            {
                              if (clauses->update_allocatable)
                                gmk = GOMP_MAP_ALWAYS_POINTER;
@@ -9781,10 +9814,12 @@ gfc_trans_oacc_declare (gfc_code *code)
   gfc_start_block (&block);
 
   oacc_clauses = gfc_trans_omp_clauses (&block, 
code->ext.oacc_declare->clauses,
-                                       code->loc, false, true);
+                                       code->loc, false, true,
+                                       EXEC_OACC_DECLARE);
   stmt = gfc_trans_omp_code (code->block->next, true);
-  stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
-                    oacc_clauses);
+  if (oacc_clauses)
+    stmt = build2_loc (input_location, construct_code, void_type_node, stmt,
+                      oacc_clauses);
   gfc_add_expr_to_block (&block, stmt);
 
   return gfc_finish_block (&block);
diff --git a/gcc/gimplify.cc b/gcc/gimplify.cc
index cf9cf613784..efa28440a80 100644
--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -13692,6 +13692,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
                g->have_offload = true;
            }
        }
+      if (lookup_attribute ("oacc declare create", DECL_ATTRIBUTES (decl)))
+       flags |= GOVD_MAP_FORCE_PRESENT;
     }
   else if (flags & GOVD_SHARED)
     {
@@ -13731,6 +13733,12 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
                 "%<target%> construct", decl);
          return 0;
        }
+      if (lookup_attribute ("oacc declare create", DECL_ATTRIBUTES (decl)))
+       {
+         code = OMP_CLAUSE_MAP;
+         flags &= ~GOVD_FIRSTPRIVATE;
+         flags |= GOVD_MAP | GOVD_MAP_FORCE_PRESENT;
+       }
     }
   else if (flags & GOVD_LASTPRIVATE)
     code = OMP_CLAUSE_LASTPRIVATE;
diff --git a/libgomp/ChangeLog.omp b/libgomp/ChangeLog.omp
index 518f51b091f..ff49b4769de 100644
--- a/libgomp/ChangeLog.omp
+++ b/libgomp/ChangeLog.omp
@@ -1,3 +1,9 @@
+2023-06-19  Julian Brown  <jul...@codesourcery.com>
+
+       * testsuite/libgomp.oacc-fortran/declare-create-1.f90: New test.
+       * testsuite/libgomp.oacc-fortran/declare-create-2.f90: New test.
+       * testsuite/libgomp.oacc-fortran/declare-create-3.f90: New test.
+
 2023-06-19  Julian Brown  <jul...@codesourcery.com>
 
        * testsuite/libgomp.oacc-c-c++-common/pr70828.c: New test.
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90 
b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90
new file mode 100644
index 00000000000..9e7e60f1440
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-1.f90
@@ -0,0 +1,21 @@
+! { dg-do run }
+
+module m
+integer :: mint
+!$acc declare create (mint)
+end module m
+
+program p
+use m
+
+mint = 0
+
+!$acc serial
+mint = 5
+!$acc end serial
+
+!$acc update host(mint)
+
+if (mint.ne.5) stop 1
+
+end program p
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90 
b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90
new file mode 100644
index 00000000000..675f6902775
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-2.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+
+module m
+integer, allocatable :: mint
+!$acc declare create (mint)
+end module m
+
+program p
+use m
+
+allocate(mint)
+
+mint = 0
+
+!$acc serial
+mint = 5
+!$acc end serial
+
+!$acc update host(mint)
+
+if (mint.ne.5) stop 1
+
+deallocate(mint)
+
+end program p
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90 
b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90
new file mode 100644
index 00000000000..16651cb1f5e
--- /dev/null
+++ b/libgomp/testsuite/libgomp.oacc-fortran/declare-create-3.f90
@@ -0,0 +1,25 @@
+! { dg-do run }
+
+module m
+integer, allocatable :: mint(:)
+!$acc declare create (mint)
+end module m
+
+program p
+use m
+
+allocate(mint(1:20))
+
+mint = 0
+
+!$acc serial
+mint = 5
+!$acc end serial
+
+!$acc update host(mint)
+
+if (any(mint.ne.5)) stop 1
+
+deallocate(mint)
+
+end program p

Reply via email to