[PR72741] Use 'oacc_build_routine_dims' for Fortran OpenACC 'routine' directives...
authorThomas Schwinge <thomas@codesourcery.com>
Fri, 22 Feb 2019 10:50:35 +0000 (11:50 +0100)
committerThomas Schwinge <tschwinge@gcc.gnu.org>
Fri, 22 Feb 2019 10:50:35 +0000 (11:50 +0100)
... instead of having an incomplete local implementation.

With these changes in place, we can then also revert the work-around r267213
"[nvptx] Unify C/Fortran routine handling in nvptx_goacc_validate_dims".

gcc/fortran/
PR fortran/72741
* gfortran.h (oacc_routine_lop): New enum.
(symbol_attribute): Use it.
* openmp.c (gfc_oacc_routine_dims): Replace with...
(gfc_oacc_routine_lop): ... this new function.
(gfc_match_oacc_routine): Adjust.
* trans-decl.c (add_attributes_to_decl): Likewise.
gcc/
PR fortran/72741
* omp-general.c (oacc_replace_fn_attrib): Mostly split out into...
(oacc_replace_fn_attrib_attr): ... this new function.
* omp-general.h (oacc_replace_fn_attrib_attr): New prototype.
* config/nvptx/nvptx.c (nvptx_goacc_validate_dims_1): Revert workaround.
gcc/testsuite/
PR fortran/72741
* gfortran.dg/goacc/classify-routine.f95: Adjust.

Co-Authored-By: Cesar Philippidis <cesar@codesourcery.com>
From-SVN: r269105

gcc/ChangeLog
gcc/config/nvptx/nvptx.c
gcc/fortran/ChangeLog
gcc/fortran/gfortran.h
gcc/fortran/openmp.c
gcc/fortran/trans-decl.c
gcc/omp-general.c
gcc/omp-general.h
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/goacc/classify-routine.f95

index 4745a1999d92ef2e1f345cd2dc5f5f7e8b79bdba..f14cbbce4775151a1d1e490e3c73ab1c45468498 100644 (file)
@@ -1,3 +1,11 @@
+2019-02-22  Thomas Schwinge  <thomas@codesourcery.com>
+
+       PR fortran/72741
+       * omp-general.c (oacc_replace_fn_attrib): Mostly split out into...
+       (oacc_replace_fn_attrib_attr): ... this new function.
+       * omp-general.h (oacc_replace_fn_attrib_attr): New prototype.
+       * config/nvptx/nvptx.c (nvptx_goacc_validate_dims_1): Revert workaround.
+
 2019-02-22  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm-cpus.in (ares): Rename to...
index 23459e1c6f4744187657fcfbfeabdbea7a152f2e..424b43ac8b4873161e673a71a8f0b6684465159b 100644 (file)
@@ -5577,41 +5577,6 @@ nvptx_goacc_validate_dims_1 (tree decl, int dims[], int fn_level, unsigned used)
   else
     gcc_unreachable ();
 
