[comp.lang.fortran] Function call optimisations

chris@mimsy.UUCP (Chris Torek) (09/22/88)

>In article <561@hudson.acc.virginia.edu> gl8f@bessel.acc.Virginia.EDU
>(Greg Lindahl) claims:
>>VAX/VMS fortran doesn't work this way, even with math library functions
>>which are known to have no side-effects. if you write
>>	a = sin(x)
>>	b = sin(x)
>>	c = sin(x)
>>it will call sin() 3 times.

In article <6370@batcomputer.tn.cornell.edu>
thompson@batcomputer.tn.cornell.edu (Steve Thompson) writes:
>I couldn't believe this when I saw it, so I checked it on my VMS V4.7/
>FORTRAN V4.8 system. Sin(x) does get called only ONCE, as you can
>easily verify by looking at the machine code listing.

Of course, none of this is relevant with regard to the intended subject
(corrected above), since `SIN' is an intrinsic in Fortran 77.

To answer that question, consider the following:

	C program 1.
		PROGRAM P
		INTEGER F
		PRINT *, F(1), F(1)
		STOP
		END

and in a separate file, with the compiler prevented (artificially if
necessary) from seeing the code for function F in program P:

	C the identity function
		INTEGER FUNCTION F(I)
		INTEGER I
		F = I
		RETURN
		END

Given this situation, may a Fortran compiler legally compile program P
such that it in fact calls function F only once?

It is true that the *order* of the calls to F is undefined, but I
do not know whether the *number* of calls to F is undefined.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jlg@lanl.gov (Jim Giles) (09/22/88)

From article <13675@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek):
> 		PROGRAM P
> 		INTEGER F
> 		PRINT *, F(1), F(1)
> 		STOP
> 		END
> 
> Given this situation, may a Fortran compiler legally compile program P
> such that it in fact calls function F only once?
> It is true that the *order* of the calls to F is undefined, but I
> do not know whether the *number* of calls to F is undefined.

As you said, Fortran doesn't guarantee the order of the calls.  It
also (in this case) prohibits several side effects (anything that
might change the value of subsequent calls and any I/O).  If both
calls were part of a singlt mathematical expression, the standard
specifically allows optimizations as long as the mathematical result
is the same (but not, necessarily, the computational result).  So, 
in an expression, the two calls could be optimized to one.  But here, you
have two expressions - so the standard doesn't explicitly allow or
prohibit the optimization in question.  I suspect that if a compiler
did optimize the second call into oblivion, you would have a tough
case to make if you claimed it was illegal.

J. Giles
Los Alamos

P.S.  I would _prefer_ that a compiler would use only one call
      if the function is a known intrinsic and that it make both
      calls for all other functions.  But the standard doesn't require
      it, so do this instead (to be safe):

      tmp = F(1)
      PRINT *, tmp, F(1)

      But, don't do this unless you actually have side effects that you
      wish to protect!  In fact, if you know there are no side effects
      you might want to replace the PRINT with:

      PRINT *, tmp, tmp

      Wouldn't it be nice if you could just declare which functions
      had side effects and which didn't?  Then the normal code would
      always work correctly and could still be optimized when it was
      safe to do so.