[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
This commit is contained in:
Thomas Schwinge 2019-02-22 11:50:35 +01:00 committed by Thomas Schwinge
parent c319667adf
commit 68034b1bc2
10 changed files with 99 additions and 69 deletions

View 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...

View 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);

View 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.

View 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;

View 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)

View 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;
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);
for (ix = GOMP_DIM_MAX; ix--;)
dims = tree_cons (build_int_cst (boolean_type_node, ix >= level),
integer_zero_node, dims);
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;

View 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

View 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);

View 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.

View 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" } }