[comp.lang.fortran] FORTRAN and

dueker@xenon.arc.nasa.gov (The Code Slinger) (02/28/91)

Here's our situation:  We've received a lot of FORTRAN 77 code from
another group of people.  This code wasn't exactly written for portability.

Among other(!) problems, some variables in some of these routines expect to
retain their values from invocation to invocation.  This, of course, is not
guaranteed (except maybe on certain systems).

We'd like to find out if anybody knows of a program that will process
FORTRAN 77 code and determine if any of the variables in a given subroutine
should be SAVEd.  (We could do this by hand, but there's a lot of code
involved, and some of those subroutines are BIG!)

So, to avoid (if possible) having to write something like this ourselves,
we'd like to know if this has already been done.  (Who wants to reinvent the
wheel, anyway?)  We'd prefer public domain/shareware/etc., but ...

Adv(Thanks)anc for any info/help/pointers/etc.

Chris

P.S.  We're currently using VAX/VMS and SUN/UNIX OS's.

------------------------------------------------------------------------
"Ah, Benson, you are so mercifully free of the ravages of intellegence!"
"Oh, thank you, Master!"             - from the movie, TIME BANDITS
------------------------------------------------------------------------
dueker@xenon.arc.nasa.gov        |   Chris Dueker (The Code Slinger)
chris@chuck.arc.nasa.gov         |   Mtn. View, CA  (Sillycon Valley!)

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (02/28/91)

In article <1991Feb28.004447.3728@nas.nasa.gov>, dueker@xenon.arc.nasa.gov (The Code Slinger) writes:
> Among other(!) problems, some variables in some of these routines expect to
> retain their values from invocation to invocation.  This, of course, is not
> guaranteed (except maybe on certain systems).
> 
> We'd like to find out if anybody knows of a program that will process
> FORTRAN 77 code and determine if any of the variables in a given subroutine
> should be SAVEd.

If your concern is just to get the code running, why not just SAVE
*all* the variables?
-- 
The purpose of advertising is to destroy the freedom of the market.

dueker@xenon.arc.nasa.gov (The Code Slinger) (03/01/91)

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes...
>dueker@xenon.arc.nasa.gov (The Code Slinger) writes:
>> Among other(!) problems, some variables in some of these routines expect to
>> retain their values from invocation to invocation.  This, of course, is not
>> guaranteed (except maybe on certain systems).
>> 
>> We'd like to find out if anybody knows of a program that will process
>> FORTRAN 77 code and determine if any of the variables in a given subroutine
>> should be SAVEd.
> 
>If your concern is just to get the code running, why not just SAVE
>*all* the variables?

Well, we'd thought of that, but a high percentage of these routines have
many, many variables, and we are concerned about efficiency.  Also, we did
manage to find one variable that never had an initial value (including not
having a DATA statement for it!).  So, at least in that particular case, a
SAVE statement would not have helped.

Also, one person e-mailed me about a software package that is much like
a lint program for FORTRAN code.  We've seen that, and even had the
opportunity to "test-drive" it for a short while.

At the time, we were just interested in a call-tree, and found that the
package saw non-existent subroutine calls.  For example, the string 'CALL'
was in a FORMAT statement, and the lint program thought that was a
subroutine call, and extracted a VERY strange subroutine name from the
format specs following it.

Chris

------------------------------------------------------------------------
"Ah, Benson, you are so mercifully free of the ravages of intellegence!"
"Oh, thank you, Master!"             - from the movie, TIME BANDITS
------------------------------------------------------------------------
dueker@xenon.arc.nasa.gov        |   Chris Dueker (The Code Slinger)
duke@well.sf.ca.us               |   Mtn. View, CA  (Sillycon Valley!)

bsmith@caldwr.water.ca.gov (Bill Smith) (03/01/91)

I too would be interested in a program to find variables that
should be saved.  I have a large FORTRAN model code that I use
that has some variables that require the save statement.  My 
problem is that the original programmer did not save just the
variables that need it but used a compiler switch to save all
variables.  This severely limits the ability of the FORTRAN 
compiler to optimize the code. (Apollo FORTRAN).   

I got the Toolpack package via anaonymous ftp in hopes it would
be able to do this but found that only the source code was included.
I looked around  some but can not find any documentation.  Is 
there an anonymous ftp site that has the Toolpack documentation?

Thanks in advance for any pointers.
-- 
bsmith@water.ca.gov

system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) (03/02/91)

