]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fortran/OpenMP: align/allocator modifiers to the allocate clause
authorTobias Burnus <tobias@codesourcery.com>
Mon, 12 Dec 2022 08:31:50 +0000 (09:31 +0100)
committerTobias Burnus <tobias@codesourcery.com>
Mon, 12 Dec 2022 08:31:50 +0000 (09:31 +0100)
gcc/fortran/ChangeLog:

* dump-parse-tree.cc (show_omp_namelist): Improve OMP_LIST_ALLOCATE
output.
* gfortran.h (struct gfc_omp_namelist): Add 'align' to 'u'.
(gfc_free_omp_namelist): Add bool arg.
* match.cc (gfc_free_omp_namelist): Likewise; free 'u.align'.
* openmp.cc (gfc_free_omp_clauses, gfc_match_omp_clause_reduction,
gfc_match_omp_flush): Update call.
(gfc_match_omp_clauses): Match 'align/allocate modifers in
'allocate' clause.
(resolve_omp_clauses): Resolve align.
* st.cc (gfc_free_statement): Update call
* trans-openmp.cc (gfc_trans_omp_clauses): Handle 'align'.

libgomp/ChangeLog:

* libgomp.texi (5.1 Impl. Status): Split allocate clause/directive
item about 'align'; mark clause as 'Y' and directive as 'N'.
* testsuite/libgomp.fortran/allocate-2.f90: New test.
* testsuite/libgomp.fortran/allocate-3.f90: New test.

(cherry picked from commit b2e1c49b4a4592f9e96ae9ece8af7d0e6527b194)

gcc/fortran/ChangeLog.omp
gcc/fortran/dump-parse-tree.cc
gcc/fortran/gfortran.h
gcc/fortran/match.cc
gcc/fortran/openmp.cc
gcc/fortran/st.cc
gcc/fortran/trans-openmp.cc
libgomp/ChangeLog.omp
libgomp/libgomp.texi
libgomp/testsuite/libgomp.fortran/allocate-2a.f90 [new file with mode: 0644]
libgomp/testsuite/libgomp.fortran/allocate-3.f90 [new file with mode: 0644]

index 6af224e8146b6030bab7a9977dba7b0b8f0fd3eb..6aec789f641761cb9033ee3657652b01ed4661bd 100644 (file)
@@ -1,3 +1,21 @@
+2022-12-12  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2022-12-09  Tobias Burnus  <tobias@codesourcery.com>
+
+       * dump-parse-tree.cc (show_omp_namelist): Improve OMP_LIST_ALLOCATE
+       output.
+       * gfortran.h (struct gfc_omp_namelist): Add 'align' to 'u'.
+       (gfc_free_omp_namelist): Add bool arg.
+       * match.cc (gfc_free_omp_namelist): Likewise; free 'u.align'.
+       * openmp.cc (gfc_free_omp_clauses, gfc_match_omp_clause_reduction,
+       gfc_match_omp_flush): Update call.
+       (gfc_match_omp_clauses): Match 'align/allocate modifers in
+       'allocate' clause.
+       (resolve_omp_clauses): Resolve align.
+       * st.cc (gfc_free_statement): Update call
+       * trans-openmp.cc (gfc_trans_omp_clauses): Handle 'align'.
+
 2022-11-28  Tobias Burnus  <tobias@codesourcery.com>
 
        Backported from master:
index ae29edb0b933ccf086a0fb829fe808327ce5b1ed..4da4d813d1d7b798f5ff74d9afa1c4df4dec3613 100644 (file)
@@ -1357,6 +1357,29 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
            }
          ns_iter = n->u2.ns;
        }
