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.