In article <112@smith.water.ca.gov> bsmith@caldwr.water.ca.gov (Bill Smith) writes:
>This severely limits the ability of the FORTRAN 
>compiler to optimize the code. (Apollo FORTRAN).   

On the Apollo system, using -O with f77 does result in a "flow analysis" that
can find some (but not all) variables that need to be saved. Look for
messages like "Use of uninitialized variable:" and "Assignment eliminated,
value never used:" - the former means that the variable is used before the
compiler thinks it got a value, and the former means that a variable appears
on the left side of an assignment but the routine never uses it again.
It can be fooled by conditional statements though, and by ENTRY
statements which expect values from other entry points to be preserved.
This analysis is not done for -g.

It seems to me that finding all such variables is an impossible task
for a routine of any complexity (e.g. containing conditional statements),
though I can see that a list of variables can be produced that do not
need to be saved under any circumstances (because they are always
defined before use in all possible paths throught the routine).
-- 
Mike Peterson, System Administrator, U/Toronto Department of Chemistry
E-mail: system@alchemy.chem.utoronto.ca
Tel: (416) 978-7094                  Fax: (416) 978-8775

tim@ksr.com (Tim Peters) (03/02/91)

In article <1991Mar1.191239.28479@alchemy.chem.utoronto.ca> system@alchemy.chem.utoronto.ca (System Admin (Mike Peterson)) writes:
> [ ... noting that on a particular compiler, avoiding -g leads to msgs
>	helpful in determing what should be SAVEd ...]
> It seems to me that finding all such variables is an impossible task
> for a routine of any complexity (e.g. containing conditional statements),
> though I can see that a list of variables can be produced that do not
> need to be saved under any circumstances (because they are always
> defined before use in all possible paths throught the routine).

Conservative approximations to the set of "live on entry" variables
(variables that *may* be referenced before being defined) are routinely
computed by optimizing compilers these days, and these are exactly the
ones that need to be SAVEd under a compiler that can't figure this out
itself.  If there's no possibility that a variable can be referenced
before being defined after entry, SAVE has no semantic meaning.  E.g.,
in

	subroutine blah1(x)
	save a
	a = 1
	print *, a
	end

the "SAVE A" means nothing since the promise that A will retain its
value between invocations of blah1 is a promise the breaking of which
has no visible effect (sure, you can look at a load map, but the load
map isn't visible to a standard-conforming test <grin>).

Identifying exactly which variables are *certain* to be used before
being defined is in general intractable; e.g., look at

      subroutine blah2(x)
      save a
      if ( x.lt.0 ) a = -1
      if ( x.eq.5 ) a = 0.
      print *, a
      end

Flow analysis easily discovers that A *may* be used (in the PRINT)
before being defined, but can't prove that it *will* be so used (good
thing, too, 'cause if the user always calls blah2 with arguments less
than 0, A will in fact never be referenced before being defined).  Thus
the SAVE may or may not mean something here, and a conservative compiler
must assume that it may.

A number of optimizing compilers for stack-based machines, particularly
those geared toward parallel environments, now ignore SAVE statements
entirely, and rely instead on this "(possibly) live on entry" criterion
to decide whether it must assign a variable to some flavor of "static"
storage.

The original poster wanted to know if a tool was available to identify
variables that "should be SAVEd".  I don't know of one, but if possible
they might try running their program through, e.g., Cray's CFT77 and
note which variables were assigned to static (as opposed to stack)
storage -- those are the variables flow analysis couldn't prove were
always defined before reference, .eq. the variables (possibly) live on
entry, .eq. the variables that should be SAVEd.

In my experience under weaker compilers, finding the scalar variables
that need to be SAVEd generally goes pretty fast 'n easy, 'cause so much
breaks so bad before they're all caught <grin>.  But there are usually a
few subtle problems that remain with local *arrays* that should have
been SAVEd -- without a flow analysis tool, patience and luck are what
it takes to fix those.

what-a-tangled-web-we've-weaved-ly y'rs  - tim

Tim Peters   Kendall Square Research Corp
tim@ksr.com,  ksr!tim@harvard.harvard.edu

iris@interet.UUCP (User) (03/06/91)

IPT in Palo Alto, CA offers a product called Fortran-Lint
which  we  use  on a Sparc station.  It is also available
for other DOS and Unix platforms.  Fortran-Lint is a very
good  global  source  code optimizer (we also use MAT and
Quibus's FORWARN; Fortran-lint  compares  favorably  with
both).

