|[2 earlier articles]|
|Re: Optimization of Uncommon Code (Was Java ByteCode ...) email@example.com (Walter Spector) (1996-07-01)|
|Re: Optimization of Uncommon Code firstname.lastname@example.org (Dwight VandenBerghe) (1996-07-02)|
|Re: Optimization of Uncommon Code email@example.com (1996-07-03)|
|Re: Optimization of Uncommon Code firstname.lastname@example.org (Jerry Leichter) (1996-07-03)|
|Re: Optimization of Uncommon Code email@example.com (Walter Spector) (1996-07-09)|
|Re: Optimization of Uncommon Code firstname.lastname@example.org (1996-07-10)|
|Re: Optimization of Uncommon Code email@example.com (1996-07-13)|
|From:||firstname.lastname@example.org (Chris Reedy)|
|Date:||13 Jul 1996 17:00:38 -0400|
|Organization:||The MITRE Corporation|
|References:||96-05-061 96-06-152 96-07-021 96-07-032 96-07-061|
> > Walter Spector wrote:
> > > Was there
> > > really a significant performance difference in the machines of the 1960s?
> Richard Weaver wrote:
> > You have the wrong decade, it was the 1950s that were different...
> > The first implementation of Fortran was on the IBM 704.
> > ...
> > The implementation of argument
> > passing was that, on entry to a subroutine/function, initialization code
> > would insert the argument addresses passed into each instruction referencing
> > those arguments. Note "each", could take a while for routines with lots of
> > references to their arguments and this occurred on every invocation.
A similar example from (a little :-)) more recent times. Around 1980 I
was developing software in PL/I on a Honeywell 6080 a machine reminiscent
of the IBM 7090 machines (36 bit words, highly non-uniform register set).
The 6080 didn't have a history of supporting stack based languages and I
needed to understand the argument passing mechanism to interface some
specialized assembly language routines. Well ...
In the calling program at the _return_ address the compiler would place a
sequence of instructions which would place the addresses of the arguments
into the A and Q registers (alternately). The called program would
immediately invoke a utility program which would save the caller's
registers and then execute in a loop (using XED and XEC instructions) the
instructions to generate the argument addresses, saving the addresses at
the beginning of the callee's stack frame (the utility program got passed
the number of arguments). The callee couldn't modify any registers until
the argument addresses had been generated, since the instructions that
generated the addresses were allowed to make use of the caller's registers
(with certain exceptions). When the callee returned it would jump to the
return address, which would re-execute (for no purpose) the argument
address generation instructions.
The worst example was those cases when the callee couldn't generate the
needed address in a single instruction. In those situations, it would,
prior to the call, generate the address, save the address in its local
memory, and the corresponding argument generation instruction would simply
load the address from local memory.
I estimated at one point that (including stack maintenance) something like
100 instructions were required to execute a call/return with a few (2-5)
arguments. I was really irked the day I realized that this could be
reduced to something like 10 instructions by having the caller simply
generate the addresses itself and store them at the end of its stack frame
(the same as the beginning of the callee's stack frame), especially since
we had been sweating blood trying to make the system run faster.
Dr. Christopher L. Reedy, Mail Stop Z667
Mitretek Systems, 7525 Colshire Drive, McLean, VA 22102-7400
Email: email@example.com Phone: (703) 610-1615 FAX: (703) 610-1603
Return to the
Search the comp.compilers archives again.