-  if (routine_p)
-    {
-      /* OpenACC routines in C arrive here with the following attributes
-        (omitting the 'omp declare target'):
-        seq   : __attribute__((oacc function (0 1, 0 1, 0 1)))
-        vector: __attribute__((oacc function (0 1, 0 1, 1 0)))
-        worker: __attribute__((oacc function (0 1, 1 0, 1 0)))
-        gang  : __attribute__((oacc function (1 0, 1 0, 1 0)))
-
-        If we take f.i. the oacc function attribute of the worker routine
-        (0 1, 1 0, 1 0), then:
-        - the slice (0, 1, 1) is interpreted by oacc_fn_attrib_level as
-          meaning: worker routine, that is:
-          - can't contain gang loop (0),
-          - can contain worker loop (1),
-          - can contain vector loop (1).
-        - the slice (1, 0, 0) is interpreted by oacc_validate_dims as the
-        dimensions: gang: 1, worker: 0, vector: 0.
-
-        OTOH, routines in Fortran arrive here with these attributes:
-        seq   : __attribute__((oacc function (0 0, 0 0, 0 0)))
-        vector: __attribute__((oacc function (0 0, 0 0, 1 0)))
-        worker: __attribute__((oacc function (0 0, 1 0, 1 0)))
-        gang  : __attribute__((oacc function (1 0, 1 0, 1 0)))
-        that is, the same as for C but with the dimensions set to 0.
-
-        This is due to a bug in the Fortran front-end: PR72741.  Work around
-        this bug by forcing the dimensions to be the same in Fortran as for C,
-        to be able to handle C and Fortran routines uniformly in this
-        function.  */
-      dims[GOMP_DIM_VECTOR] = fn_level > GOMP_DIM_VECTOR ? 1 : 0;
-      dims[GOMP_DIM_WORKER] = fn_level > GOMP_DIM_WORKER ? 1 : 0;
-      dims[GOMP_DIM_GANG] = fn_level > GOMP_DIM_GANG ? 1 : 0;
-    }
-
   if (oacc_min_dims_p)
     {
       gcc_assert (dims[GOMP_DIM_VECTOR] == 1);
index 74a6890ed7004a66690f172325f4d2c79f2e7b5d..0eb860449ca9f074969c12e63ef910c5f9bb7bc2 100644 (file)
@@ -1,3 +1,14 @@
+2019-02-22  Thomas Schwinge  <thomas@codesourcery.com>
+           Cesar Philippidis  <cesar@codesourcery.com>
+
+       PR fortran/72741
+       * gfortran.h (oacc_routine_lop): New enum.
+       (symbol_attribute): Use it.
+       * openmp.c (gfc_oacc_routine_dims): Replace with...
+       (gfc_oacc_routine_lop): ... this new function.
+       (gfc_match_oacc_routine): Adjust.
+       * trans-decl.c (add_attributes_to_decl): Likewise.
+
 2019-02-22  Thomas Schwinge  <thomas@codesourcery.com>
 
        * openmp.c (gfc_match_oacc_declare): Revert earlier changes.
index 6c4e839c489c47a16f08fdac2e14bdff05a08e95..f0258b39ffd16aa538372eca0b4b3e929f133aca 100644 (file)
@@ -317,6 +317,15 @@ enum save_state
 { SAVE_NONE = 0, SAVE_EXPLICIT, SAVE_IMPLICIT
 };
 
+/* OpenACC 'routine' directive's level of parallelism.  */
+enum oacc_routine_lop
+{ OACC_ROUTINE_LOP_NONE = 0,
+  OACC_ROUTINE_LOP_GANG,
+  OACC_ROUTINE_LOP_WORKER,
+  OACC_ROUTINE_LOP_VECTOR,
+  OACC_ROUTINE_LOP_SEQ
+};
+
 /* Strings for all symbol attributes.  We use these for dumping the
    parse tree, in error messages, and also when reading and writing
    modules.  In symbol.c.  */
@@ -904,8 +913,8 @@ typedef struct
   unsigned oacc_declare_device_resident:1;
   unsigned oacc_declare_link:1;
 
-  /* This is an OpenACC acclerator function at level N - 1  */
-  unsigned oacc_function:3;
+  /* OpenACC 'routine' directive's level of parallelism.  */
+  ENUM_BITFIELD (oacc_routine_lop) oacc_routine_lop:3;
 
   /* Attributes set by compiler extensions (!GCC$ ATTRIBUTES).  */
   unsigned ext_attr:EXT_ATTR_NUM;
index 8aa4a2f18c41c8f24cc3e2ce6d66415e7296270a..dfd4be86d50e94cae014d2a24a0d7ea83d81ae3e 100644 (file)
@@ -2232,34 +2232,43 @@ gfc_match_oacc_cache (void)
   return MATCH_YES;
 }
 
-/* Determine the loop level for a routine.   */
+/* Determine the OpenACC 'routine' directive's level of parallelism.  */
 
