|Re: Parameter registers (somewhat lengthly) firstname.lastname@example.org (1991-05-01)|
|From:||email@example.com (Rick Gorton)|
|Keywords:||optimize, registers, Pascal, Modula|
|Date:||Wed, 1 May 91 09:27:12 EDT|
> Does anyone know how nested procedures affect the ability to pass parameters
> via registers? ...
> [Can one reference a named parameter in an enclosing procedure? If so, I
> can imagine that would force them onto the stack. -John]
There are a number of items to consider. I've probably missed a
few, but this should be a good start:
1) For Pascal and Modula, you usually have the body of the nested
procedure (A) available for analysis before the caller to (A)
is compiled. For other languages (PL/I for example), the call
to (A) can occur lexically before the actual body of (A).
If you have a multiple-pass compiler, or aren't doing
inter-procedural analysis, you either have all the information,
for the optimizer to play with, or don't care.
If you are trying to optimize, but not do inter-procedural
analysis, treat [current and] outer scope variables as volatile
2) You presumably want your Pascal/Modula code to be able to
talk to your C code without having to add interludes, so
your calling convention needs to be consistent on the architecture
you are using. (See things like the 88Open ABI, SPARC architecture
manuals, etc.) From the perspective of register use, (unless you
are doing inter-procedural analysis) the parameter registers
are volatile across calls. If you don't need to make the
compiler talk with any other language, then you can say
"Well, we pass the first 17 parameters in registers, and then
pass the rest on the stack." For architectures with parameter
registers available, this means the parameter homing area.
(Which needs to be spelled out by the ABI)
3) When passing parameters in languages which permit nesting, you
are usually passing by reference, not by value. So you are
really passing a pointer to the memory location. If you actually
do pass by value, and can guarantee that none of the code
is trying to compute the address of the item being passed, then you
don't need to force it to the stack.
4) FUNCTION/PROCEDURE/ENTRY variables throw a nasty monkey wrench into
the works. If you have one of these in an external source module,
then all that nifty CSE-ing (Common Subexpression Elimination) you
did on the pointers in that block has to be treated as volatile across
5) Lexical uplevel variable access. If you have a register you can
dedicate to holding the frame pointer of the lexical caller routine,
you can use that to reference variables up one level. It can't be
the dynamic frame pointer, because if you have A, B, and C all nested
inside of D, and A, B, and C, all call each other, and they all
reference D's variables, the dynamic caller to A may actually be C.
But if you want to reference data more than one level up, you will
probably want to dedicate a location on the frame for the lexical
uplevel pointer, because you really don't know how many levels deep
you are at a given time. Using a dedicated frame location will also
permit inter-language manipulation (C could know about the frame/stack
layout and tinker with data in the Pascal code).
Hope this helps, (and hasn't muddled things too much)
Richard Gorton firstname.lastname@example.org (508) 626-0006
Language Processors, Inc. Framingham, MA 01760
Return to the
Search the comp.compilers archives again.