On Fri, Jul 08, 2016 at 09:19:01AM -0700, Cesar Philippidis wrote:
> 2016-07-08 Cesar Philippidis <[email protected]>
>
> gcc/fortran/
> * parse.c (matcha): Define.
> (decode_oacc_directive): Add spec_only local var and set it. Use
> matcha to parse acc data, enter data, exit data, host_data, parallel,
> kernels, update and wait directives. Return ST_GET_FCN_CHARACTERISTICS
> if a non-declarative directive could be matched.
>
> gcc/testsuite/
> * gfortran.dg/goacc/pr71704-acc.f90: New test.
I'd drop the -acc suffix, the directory is enough to differentiate the gomp
vs. goacc test.
> --- a/gcc/fortran/parse.c
> +++ b/gcc/fortran/parse.c
> @@ -589,11 +589,25 @@ decode_statement (void)
> return ST_NONE;
> }
>
> +/* Like match, but don't match anything if not -fopenacc
> + and if spec_only, goto do_spec_only without actually matching. */
The comment doesn't match what the macro does. The whole
decode_oacc_directive function is only called if -fopenacc, so
it is really "Like a match and if spec_only, ..."
> +#define matcha(keyword, subr, st) \
> + do { \
> + if (spec_only && gfc_match (keyword) == MATCH_YES) \
> + goto do_spec_only; \
> + else if (match_word (keyword, subr, &old_locus) \
> + == MATCH_YES) \
> + return st; \
> + else \
> + undo_new_statement (); \
> + } while (0);
> +
> static gfc_statement
> decode_oacc_directive (void)
> {
> locus old_locus;
> char c;
> + bool spec_only = false;
>
> gfc_enforce_clean_symbol_state ();
>
> @@ -608,6 +622,10 @@ decode_oacc_directive (void)
> return ST_NONE;
> }
>
> + if (gfc_current_state () == COMP_FUNCTION
> + && gfc_current_block ()->result->ts.kind == -1)
> + spec_only = true;
> +
> gfc_unset_implicit_pure (NULL);
>
> old_locus = gfc_current_locus;
> @@ -627,7 +645,7 @@ decode_oacc_directive (void)
> match ("cache", gfc_match_oacc_cache, ST_OACC_CACHE);
Why isn't ST_OACC_ATOMIC matcha?
At least from the case_executable/case_exec_markers vs.
case_decl defines, all directives but "routine" and "declare" should
be matcha IMHO.
Also, can you figure out in the OpenACC standard and/or discuss on lang
committee whether acc declare and/or acc routine can appear anywhere in the
specification part, or need to be ordered certain way?
If like in OpenMP they can appear anywhere, then
case ST_OACC_ROUTINE: case ST_OACC_DECLARE
should move from case_decl to case_omp_decl macro.
> break;
> case 'd':
> - match ("data", gfc_match_oacc_data, ST_OACC_DATA);
> + matcha ("data", gfc_match_oacc_data, ST_OACC_DATA);
> match ("declare", gfc_match_oacc_declare, ST_OACC_DECLARE);
> break;
> case 'e':
> @@ -639,19 +657,19 @@ decode_oacc_directive (void)
> match ("end loop", gfc_match_omp_eos, ST_OACC_END_LOOP);
> match ("end parallel loop", gfc_match_omp_eos,
> ST_OACC_END_PARALLEL_LOOP);
> match ("end parallel", gfc_match_omp_eos, ST_OACC_END_PARALLEL);
> - match ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
> - match ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
> + matcha ("enter data", gfc_match_oacc_enter_data, ST_OACC_ENTER_DATA);
> + matcha ("exit data", gfc_match_oacc_exit_data, ST_OACC_EXIT_DATA);
> break;
> case 'h':
> - match ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
> + matcha ("host_data", gfc_match_oacc_host_data, ST_OACC_HOST_DATA);
> break;
> case 'p':
> match ("parallel loop", gfc_match_oacc_parallel_loop,
> ST_OACC_PARALLEL_LOOP);
> - match ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
> + matcha ("parallel", gfc_match_oacc_parallel, ST_OACC_PARALLEL);
> break;
> case 'k':
> match ("kernels loop", gfc_match_oacc_kernels_loop,
> ST_OACC_KERNELS_LOOP);
> - match ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
> + matcha ("kernels", gfc_match_oacc_kernels, ST_OACC_KERNELS);
> break;
> case 'l':
> match ("loop", gfc_match_oacc_loop, ST_OACC_LOOP);
> @@ -660,10 +678,10 @@ decode_oacc_directive (void)
> match ("routine", gfc_match_oacc_routine, ST_OACC_ROUTINE);
> break;
> case 'u':
> - match ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
> + matcha ("update", gfc_match_oacc_update, ST_OACC_UPDATE);
> break;
> case 'w':
> - match ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
> + matcha ("wait", gfc_match_oacc_wait, ST_OACC_WAIT);
> break;
> }
>
> @@ -678,6 +696,13 @@ decode_oacc_directive (void)
> gfc_error_recovery ();
>
> return ST_NONE;
> +
> + do_spec_only:
> + reject_statement ();
> + gfc_clear_error ();
> + gfc_buffer_error (false);
> + gfc_current_locus = old_locus;
> + return ST_GET_FCN_CHARACTERISTICS;
> }
>
> /* Like match, but set a flag simd_matched if keyword matched
Jakub