aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2019-02-22 11:50:35 +0100
committerThomas Schwinge <tschwinge@gcc.gnu.org>2019-02-22 11:50:35 +0100
commit68034b1bc2058fd3c78b0f583e718e8443346580 (patch)
treebdb11b9ae34f705b45276d4d5b45627460b70e74 /gcc/fortran
parentc319667adff8cc10e87ff836f72d5a7471e942c6 (diff)
downloadgcc-68034b1bc2058fd3c78b0f583e718e8443346580.zip
gcc-68034b1bc2058fd3c78b0f583e718e8443346580.tar.gz
gcc-68034b1bc2058fd3c78b0f583e718e8443346580.tar.bz2
[PR72741] Use 'oacc_build_routine_dims' for Fortran OpenACC 'routine' directives, too
... 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
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog11
-rw-r--r--gcc/fortran/gfortran.h13
-rw-r--r--gcc/fortran/openmp.c41
-rw-r--r--gcc/fortran/trans-decl.c34
4 files changed, 71 insertions, 28 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 74a6890..0eb8604 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,4 +1,15 @@
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.
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 6c4e839..f0258b3 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -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;
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 8aa4a2f..dfd4be8 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -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)
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 3604cfc..20d4530 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -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;