Among  its  vast  array  of  very   useful   diagnostics,
Fortran-lint  includes an apparently very rigorously com-
plete, if a bit conservative,  list  of  variables  which
_may_  be referenced before set.   If you SAVE these, you
should be ok.  (You may also catch a few real bugs!)

Iris Engelson
Interet

peterson@fman.enet.dec.com (Bob Peterson) (03/06/91)

Even if the compiler doesn't do the flow analysis completely, shouldn't
it be a safe bet that SAVEd variables operate as fast or faster than
unsaved variables?  This presumes you aren't using an overlaid memory
system, but that unSAVEd variables are stack-based (automatic) and
SAVEd variables are statically allocated.  Overlays may throw in kinks
I am not familiar with.

\bob

khb@chiba.Eng.Sun.COM (Keith Bierman fpgroup) (03/06/91)

In article <1991Mar5.194219@fman.enet.dec.com> peterson@fman.enet.dec.com (Bob Peterson) writes:

..
   it be a safe bet that SAVEd variables operate as fast or faster than
...

No. SAVEd variables must be written to memory. UnSAVEd variables may
turn out to be just register references.

Admittedly this is unlikely to be very important in any real Fortran code.
--
----------------------------------------------------------------
Keith H. Bierman    kbierman@Eng.Sun.COM | khb@chiba.Eng.Sun.COM
SMI 2550 Garcia 12-33			 | (415 336 2648)   
    Mountain View, CA 94043

maine@altair.dfrf.nasa.gov (Richard Maine) (03/06/91)

On 6 Mar 91 02:07:57 GMT, khb@chiba.Eng.Sun.COM (Keith Bierman fpgroup) said:

Keith> In article <1991Mar5.194219@fman.enet.dec.com> peterson@fman.enet.dec.com (Bob Peterson) writes:

Bob>    it be a safe bet that SAVEd variables operate as fast or faster than

Keith> No. SAVEd variables must be written to memory. UnSAVEd variables may
Keith> turn out to be just register references.

Also, if there are multiple subroutines with large SAVEd arrays, this
can increase the program's memory usage enough to slow things down
(or even keep them from running at all).  If these multiple subroutines
are never simultaneously "active" in the call chain, (for instance if
they are alternative algorithms) then an unSAVED equivalent can be
smaller and faster.

This kind of thing does happen in real programs.  Of course, it is
only an issue for arrays; scalar variables are very unlikely to take
enough space to have noticable effect.


--
--
Richard Maine
maine@altair.dfrf.nasa.gov

peterson@fman.enet.dec.com (Bob Peterson) (03/07/91)

Keith> In article <1991Mar5.194219@fman.enet.dec.com> writes:

Keith> No. SAVEd variables must be written to memory. UnSAVEd variables may
Keith> turn out to be just register references.

They have to be written to memory when the routine is done, or if it
calls external routines.  Meanwhile they can be held in registers.
Without a VOLATILE declaration or address-taking operator (such as
%LOC() or LOC()) the keeping things in registers may hurt asynchronous
accesses to the variable from outside agent, but this is not the norm
in Fortran.

Without flow analysis either built into the compiler, or an external
tool like the original poster wanted, then depending on the situation
the cost of the write to memory may be cheaper than wading through the
code by hand to do your own flow analysis.


Richard in article <MAINE.91Mar5212710@ra.dfrf.nasa.gov> writes:
> Also, if there are multiple subroutines with large SAVEd arrays, this
> can increase the program's memory usage enough to slow things down
> (or even keep them from running at all).  If these multiple subroutines
> are never simultaneously "active" in the call chain, (for instance if
> they are alternative algorithms) then an unSAVED equivalent can be
> smaller and faster.

Quite true, even in some (all?) virtual memory operating systems.  A
good flow-analyzing, inlining, globally optimizing compiler is then
worth its weight in zorkmids.

vsnyder@jato.jpl.nasa.gov (Van Snyder) (03/08/91)

In article <1991Mar5.194219@fman.enet.dec.com> peterson@fman.enet.dec.com (Bob Peterson) writes:
>Even if the compiler doesn't do the flow analysis completely, shouldn't
>it be a safe bet that SAVEd variables operate as fast or faster than
>unsaved variables?... 
On anything 80x86, stack references are faster than other kinds.

Van.
-- 
vsnyder@jato.Jpl.Nasa.Gov
ames!elroy!jato!vsnyder
vsnyder@jato.uucp