+      if (list_type == OMP_LIST_ALLOCATE)
+       {
+         if (n->expr)
+           {
+             fputs ("allocator(", dumpfile);
+             show_expr (n->expr);
+             fputc (')', dumpfile);
+           }
+         if (n->expr && n->u.align)
+           fputc (',', dumpfile);
+         if (n->u.align)
+           {
+             fputs ("allocator(", dumpfile);
+             show_expr (n->u.align);
+             fputc (')', dumpfile);
+           }
+         if (n->expr || n->u.align)
+           fputc (':', dumpfile);
+         fputs (n->sym->name, dumpfile);
+         if (n->next)
+           fputs (") ALLOCATE(", dumpfile);
+         continue;
+       }
       if (list_type == OMP_LIST_REDUCTION)
        switch (n->u.reduction_op)
          {
index 97c30fd3a5f26d0bb3666e9af3a48720c172828b..85dcc3931f4ce3b656863c5015dcdcf983cf2b2a 100644 (file)
@@ -1351,6 +1351,7 @@ typedef struct gfc_omp_namelist
       gfc_omp_reduction_op reduction_op;
       gfc_omp_depend_doacross_op depend_doacross_op;
       gfc_omp_map_op map_op;
+      gfc_expr *align;
       struct
        {
          ENUM_BITFIELD (gfc_omp_linear_op) op:4;
@@ -3592,7 +3593,7 @@ void gfc_free_iterator (gfc_iterator *, int);
 void gfc_free_forall_iterator (gfc_forall_iterator *);
 void gfc_free_alloc_list (gfc_alloc *);
 void gfc_free_namelist (gfc_namelist *);
-void gfc_free_omp_namelist (gfc_omp_namelist *, bool);
+void gfc_free_omp_namelist (gfc_omp_namelist *, bool, bool);
 void gfc_free_equiv (gfc_equiv *);
 void gfc_free_equiv_until (gfc_equiv *, gfc_equiv *);
 void gfc_free_data (gfc_data *);
index 55779a51054f10df3cfc9c236dee2b0eb23bec74..9bca21f5ec99b9361fbecf4ab7be00ccfaf73983 100644 (file)
@@ -5518,13 +5518,15 @@ gfc_free_namelist (gfc_namelist *name)
 /* Free an OpenMP namelist structure.  */
 
 void
-gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns)
+gfc_free_omp_namelist (gfc_omp_namelist *name, bool free_ns, bool free_align)
 {
   gfc_omp_namelist *n;
 
   for (; name; name = n)
     {
       gfc_free_expr (name->expr);
+      if (free_align)
+       gfc_free_expr (name->u.align);
       if (free_ns)
        gfc_free_namespace (name->u2.ns);
       else if (name->u2.udr)
index 26c1385beb03d86bbabeed5d5ad1c7772b705619..9566910ba5d45599203cfd2a2780efcc87869cc9 100644 (file)
@@ -197,7 +197,8 @@ gfc_free_omp_clauses (gfc_omp_clauses *c)
   gfc_free_expr (c->vector_length_expr);
   for (i = 0; i < OMP_LIST_NUM; i++)
     gfc_free_omp_namelist (c->lists[i],
-                          i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND);
+                          i == OMP_LIST_AFFINITY || i == OMP_LIST_DEPEND,
+                          i == OMP_LIST_ALLOCATE);
   gfc_free_expr_list (c->wait_list);
   gfc_free_expr_list (c->tile_list);
   free (CONST_CAST (char *, c->critical_name));
@@ -565,7 +566,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false);
+  gfc_free_omp_namelist (head, false, false);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -655,7 +656,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP variable list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false);
+  gfc_free_omp_namelist (head, false, false);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -764,7 +765,7 @@ syntax:
   gfc_error ("Syntax error in OpenMP SINK dependence-type list at %C");
 
 cleanup:
-  gfc_free_omp_namelist (head, false);
+  gfc_free_omp_namelist (head, false, false);
   gfc_current_locus = old_loc;
   return MATCH_ERROR;
 }
@@ -1492,7 +1493,7 @@ gfc_match_omp_clause_reduction (char pc, gfc_omp_clauses *c, bool openacc,
       *head = NULL;
       gfc_error_now ("!$OMP DECLARE REDUCTION %s not found at %L",
                     buffer, &old_loc);
-      gfc_free_omp_namelist (n, false);
+      gfc_free_omp_namelist (n, false, false);
     }
   else
     for (n = *head; n; n = n->next)
