[PATCH][RFC]Overloading intrinsics

Richard Biener richard.guenther@gmail.com
Wed Oct 31 09:40:00 GMT 2018


On Tue, Oct 30, 2018 at 4:40 PM Martin Liška <mliska@suse.cz> wrote:
>
> On 10/29/18 4:24 PM, Richard Biener wrote:
> > On Mon, Oct 29, 2018 at 2:49 PM Martin Liška <mliska@suse.cz> wrote:
> >>
> >> Hi.
> >>
> >> Unlike the C and C++ front-ends, GNU Fortran does not know about
> >> vector implementations of math routines provided by GLIBC. This
> >> prevents vectorization of many loops which is a frequent cause of
> >> performance that is worse than compilers with their own math library
> >> such as ICC.
> >>
> >> The purpose of the patch is to provide a mechanism that will tell Fotran FE
> >> which intrinsics have simd cloned in math library.
> >>
> >> I've been cooperating with Paul and we came to a proof-of-concept that consists
> >> of 2 parts (patches):
> >>
> >> The first patch adds support for inclusion a module via
> >> command line. The module will be provided by glibc in order to synchronize which functions
> >> are provided by a glibc version. Paul is suggesting to maybe include that into load machinery
> >> of IEEE module.
> >>
> >> Second patch propagates information about newly introduced attribute simd_notinbranch into
> >> gfc_intrinsic_sym. That is later used to modify a corresponding __bultin_*.
> >>
> >> Definition of the intrinsics module and it's usage can look like:
> >>
> >> cat ~/Programming/testcases/use.f90
> >> module overload
> >>   interface
> >>     function sin(arg)
> >>       !GCC$ attributes simd_notinbranch :: sin
> >>       real, intent(in) :: arg
> >>       real :: sin
> >>     end function sin
> >>   end interface
> >> end module
> >>
> >> program test_overloaded_intrinsic
> >>   real(4) :: x(3200), y(3200), z(3200)
> >>
> >>   ! this should be using simd clone
> >>   y = sin(x)
> >>   print *, y
> >>
> >>   ! this not
> >>   z = cos(x)
> >>   print *, z
> >> end
> >>
> >> Then using my patches one can see:
> >> $ ./xgcc -B. ~/Programming/testcases/use.f90 -c -Ofast -fdump-tree-optimized=/dev/stdout -c
> >>
> >> ;; Function test_overloaded_intrinsic (MAIN__, funcdef_no=0, decl_uid=3815, cgraph_uid=1, symbol_order=0) (executed once)
> >>
> >> test_overloaded_intrinsic ()
> >> {
> >> ...
> >>   vect__3.14_58 = sinf.simdclone.0 (vect__2.13_60);
> >>   MEM[symbol: y, index: ivtmp.35_47, offset: 0B] = vect__3.14_58;
> >> ...
> >>   _6 = __builtin_cosf (_5);
> >>   MEM[symbol: z, index: ivtmp.30_46, offset: 0B] = _6;
> >> ...
> >> }
> >>
> >> That's what I have. I would like to ask Fortran folks about their opinion? I know
> >> the part in gfc_match_gcc_attributes is bit tricky, but apart from that the rest
> >> should be well formed.
> >>
> >> Thoughts?
> >
> > The gfc_conv_intrinsic_lib_function should be in
> > gfc_get_intrinsic_lib_fndecl instead I think
> > as you are adding the attribute once for each call it seems.  I think
> > that it would be more
>
> Hi.
>
> I fixed that by clearing of simd attribute. But yes, it makes sense to set
> it just once.
>
> > forward-looking to make the gfc_intrinsics_sym->simd flag a 'tree
> > attributes' list instead.
>
> Well, I believe all the flags gfc_intrinsic_sym flags are used in very similar way
> as I use it for simd flag.
>
> >
> > That you do the matching in gfc_match_gcc_attributes is quite odd IMHO
> > but you said
> > that already.  I'd say a more proper place would be where the FE
> > "ends" parsing of
> > the specification part of an interface.
>
> I improved that and I also do it only for a module with 'vector_math' name.
> Will we want that?

I don't think so.

> >
> > Of course simd_notinbranch isn't exactly supporting all simd variants,
> > but not sure
> > how difficult it is to add this as 'simd' with arguments...
>
> Will we need multiple variants?

The simd attribute can be used on regular functions as well to get vectorization
without -fopenmp-simd.  But yes, for a standard vectorized math libary full
functionality isn't needed.

> >
> > Some bikeshedding on the other part:
> >
> > +module-include
> > +Fortran Joined Separate
> > +Use implicitelly a module
> > +
> >
> > module-use or use-module or simply use?  Or import?  include sounds so C-ish.
>
> Yep, I prefer module-use.
>
> >
> > +void
> > +gfc_add_implicit_use (const char *module_name)
> > +{
> > +  implicit_module_name = module_name;
> > +}
> >
> > so this works for exactly one module...
>
> I extended that to support multiple ones.
>
> >
> > I guess the part that is missing is to add target specific specs
> > fragments adding
> > -use FOO for fortran invocations, allowing FOO to not exist(?).
>
> Will take a look at that.
>
> Now I've tried to separate real module and it's usage and I see strange error:
>
> $ cat ~/Programming/testcases/module.f90
> module vector_math
>   interface
>     function sin(arg)
>       !GCC$ attributes simd_notinbranch :: sin
>       real, intent(in) :: arg
>       real :: sin
>     end function sin
>   end interface
> end module
>
> $ ./xgcc -B. -Ofast -c ~/Programming/testcases/module.f90
>
> $ cat ~/Programming/testcases/use.f90
> program test_overloaded_intrinsic
>   use vector_math
>   real(4) :: x(3200), y(3200), z(3200)
>
>   ! this should be using simd clone
>   y = sin(x)
>   print *, y
>
>   ! this not
>   z = cos(x)
>   print *, z
>
>   z = sin (z)
>   print *, z
> end
>
> $ ./xgcc -B. -Ofast -c ~/Programming/testcases/use.f90
> /home/marxin/Programming/testcases/use.f90:6:10:
>
>     6 |   y = sin(x)
>       |          1
> Error: Rank mismatch in argument ‘arg’ at (1) (scalar and rank-1)
> /home/marxin/Programming/testcases/use.f90:13:11:
>
>    13 |   z = sin (z)
>       |           1
> Error: Rank mismatch in argument ‘arg’ at (1) (scalar and rank-1)
>
> Thanks,
> Martin
>
> >
> > Richard.
> >
> >
> >> Thanks,
> >> Martin
> >>
>



More information about the Fortran mailing list