code generation
play

Code Generation & 1. Allocating temporaries in the activation - PowerPoint PPT Presentation

Lecture Outline Code Generation & 1. Allocating temporaries in the activation record Parameter Passing Lets optimize our code generator a bit 2. A deeper look into calling sequences Caller/Callee responsibilities 3. Parameter


  1. Lecture Outline Code Generation & 1. Allocating temporaries in the activation record Parameter Passing – Let’s optimize our code generator a bit 2. A deeper look into calling sequences – Caller/Callee responsibilities 3. Parameter passing mechanisms – call-by-value, call-by-reference, call-by-value-result, call-by-name and call-by-need 2 Compiler Design I (2011) Extra Material in the Appendix (not covered in lecture) 4. Code generation for OO languages – Object memory layout An Optimization: – Dynamic dispatch Temporaries in the Activation Record 5. Code generation of data structure references – Address calculations – Array references 6. Code generation for logical expressions Topic 1 – Short-circuiting 3 Compiler Design I (2011)

  2. Review Review (Cont.) • The stack machine has activation records and • Advantage: Simple code generation intermediate results interleaved on the stack • Disadvantage: Slow code • The code generator must assign a location in – Storing/loading temporaries requires a store/load the AR for each temporary and $sp adjustment cgen(e 1 ) ; eval e 1 cgen(e 1 + e 2 ) = These get put here when AR ; save its value sw $a0 0($sp) we evaluate compound Temporaries ; adjust $sp (!) addiu $sp $sp-4 expressions like e 1 + e 2 AR cgen(e 2 ) ; eval e 2 (need to store e 1 while ; get e 1 Temporaries evaluating e 2 ) lw $t1 4($sp) ; $a0 = e 1 + e 2 add $a0 $t1 $a0 ; adjust $sp (!) addiu $sp $sp-4 5 6 Compiler Design I (2011) Compiler Design I (2011) An Optimization Improved Code • Idea: Predict how $sp will move at run time Old method New idea – Do this prediction at compile time cgen(e 1 + e 2 ) = cgen(e 1 + e 2 ) = – Move $sp to its limit, at the beginning cgen(e 1 ) cgen(e 1 ) sw $a0 0($sp) sw $a0 ?($fp) • The code generator must statically assign a addiu $sp $sp-4 location in the AR for each temporary statically cgen(e 2 ) cgen(e 2 ) allocate lw $t1 4($sp) lw $t1 ?($fp) add $a0 $t1 $a0 add $a0 $t1 $a0 addiu $sp $sp-4 7 8 Compiler Design I (2011) Compiler Design I (2011)

  3. Example How Many Stack Slots? add(w,x,y,z) • Let NS(e) = # of slots needed to evaluate e begin – Includes slots for arguments to functions x + (y + (z + (w + 42))) end • E.g: NS(e 1 + e 2 ) – Needs at least as many slots as NS(e 1 ) • What intermediate values are placed on the – Needs at least one slot to hold e 1 , plus as many slots stack? as NS(e 2 ), i.e. 1 + NS(e 2 ) • How many slots are needed in the AR to hold • Space used for temporaries in e 1 can be reused these values? for temporaries in e 2 9 10 Compiler Design I (2011) Compiler Design I (2011) The Equations for Mini Bar The Revised Activation Record • For a function definition f(x 1 ,…,x n ) begin e end the AR has 2 + NS(e) elements NS(e 1 + e 2 ) = max(NS(e 1 ), 1 + NS(e 2 )) NS(e 1 - e 2 ) = max(NS(e 1 ), 1 + NS(e 2 )) – Return address NS(if e 1 = e 2 then e 3 else e 4 ) = – Frame pointer max(NS(e 1 ), 1 + NS(e 2 ), NS(e 3 ), NS(e 4 )) – NS(e) locations for intermediate results NS(f(e 1 ,…,e n )) = max(NS(e 1 ), 1 + NS(e 2 ), 2 + NS(e 3 ), … , (n-1) + NS(e n ), n) NS(int) = 0 • Note that f’s arguments are now considered to NS(id) = 0 be part of its caller’s AR Rule for f(e 1 , … , e n ): Each time we evaluate an argument, we put it on the stack. 11 12 Compiler Design I (2011) Compiler Design I (2011)

  4. Picture: Activation Record Revised Code Generation • Code generation must know how many slots are in use at each point x n . . . pushed by caller • Add a new argument to code generation: the x 1 popped position of the next available slot Old FP by callee Return Addr. FP FP − 4 saved by Temp NS(e) callee . . . increasing Temp 1 values of addresses (this diagram disagrees direction of stack growth slightly with lecture 12: here, the callee saves FP) 13 14 Compiler Design I (2011) Compiler Design I (2011) Improved Code Notes • The slots for temporary values are still used Old method New method like a stack, but we predict usage at compile cgen(e 1 + e 2 ) = cgen(e 1 + e 2 , ns) = time cgen(e 1 ) cgen(e 1 , ns) compile-time – This saves us from doing that work at run time prediction sw $a0 ns ($fp) sw $a0 0($sp) – Allocate all needed slots at start of a function addiu $sp $sp -4 static allocation cgen(e 2 ) cgen(e 2 , ns+4) Exerc. Write some code which runs slower after lw $t1 ns ($fp) lw $t1 4($sp) performing the optimization just presented add $a0 $t1 $a0 add $a0 $t1 $a0 – Hint: Think about memory usage (& caches, etc.) addiu $sp $sp 4 15 16 Compiler Design I (2011) Compiler Design I (2011)

  5. Handling Procedure Calls and Returns Calling sequence: a code sequence that sets up a procedure call – allocates an activation record (model-dependent) A Deeper Look into Calling Sequences – loads actual parameters – saves machine state (return address, etc.) – transfers control to callee Topic 2 Return sequence: a code sequence that handles the return from a procedure call – deallocates the activation record – sets up return value (if any) – restores machine state (stack pointer, PC, etc.) 18 Compiler Design I (2011) Calling Sequences: Division of Responsibilities Calling Sequences: Layout Issues General rule of thumb: Fields that are fixed early, • The code in a calling sequence is often divided are placed near the middle of the activation up between the caller and the callee record caller Calling sequence • The caller has to evaluate the actual callee code parameters, and retrieve the return value • If there are m calls to a procedure, the instructions in the caller’s part of the calling sequence is repeated m – these fields should be located near the caller’s times, while the callee’s part is repeated exactly once activation record – This suggests that we should try to put as much of • The callee has to fill in machine status fields so the calling sequence as possible in the callee that the callee can restore state on return – However, it may be possible to carry out more call- – the caller should have easy access to this part of the specific optimization by putting more of the code into the caller instead of the callee callee’s activation record 19 20 Compiler Design I (2011) Compiler Design I (2011)

  6. Calling/Return Sequences: Typical Actions Example Activation Record: The SPARC Typical calling sequence: Registers high addresses 1. caller evaluates actuals; pushes them on the stack g0-g7 global registers caller’s frame 2. caller saves machine status on the stack (in the o0-o7 outgoing args current fp locals and caller’s sp callee’s AR) and updates the stack pointer local registers l0-l7 varies temporaries incoming args 3. caller transfers control to the callee i0-i7 outgoing args varies 4. callee saves registers, initializes local data, and not in o0-o5 stack begins execution function return address space to save growth o0-05 6 words caller’s o7 /callee’s i7 if necessary addr of return value 1 word Typical return sequence: space to save 1. callee stores return value in the appropriate place i0-i7 and l0-l7 16 words if necessary current sp 2. callee restores registers and old stack pointer callee’s fp callee’s frame 3. callee branches to the return address low addresses 21 22 Compiler Design I (2011) Compiler Design I (2011) Example Activation Record: Intel x86 Example Activation Record: MIPS R3000 high addresses high addresses caller’s frame caller’s frame incoming incoming arguments arguments return address locals and temporaries stack stack saved growth growth registers callee-save frame ptr registers saved ebp ebp outgoing locals and temporaries arguments stack ptr stack ptr esp $sp callee’s frame callee’s frame low addresses low addresses 23 24 Compiler Design I (2011) Compiler Design I (2011)

  7. Parameter Passing Mechanisms • There are many semantic issues in programming languages centering on when values are computed, and the scopes of names Parameter Passing Mechanisms – Evaluation is the heart of computation – Names are most primitive abstraction mechanism Topic 3 • We will focus on parameter passing – When are arguments of function calls evaluated? – What are formal parameters bound to? 26 Compiler Design I (2011) Parameter Passing Mechanisms (Cont.) Call-by-value First, an issue not discussed much… C uses call-by-value everywhere (except macros...) Default mechanism in Pascal and in Ada Order of argument evaluation - “Usually” not important for the execution of a callByValue(int y) program { output: y = y + 1; – However, in languages that permit side-effects in x = 42 print(y); call arguments, different evaluation orders may y = 43 } give different results x = 42 e.g. a call f(++x,x) in C main() x’s value does not { – A “standard” evaluation order is then specified change when y’s int x = 42; C compilers typically evaluate their arguments right-to-left. value is changed print(x); Why? callByValue(x); print(x); } 27 28 Compiler Design I (2011) Compiler Design I (2011)

Recommend


More recommend