@@ -2332,7 +2333,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
 
              if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
                {
-                 gfc_free_omp_namelist (*head, false);
+                 gfc_free_omp_namelist (*head, false, false);
                  gfc_current_locus = old_loc;
                  *head = NULL;
                  break;
@@ -2400,17 +2401,33 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
              && gfc_match ("allocate ( ") == MATCH_YES)
            {
              gfc_expr *allocator = NULL;
+             gfc_expr *align = NULL;
              old_loc = gfc_current_locus;
-             m = gfc_match_expr (&allocator);
-             if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
+             if ((m = gfc_match ("allocator ( %e )", &allocator)) == MATCH_YES)
+               gfc_match (" , align ( %e )", &align);
+             else if ((m = gfc_match ("align ( %e )", &align)) == MATCH_YES)
+               gfc_match (" , allocator ( %e )", &allocator);
+
+             if (m == MATCH_YES)
                {
-                 /* If no ":" then there is no allocator, we backtrack
-                    and read the variable list.  */
-                 gfc_free_expr (allocator);
-                 allocator = NULL;
-                 gfc_current_locus = old_loc;
+                 if (gfc_match (" : ") != MATCH_YES)
+                   {
+                     gfc_error ("Expected %<:%> at %C");
+                     goto error;
+                   }
+               }
+             else
+               {
+                 m = gfc_match_expr (&allocator);
+                 if (m == MATCH_YES && gfc_match (" : ") != MATCH_YES)
+                   {
+                      /* If no ":" then there is no allocator, we backtrack
+                         and read the variable list.  */
+                     gfc_free_expr (allocator);
+                     allocator = NULL;
+                     gfc_current_locus = old_loc;
+                   }
                }
-
              gfc_omp_namelist **head = NULL;
              m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_ALLOCATE],
                                               true, NULL, &head);
@@ -2418,16 +2435,18 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
              if (m != MATCH_YES)
                {
                  gfc_free_expr (allocator);
+                 gfc_free_expr (align);
                  gfc_error ("Expected variable list at %C");
                  goto error;
                }
 
              for (gfc_omp_namelist *n = *head; n; n = n->next)
-               if (allocator)
-                 n->expr = gfc_copy_expr (allocator);
-               else
-                 n->expr = NULL;
+               {
+                 n->expr = (allocator) ? gfc_copy_expr (allocator) : NULL;
+                 n->u.align = (align) ? gfc_copy_expr (align) : NULL;
+               }
              gfc_free_expr (allocator);
