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. > +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? > +} > + > + > +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. > @@ -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. > + 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. Jakub