-static int
-gfc_oacc_routine_dims (gfc_omp_clauses *clauses)
+static oacc_routine_lop
+gfc_oacc_routine_lop (gfc_omp_clauses *clauses)
 {
-  int level = -1;
+  oacc_routine_lop ret = OACC_ROUTINE_LOP_SEQ;
 
   if (clauses)
     {
-      unsigned mask = 0;
+      unsigned n_lop_clauses = 0;
 
       if (clauses->gang)
-       level = GOMP_DIM_GANG, mask |= GOMP_DIM_MASK (level);
+       {
+         ++n_lop_clauses;
+         ret = OACC_ROUTINE_LOP_GANG;
+       }
       if (clauses->worker)
-       level = GOMP_DIM_WORKER, mask |= GOMP_DIM_MASK (level);
+       {
+         ++n_lop_clauses;
+         ret = OACC_ROUTINE_LOP_WORKER;
+       }
       if (clauses->vector)
-       level = GOMP_DIM_VECTOR, mask |= GOMP_DIM_MASK (level);
+       {
+         ++n_lop_clauses;
+         ret = OACC_ROUTINE_LOP_VECTOR;
+       }
       if (clauses->seq)
-       level = GOMP_DIM_MAX, mask |= GOMP_DIM_MASK (level);
+       {
+         ++n_lop_clauses;
+         ret = OACC_ROUTINE_LOP_SEQ;
+       }
 
-      if (mask != (mask & -mask))
+      if (n_lop_clauses > 1)
        gfc_error ("Multiple loop axes specified for routine");
     }
 
-  if (level < 0)
-    level = GOMP_DIM_MAX;
-
-  return level;
+  return ret;
 }
 
 match
@@ -2352,8 +2361,8 @@ gfc_match_oacc_routine (void)
                                       gfc_current_ns->proc_name->name,
                                       &old_loc))
        goto cleanup;
-      gfc_current_ns->proc_name->attr.oacc_function
-       = gfc_oacc_routine_dims (c) + 1;
+      gfc_current_ns->proc_name->attr.oacc_routine_lop
+       = gfc_oacc_routine_lop (c);
     }
 
   if (n)
index 3604cfcf5cb3e2858da27ef7dd33cee2f27e7722..20d453051a2944c06e32e8dd9e5e6a83b6eed9b4 100644 (file)
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "trans-stmt.h"
 #include "gomp-constants.h"
 #include "gimplify.h"
+#include "omp-general.h"
 
 #define MAX_LABEL_VALUE 99999
 
@@ -1406,18 +1407,31 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list)
     list = tree_cons (get_identifier ("omp declare target"),
                      NULL_TREE, list);
 
-  if (sym_attr.oacc_function)
+  if (sym_attr.oacc_routine_lop != OACC_ROUTINE_LOP_NONE)
     {
-      tree dims = NULL_TREE;
-      int ix;
-      int level = sym_attr.oacc_function - 1;
-
-      for (ix = GOMP_DIM_MAX; ix--;)
-       dims = tree_cons (build_int_cst (boolean_type_node, ix >= level),
-                         integer_zero_node, dims);
+      omp_clause_code code;
+      switch (sym_attr.oacc_routine_lop)
+       {
+       case OACC_ROUTINE_LOP_GANG:
+         code = OMP_CLAUSE_GANG;
+         break;
+       case OACC_ROUTINE_LOP_WORKER:
+         code = OMP_CLAUSE_WORKER;
+         break;
+       case OACC_ROUTINE_LOP_VECTOR:
+         code = OMP_CLAUSE_VECTOR;
+         break;
+       case OACC_ROUTINE_LOP_SEQ:
+         code = OMP_CLAUSE_SEQ;
+         break;
+       case OACC_ROUTINE_LOP_NONE:
+       default:
+         gcc_unreachable ();
+       }
+      tree c = build_omp_clause (UNKNOWN_LOCATION, code);
 
-      list = tree_cons (get_identifier ("oacc function"),
-                       dims, list);
+      tree dims = oacc_build_routine_dims (c);
+      list = oacc_replace_fn_attrib_attr (list, dims);
     }
 
   return list;
