🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.misc
Article #1943

Re: Whether cc after f2c can optimize arrays as well as f77 can

#1943
From: Jim Giles
Date: Tue, 06 Nov 1990 21:02
99 lines
5163 bytes
It would actually never occur to me to post something out of a private
email conversation onto the net without the other person's permission.
But, since you have done so, I will continue the discussion in a public
venue.  In fact, I was wondering how to introduce this topic onto the
net myself.

From article <2779:Nov608:20:1990@kramden.acf.nyu.edu>, by brnstnd@kramden.acf.nyu.edu (Dan Bernstein):
> In article <4869@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
> [...]
> :   [ file1: int a; int b; main() { ... sub(&a); ... } ]
> :   [ file2: extern int a; sub(x) int *x; { ... } ]
> :   [ file3: extern int b; sub(x) int *x; { ... } ]

These three separate file descriptions I sent (in a somewhat more
legible form) as an example of the fact that _some_ decision _must_
be made at load time with respect to aliasing.  As can be seen, the
main code has a global called 'a' and sends it (call-by-reference)
to a procedure called 'sub'.  The other two files give two alternate
definitions of the procedure.  If the main code is loaded with the
version of 'sub' in file2, then the argument and the global would be
aliased in that context - either slow code or unsafe optimizations
must be accepted.  If the version of 'sub' from file3 is loaded,
then this problem doesn't arise and we would prefer the optimized
version.

> [...]
> : The compiler expands file2's sub() into two functions:
> : 
> :   subf(x) int *x; /* possibly */ aliased global, x; { ... }
> :   subg(x) int *x; /* no aliasing allowed */ { ... }
> : 
> : Similarly for file3.

This was his proposed solution which he claims solves the problem
without any loader intervention (indeed, without load-time action
of any kind).  Presumably, this produces 4 object files (or at least
4 object versions of 'sub').  For convenience, let's call these
'subf2.o', 'subg2.o' (both from the definition in file2), 'subf3.o'
and 'subg3.o' (both from the definition of file3).

> : 
> : The compiler compiles file1's main() into two functions, only one of
> : which will be used:
> : 
> :   main() /* no aliasing allowed */ { ... subf(x) ... }
> : 
> : Must I keep explaining?

Yes, I think you must.  At this point, you have 6 object modules.
The two from file1 are presumably identical since there is no
hidden aliasing possible in 'main' (not any shown in the example
anyway).  Let us call this 'main.o' since it doesn't matter which
of the 'main' versions I use.

Now, to load and run the code, I do what?  Well, somehow, I must decide
which of the four versions of 'sub' to load with 'main'.  Half of this
decision is the same as always, I must decide whether I want the version
from file2 of the one from file3.  But, the next decision is more
difficult: which of 'subf.o' and 'subg.o' should I load?  Well, a
quick examination of the files shows me that I should either use
'subf2.o' (the one from file2 that allows aliasing) or I should
use 'subg3.o' (the one from file3 which is optimized).

But, wait a minute!!  How did I decide that?  I did it by looking the
the relevant code in the caller and the callee (an interprocedural
analysis - I always said there'd be one of those).  And, I made the
decision at load-time (exactly the time I always said the decision
would be made).  Further, the loader itself could have made the
decision if the compiler passed the right information along (which
is what I always recommended).

> [...]
> : To do a better job, of course, you can add more levels between ``all
> : variables may be aliased'' and ``no variables are aliased.'' For
> : example: ``Any parameter may be aliased with a.'' ``Any parameter may be
> : aliased with b.'' [...]

I pointed out repeatedly in email that many compilers already have
this feature: it doesn't solve or even address the problem, which
was (as Walker put it), HOW DOES THE USER _KNOW_ what to assert
with all these declaraions?  It requires an interprocedural analysis.

> [...]
> : The most flexible (and arguably the best) solution is to let the
> : programmer assert the lack of aliasing between any variables at any
> : time. Q provides sufficiently general mechanisms for this.

As long as the _LOADER_ checks the consistency of these assertions
across procedure calls, this is indeed adequate.  Feedback from such
_LOADER_ tests would be sufficient to tell the user the interprocedural
information needed (though, through trial and error).

By the way, as I've pointed out before, the _LACK_ of aliasing
should be the default - the presence of possible aliasing should
require the assertion.  It makes sense to make the most commonly
desired configuration be the default.  You always ask for the
reverse of that.

J. Giles
Technical Details
Message-ID: <5085@lanl.gov>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!jlg
References: <2779:Nov608:20:1990@kramden.acf.nyu.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!lanl!jlg
From: jlg@lanl.gov (Jim Giles)
Newsgroups: comp.lang.misc
Subject: Re: Whether cc after f2c can optimize arrays as well as f77 can
Message-ID: <5085@lanl.gov>
Date: 6 Nov 90 21:02:26 GMT
References: <2779:Nov608:20:1990@kramden.acf.nyu.edu>
Organization: Los Alamos Natl Lab, Los Alamos, N.M.
Lines: 99