On Wed, Nov 14, 2018 at 11:06:04AM +0100, Martin Liška wrote:
> Question I have is about default search locations for the header file. On my 
> machine I can
> see:
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../../x86_64-pc-linux-gnu/lib/x86_64-pc-linux-gnu/9.0.0/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../../x86_64-pc-linux-gnu/lib/../lib64/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../x86_64-pc-linux-gnu/9.0.0/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../../lib64/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/lib/x86_64-pc-linux-gnu/9.0.0/math-vector-fortran.h", R_OK) = -1 
> ENOENT (No such file or directory)
> access("/lib/../lib64/math-vector-fortran.h", R_OK) = -1 ENOENT (No such file 
> or directory)
> access("/usr/lib/x86_64-pc-linux-gnu/9.0.0/math-vector-fortran.h", R_OK) = -1 
> ENOENT (No such file or directory)
> access("/usr/lib/../lib64/math-vector-fortran.h", R_OK) = -1 ENOENT (No such 
> file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../../x86_64-pc-linux-gnu/lib/math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/home/marxin/bin/gcc2/lib64/gcc/x86_64-pc-linux-gnu/9.0.0/../../../math-vector-fortran.h",
>  R_OK) = -1 ENOENT (No such file or directory)
> access("/lib/math-vector-fortran.h", R_OK) = -1 ENOENT (No such file or 
> directory)
> access("/usr/lib/math-vector-fortran.h", R_OK) = -1 ENOENT (No such file or 
> directory)
> 
> Aren't these locations desired for libraries, instead of include locations?

That isn't correct indeed.
What about find_a_file (&include_prefixes, ... )?
Though, in the design where to put the file we really need to have multilib
(and multiarch on Debian/Ubuntu) in mind, because e.g. on x86_64-linux you
want to find a m64 version of the header for -m64, but a different for -m32
and there is always the possibility somebody installs a 32-bit gfortran on 
x86_64.

> --- a/gcc/config/gnu-user.h
> +++ b/gcc/config/gnu-user.h
> @@ -170,3 +170,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>    LD_STATIC_OPTION " --whole-archive -llsan --no-whole-archive " \
>    LD_DYNAMIC_OPTION "}}%{!static-liblsan:-llsan}"
>  #endif
> +
> +#undef TARGET_F951_NOSTDINC_OPTIONS
> +#define TARGET_F951_NOSTDINC_OPTIONS "%:fortran-header-file(-fpre-include= 
> math-vector-fortran.h)"

Too long line, use some \s to split it up.

> +   Flags are one of:
> +     - omp-simd-notinbranch.

So omp-simd-notinbranch or omp_simd_notinbranch?
Any particular reason for this weird syntax and for not also
supporting inbranch or just simd?

> +
> +   When we come here, we have already matched the !GCC$ builtin string.  */
> +match
> +gfc_match_gcc_builtin (void)
> +{
> +  char builtin[GFC_MAX_SYMBOL_LEN + 1];
> +
> +  if (gfc_match_name (builtin) != MATCH_YES)
> +    return MATCH_ERROR;
> +
> +  gfc_gobble_whitespace ();
> +  if (gfc_match ("attributes") != MATCH_YES)
> +    return MATCH_ERROR;
> +
> +  gfc_gobble_whitespace ();
> +  if (gfc_match ("omp_simd_notinbranch") != MATCH_YES)
> +    return MATCH_ERROR;

Why so many gfc_match calls?  Can't you e.g. just do
  if (gfc_match ("%n attributes simd", builtin) != MATCH_YES)
    return MATCH_ERROR;

  int builtin_kind = 0; /* Or whatever, just want to show the parsing here.  */
  if (gfc_match ("(notinbranch)") == MATCH_YES)
    builtin_kind = -1;
  else if (gfc_match ("(inbranch)") == MATCH_YES)
    builtin_kind = 1;

The space in gfc_match indicates gfc_gobble_whitespace (), i.e. optionally
eating whitespace (note, in fixed form white space is optionally eaten
pretty much always).  If you want a mandatory space, there is "% ".
So it depends in if in fixed form we want to support e.g.
!GCC$ BUI L    TIN SINf ATTRI BUT ESSIMD(NOT IN BRANCH)
and in free form e.g.
!gcc$ builtin sinf attributessimd (notinbranch)
I wouldn't use omp_simd because in C/C++ the attribute is called simd.
> +
> +  char *r = XNEWVEC (char, strlen (builtin) + 32);
> +  sprintf (r, "__builtin_%s", builtin);
> +  vectorized_builtins.safe_push (r);

Perhaps make it vector of const char *, int pairs, so that you can
encode no argument (aka inbranch + notinbranch) vs. inbranch vs. notinbranch?

>  #define F951_OPTIONS        "%(cc1_options) %{J*} \
> -                          %{!nostdinc:-fintrinsic-modules-path finclude%s}\
> +                          %{!nostdinc:-fintrinsic-modules-path finclude%s " \
> +                            TARGET_F951_NOSTDINC_OPTIONS "}\

I wouldn't stick it inside of %{!nostdinc:, but let config/gnu-user.h decide
about that (i.e. wrap it into %{!nostdinc: ... } there).

> --- a/gcc/fortran/lang.opt
> +++ b/gcc/fortran/lang.opt
> @@ -662,6 +662,10 @@ fprotect-parens
>  Fortran Var(flag_protect_parens) Init(-1)
>  Protect parentheses in expressions.
>  
> +fpre-include=
> +Fortran RejectNegative JoinedOrMissing Var(flag_pre_include) Undocumented
> +Path to header file that should be pre-included before each compilation unit.

Why OrMissing?  If the argument is missing, that should be an error, you
can't load "".

> --- a/gcc/fortran/scanner.c
> +++ b/gcc/fortran/scanner.c
> @@ -2365,6 +2365,16 @@ load_file (const char *realfilename, const char 
> *displayedname, bool initial)
>           }
>       }
>  
> +      /* Make a guard to prevent recursive inclusion.  */
> +      static bool preinclude_done = false;
> +      if (!preinclude_done)
> +     {
> +       preinclude_done = true;
> +       if (flag_pre_include != NULL && !load_file (flag_pre_include, NULL,
> +                                                   false))
> +         exit (FATAL_EXIT_CODE);
> +     }

Why in load_file?  I'd handle this in gfc_new_file, where it is called just
once.  Formatting - would be nicer to put && on the next line and not wrap
load_file args.

> +static const char *
> +find_fortran_header_file (int argc, const char **argv)
> +{
> +  if (argc != 2)
> +    return NULL;
> +
> +  const char *path = find_file (argv[1]);
> +  if (path != argv[1])
> +      return concat (argv[0], path, NULL);

I wouldn't call it fortran_header_file but fortran_preinclude_file
(both in what appears in spec and the name of the callback).

Plus, the patch lacks testcases.  I'd use dg-options "-nostdinc"
so that in that testcase it isn't preincluded, and have one free form and
one fixed form testcase that has various forms of the !gcc$ builtin
for a couple of builtins + some calls to them and check how they are handled
(perhaps limited to the one or two ABIs that support those)?

        Jakub

Reply via email to