This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to add intrinsic functions to gfortran?


On Sat, May 29, 2004 at 01:47:07AM +0100, Paul Brook wrote:
> On Friday 28 May 2004 20:08, Steve Kargl wrote:
>
> > I've implemented G77's irand(), srand(), and rand()
> > procedures.  srand() is an intrinsic subroutine and
> > as far as I can tell it is seen, works, and is used by
> > gfortran.  On the other hand, irand() and rand() are
> > not working and I suspect some name mangling is need.
> 
> This is a good thing, however we need a way for the user to disable these 
> additional intrinsics.

I'm still trying to get a grasp on the gfortran internals.

Is it possible to generate more than one table of intrinsic
names and then choose the table based on -std=gnu or -std=f95? 

> Actually the whole registering/checking/resolution of intrinsics needs a 
> rewrite to make it easy to add and maintain new intrinsics.

This is probably of the same TODO list as MPFR rewrite.  BTW,
I read the MPFR doc last week and will start to experiment with
it soon.

> > In intrinsic.c, I have
> >
> >   add_sym_1 ("irand", 0, 1, BT_INTEGER, di,
> > 	     gfc_check_irand, gfc_simplify_irand, NULL,
> > 	     i, BT_INTEGER, di, 0);
> >
> >   make_generic ("irand", GFC_ISYM_IRAND);
> >
> > where GFC_ISYM_IRAND is added to "enum gfc_generic_isym_id" in
> > gfortran.h.   gfc_simplify_irand is required or gfortran yields
> > an ICE.  It looks like
> >
> >    gfc_expr *
> >    gfc_simplify_irand (gfc_expr * e)
> >    {
        (snip)
> >    }
> 
> The simplify functions basically perform constant folding. The above routine 
> effectively says that the function will return its argument unmodified, and 
> makes the substitution if the value if known at compile time.
> 
> I'd guess that irand doesn't need/want a simplify function.

I tried irand without a simplify function, but I got an ICE.
If I do 
    integer i
    i = 0
    i = irand(i)

I get sent into trans-intrinsics.c where I'm completely lost.

> 
> > Any hints would be appreciated.
> 
> The code generation for intrinsic functions is in trans-intrinsic.c.
> The best starting point is probably gfc_conv_intrinsic_function.

Yeah! I finally figured out that this is where I need to make
further modifications, but I'm completely lost.  I tried to
add 

LIBF_FUNCTION (IRAND, "irand", false),

in gfc_intrinsic_map[], but gfc_get_intrinsic_lib_fndecl only
applies to intrinsics that return REAL or COMPLEX values.

> a) Generate inline code, possibly including calls to helper functions.
> In this case this probably means the libc rand() and srand() functions.
> The resolved name is usually ignored, although you may still need the 
> resolution function.

The G77 implementations do use the libc rand() and srand().  I choose
to actually re-implement the functions to avoid a tangle of #ifdefs
and configure magic.  My implementation is 29 lines of code, and 
should be portable to any system that gfortran runs on.

> b) let it drop through to gfc_conv_intrinsic_funcall (Like MATMUL and 
> DOT_PRODUCT). This uses the resolved name, and it will be called exactly like 
> and external function.

I think this is what I'm looking for.

> 
> HTH
>

Actually, it did help.  I mean "How hard can it be to add a
simple intrinsic function to gfortran?"  :-O

-- 
Steve


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]