diff options
author | cesar <cesar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-30 19:09:33 +0000 |
---|---|---|
committer | cesar <cesar@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-30 19:09:33 +0000 |
commit | 7c1a959803b435b641209d068a385a1175d6c61a (patch) | |
tree | 68145daf074ea8294cdb3c958aa8fd3af1344384 /gcc/fortran | |
parent | 9ce9d47e8dfd4a287a7d9f0680f5a6d2996657c9 (diff) | |
download | gcc-7c1a959803b435b641209d068a385a1175d6c61a.tar.gz |
gcc/
* tree-nested.c (convert_nonlocal_omp_clauses): Add support for
OMP_CLAUSE_{NUM_GANGS,NUM_VECTORS,VECTOR_LENGTH,SEQ}.
(convert_local_omp_clauses): Likewise.
gcc/fortran/
* f95-lang.c (gfc_attribute_table): Add an "oacc function"
attribute.
* gfortran.h (symbol_attribute): Add an oacc_function bit-field.
(gfc_oacc_routine_name): New struct;
(gfc_get_oacc_routine_name): New macro.
(gfc_namespace): Add oacc_routine_clauses, oacc_routine_names and
oacc_routine fields.
(gfc_exec_op): Add EXEC_OACC_ROUTINE.
* openmp.c (OACC_ROUTINE_CLAUSES): New mask.
(gfc_oacc_routine_dims): New function.
(gfc_match_oacc_routine): Add support for named routines and the
gang, worker vector and seq clauses.
* parse.c (is_oacc): Add EXEC_OACC_ROUTINE.
* resolve.c (gfc_resolve_blocks): Likewise.
* st.c (gfc_free_statement): Likewise.
* trans-decl.c (add_attributes_to_decl): Attach an 'oacc function'
attribute and shape geometry for acc routine.
gcc/testsuite/
* gfortran.dg/goacc/routine-3.f90: New test.
* gfortran.dg/goacc/routine-4.f90: New test.
* gfortran.dg/goacc/routine-5.f90: New test.
* gfortran.dg/goacc/routine-6.f90: New test.
* gfortran.dg/goacc/subroutines: New test.
libgomp/
* libgomp.oacc-fortran/routine-5.f90: New test.
* libgomp.oacc-fortran/routine-7.f90: New test.
* libgomp.oacc-fortran/routine-9.f90: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231081 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/fortran/f95-lang.c | 2 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 24 | ||||
-rw-r--r-- | gcc/fortran/openmp.c | 138 | ||||
-rw-r--r-- | gcc/fortran/parse.c | 1 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 1 | ||||
-rw-r--r-- | gcc/fortran/st.c | 1 | ||||
-rw-r--r-- | gcc/fortran/trans-decl.c | 15 |
8 files changed, 167 insertions, 37 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c7c50647d00..52dcc826538 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,25 @@ +2015-11-30 Cesar Philippidis <cesar@codesourcery.com> + James Norris <jnorris@codesourcery.com> + Nathan Sidwell <nathan@codesourcery.com> + + * f95-lang.c (gfc_attribute_table): Add an "oacc function" + attribute. + * gfortran.h (symbol_attribute): Add an oacc_function bit-field. + (gfc_oacc_routine_name): New struct; + (gfc_get_oacc_routine_name): New macro. + (gfc_namespace): Add oacc_routine_clauses, oacc_routine_names and + oacc_routine fields. + (gfc_exec_op): Add EXEC_OACC_ROUTINE. + * openmp.c (OACC_ROUTINE_CLAUSES): New mask. + (gfc_oacc_routine_dims): New function. + (gfc_match_oacc_routine): Add support for named routines and the + gang, worker vector and seq clauses. + * parse.c (is_oacc): Add EXEC_OACC_ROUTINE. + * resolve.c (gfc_resolve_blocks): Likewise. + * st.c (gfc_free_statement): Likewise. + * trans-decl.c (add_attributes_to_decl): Attach an 'oacc function' + attribute and shape geometry for acc routine. + 2015-11-30 Paul Thomas <pault@gcc.gnu.org> PR fortran/68534 diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 605c2abd01d..8556b706365 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -93,6 +93,8 @@ static const struct attribute_spec gfc_attribute_table[] = affects_type_identity } */ { "omp declare target", 0, 0, true, false, false, gfc_handle_omp_declare_target_attribute, false }, + { "oacc function", 0, -1, true, false, false, + gfc_handle_omp_declare_target_attribute, false }, { NULL, 0, 0, false, false, false, NULL, false } }; diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 5487c9343e4..0628e8628c2 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -848,6 +848,9 @@ 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; + /* Attributes set by compiler extensions (!GCC$ ATTRIBUTES). */ unsigned ext_attr:EXT_ATTR_NUM; @@ -1606,6 +1609,16 @@ gfc_dt_list; /* A list of all derived types. */ extern gfc_dt_list *gfc_derived_types; +typedef struct gfc_oacc_routine_name +{ + struct gfc_symbol *sym; + struct gfc_omp_clauses *clauses; + struct gfc_oacc_routine_name *next; +} +gfc_oacc_routine_name; + +#define gfc_get_oacc_routine_name() XCNEW (gfc_oacc_routine_name) + /* A namespace describes the contents of procedure, module, interface block or BLOCK construct. */ /* ??? Anything else use these? */ @@ -1672,6 +1685,12 @@ typedef struct gfc_namespace /* !$ACC DECLARE. */ gfc_oacc_declare *oacc_declare; + /* !$ACC ROUTINE clauses. */ + gfc_omp_clauses *oacc_routine_clauses; + + /* !$ACC ROUTINE names. */ + gfc_oacc_routine_name *oacc_routine_names; + gfc_charlen *cl_list, *old_cl_list; gfc_dt_list *derived_types; @@ -1717,6 +1736,9 @@ typedef struct gfc_namespace /* Set to 1 for !$OMP DECLARE REDUCTION namespaces. */ unsigned omp_udr_ns:1; + + /* Set to 1 for !$ACC ROUTINE namespaces. */ + unsigned oacc_routine:1; } gfc_namespace; @@ -2344,7 +2366,7 @@ enum gfc_exec_op EXEC_READ, EXEC_WRITE, EXEC_IOLENGTH, EXEC_TRANSFER, EXEC_DT_END, EXEC_BACKSPACE, EXEC_ENDFILE, EXEC_INQUIRE, EXEC_REWIND, EXEC_FLUSH, EXEC_LOCK, EXEC_UNLOCK, - EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, + EXEC_OACC_KERNELS_LOOP, EXEC_OACC_PARALLEL_LOOP, EXEC_OACC_ROUTINE, EXEC_OACC_PARALLEL, EXEC_OACC_KERNELS, EXEC_OACC_DATA, EXEC_OACC_HOST_DATA, EXEC_OACC_LOOP, EXEC_OACC_UPDATE, EXEC_OACC_WAIT, EXEC_OACC_CACHE, EXEC_OACC_ENTER_DATA, EXEC_OACC_EXIT_DATA, EXEC_OACC_ATOMIC, diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index a07cee1a0b9..730b7f98cd0 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -1318,6 +1318,8 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, | OMP_CLAUSE_DELETE) #define OACC_WAIT_CLAUSES \ (OMP_CLAUSE_ASYNC) +#define OACC_ROUTINE_CLAUSES \ + (OMP_CLAUSE_GANG | OMP_CLAUSE_WORKER | OMP_CLAUSE_VECTOR | OMP_CLAUSE_SEQ) match @@ -1619,13 +1621,44 @@ gfc_match_oacc_cache (void) return MATCH_YES; } +/* Determine the loop level for a routine. */ + +static int +gfc_oacc_routine_dims (gfc_omp_clauses *clauses) +{ + int level = -1; + + if (clauses) + { + unsigned mask = 0; + + if (clauses->gang) + level = GOMP_DIM_GANG, mask |= GOMP_DIM_MASK (level); + if (clauses->worker) + level = GOMP_DIM_WORKER, mask |= GOMP_DIM_MASK (level); + if (clauses->vector) + level = GOMP_DIM_VECTOR, mask |= GOMP_DIM_MASK (level); + if (clauses->seq) + level = GOMP_DIM_MAX, mask |= GOMP_DIM_MASK (level); + + if (mask != (mask & -mask)) + gfc_error ("Multiple loop axes specified for routine"); + } + + if (level < 0) + level = GOMP_DIM_MAX; + + return level; +} match gfc_match_oacc_routine (void) { locus old_loc; - gfc_symbol *sym; + gfc_symbol *sym = NULL; match m; + gfc_omp_clauses *c = NULL; + gfc_oacc_routine_name *n = NULL; old_loc = gfc_current_locus; @@ -1640,52 +1673,85 @@ gfc_match_oacc_routine (void) goto cleanup; } - if (m == MATCH_NO - && gfc_current_ns->proc_name - && gfc_match_omp_eos () == MATCH_YES) + if (m == MATCH_YES) { - if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr, - gfc_current_ns->proc_name->name, - &old_loc)) - goto cleanup; - return MATCH_YES; - } + char buffer[GFC_MAX_SYMBOL_LEN + 1]; + gfc_symtree *st; - if (m != MATCH_YES) - return m; + m = gfc_match_name (buffer); + if (m == MATCH_YES) + { + st = gfc_find_symtree (gfc_current_ns->sym_root, buffer); + if (st) + { + sym = st->n.sym; + if (strcmp (sym->name, gfc_current_ns->proc_name->name) == 0) + sym = NULL; + } - /* Scan for a function name. */ - m = gfc_match_symbol (&sym, 0); + if (st == NULL + || (sym + && !sym->attr.external + && !sym->attr.function + && !sym->attr.subroutine)) + { + gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, " + "invalid function name %s", + (sym) ? sym->name : buffer); + gfc_current_locus = old_loc; + return MATCH_ERROR; + } + } + else + { + gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C"); + gfc_current_locus = old_loc; + return MATCH_ERROR; + } - if (m != MATCH_YES) - { - gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C"); - gfc_current_locus = old_loc; - return MATCH_ERROR; + if (gfc_match_char (')') != MATCH_YES) + { + gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting" + " ')' after NAME"); + gfc_current_locus = old_loc; + return MATCH_ERROR; + } } - if (!sym->attr.external && !sym->attr.function && !sym->attr.subroutine) - { - gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, invalid" - " function name %qs", sym->name); - gfc_current_locus = old_loc; - return MATCH_ERROR; - } + if (gfc_match_omp_eos () != MATCH_YES + && (gfc_match_omp_clauses (&c, OACC_ROUTINE_CLAUSES, false, false, true) + != MATCH_YES)) + return MATCH_ERROR; - if (gfc_match_char (')') != MATCH_YES) + if (sym != NULL) { - gfc_error ("Syntax error in !$ACC ROUTINE ( NAME ) at %C, expecting" - " ')' after NAME"); - gfc_current_locus = old_loc; - return MATCH_ERROR; + n = gfc_get_oacc_routine_name (); + n->sym = sym; + n->clauses = NULL; + n->next = NULL; + if (gfc_current_ns->oacc_routine_names != NULL) + n->next = gfc_current_ns->oacc_routine_names; + + gfc_current_ns->oacc_routine_names = n; } - - if (gfc_match_omp_eos () != MATCH_YES) + else if (gfc_current_ns->proc_name) { - gfc_error ("Unexpected junk after !$ACC ROUTINE at %C"); - goto cleanup; + if (!gfc_add_omp_declare_target (&gfc_current_ns->proc_name->attr, + gfc_current_ns->proc_name->name, + &old_loc)) + goto cleanup; + gfc_current_ns->proc_name->attr.oacc_function + = gfc_oacc_routine_dims (c) + 1; } - return MATCH_YES; + + if (n) + n->clauses = c; + else if (gfc_current_ns->oacc_routine) + gfc_current_ns->oacc_routine_clauses = c; + + new_st.op = EXEC_OACC_ROUTINE; + new_st.ext.omp_clauses = c; + return MATCH_YES; cleanup: gfc_current_locus = old_loc; diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index b2806214e1a..b2d15a89aeb 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -5786,6 +5786,7 @@ is_oacc (gfc_state_data *sd) case EXEC_OACC_ENTER_DATA: case EXEC_OACC_EXIT_DATA: case EXEC_OACC_ATOMIC: + case EXEC_OACC_ROUTINE: return true; default: diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 685e3f54007..febf0fa28d6 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -9373,6 +9373,7 @@ gfc_resolve_blocks (gfc_code *b, gfc_namespace *ns) case EXEC_OACC_ENTER_DATA: case EXEC_OACC_EXIT_DATA: case EXEC_OACC_ATOMIC: + case EXEC_OACC_ROUTINE: case EXEC_OMP_ATOMIC: case EXEC_OMP_CRITICAL: case EXEC_OMP_DISTRIBUTE: diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c index d0a11aab793..566150b1cc2 100644 --- a/gcc/fortran/st.c +++ b/gcc/fortran/st.c @@ -202,6 +202,7 @@ gfc_free_statement (gfc_code *p) case EXEC_OACC_CACHE: case EXEC_OACC_ENTER_DATA: case EXEC_OACC_EXIT_DATA: + case EXEC_OACC_ROUTINE: case EXEC_OMP_CANCEL: case EXEC_OMP_CANCELLATION_POINT: case EXEC_OMP_DISTRIBUTE: diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 39ff8e27f5b..331b43da413 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see #include "trans-const.h" /* Only for gfc_trans_code. Shouldn't need to include this. */ #include "trans-stmt.h" +#include "gomp-constants.h" #define MAX_LABEL_VALUE 99999 @@ -1304,6 +1305,20 @@ 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) + { + 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); + + list = tree_cons (get_identifier ("oacc function"), + dims, list); + } + return list; } |