index 0f66ba0c5d86e173fe991cd9b6071532f8c39d8a..356772ff4582185d2f410160aa02ec19599d0192 100644 (file)
@@ -540,16 +540,26 @@ oacc_launch_pack (unsigned code, tree device, unsigned op)
 
 /* Replace any existing oacc fn attribute with updated dimensions.  */
 
-void
-oacc_replace_fn_attrib (tree fn, tree dims)
+/* Variant working on a list of attributes.  */
+
+tree
+oacc_replace_fn_attrib_attr (tree attribs, tree dims)
 {
   tree ident = get_identifier (OACC_FN_ATTRIB);
-  tree attribs = DECL_ATTRIBUTES (fn);
 
   /* If we happen to be present as the first attrib, drop it.  */
   if (attribs && TREE_PURPOSE (attribs) == ident)
     attribs = TREE_CHAIN (attribs);
-  DECL_ATTRIBUTES (fn) = tree_cons (ident, dims, attribs);
+  return tree_cons (ident, dims, attribs);
+}
+
+/* Variant working on a function decl.  */
+
+void
+oacc_replace_fn_attrib (tree fn, tree dims)
+{
+  DECL_ATTRIBUTES (fn)
+    = oacc_replace_fn_attrib_attr (DECL_ATTRIBUTES (fn), dims);
 }
 
 /* Scan CLAUSES for launch dimensions and attach them to the oacc
index 0cbbb31e73bb240e9cd40c8837f31bffa9e16ecd..60faa5213a27e7166cc53e5b62949f2968f8ae46 100644 (file)
@@ -81,6 +81,7 @@ extern gimple *omp_build_barrier (tree lhs);
 extern poly_uint64 omp_max_vf (void);
 extern int omp_max_simt_vf (void);
 extern tree oacc_launch_pack (unsigned code, tree device, unsigned op);
+extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims);
 extern void oacc_replace_fn_attrib (tree fn, tree dims);
 extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args);
 extern tree oacc_build_routine_dims (tree clauses);
index 12901a9361a6ebcdc69e8559c2bf98bfbc78d75f..dec48441f3099675a168050b53b5a4388c29e037 100644 (file)
@@ -1,5 +1,8 @@
 2019-02-22  Thomas Schwinge  <thomas@codesourcery.com>
 
+       PR fortran/72741
+       * gfortran.dg/goacc/classify-routine.f95: Adjust.
+
        * c-c++-common/goacc/routine-5.c: Revert earlier changes.
        * g++.dg/goacc/template.C: Likewise.
 
index 5cf4c13acb815ea65b989a840347a4e32215e1c2..e435f5d7eaef155cea172710cb3181f2cfa4a4b3 100644 (file)
@@ -21,10 +21,10 @@ subroutine ROUTINE
 end subroutine ROUTINE
 
 ! Check the offloaded function's attributes.
-! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp declare target, oacc function \\(0 0, 1 0, 1 0\\)\\)\\)" 1 "ompexp" } }
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(omp declare target, oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "ompexp" } }
 
 ! Check the offloaded function's classification and compute dimensions (will
 ! always be 1 x 1 x 1 for non-offloading compilation).
 ! { dg-final { scan-tree-dump-times "(?n)Function is OpenACC routine level 1" 1 "oaccdevlow" } }
 ! { dg-final { scan-tree-dump-times "(?n)Compute dimensions \\\[1, 1, 1\\\]" 1 "oaccdevlow" } }
-! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target, oacc function \\(0 0, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } }
+! { dg-final { scan-tree-dump-times "(?n)__attribute__\\(\\(oacc function \\(0 1, 1 1, 1 1\\), omp declare target, oacc function \\(0 1, 1 0, 1 0\\)\\)\\)" 1 "oaccdevlow" } }