On 11/13/2014 08:43 AM, Jakub Jelinek wrote: > On Thu, Nov 06, 2014 at 02:25:52PM -0800, Cesar Philippidis wrote: >> * cpp.c (cpp_define_builtins): Conditionally define _OPENACC. >> * dump-parse-tree.c >> (show_omp_node): Dump also OpenACC executable statements. > > Put (show_omp_node): ... and what fits on the same line as * > dump-parse-tree.c, don't wrap prematurely. > >> +#undef DEF_GOACC_BUILTIN_COMPILER >> + /* TODO: this is not doing the right thing. */ > > Can you please avoid the TODOs in the source? If it is not the right > thing, either do something better, or file a PR to schedule such work for > the future. > >> + struct gfc_expr *gang_expr; >> + struct gfc_expr *worker_expr; >> + struct gfc_expr *vector_expr; >> + struct gfc_expr *num_gangs_expr; >> + struct gfc_expr *num_workers_expr; >> + struct gfc_expr *vector_length_expr; >> + gfc_expr_list *wait_list; >> + gfc_expr_list *tile_list; >> + unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1; >> + unsigned wait:1, par_auto:1, gang_static:1; >> + >> + /* Directive specific data. */ >> + union >> + { >> + /* !$ACC DECLARE locus. */ >> + locus loc; >> + } >> + ext; > > Perhaps turn it into a union only when you have more than one field? > And if we start to use unions, I bet we should do something with having > such huge struct with most of the empty pointers anyway, add some hierarchy > to those. > >> --- a/gcc/fortran/match.c >> +++ b/gcc/fortran/match.c >> @@ -2491,7 +2491,7 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op) >> >> if (o != NULL) >> { >> - gfc_error ("%s statement at %C leaving OpenMP structured block", >> + gfc_error ("%s statement at %C leaving OpenMP or OpenACC structured >> block", >> gfc_ascii_statement (st)); >> return MATCH_ERROR; >> } > > I think it would be better to specify which (ie. compute > is_oacc and have two different format strings, is_oacc ? " ... " : " ... "). > >> -/* Match OpenMP directive clauses. MASK is a bitmask of >> +/* OpenACC 2.0 clauses. */ >> +#define OMP_CLAUSE_ASYNC (1ULL << 32) > > As C++98 doesn't mandate long long type, I'm afraid we shouldn't use > 1ULL; we require some 64-bit type though, so perhaps just use > ((uint64_t) 1 << 32) etc.? > >> +#define OMP_CLAUSE_NUM_GANGS (1ULL << 33) >> +#define OMP_CLAUSE_NUM_WORKERS (1ULL << 34) >> +#define OMP_CLAUSE_VECTOR_LENGTH (1ULL << 35) >> +#define OMP_CLAUSE_COPY (1ULL << 36) >> +#define OMP_CLAUSE_COPYOUT (1ULL << 37) >> +#define OMP_CLAUSE_CREATE (1ULL << 38) >> +#define OMP_CLAUSE_PRESENT (1ULL << 39) >> +#define OMP_CLAUSE_PRESENT_OR_COPY (1ULL << 40) >> +#define OMP_CLAUSE_PRESENT_OR_COPYIN (1ULL << 41) >> +#define OMP_CLAUSE_PRESENT_OR_COPYOUT (1ULL << 42) >> +#define OMP_CLAUSE_PRESENT_OR_CREATE (1ULL << 43) >> +#define OMP_CLAUSE_DEVICEPTR (1ULL << 44) >> +#define OMP_CLAUSE_GANG (1ULL << 45) >> +#define OMP_CLAUSE_WORKER (1ULL << 46) >> +#define OMP_CLAUSE_VECTOR (1ULL << 47) >> +#define OMP_CLAUSE_SEQ (1ULL << 48) >> +#define OMP_CLAUSE_INDEPENDENT (1ULL << 49) >> +#define OMP_CLAUSE_USE_DEVICE (1ULL << 50) >> +#define OMP_CLAUSE_DEVICE_RESIDENT (1ULL << 51) >> +#define OMP_CLAUSE_HOST_SELF (1ULL << 52) >> +#define OMP_CLAUSE_OACC_DEVICE (1ULL << 53) >> +#define OMP_CLAUSE_WAIT (1ULL << 54) >> +#define OMP_CLAUSE_DELETE (1ULL << 55) >> +#define OMP_CLAUSE_AUTO (1ULL << 56) >> +#define OMP_CLAUSE_TILE (1ULL << 57) > >> static match >> -gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned int mask, >> - bool first = true, bool needs_space = true) >> +gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask, >> + bool first = true, bool needs_space = true, > > See above, use uint64_t. > >> + c->async_expr = gfc_get_constant_expr (BT_INTEGER, >> + gfc_default_integer_kind, >> + &gfc_current_locus); >> + /* TODO XXX: FIX -1 (acc_async_noval). */ > > Please use gomp-constants.h for this, or some other enum, and avoid > TODO XXX comments in the source.
Thomas told me that he fix this when he updates gomp-constants.h. >> +static gfc_statement >> +omp_code_to_statement (gfc_code *code) >> +{ >> +switch (code->op) >> + { >> + case EXEC_OMP_PARALLEL: >> + return ST_OMP_PARALLEL; > > Wrong formatting. switch should be indented by 2 spaces, { after it by 4, > case by 4 too and return by 6 spaces. > >> + default: >> + gcc_unreachable (); >> + } > ... > >> +oacc_code_to_statement (gfc_code *code) >> +{ >> +switch (code->op) >> + { > > Likewise here. > >> +static void >> +resolve_oacc_loop(gfc_code *code) > > Formatting - missing space before (, please check it everywhere. > >> +static void >> +resolve_oacc_cache (gfc_code *code) >> +{ >> + gfc_error ("Sorry, !$ACC cache unimplemented yet at %L", &code->loc); > > Shouldn't this be sorry ("...") instead? That introduced an ICE. I've created a PR for it here: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63861 >> +} >> + >> + >> +void >> +gfc_resolve_oacc_declare (gfc_namespace *ns) >> +{ >> + int list; >> + gfc_omp_namelist *n; >> + locus loc; >> + static const char *clause_names[] = {"COPY", "COPYIN", "COPYOUT", >> "CREATE", > > Missing space after { ? > >> + "DELETE", "PRESENT", "PRESENT_OR_COPY", "PRESENT_OR_COPYIN", >> + "PRESENT_OR_COPYOUT", "PRESENT_OR_CREATE", "DEVICEPTR", >> + "DEVICE_RESIDENT"}; > > and before }. > >> + /* FIXME: handle omp_list_map. */ > > Please avoid fixmes, either fix it, or file a PR. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63859 >> @@ -3568,9 +3813,13 @@ static void >> parse_critical_block (void) >> { >> gfc_code *top, *d; >> - gfc_state_data s; >> + gfc_state_data s, *sd; >> gfc_statement st; >> >> + for (sd = gfc_state_stack; sd; sd = sd->previous) >> + if (sd->state == COMP_OMP_STRUCTURED_BLOCK) >> + gfc_error_now ("CRITICAL block inside of OpenMP or OpenACC region at >> %C"); > > Couldn't you determine which one and make the diagnostics explicit? > >> --- a/gcc/fortran/scanner.c >> +++ b/gcc/fortran/scanner.c >> @@ -55,9 +55,11 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs; >> >> static gfc_file *file_head, *current_file; >> >> -static int continue_flag, end_flag, openmp_flag, gcc_attribute_flag; >> +static int continue_flag, end_flag, gcc_attribute_flag; >> +static int openmp_flag, openacc_flag; /* If !$omp/!$acc occurred in current >> comment line */ > > Too long line. Best put it above the two flags. > End the comment with ". */" (dot and one space missing). > >> + gcc_assert(gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]); > > Formatting, missing space before (. > >> /* See if this line is a continuation line. */ >> - if (openmp_flag != prev_openmp_flag) >> - { >> - openmp_flag = prev_openmp_flag; >> - goto not_continuation; >> - } >> + if (gfc_option.gfc_flag_openmp) >> + if (openmp_flag != prev_openmp_flag) >> + { >> + openmp_flag = prev_openmp_flag; >> + goto not_continuation; >> + } >> + if (gfc_option.gfc_flag_openacc) >> + if (openacc_flag != prev_openacc_flag) >> + { >> + openacc_flag = prev_openacc_flag; >> + goto not_continuation; >> + } > > Why the guards by gfc_flag_open* ? What happens > if both -fopenmp -fopenacc is enabled? > And, if it is right this way, the nested ifs are weird, > use if (gfc_option.gfc_flag_openmp && openmp_flag != prev_openmp_flag) > instead. Using -fopenmp with -fopenacc is broken. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63858 >> + if (clauses->async_expr) >> + OMP_CLAUSE_ASYNC_EXPR (c) = >> + gfc_convert_expr_to_tree (block, clauses->async_expr); > > = should be on the next line. > >> + tree num_gangs_var = >> + gfc_convert_expr_to_tree (block, clauses->num_gangs_expr); > > Likewise and several times more. > > LGTM otherwise. Thanks. I couldn't figure out how to assign the bugs in the PR. Maybe my account doesn't have permission to do so. Regardless, I'll work on them. I've applied the attached patch to gomp-4_0-branch. It should address all of your requests. I'll regenerate a complete patch later. Thomas told me that he would merge the fortran FE along with the middle end when the time comes. This patch also includes a change to a gomp test. That change is specific to gomp-4_0-branch, so if it looks out of place just ignore it. Cesar
2014-11-13 Cesar Philippidis <ce...@codesourcery.com> gcc/fortran/ * f95-lang.c (DEF_GOACC_BUILTIN_COMPILER): Remove bogus TODO. * gfortran.h (gfc_omp_clauses): Move loc out of the ext union and remove the ext union. * match.c (match_exit_cycle): Make the error message specific to OpenMP/OpenACC. * openmp.c (OMP_CLAUSE_PRIVATE, OMP_CLAUSE_FIRSTPRIVATE, OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_COPYPRIVATE, OMP_CLAUSE_SHARED OMP_CLAUSE_COPYIN, OMP_CLAUSE_REDUCTION, OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS, OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_DEFAULT, OMP_CLAUSE_ORDERED, OMP_CLAUSE_COLLAPSE, OMP_CLAUSE_UNTIED, OMP_CLAUSE_FINAL, OMP_CLAUSE_MERGEABLE, OMP_CLAUSE_ALIGNED, OMP_CLAUSE_DEPEND, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_LINEAR, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_PROC_BIND, OMP_CLAUSE_SAFELEN, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_UNIFORM, OMP_CLAUSE_DEVICE, OMP_CLAUSE_MAP, OMP_CLAUSE_TOOMP_CLAUSE_FROM, OMP_CLAUSE_NUM_TEAMS, OMP_CLAUSE_THREAD_LIMIT, OMP_CLAUSE_DIST_SCHEDULE, OMP_CLAUSE_ASYNC, OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, OMP_CLAUSE_VECTOR_LENGTH, OMP_CLAUSE_COPY, OMP_CLAUSE_COPYOUT, OMP_CLAUSE_CREATE, OMP_CLAUSE_PRESENT, OMP_CLAUSE_PRESENT_OR_COPY, OMP_CLAUSE_PRESENT_OR_COPYIN, OMP_CLAUSE_PRESENT_OR_COPYOUT, OMP_CLAUSE_PRESENT_OR_CREATE, OMP_CLAUSE_DEVICEPTR, OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ, OMP_CLAUSE_INDEPENDENT, OMP_CLAUSE_USE_DEVICE, OMP_CLAUSE_DEVICE_RESIDENT, OMP_CLAUSE_HOST_SELF, OMP_CLAUSE_OACC_DEVICE, OMP_CLAUSE_WAIT, OMP_CLAUSE_DELETE, OMP_CLAUSE_AUTO, OMP_CLAUSE_TILE): Use unit64_t for the bitmasks. (gfc_match_omp_clauses): Use unit64_t for mask. (gfc_match_oacc_declare): Update usage of omp_clause->loc. (omp_code_to_statement): Fix whitespace. (oacc_code_to_statement): Likewise. (resolve_oacc_loop):Likewise. (resolve_oacc_cache): Replace gfc_error with a sorry for this unimplemented directive. (gfc_resolve_oacc_declare): Update usage of omp_clause->loc. Remove FIXME and TODO, see PR63869. * parse.c (parse_critical_block): Make the error message specific to OpenMP/OpenACC. (is_oacc): New function. * parse.h (is_oacc): Declare. * scanner.c (openmp_flag, openacc_flag): Move comment. (gfc_next_char_literal): Merge nested if stmts. * trans-openmp.c (gfc_trans_omp_clauses): Fix whitespace. (gfc_trans_oacc_declare): Fix whitespace. gcc/testsuite/ * gfortran.dg/gomp/omp_do1.f90: Update expected error. diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 4451c61..cd43112 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -1189,7 +1189,6 @@ gfc_init_builtin_functions (void) gfc_define_builtin ("__builtin_" name, builtin_types[type], \ code, name, attr); #undef DEF_GOACC_BUILTIN_COMPILER - /* TODO: this is not doing the right thing. */ #define DEF_GOACC_BUILTIN_COMPILER(code, name, type, attr) \ gfc_define_builtin (name, builtin_types[type], code, name, attr); #include "../oacc-builtins.def" diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index aed37d3..9624b3b 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1262,14 +1262,8 @@ typedef struct gfc_omp_clauses gfc_expr_list *tile_list; unsigned async:1, gang:1, worker:1, vector:1, seq:1, independent:1; unsigned wait:1, par_auto:1, gang_static:1; + locus loc; - /* Directive specific data. */ - union - { - /* !$ACC DECLARE locus. */ - locus loc; - } - ext; } gfc_omp_clauses; diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index ba5f8ad..7d7982e 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -2491,8 +2491,8 @@ match_exit_cycle (gfc_statement st, gfc_exec_op op) if (o != NULL) { - gfc_error ("%s statement at %C leaving OpenMP or OpenACC structured block", - gfc_ascii_statement (st)); + gfc_error ("%s statement at %C leaving %s structured block", + gfc_ascii_statement (st), is_oacc (p) ? "OpenACC" : "OpenMP"); return MATCH_ERROR; } diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c index 47c146e..15b221d 100644 --- a/gcc/fortran/openmp.c +++ b/gcc/fortran/openmp.c @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see #include "match.h" #include "parse.h" #include "hash-set.h" +#include "diagnostic.h" /* Match an end of OpenMP directive. End of OpenMP directive is optional whitespace, followed by '\n' or comment '!'. */ @@ -391,66 +392,66 @@ match_oacc_clause_gang (gfc_omp_clauses *cp) return gfc_match (" %e )", &cp->gang_expr); } -#define OMP_CLAUSE_PRIVATE (1U << 0) -#define OMP_CLAUSE_FIRSTPRIVATE (1U << 1) -#define OMP_CLAUSE_LASTPRIVATE (1U << 2) -#define OMP_CLAUSE_COPYPRIVATE (1U << 3) -#define OMP_CLAUSE_SHARED (1U << 4) -#define OMP_CLAUSE_COPYIN (1U << 5) -#define OMP_CLAUSE_REDUCTION (1U << 6) -#define OMP_CLAUSE_IF (1U << 7) -#define OMP_CLAUSE_NUM_THREADS (1U << 8) -#define OMP_CLAUSE_SCHEDULE (1U << 9) -#define OMP_CLAUSE_DEFAULT (1U << 10) -#define OMP_CLAUSE_ORDERED (1U << 11) -#define OMP_CLAUSE_COLLAPSE (1U << 12) -#define OMP_CLAUSE_UNTIED (1U << 13) -#define OMP_CLAUSE_FINAL (1U << 14) -#define OMP_CLAUSE_MERGEABLE (1U << 15) -#define OMP_CLAUSE_ALIGNED (1U << 16) -#define OMP_CLAUSE_DEPEND (1U << 17) -#define OMP_CLAUSE_INBRANCH (1U << 18) -#define OMP_CLAUSE_LINEAR (1U << 19) -#define OMP_CLAUSE_NOTINBRANCH (1U << 20) -#define OMP_CLAUSE_PROC_BIND (1U << 21) -#define OMP_CLAUSE_SAFELEN (1U << 22) -#define OMP_CLAUSE_SIMDLEN (1U << 23) -#define OMP_CLAUSE_UNIFORM (1U << 24) -#define OMP_CLAUSE_DEVICE (1U << 25) -#define OMP_CLAUSE_MAP (1U << 26) -#define OMP_CLAUSE_TO (1U << 27) -#define OMP_CLAUSE_FROM (1U << 28) -#define OMP_CLAUSE_NUM_TEAMS (1U << 29) -#define OMP_CLAUSE_THREAD_LIMIT (1U << 30) -#define OMP_CLAUSE_DIST_SCHEDULE (1U << 31) +#define OMP_CLAUSE_PRIVATE ((uint64_t) 1 << 0) +#define OMP_CLAUSE_FIRSTPRIVATE ((uint64_t) 1 << 1) +#define OMP_CLAUSE_LASTPRIVATE ((uint64_t) 1 << 2) +#define OMP_CLAUSE_COPYPRIVATE ((uint64_t) 1 << 3) +#define OMP_CLAUSE_SHARED ((uint64_t) 1 << 4) +#define OMP_CLAUSE_COPYIN ((uint64_t) 1 << 5) +#define OMP_CLAUSE_REDUCTION ((uint64_t) 1 << 6) +#define OMP_CLAUSE_IF ((uint64_t) 1 << 7) +#define OMP_CLAUSE_NUM_THREADS ((uint64_t) 1 << 8) +#define OMP_CLAUSE_SCHEDULE ((uint64_t) 1 << 9) +#define OMP_CLAUSE_DEFAULT ((uint64_t) 1 << 10) +#define OMP_CLAUSE_ORDERED ((uint64_t) 1 << 11) +#define OMP_CLAUSE_COLLAPSE ((uint64_t) 1 << 12) +#define OMP_CLAUSE_UNTIED ((uint64_t) 1 << 13) +#define OMP_CLAUSE_FINAL ((uint64_t) 1 << 14) +#define OMP_CLAUSE_MERGEABLE ((uint64_t) 1 << 15) +#define OMP_CLAUSE_ALIGNED ((uint64_t) 1 << 16) +#define OMP_CLAUSE_DEPEND ((uint64_t) 1 << 17) +#define OMP_CLAUSE_INBRANCH ((uint64_t) 1 << 18) +#define OMP_CLAUSE_LINEAR ((uint64_t) 1 << 19) +#define OMP_CLAUSE_NOTINBRANCH ((uint64_t) 1 << 20) +#define OMP_CLAUSE_PROC_BIND ((uint64_t) 1 << 21) +#define OMP_CLAUSE_SAFELEN ((uint64_t) 1 << 22) +#define OMP_CLAUSE_SIMDLEN ((uint64_t) 1 << 23) +#define OMP_CLAUSE_UNIFORM ((uint64_t) 1 << 24) +#define OMP_CLAUSE_DEVICE ((uint64_t) 1 << 25) +#define OMP_CLAUSE_MAP ((uint64_t) 1 << 26) +#define OMP_CLAUSE_TO ((uint64_t) 1 << 27) +#define OMP_CLAUSE_FROM ((uint64_t) 1 << 28) +#define OMP_CLAUSE_NUM_TEAMS ((uint64_t) 1 << 29) +#define OMP_CLAUSE_THREAD_LIMIT ((uint64_t) 1 << 30) +#define OMP_CLAUSE_DIST_SCHEDULE ((uint64_t) 1 << 31) /* OpenACC 2.0 clauses. */ -#define OMP_CLAUSE_ASYNC (1ULL << 32) -#define OMP_CLAUSE_NUM_GANGS (1ULL << 33) -#define OMP_CLAUSE_NUM_WORKERS (1ULL << 34) -#define OMP_CLAUSE_VECTOR_LENGTH (1ULL << 35) -#define OMP_CLAUSE_COPY (1ULL << 36) -#define OMP_CLAUSE_COPYOUT (1ULL << 37) -#define OMP_CLAUSE_CREATE (1ULL << 38) -#define OMP_CLAUSE_PRESENT (1ULL << 39) -#define OMP_CLAUSE_PRESENT_OR_COPY (1ULL << 40) -#define OMP_CLAUSE_PRESENT_OR_COPYIN (1ULL << 41) -#define OMP_CLAUSE_PRESENT_OR_COPYOUT (1ULL << 42) -#define OMP_CLAUSE_PRESENT_OR_CREATE (1ULL << 43) -#define OMP_CLAUSE_DEVICEPTR (1ULL << 44) -#define OMP_CLAUSE_GANG (1ULL << 45) -#define OMP_CLAUSE_WORKER (1ULL << 46) -#define OMP_CLAUSE_VECTOR (1ULL << 47) -#define OMP_CLAUSE_SEQ (1ULL << 48) -#define OMP_CLAUSE_INDEPENDENT (1ULL << 49) -#define OMP_CLAUSE_USE_DEVICE (1ULL << 50) -#define OMP_CLAUSE_DEVICE_RESIDENT (1ULL << 51) -#define OMP_CLAUSE_HOST_SELF (1ULL << 52) -#define OMP_CLAUSE_OACC_DEVICE (1ULL << 53) -#define OMP_CLAUSE_WAIT (1ULL << 54) -#define OMP_CLAUSE_DELETE (1ULL << 55) -#define OMP_CLAUSE_AUTO (1ULL << 56) -#define OMP_CLAUSE_TILE (1ULL << 57) +#define OMP_CLAUSE_ASYNC ((uint64_t) 1 << 32) +#define OMP_CLAUSE_NUM_GANGS ((uint64_t) 1 << 33) +#define OMP_CLAUSE_NUM_WORKERS ((uint64_t) 1 << 34) +#define OMP_CLAUSE_VECTOR_LENGTH ((uint64_t) 1 << 35) +#define OMP_CLAUSE_COPY ((uint64_t) 1 << 36) +#define OMP_CLAUSE_COPYOUT ((uint64_t) 1 << 37) +#define OMP_CLAUSE_CREATE ((uint64_t) 1 << 38) +#define OMP_CLAUSE_PRESENT ((uint64_t) 1 << 39) +#define OMP_CLAUSE_PRESENT_OR_COPY ((uint64_t) 1 << 40) +#define OMP_CLAUSE_PRESENT_OR_COPYIN ((uint64_t) 1 << 41) +#define OMP_CLAUSE_PRESENT_OR_COPYOUT ((uint64_t) 1 << 42) +#define OMP_CLAUSE_PRESENT_OR_CREATE ((uint64_t) 1 << 43) +#define OMP_CLAUSE_DEVICEPTR ((uint64_t) 1 << 44) +#define OMP_CLAUSE_GANG ((uint64_t) 1 << 45) +#define OMP_CLAUSE_WORKER ((uint64_t) 1 << 46) +#define OMP_CLAUSE_VECTOR ((uint64_t) 1 << 47) +#define OMP_CLAUSE_SEQ ((uint64_t) 1 << 48) +#define OMP_CLAUSE_INDEPENDENT ((uint64_t) 1 << 49) +#define OMP_CLAUSE_USE_DEVICE ((uint64_t) 1 << 50) +#define OMP_CLAUSE_DEVICE_RESIDENT ((uint64_t) 1 << 51) +#define OMP_CLAUSE_HOST_SELF ((uint64_t) 1 << 52) +#define OMP_CLAUSE_OACC_DEVICE ((uint64_t) 1 << 53) +#define OMP_CLAUSE_WAIT ((uint64_t) 1 << 54) +#define OMP_CLAUSE_DELETE ((uint64_t) 1 << 55) +#define OMP_CLAUSE_AUTO ((uint64_t) 1 << 56) +#define OMP_CLAUSE_TILE ((uint64_t) 1 << 57) /* Helper function for OpenACC and OpenMP clauses involving memory mapping. */ @@ -475,7 +476,7 @@ gfc_match_omp_map_clause (gfc_omp_namelist **list, gfc_omp_map_op map_op) clauses that are allowed for a particular directive. */ static match -gfc_match_omp_clauses (gfc_omp_clauses **cp, unsigned long long mask, +gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask, bool first = true, bool needs_space = true, bool openacc = false) { @@ -1294,7 +1295,7 @@ gfc_match_oacc_declare (void) return MATCH_ERROR; new_st.ext.omp_clauses = c; - new_st.ext.omp_clauses->ext.loc = gfc_current_locus; + new_st.ext.omp_clauses->loc = gfc_current_locus; return MATCH_YES; } @@ -4267,57 +4268,57 @@ oacc_is_kernels (gfc_code *code) static gfc_statement omp_code_to_statement (gfc_code *code) { -switch (code->op) - { - case EXEC_OMP_PARALLEL: - return ST_OMP_PARALLEL; - case EXEC_OMP_PARALLEL_SECTIONS: - return ST_OMP_PARALLEL_SECTIONS; - case EXEC_OMP_SECTIONS: - return ST_OMP_SECTIONS; - case EXEC_OMP_ORDERED: - return ST_OMP_ORDERED; - case EXEC_OMP_CRITICAL: - return ST_OMP_CRITICAL; - case EXEC_OMP_MASTER: - return ST_OMP_MASTER; - case EXEC_OMP_SINGLE: - return ST_OMP_SINGLE; - case EXEC_OMP_TASK: - return ST_OMP_TASK; - case EXEC_OMP_WORKSHARE: - return ST_OMP_WORKSHARE; - case EXEC_OMP_PARALLEL_WORKSHARE: - return ST_OMP_PARALLEL_WORKSHARE; - case EXEC_OMP_DO: - return ST_OMP_DO; - default: - gcc_unreachable (); - } + switch (code->op) + { + case EXEC_OMP_PARALLEL: + return ST_OMP_PARALLEL; + case EXEC_OMP_PARALLEL_SECTIONS: + return ST_OMP_PARALLEL_SECTIONS; + case EXEC_OMP_SECTIONS: + return ST_OMP_SECTIONS; + case EXEC_OMP_ORDERED: + return ST_OMP_ORDERED; + case EXEC_OMP_CRITICAL: + return ST_OMP_CRITICAL; + case EXEC_OMP_MASTER: + return ST_OMP_MASTER; + case EXEC_OMP_SINGLE: + return ST_OMP_SINGLE; + case EXEC_OMP_TASK: + return ST_OMP_TASK; + case EXEC_OMP_WORKSHARE: + return ST_OMP_WORKSHARE; + case EXEC_OMP_PARALLEL_WORKSHARE: + return ST_OMP_PARALLEL_WORKSHARE; + case EXEC_OMP_DO: + return ST_OMP_DO; + default: + gcc_unreachable (); + } } static gfc_statement oacc_code_to_statement (gfc_code *code) { -switch (code->op) - { - case EXEC_OACC_PARALLEL: - return ST_OACC_PARALLEL; - case EXEC_OACC_KERNELS: - return ST_OACC_KERNELS; - case EXEC_OACC_DATA: - return ST_OACC_DATA; - case EXEC_OACC_HOST_DATA: - return ST_OACC_HOST_DATA; - case EXEC_OACC_PARALLEL_LOOP: - return ST_OACC_PARALLEL_LOOP; - case EXEC_OACC_KERNELS_LOOP: - return ST_OACC_KERNELS_LOOP; - case EXEC_OACC_LOOP: - return ST_OACC_LOOP; - default: - gcc_unreachable (); - } + switch (code->op) + { + case EXEC_OACC_PARALLEL: + return ST_OACC_PARALLEL; + case EXEC_OACC_KERNELS: + return ST_OACC_KERNELS; + case EXEC_OACC_DATA: + return ST_OACC_DATA; + case EXEC_OACC_HOST_DATA: + return ST_OACC_HOST_DATA; + case EXEC_OACC_PARALLEL_LOOP: + return ST_OACC_PARALLEL_LOOP; + case EXEC_OACC_KERNELS_LOOP: + return ST_OACC_KERNELS_LOOP; + case EXEC_OACC_LOOP: + return ST_OACC_LOOP; + default: + gcc_unreachable (); + } } static void @@ -4581,7 +4582,7 @@ gfc_resolve_oacc_blocks (gfc_code *code, gfc_namespace *ns) static void -resolve_oacc_loop(gfc_code *code) +resolve_oacc_loop (gfc_code *code) { gfc_code *do_code; int collapse; @@ -4601,7 +4602,7 @@ resolve_oacc_loop(gfc_code *code) static void resolve_oacc_cache (gfc_code *code) { - gfc_error ("Sorry, !$ACC cache unimplemented yet at %L", &code->loc); + sorry ("Sorry, !$ACC cache unimplemented yet"); } @@ -4615,10 +4616,9 @@ gfc_resolve_oacc_declare (gfc_namespace *ns) if (ns->oacc_declare_clauses == NULL) return; - loc = ns->oacc_declare_clauses->ext.loc; + loc = ns->oacc_declare_clauses->loc; - /* FIXME: handle omp_list_map. */ - for (/* TODO */ list = OMP_LIST_DEVICE_RESIDENT; + for (list = OMP_LIST_DEVICE_RESIDENT; list <= OMP_LIST_DEVICE_RESIDENT; list++) for (n = ns->oacc_declare_clauses->lists[list]; n; n = n->next) { @@ -4627,7 +4627,7 @@ gfc_resolve_oacc_declare (gfc_namespace *ns) gfc_error ("PARAMETER object '%s' is not allowed at %L", n->sym->name, &loc); } - for (/* TODO */ list = OMP_LIST_DEVICE_RESIDENT; + for (list = OMP_LIST_DEVICE_RESIDENT; list <= OMP_LIST_DEVICE_RESIDENT; list++) for (n = ns->oacc_declare_clauses->lists[list]; n; n = n->next) { diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 33b10cd..15702b7 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -3818,7 +3818,9 @@ parse_critical_block (void) for (sd = gfc_state_stack; sd; sd = sd->previous) if (sd->state == COMP_OMP_STRUCTURED_BLOCK) - gfc_error_now ("CRITICAL block inside of OpenMP or OpenACC region at %C"); + gfc_error_now (is_oacc (sd) + ? "CRITICAL block inside of OpenACC region at %C" + : "CRITICAL block inside of OpenMP region at %C"); s.ext.end_do_label = new_st.label1; @@ -5545,3 +5547,28 @@ duplicate_main: gfc_done_2 (); return true; } + +/* Return true if this state data represents an OpenACC region. */ +bool +is_oacc (gfc_state_data *sd) +{ + switch (sd->construct->op) + { + case EXEC_OACC_PARALLEL_LOOP:break; + case EXEC_OACC_PARALLEL: + case EXEC_OACC_KERNELS_LOOP: + case EXEC_OACC_KERNELS: + case EXEC_OACC_DATA: + case EXEC_OACC_HOST_DATA: + case EXEC_OACC_LOOP: + case EXEC_OACC_UPDATE: + case EXEC_OACC_WAIT: + case EXEC_OACC_CACHE: + case EXEC_OACC_ENTER_DATA: + case EXEC_OACC_EXIT_DATA: + return true; + + default: + return false; + } +} diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h index be09a97..da7c4e1 100644 --- a/gcc/fortran/parse.h +++ b/gcc/fortran/parse.h @@ -69,4 +69,5 @@ match gfc_match_enumerator_def (void); void gfc_free_enum_history (void); extern bool gfc_matching_function; match gfc_match_prefix (gfc_typespec *); +bool is_oacc (gfc_state_data *); #endif /* GFC_PARSE_H */ diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index 85ce3f8..fa9ebea 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -56,7 +56,8 @@ gfc_directorylist *include_dirs, *intrinsic_modules_dirs; static gfc_file *file_head, *current_file; static int continue_flag, end_flag, gcc_attribute_flag; -static int openmp_flag, openacc_flag; /* If !$omp/!$acc occurred in current comment line */ +/* If !$omp/!$acc occurred in current comment line. */ +static int openmp_flag, openacc_flag; static int continue_count, continue_line; static locus openmp_locus; static locus openacc_locus; @@ -1363,7 +1364,7 @@ restart: { for (i = 0; i < 5; i++, c = next_char ()) { - gcc_assert(gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]); + gcc_assert (gfc_wide_tolower (c) == (unsigned char) "!$acc"[i]); if (i == 4) old_loc = gfc_current_locus; } @@ -1431,18 +1432,16 @@ restart: skip_fixed_comments (); /* See if this line is a continuation line. */ - if (gfc_option.gfc_flag_openmp) - if (openmp_flag != prev_openmp_flag) - { - openmp_flag = prev_openmp_flag; - goto not_continuation; - } - if (gfc_option.gfc_flag_openacc) - if (openacc_flag != prev_openacc_flag) - { - openacc_flag = prev_openacc_flag; - goto not_continuation; - } + if (gfc_option.gfc_flag_openmp && openmp_flag != prev_openmp_flag) + { + openmp_flag = prev_openmp_flag; + goto not_continuation; + } + if (gfc_option.gfc_flag_openacc && openacc_flag != prev_openacc_flag) + { + openacc_flag = prev_openacc_flag; + goto not_continuation; + } if (!openmp_flag && !openacc_flag) for (i = 0; i < 5; i++) diff --git a/gcc/fortran/trans-openmp.c b/gcc/fortran/trans-openmp.c index 6967c4f..aec2ce7 100644 --- a/gcc/fortran/trans-openmp.c +++ b/gcc/fortran/trans-openmp.c @@ -2502,8 +2502,8 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, { c = build_omp_clause (where.lb->location, OMP_CLAUSE_ASYNC); if (clauses->async_expr) - OMP_CLAUSE_ASYNC_EXPR (c) = - gfc_convert_expr_to_tree (block, clauses->async_expr); + OMP_CLAUSE_ASYNC_EXPR (c) + = gfc_convert_expr_to_tree (block, clauses->async_expr); else OMP_CLAUSE_ASYNC_EXPR (c) = NULL; omp_clauses = gfc_trans_add_clause (c, omp_clauses); @@ -2532,36 +2532,36 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, } if (clauses->num_gangs_expr) { - tree num_gangs_var = - gfc_convert_expr_to_tree (block, clauses->num_gangs_expr); + tree num_gangs_var + = gfc_convert_expr_to_tree (block, clauses->num_gangs_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_GANGS); OMP_CLAUSE_NUM_GANGS_EXPR (c) = num_gangs_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } if (clauses->num_workers_expr) { - tree num_workers_var = - gfc_convert_expr_to_tree (block, clauses->num_workers_expr); + tree num_workers_var + = gfc_convert_expr_to_tree (block, clauses->num_workers_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_NUM_WORKERS); - OMP_CLAUSE_NUM_WORKERS_EXPR (c)= num_workers_var; + OMP_CLAUSE_NUM_WORKERS_EXPR (c) = num_workers_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } if (clauses->vector_length_expr) { - tree vector_length_var = - gfc_convert_expr_to_tree (block, clauses->vector_length_expr); + tree vector_length_var + = gfc_convert_expr_to_tree (block, clauses->vector_length_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR_LENGTH); - OMP_CLAUSE_VECTOR_LENGTH_EXPR (c)= vector_length_var; + OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = vector_length_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } if (clauses->vector) { if (clauses->vector_expr) { - tree vector_var = - gfc_convert_expr_to_tree (block, clauses->vector_expr); + tree vector_var + = gfc_convert_expr_to_tree (block, clauses->vector_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_VECTOR); - OMP_CLAUSE_VECTOR_EXPR (c)= vector_var; + OMP_CLAUSE_VECTOR_EXPR (c) = vector_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } else @@ -2574,10 +2574,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, { if (clauses->worker_expr) { - tree worker_var = - gfc_convert_expr_to_tree (block, clauses->worker_expr); + tree worker_var + = gfc_convert_expr_to_tree (block, clauses->worker_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_WORKER); - OMP_CLAUSE_WORKER_EXPR (c)= worker_var; + OMP_CLAUSE_WORKER_EXPR (c) = worker_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } else @@ -2590,10 +2590,10 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses, { if (clauses->gang_expr) { - tree gang_var = - gfc_convert_expr_to_tree (block, clauses->gang_expr); + tree gang_var + = gfc_convert_expr_to_tree (block, clauses->gang_expr); c = build_omp_clause (where.lb->location, OMP_CLAUSE_GANG); - OMP_CLAUSE_GANG_EXPR (c)= gang_var; + OMP_CLAUSE_GANG_EXPR (c) = gang_var; omp_clauses = gfc_trans_add_clause (c, omp_clauses); } else @@ -4323,8 +4323,8 @@ gfc_trans_oacc_declare (stmtblock_t *block, gfc_namespace *ns) { tree oacc_clauses; oacc_clauses = gfc_trans_omp_clauses (block, ns->oacc_declare_clauses, - ns->oacc_declare_clauses->ext.loc); - return build1_loc (ns->oacc_declare_clauses->ext.loc.lb->location, + ns->oacc_declare_clauses->loc); + return build1_loc (ns->oacc_declare_clauses->loc.lb->location, OACC_DECLARE, void_type_node, oacc_clauses); } diff --git a/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90 b/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90 index 7cfa3f0..c97af1d 100644 --- a/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90 +++ b/gcc/testsuite/gfortran.dg/gomp/omp_do1.f90 @@ -44,7 +44,7 @@ outer: do i = 1, 30 end do outer last: do i = 1, 30 !$omp parallel - if (i .eq. 21) exit last ! { dg-error "leaving OpenMP or OpenACC structured block" } + if (i .eq. 21) exit last ! { dg-error "leaving OpenMP structured block" } !$omp end parallel end do last !$omp parallel do shared (i)