This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
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