aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/nvptx/nvptx.c35
-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
-rw-r--r--gcc/omp-general.c18
-rw-r--r--gcc/omp-general.h1
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gfortran.dg/goacc/classify-routine.f954
10 files changed, 99 insertions, 69 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4745a19..f14cbbce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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...
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index 23459e1c..424b43a 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -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);
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;
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 0f66ba0..356772f 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -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
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index 0cbbb31..60faa52 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 12901a9..dec4844 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gfortran.dg/goacc/classify-routine.f95 b/gcc/testsuite/gfortran.dg/goacc/classify-routine.f95
index 5cf4c13..e435f5d 100644
--- a/gcc/testsuite/gfortran.dg/goacc/classify-routine.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/classify-routine.f95
@@ -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" } }