Commit 68034b1b by Thomas Schwinge Committed by Thomas Schwinge

[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
parent c319667a
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> 2019-02-22 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm-cpus.in (ares): Rename to... * config/arm/arm-cpus.in (ares): Rename to...
......
...@@ -5577,41 +5577,6 @@ nvptx_goacc_validate_dims_1 (tree decl, int dims[], int fn_level, unsigned used) ...@@ -5577,41 +5577,6 @@ nvptx_goacc_validate_dims_1 (tree decl, int dims[], int fn_level, unsigned used)
else else
gcc_unreachable (); 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) if (oacc_min_dims_p)
{ {
gcc_assert (dims[GOMP_DIM_VECTOR] == 1); gcc_assert (dims[GOMP_DIM_VECTOR] == 1);
......
2019-02-22 Thomas Schwinge <thomas@codesourcery.com> 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. * openmp.c (gfc_match_oacc_declare): Revert earlier changes.
......
...@@ -317,6 +317,15 @@ enum save_state ...@@ -317,6 +317,15 @@ enum save_state
{ SAVE_NONE = 0, SAVE_EXPLICIT, SAVE_IMPLICIT { 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 /* Strings for all symbol attributes. We use these for dumping the
parse tree, in error messages, and also when reading and writing parse tree, in error messages, and also when reading and writing
modules. In symbol.c. */ modules. In symbol.c. */
...@@ -904,8 +913,8 @@ typedef struct ...@@ -904,8 +913,8 @@ typedef struct
unsigned oacc_declare_device_resident:1; unsigned oacc_declare_device_resident:1;
unsigned oacc_declare_link:1; unsigned oacc_declare_link:1;
/* This is an OpenACC acclerator function at level N - 1 */ /* OpenACC 'routine' directive's level of parallelism. */
unsigned oacc_function:3; ENUM_BITFIELD (oacc_routine_lop) oacc_routine_lop:3;
/* Attributes set by compiler extensions (!GCC$ ATTRIBUTES). */ /* Attributes set by compiler extensions (!GCC$ ATTRIBUTES). */
unsigned ext_attr:EXT_ATTR_NUM; unsigned ext_attr:EXT_ATTR_NUM;
......
...@@ -2232,34 +2232,43 @@ gfc_match_oacc_cache (void) ...@@ -2232,34 +2232,43 @@ gfc_match_oacc_cache (void)
return MATCH_YES; return MATCH_YES;
} }
/* Determine the loop level for a routine. */ /* Determine the OpenACC 'routine' directive's level of parallelism. */
static int static oacc_routine_lop
gfc_oacc_routine_dims (gfc_omp_clauses *clauses) gfc_oacc_routine_lop (gfc_omp_clauses *clauses)
{ {
int level = -1; oacc_routine_lop ret = OACC_ROUTINE_LOP_SEQ;
if (clauses) if (clauses)
{ {
unsigned mask = 0; unsigned n_lop_clauses = 0;
if (clauses->gang) if (clauses->gang)
level = GOMP_DIM_GANG, mask |= GOMP_DIM_MASK (level); {
++n_lop_clauses;
ret = OACC_ROUTINE_LOP_GANG;
}
if (clauses->worker) if (clauses->worker)
level = GOMP_DIM_WORKER, mask |= GOMP_DIM_MASK (level); {
++n_lop_clauses;
ret = OACC_ROUTINE_LOP_WORKER;
}
if (clauses->vector) if (clauses->vector)
level = GOMP_DIM_VECTOR, mask |= GOMP_DIM_MASK (level); {
++n_lop_clauses;
ret = OACC_ROUTINE_LOP_VECTOR;
}
if (clauses->seq) 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"); gfc_error ("Multiple loop axes specified for routine");
} }
if (level < 0) return ret;
level = GOMP_DIM_MAX;
return level;
} }
match match
...@@ -2352,8 +2361,8 @@ gfc_match_oacc_routine (void) ...@@ -2352,8 +2361,8 @@ gfc_match_oacc_routine (void)
gfc_current_ns->proc_name->name, gfc_current_ns->proc_name->name,
&old_loc)) &old_loc))
goto cleanup; goto cleanup;
gfc_current_ns->proc_name->attr.oacc_function gfc_current_ns->proc_name->attr.oacc_routine_lop
= gfc_oacc_routine_dims (c) + 1; = gfc_oacc_routine_lop (c);
} }
if (n) if (n)
......
...@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "trans-stmt.h" #include "trans-stmt.h"
#include "gomp-constants.h" #include "gomp-constants.h"
#include "gimplify.h" #include "gimplify.h"
#include "omp-general.h"
#define MAX_LABEL_VALUE 99999 #define MAX_LABEL_VALUE 99999
...@@ -1406,18 +1407,31 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list) ...@@ -1406,18 +1407,31 @@ add_attributes_to_decl (symbol_attribute sym_attr, tree list)
list = tree_cons (get_identifier ("omp declare target"), list = tree_cons (get_identifier ("omp declare target"),
NULL_TREE, list); NULL_TREE, list);
if (sym_attr.oacc_function) if (sym_attr.oacc_routine_lop != OACC_ROUTINE_LOP_NONE)
{ {
tree dims = NULL_TREE; omp_clause_code code;
int ix; switch (sym_attr.oacc_routine_lop)
int level = sym_attr.oacc_function - 1; {
case OACC_ROUTINE_LOP_GANG:
for (ix = GOMP_DIM_MAX; ix--;) code = OMP_CLAUSE_GANG;
dims = tree_cons (build_int_cst (boolean_type_node, ix >= level), break;
integer_zero_node, dims); 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"), tree dims = oacc_build_routine_dims (c);
dims, list); list = oacc_replace_fn_attrib_attr (list, dims);
} }
return list; return list;
......
...@@ -540,16 +540,26 @@ oacc_launch_pack (unsigned code, tree device, unsigned op) ...@@ -540,16 +540,26 @@ oacc_launch_pack (unsigned code, tree device, unsigned op)
/* Replace any existing oacc fn attribute with updated dimensions. */ /* Replace any existing oacc fn attribute with updated dimensions. */
void /* Variant working on a list of attributes. */
oacc_replace_fn_attrib (tree fn, tree dims)
tree
oacc_replace_fn_attrib_attr (tree attribs, tree dims)
{ {
tree ident = get_identifier (OACC_FN_ATTRIB); 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 we happen to be present as the first attrib, drop it. */
if (attribs && TREE_PURPOSE (attribs) == ident) if (attribs && TREE_PURPOSE (attribs) == ident)
attribs = TREE_CHAIN (attribs); 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 /* Scan CLAUSES for launch dimensions and attach them to the oacc
......
...@@ -81,6 +81,7 @@ extern gimple *omp_build_barrier (tree lhs); ...@@ -81,6 +81,7 @@ extern gimple *omp_build_barrier (tree lhs);
extern poly_uint64 omp_max_vf (void); extern poly_uint64 omp_max_vf (void);
extern int omp_max_simt_vf (void); extern int omp_max_simt_vf (void);
extern tree oacc_launch_pack (unsigned code, tree device, unsigned op); 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_replace_fn_attrib (tree fn, tree dims);
extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args); extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args);
extern tree oacc_build_routine_dims (tree clauses); extern tree oacc_build_routine_dims (tree clauses);
......
2019-02-22 Thomas Schwinge <thomas@codesourcery.com> 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. * c-c++-common/goacc/routine-5.c: Revert earlier changes.
* g++.dg/goacc/template.C: Likewise. * g++.dg/goacc/template.C: Likewise.
......
...@@ -21,10 +21,10 @@ subroutine ROUTINE ...@@ -21,10 +21,10 @@ subroutine ROUTINE
end subroutine ROUTINE end subroutine ROUTINE
! Check the offloaded function's attributes. ! 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 ! Check the offloaded function's classification and compute dimensions (will
! always be 1 x 1 x 1 for non-offloading compilation). ! 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)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)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" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment