On Tue, Jun 03, 2014 at 09:42:39AM +0200, FX wrote: > > As discussed with Tobias on IRC yesterday, the fact that I'd like to > > eventually backport the Fortran OpenMP 4.0 support to 4.9 branch > > poses a problem with the module.c changes > > But this is by design, because we’re not supposed to add new features > (especially API-changing or module-changing ones) in a release branch. > The compatibility fixes you propose will increase the complexity of the > module reader code, and creates some precedent. > > I don’t think there’s much pressure from the “general public” for Fortran > OpenMP 4.0, so having it in 4.10 only rather than 4.9 is probably not such > a big deal.
We have some precedents already, e.g. 4.8.1 adding remaining C++11 bits to complete C++11 support, instead of waiting for 4.9.0, and IMHO this is similar, OpenMP 4.0 shipped only incomplete support in 4.9.0 (everything but Fortran), and shouldn't be that risky to backport. For the conditional MOD_VERSION I meant something like (incremental patch), MOD_VERSION_OMP4 content is open for bikeshedding, can be "13" etc. If it is "13", then perhaps such a patch could be applied only to 4.9.x, but we'd need to make sure that if any new extensions to module.c are added on the trunk, then MOD_VERSION is bumped there to "14". --- gcc/fortran/module.c.jj 2014-06-02 16:23:21.000000000 +0200 +++ gcc/fortran/module.c 2014-06-05 09:28:39.616639930 +0200 @@ -82,7 +82,8 @@ along with GCC; see the file COPYING3. /* Don't put any single quote (') in MOD_VERSION, if you want it to be recognized. */ -#define MOD_VERSION "13" +#define MOD_VERSION "12" +#define MOD_VERSION_OMP4 "12 OpenMP 4" /* Structure that describes a position within a module file. */ @@ -196,6 +197,7 @@ static char* module_content; static long module_pos; static int module_line, module_column, only_flag; static int prev_module_line, prev_module_column; +static bool module_omp4; static enum { IO_INPUT, IO_OUTPUT } @@ -4064,7 +4066,13 @@ mio_symbol (gfc_symbol *sym) if (sym->formal_ns && sym->formal_ns->proc_name == sym && sym->formal_ns->entries == NULL) - mio_omp_declare_simd (sym->formal_ns, &sym->formal_ns->omp_declare_simd); + { + if (module_omp4) + mio_omp_declare_simd (sym->formal_ns, + &sym->formal_ns->omp_declare_simd); + else if (iomode == IO_OUTPUT) + gcc_assert (sym->formal_ns->omp_declare_simd == NULL); + } mio_rparen (); } @@ -4871,7 +4879,8 @@ read_module (void) /* Skip OpenMP UDRs. */ get_module_locus (&omp_udrs); - skip_list (); + if (module_omp4) + skip_list (); mio_lparen (); @@ -5138,9 +5147,12 @@ read_module (void) load_commons (); load_equiv (); - /* Load OpenMP user defined reductions. */ - set_module_locus (&omp_udrs); - load_omp_udrs (); + if (module_omp4) + { + /* Load OpenMP user defined reductions. */ + set_module_locus (&omp_udrs); + load_omp_udrs (); + } /* At this point, we read those symbols that are needed but haven't been loaded yet. If one symbol requires another, the other gets @@ -5842,11 +5854,16 @@ write_module (void) write_char ('\n'); write_char ('\n'); - mio_lparen (); - write_omp_udrs (gfc_current_ns->omp_udr_root); - mio_rparen (); - write_char ('\n'); - write_char ('\n'); + if (module_omp4) + { + mio_lparen (); + write_omp_udrs (gfc_current_ns->omp_udr_root); + mio_rparen (); + write_char ('\n'); + write_char ('\n'); + } + else + gcc_assert (gfc_current_ns->omp_udr_root == NULL); /* Write symbol information. First we traverse all symbols in the primary namespace, writing those that need to be written. @@ -5916,6 +5933,19 @@ read_crc32_from_module_file (const char* } +/* Set module_omp4 if any symbol has !$OMP DECLARE SIMD directives. */ + +static void +find_omp_declare_simd (gfc_symtree *st) +{ + gfc_symbol *sym = st->n.sym; + if (sym->formal_ns + && sym->formal_ns->proc_name == sym + && sym->formal_ns->omp_declare_simd) + module_omp4 = true; +} + + /* Given module, dump it to disk. If there was an error while processing the module, dump_flag will be set to zero and we delete the module file, even if it was already there. */ @@ -5958,6 +5988,12 @@ gfc_dump_module (const char *name, int d if (gfc_cpp_makedep ()) gfc_cpp_add_target (filename); + module_omp4 = false; + if (gfc_current_ns->omp_udr_root) + module_omp4 = true; + else + gfc_traverse_symtree (gfc_current_ns->sym_root, find_omp_declare_simd); + /* Write the module to the temporary file. */ module_fp = gzopen (filename_tmp, "w"); if (module_fp == NULL) @@ -5965,7 +6001,7 @@ gfc_dump_module (const char *name, int d filename_tmp, xstrerror (errno)); gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n", - MOD_VERSION, gfc_source_file); + module_omp4 ? MOD_VERSION_OMP4 : MOD_VERSION, gfc_source_file); /* Write the module itself. */ iomode = IO_OUTPUT; @@ -6756,6 +6792,8 @@ gfc_use_module (gfc_use_list *module) read_module_to_tmpbuf (); gzclose (module_fp); + module_omp4 = false; + /* Skip the first line of the module, after checking that this is a gfortran module file. */ line = 0; @@ -6775,11 +6813,15 @@ gfc_use_module (gfc_use_list *module) if (strcmp (atom_name, " version") != 0 || module_char () != ' ' || parse_atom () != ATOM_STRING - || strcmp (atom_string, MOD_VERSION)) + || (strcmp (atom_string, MOD_VERSION) + && strcmp (atom_string, MOD_VERSION_OMP4))) gfc_fatal_error ("Cannot read module file '%s' opened at %C," " because it was created by a different" " version of GNU Fortran", filename); + if (strcmp (atom_string, MOD_VERSION_OMP4) == 0) + module_omp4 = true; + free (atom_string); } Jakub