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.