[comp.compilers] Parameter registers

rcg@lpi.liant.com (Rick Gorton) (05/01/91)

> 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
   across calls.

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
   that call.

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)
	rick

Richard Gorton               rcg@lpi.liant.com  (508) 626-0006
Language Processors, Inc.    Framingham, MA 01760
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.