+             gfc_free_expr (align);
              continue;
            }
          if ((mask & OMP_CLAUSE_AT)
@@ -3256,7 +3275,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
                    end_colon = true;
                  else if (gfc_match (" )") != MATCH_YES)
                    {
-                     gfc_free_omp_namelist (*head, false);
+                     gfc_free_omp_namelist (*head, false, false);
                      gfc_current_locus = old_loc;
                      *head = NULL;
                      break;
@@ -3267,7 +3286,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
                {
                  if (gfc_match (" %e )", &step) != MATCH_YES)
                    {
-                     gfc_free_omp_namelist (*head, false);
+                     gfc_free_omp_namelist (*head, false, false);
                      gfc_current_locus = old_loc;
                      *head = NULL;
                      goto error;
@@ -3364,7 +3383,7 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
                    }
                  if (has_error)
                    {
-                     gfc_free_omp_namelist (*head, false);
+                     gfc_free_omp_namelist (*head, false, false);
                      *head = NULL;
                      goto error;
                    }
@@ -5176,14 +5195,14 @@ gfc_match_omp_flush (void)
     {
       gfc_error ("List specified together with memory order clause in FLUSH "
                 "directive at %C");
-      gfc_free_omp_namelist (list, false);
+      gfc_free_omp_namelist (list, false, false);
       gfc_free_omp_clauses (c);
       return MATCH_ERROR;
     }
   if (gfc_match_omp_eos () != MATCH_YES)
     {
       gfc_error ("Unexpected junk after $OMP FLUSH statement at %C");
-      gfc_free_omp_namelist (list, false);
+      gfc_free_omp_namelist (list, false, false);
       gfc_free_omp_clauses (c);
       return MATCH_ERROR;
     }
@@ -8070,19 +8089,36 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
   if (omp_clauses->lists[OMP_LIST_ALLOCATE])
     {
       for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
-       if (n->expr && (n->expr->ts.type != BT_INTEGER
-           || n->expr->ts.kind != gfc_c_intptr_kind))
-         {
-           gfc_error ("Expected integer expression of the "
-                      "'omp_allocator_handle_kind' kind at %L",
-                      &n->expr->where);
-           break;
-         }
+       {
+         if (n->expr && (!gfc_resolve_expr (n->expr)
+                         || n->expr->ts.type != BT_INTEGER
+                         || n->expr->ts.kind != gfc_c_intptr_kind))
+           {
+             gfc_error ("Expected integer expression of the "
+                        "%<omp_allocator_handle_kind%> kind at %L",
+                        &n->expr->where);
+             break;
+           }
+         if (!n->u.align)
+           continue;
+         int alignment = 0;
+         if (!gfc_resolve_expr (n->u.align)
+             || n->u.align->ts.type != BT_INTEGER
+             || n->u.align->rank != 0
+             || gfc_extract_int (n->u.align, &alignment)
+             || alignment <= 0)
+           {
+             gfc_error ("ALIGN modifier requires a scalar positive "
+                        "constant integer alignment expression at %L",
+                        &n->u.align->where);
+             break;
+           }
+       }
 
       /* Check for 2 things here.
-     1.  There is no duplication of variable in allocate clause.
-     2.  Variable in allocate clause are also present in some
-        privatization clase (non-composite case).  */
+        1.  There is no duplication of variable in allocate clause.
+        2.  Variable in allocate clause are also present in some
+            privatization clase (non-composite case).  */
       for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
        n->sym->mark = 0;
 
@@ -8099,7 +8135,7 @@ resolve_omp_clauses (gfc_code *code, gfc_omp_clauses *omp_clauses,
                {
                  prev->next = n->next;
                  n->next = NULL;
-                 gfc_free_omp_namelist (n, 0);
+                 gfc_free_omp_namelist (n, false, true);
                  n = prev->next;
                }
              continue;
index 90b4417239de6e162167b2e6225ec3d3f1c91e1a..a02d5c0ce7d495447ad96e1c3d9349ceb6709cdf 100644 (file)
@@ -287,7 +287,7 @@ gfc_free_statement (gfc_code *p)
       break;
 
     case EXEC_OMP_FLUSH:
-      gfc_free_omp_namelist (p->ext.omp_namelist, false);
+      gfc_free_omp_namelist (p->ext.omp_namelist, false, false);
       break;
 
     case EXEC_OMP_BARRIER:
index 892f0623243cfebf3a65076ed8dea21eb5914eef..1ac7418495fb230167af4ca92643a5f50ac60233 100644 (file)
@@ -4119,6 +4119,14 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
                        allocator_ = gfc_evaluate_now (se.expr, block);
                        OMP_ALLOCATE_ALLOCATOR (node) = allocator_;
                      }
+                   if (n->u.align)
+                     {
+                       tree align_;
+                       gfc_init_se (&se, NULL);
+                       gfc_conv_expr (&se, n->u.align);
+                       align_ = gfc_evaluate_now (se.expr, block);
+                       OMP_CLAUSE_ALLOCATE_ALIGN (node) = align_;
+                     }
                    omp_clauses = gfc_trans_add_clause (node, omp_clauses);
                  }
              }
index 391545c4e344146cee72d5eea3b3deff2e57f3f3..cb57ecfee3eb54a5024de25501e9ad248bc76c35 100644 (file)
@@ -1,3 +1,12 @@
+2022-12-12  Tobias Burnus  <tobias@codesourcery.com>
+
+       Backported from master:
+       2022-12-09  Tobias Burnus  <tobias@codesourcery.com>
+       * libgomp.texi (5.1 Impl. Status): Split allocate clause/directive
+       item about 'align'; mark clause as 'Y' and directive as 'N'.
+       * testsuite/libgomp.fortran/allocate-2.f90: New test.
+       * testsuite/libgomp.fortran/allocate-3.f90: New test.
+
 2022-12-06  Marcel Vollweiler  <marcel@codesourcery.com>
 
        Backported from master:
index 88bc712aab26fe7a67f0012d386d414d075d3467..896d187f1ff3b2acd17e7741af96e1f2603150f7 100644 (file)
@@ -296,8 +296,8 @@ The OpenMP 4.5 specification is fully supported.
 @item Loop transformation constructs @tab N @tab
 @item @code{strict} modifier in the @code{grainsize} and @code{num_tasks}
       clauses of the @code{taskloop} construct @tab Y @tab
-@item @code{align} clause/modifier in @code{allocate} directive/clause
-      and @code{allocator} directive @tab P @tab C/C++ on clause only
+@item @code{align} clause in @code{allocate} directive @tab N @tab
+@item @code{align} modifier in @code{allocate} clause @tab Y @tab
 @item @code{thread_limit} clause to @code{target} construct @tab Y @tab
 @item @code{has_device_addr} clause to @code{target} construct @tab Y @tab
 @item Iterators in @code{target update} motion clauses and @code{map}
diff --git a/libgomp/testsuite/libgomp.fortran/allocate-2a.f90 b/libgomp/testsuite/libgomp.fortran/allocate-2a.f90
new file mode 100644 (file)
index 0000000..10cac50
--- /dev/null
@@ -0,0 +1,26 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+use omp_lib
+implicit none
+integer :: q, x,y,z
+
+!$omp parallel  &
+!$omp&   allocate(omp_low_lat_mem_alloc : x) &
+!$omp&   allocate(omp_cgroup_mem_alloc : y) &
+!$omp&   allocate(omp_pteam_mem_alloc : z) &
+!$omp&   firstprivate(q, x,y,z)
+!$omp end parallel
+
+!$omp parallel &
+!$omp&   allocate(align ( 64 ), allocator(omp_default_mem_alloc) : x) &
+!$omp&   allocate(allocator(omp_large_cap_mem_alloc) : y) &
+!$omp&   allocate(allocator ( omp_high_bw_mem_alloc ) , align ( 32 ) : z) &
+!$omp&   allocate(align (16 ): q) &
+!$omp&   firstprivate(q, x,y,z)
+!$omp end parallel
+end
+
+! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(q\\) firstprivate\\(x\\) firstprivate\\(y\\) firstprivate\\(z\\) allocate\\(allocator\\(5\\):x\\) allocate\\(allocator\\(6\\):y\\) allocate\\(allocator\\(7\\):z\\)" 1 "original" } }
+! { dg-final { scan-tree-dump-times "#pragma omp parallel firstprivate\\(q\\) firstprivate\\(x\\) firstprivate\\(y\\) firstprivate\\(z\\) allocate\\(allocator\\(1\\),align\\(64\\):x\\) allocate\\(allocator\\(2\\):y\\) allocate\\(allocator\\(4\\),align\\(32\\):z\\) allocate\\(align\\(16\\):q\\)" 1 "original" } }
+
diff --git a/libgomp/testsuite/libgomp.fortran/allocate-3.f90 b/libgomp/testsuite/libgomp.fortran/allocate-3.f90
new file mode 100644 (file)
index 0000000..a398191
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-additional-options "-fdump-tree-original" }
+
+use omp_lib
+implicit none
+integer :: q, x,y,z
+
+!$omp parallel allocate(align ( 64 ) x)  ! { dg-error "37:Expected ':' at" }
+!$omp parallel allocate(align ( 64 ), x)  ! { dg-error "37:Expected ':' at" }
+!$omp parallel allocate(allocator ( omp_high_bw_mem_alloc ) x)  ! { dg-error "60:Expected ':' at" }
+!$omp parallel allocate(allocator ( omp_high_bw_mem_alloc ) , x)  ! { dg-error "60:Expected ':' at" }
+
+!$omp parallel allocate( omp_high_bw_mem_alloc, align(12) : x)  ! { dg-error "26:Expected variable list at" }
+!$omp parallel allocate( align(12), omp_high_bw_mem_alloc : x)  ! { dg-error "35:Expected ':' at" }
+
+!$omp parallel allocate( omp_high_bw_mem_alloc x)  ! { dg-error "26:Expected variable list at" }
+
+!$omp parallel allocate( omp_high_bw_mem_alloc , x) firstprivate(x) ! { dg-error "'omp_high_bw_mem_alloc' specified in 'allocate' clause at \\(1\\) but not in an explicit privatization clause" }
+! { dg-error "Object 'omp_high_bw_mem_alloc' is not a variable" "" { target *-*-* } .-1 }
+!$omp end parallel
+
+!$omp parallel allocate( omp_high_bw_mem_alloc , x) firstprivate(x, omp_high_bw_mem_alloc)
+! { dg-error "Object 'omp_high_bw_mem_alloc' is not a variable" "" { target *-*-* } .-1 }
+!$omp end parallel
+
+!$omp parallel allocate( align(q) : x) firstprivate(x) ! { dg-error "31:ALIGN modifier requires a scalar positive constant integer alignment expression at" }
+!$omp end parallel
+end