Winter 2006-2007 Compiler Construction T12 – Code Generation Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv University.

Slides:



Advertisements
Similar presentations
The University of Adelaide, School of Computer Science
Advertisements

Intermediate Representation III. 2 PAs PA2 deadline is
A simple register allocation optimization scheme.
Winter Compiler Construction T7 – semantic analysis part II type-checking Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv.
Compiler Construction Intermediate Representation III Activation Records Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University.
Assembly Language for Intel-Based Computers Chapter 8: Advanced Procedures Kip R. Irvine.
Lecture 13 – Compiling Object-Oriented Programs Eran Yahav 1 Reference: MCD
Lecture 10 – Activation Records Eran Yahav 1 Reference: Dragon 7.1,7.2. MCD 6.3,
Lecture 11 – Code Generation Eran Yahav 1 Reference: Dragon 8. MCD
University of Washington Last Time For loops  for loop → while loop → do-while loop → goto version  for loop → while loop → goto “jump to middle” version.
Compiler Construction Code Generation II Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
1 Storage Registers vs. memory Access to registers is much faster than access to memory Goal: store as much data as possible in registers Limitations/considerations:
Machine-Level Programming III: Procedures Apr. 17, 2006 Topics IA32 stack discipline Register saving conventions Creating pointers to local variables CS213.
PC hardware and x86 3/3/08 Frans Kaashoek MIT
1 Function Calls Professor Jennifer Rexford COS 217 Reading: Chapter 4 of “Programming From the Ground Up” (available online from the course Web site)
Accessing parameters from the stack and calling functions.
– 1 – , F’02 ICS05 Instructor: Peter A. Dinda TA: Bin Lin Recitation 4.
Run time vs. Compile time
Compiler Summary Mooly Sagiv html://
Compiler Construction Recap Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
Assembly תרגול 8 פונקציות והתקפת buffer.. Procedures (Functions) A procedure call involves passing both data and control from one part of the code to.
Compiler Construction Activation records Code Generation Rina Zviel-Girshin and Ohad Shacham School of Computer Science Tel-Aviv University.
Stack Activation Records Topics IA32 stack discipline Register saving conventions Creating pointers to local variables February 6, 2003 CSCE 212H Computer.
Compiler Construction Code Generation I Ran Shaham and Ohad Shacham School of Computer Science Tel-Aviv University.
6.828: PC hardware and x86 Frans Kaashoek
Computer Architecture and Operating Systems CS 3230 :Assembly Section Lecture 7 Department of Computer Science and Software Engineering University of Wisconsin-Platteville.
Lecture 10 – Code Generation Eran Yahav 1 Reference: Dragon 8. MCD
1 Carnegie Mellon Stacks : Introduction to Computer Systems Recitation 5: September 24, 2012 Joon-Sup Han Section F.
Runtime Environments Compiler Construction Chapter 7.
Code Generation Gülfem Savrun Yeniçeri CS 142 (b) 02/26/2013.
CSc 453 Runtime Environments Saumya Debray The University of Arizona Tucson.
Fabián E. Bustamante, Spring 2007 Machine-Level Programming III - Procedures Today IA32 stack discipline Register saving conventions Creating pointers.
Assembly Language for Intel-Based Computers, 6 th Edition Chapter 8: Advanced Procedures (c) Pearson Education, All rights reserved. You may.
Activation Records CS 671 February 7, CS 671 – Spring The Compiler So Far Lexical analysis Detects inputs with illegal tokens Syntactic analysis.
Code Generation III. PAs PA4 5.1 – 7.2 PA5 (bonus) 24.1 –
COP4020 Programming Languages Subroutines and Parameter Passing Prof. Xin Yuan.
Activation Records (in Tiger) CS 471 October 24, 2007.
Winter Compiler Construction T11 – Activation records + Introduction to x86 assembly Mooly Sagiv and Roman Manevich School of Computer Science.
Machine-level Programming III: Procedures Topics –IA32 stack discipline –Register saving conventions –Creating pointers to local variables.
CS412/413 Introduction to Compilers and Translators Spring ’99 Lecture 11: Functions and stack frames.
Intermediate Representation II Storage Allocation and Management EECS 483 – Lecture 18 University of Michigan Wednesday, November 8, 2006.
Compiler Construction Code Generation Activation Records
University of Amsterdam Computer Systems – the instruction set architecture Arnoud Visser 1 Computer Systems The instruction set architecture.
1 Assembly Language: Function Calls Jennifer Rexford.
Compiler Principles Fall Compiler Principles Lecture 8: Intermediate Representation Roman Manevich Ben-Gurion University.
Code Generation II. 2 Compiler IC Program ic x86 executable exe Lexical Analysis Syntax Analysis Parsing ASTSymbol Table etc. Inter. Rep. (IR) Code Generation.
Overview of Back-end for CComp Zhaopeng Li Software Security Lab. June 8, 2009.
Winter Compiler Construction T10 – IR part 3 + Activation records Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv University.
LECTURE 19 Subroutines and Parameter Passing. ABSTRACTION Recall: Abstraction is the process by which we can hide larger or more complex code fragments.
IA32 Stack –Region of memory managed with stack discipline –Grows toward lower addresses –Register %esp indicates lowest stack address address of top element.
Reading Condition Codes (Cont.)
Credits and Disclaimers
C function call conventions and the stack
143A: Principles of Operating Systems Lecture 4: Calling conventions
Homework In-line Assembly Code Machine Language
Introduction to Compilers Tim Teitelbaum
Recitation 2 – 2/4/01 Outline Machine Model
Machine-Level Programming 4 Procedures
Condition Codes Single Bit Registers
Procedures – Overview Lecture 19 Mon, Mar 28, 2005.
Winter Compiler Construction T10 – IR part 3
Code Generation Part I Chapter 9
Machine-Level Programming III: Procedures Sept 18, 2001
Multi-modules programming
X86 Assembly Review.
Credits and Disclaimers
Computer Architecture and System Programming Laboratory
Presentation transcript:

Winter Compiler Construction T12 – Code Generation Mooly Sagiv and Roman Manevich School of Computer Science Tel-Aviv University

2 Notes Weighted register allocation in LIR Can use for all expression types (not just for commutative operators) Get to know LIR optimization algorithms for exam Must reset LIR register counter after every IC statement: x=y; y=z; should not be translated to Move y,R0 Move R0,x Move z,R1 Move R1,y But rather to Move y,R0 Move R0,x # Finished translating statement. Set c=0 Move z,R0 Move R0,y

3 Weighted register allocation Can save registers by re-ordering subtree computations Label each node with its weight Weight = number of registers needed Leaf weight known Internal node weight w(left) > w(right) then w = left w(right) > w(left) then w = right w(right) = w(left) then w = left + 1 Choose heavier child as first to be translated WARNING: have to check that no side-effects exist before attempting to apply this optimization (pre-pass on the tree)

4 Weighted reg. alloc. example b 5c * array access + a baseindex W=1 W=2W=1W=2 Phase 1: - check absence of side-effects in expression tree - assign weight to each AST node R0 := TR[ a+b[5*c] ]

5 Weighted reg. alloc. example R0 := TR[ a+b[5*c] ] b 5c * array access + a R0 baseindex W=1 W=2W=1 W=2 R1 Phase 2: use weights to decide on order of translation Heavier sub-tree Move c,R0 Mul 5,R0 Move b,R1 MoveArray R1[R0],R0 Add a,R0

6 Today: Assembling and linking Code generation Runtime checks Optimizations Labels/jumps Register allocation for basic blocks Today IC Language ic Executable code exe Lexical Analysis Syntax Analysis Parsing ASTSymbol Table etc. Inter. Rep. (IR) Code Generation Next time: PA5 Recap Final exam practice questions

7 Intel IA-32 assembly Going from assembly to binary Assembler tool: GNU assembler ( as ) Linker tool: GNU linker ( ld ) Use Cygwin on WindowsCygwin IMPORTANT: select binutils and gcc when installing cygwin Tools usually pre-exist on Linux environment Supporting materials for PA5 on web site

8 From assembly to executable Lexical Analysis Syntax Analysis Parsing ASTSymbol Table etc. Inter. Rep. (IR) Code Generation IC Program prog.ic x86 assembly prog.s x86 assembly prog.s libic.a (libic + gc) GNU assembler prog.o GNU linker prog.exe Can automate compilation+assembling+linking with script / Ant

9 How do you get an object file from generated.s file? (Under Windows using Cygwin) From assembly file to object file GNU Assembler Assmebly Program (file.s) Object file (file.o) as -o file.o file.s

10 How do you get an exe file from generated.o file? (Under Windows using Cygwin) From object file to executable File Executable code (file.exe) exe Object files / Libraries (libic.a) Linker Object file (file.o) ld -o file.exe file.o /lib/crt0.o libic.a -lcygwin -lkernel32 IMPORTANT: don’t change order of arguments

11 LIR to assembly Need to know how to translate: Function bodies Translation for each kind of LIR instruction Calling sequences Correctly access parameters and variables (and LIR register) Compute offsets for parameter and variables Dispatch tables String literals Runtime checks Error handlers

12 Reminder: accessing variables Use offset from frame pointer Remember – stack grows downwards Above EBP = parameters Below EBP = locals (and spilled LIR registers) Examples %ebp + 4 = return address %ebp + 8 = first parameter %ebp – 4 = first local …… SP FP Return address param n … param1 local 1 … local n Previous fp param n … param 1 FP+8 FP-4

13 Translating LIR instructions Translate function bodies: 1. Compute offsets for: Local variables (-4,-8,-12,…) LIR registers (considered extra local variables) Function parameters (+8,+12,+16,…) Take this parameter into account 2. Translate instruction list for each function Local translation for each LIR instruction Local (machine) register allocation

14 Memory offsets implementation // MethodLayout instance per function declaration class MethodLayout { // Maps variables/parameters/LIR registers to // offsets relative to frame pointer (BP) Map memoryToOffset; } void foo(int x, int y) { int z = x + y; g = z; // g is a field Library.printi(z); } virtual function takes one extra parameter: this MethodLayout for foo MemoryOffset this +8 x +12 y +16 z -4 R0 -8 R1 -12 _A_foo: Move x,R0 Add y,R0 Move R0,z Move this,R1 MoveField R0,R1.1 Library __printi(R0),Rdummy (manual) LIR translation 1 PA4 PA5

15 Memory offsets example MethodLayout for foo _A_foo: Move x,R0 Add y,R0 Move R0,z Move this,R1 MoveField R0,R1.1 Library __printi(R0),Rdummy _A_foo: push %ebp # prologue mov %esp,%ebp mov 12(%ebp),%eax # Move x,R1 mov %eax,-8(%ebp) mov 16(%ebp),%eax # Add y,R1 add -8(%ebp),%eax mov %eax,-8(%ebp) mov -8(%ebp),%eax # Move R1,z mov %eax,-4(%ebp) mov 8(%ebp),%eax # Move this,R2 mov %eax,-12(%ebp) mov -8(%ebp),%eax # MoveField R1,R2.1 mov -12(%ebp),%ebx mov %eax,8(%ebx) mov -8(%ebp),%eax # Library __printi(R1) push %eax call __printi add $4,%esp _A_foo_epilogoue: mov %ebp,%esp # epilogoue pop %ebp ret LIR translation (optimized) Translation to x86 assembly (non-optimized) MemoryOffset this +8 x +12 y +16 z -4 R1 -8 R

16 Instruction-specific register allocation Non-optimized translation Each non-call instruction has fixed number of variables/registers Naïve (very inefficient) translation Use direct algorithm for register allocation Example: Move x,R1 translates into move x offset (%ebp),%ebx move %ebx,R1 offset (%ebp) Register hard-coded in translation

17 Translating instructions 1 LIR InstructionTranslation MoveArray R1[R2],R3mov -8(%ebp),%ebx # -8(%ebp)=R1 mov -12(%ebp),%ecx # -12(%ebp)=R2 mov (%ebx,%ecx,4),%ebx mov %ebx,-16(%ebp) # -16(%ebp)=R3 MoveField x,R2.3mov -12(%ebp),%ebx # -12(%ebp)=R2 mov -8(%ebp),%eax # -12(%ebp)=x mov %eax,12(%ebx) # 12=3*4 MoveField _DV_A,R1.0movl $_DV_A,(%ebx) # (%ebx)=R1.0 ( movl means move 4 bytes) ArrayLength y,R1mov -8(%ebp),%ebx # -8(%ebp)=y mov -4(%ebx),%ebx # load size mov %ebx,-12(%ebp) # -12(%ebp)=R1 Add R1,R2mov -16(%ebp),%eax # -16(%ebp)=R1 add -20(%ebp),%eax # -20(%ebp)=R2 mov %eax,-20(%ebp) # store in R2

18 Translating instructions 2 LIR InstructionTranslation Mul R1,R2mov -8(%ebp),%eax # -8(%ebp)=R2 imul -4(%ebp),%eax # -4(%ebp)=R1 mov %eax,-8(%ebp) Div R1,R2 (idiv divides EDX:EAX stores quotient in EAX stores remainder in EDX) mov $0,%edx mov -8(%ebp),%eax # -8(%ebp)=R2 mov -4(%ebp),%ebx # -4(%ebp)=R1 idiv %ebx mov %eax,-8(%ebp) # store in R2 Mod R1,R2mov $0,%edx mov -8(%ebp),%eax # -8(%ebp)=R2 mov -4(%ebp),%ebx # -4(%ebp)=R1 idiv %ebx mov %edx,-8(%ebp) Compare R1,xmov -4(%ebp),%eax # -4(%ebp)=x cmp -8(%ebp),%eax # -8(%ebp)=R1 Return R1 (returned value stored in EAX register) mov -8(%ebp),%eax # -8(%ebp)=R1 jmp _A_foo_epilogue Return Rdummy # return; jmp _A_foo_epilogue

19 Implementation Hacker’s approach: translate directly to strings Prohibits any further optimizations Prohibits sanity checks – expect more bugs Not flexible (what if we want to support Intel syntax?) Create classes for Assembly instruction: ASMInstr Operand types: LIR register Actual register Local variable Parameter Immediate Memory displacement

20 Possible operand hierarchy ASMOperand ImmediateMemory Reg Variable Parameter Displacement IntegerLiteral X86Reg

21 Possible instruction hierarchy ASMInstr BinOpInstrUnOpInstrCallInstrLabelInstrRetInstr abstract class ASMInstr { public abstract List getOperands(); public abstract List getRegisters(); } JumpInstrCondJumpInstr ASMInstr

22 Implementation example class BinOpInstr extends ASMInstr { public final Operand src; public final Operand dst; public final String name; public BinOpInstr(String name, Operand src, Operand dst) { // Sanity check if (src instanceof Memory && dst instanceof Memory) { throw new RuntimeException(“Too many memory operands for arith instruction!”); this.name = name; this.src = src; this.dst = dst; } public String toString() { if (ASMInstr.intelSyntax) { return name + “ “ + src + “,” + dst; } else { return name + “ “ + dst + “,” + src; } } }

23 Handling functions Need to implement call sequence Caller code: Pre-call code: Push caller-save registers Push parameters Call (special treatment for virtual function calls) Post-call code: Copy returned value (if needed) Pop parameters Pop callee-save registers Callee code Each function has prologue and epilogue

24 call caller callee return caller Caller push code Callee push code (prologue) Callee pop code (epilogue) Copy returned value Caller pop code Push caller-save registers Push actual parameters (in reverse order) push return address Jump to call address Push current base-pointer bp = sp Push local variables Push callee-save registers Pop callee-save registers Pop callee activation record Pop old base-pointer pop return address Jump to address Pop parameters Pop caller-save registers Call sequences

25 Translating static calls StaticCall _A_foo(a=R1,b=5,c=x),R3 LIR code: # push parameters mov -4(%ebp),%eax # push x push %eax push $5 # push 5 mov -8(%ebp),%eax # push R1 push %eax # push caller-saved registers push %eax push %ecx push %edx call _A_foo # pop parameters (3 params*4 bytes = 12) add $12,%esp # pop caller-saved registers pop %edx pop %ecx pop %eax Optional: only if register allocation optimization is used (in PA5) mov %eax,-16(%ebp) # store returned value in R3 Only if return register is not Rdummy Optional: only if register allocation optimization is used (in PA5)

26 Translating virtual calls VirtualCall R1.2(a=R1,b=5,c=x),R3 # push parameters mov -4(%ebp),%eax # push x push %eax push $5 # push 5 mov -8(%ebp),%eax # push R1 push %eax # push caller-saved registers push %eax push %ecx push %edx LIR code: # pop parameters (3 params+this * 4 bytes = 16) add $16,%esp # pop caller-saved registers pop %edx pop %ecx pop %eax mov %eax,-16(%ebp) # store returned value in R3 x y DVPtr R1 0_A_rise 1_A_shine 2_A_twinkle _DV_A # Find address of virtual method and call it mov -8(%ebp),%eax # load this push %eax # push this mov 0(%eax),%eax # Load dispatch table address call *8(%eax) # Call table entry 2 (2*4=8)

27 Library function calls Same as static function calls Reference type arguments require non-null runtime check (explained soon)

28 Function prologue/epilogue _A_foo: # prologue push %ebp mov %esp,%ebp # push local variables of foo sub $12,%esp # 3 local vars+regs * 4 = 12 # push callee-saved registers push %ebx push %esi push %edi function body # pop callee-saved registers pop %edi pop %esi pop %ebx # push local variables of foo sub $12,%esp # 3 local vars+regs * 4 = 12 mov %ebp,%esp pop %ebp ret _A_foo_epilogoue: # extra label for each function Optional: only if register allocation optimization is used (in PA5)

29 Representing dispatch tables class A { void sleep() {…} void rise() {…} void shine() {…} static void foo() {…} } class B extends A { void rise() {…} void shine() {…} void twinkle() {…} } _DV_A: [_A_sleep,_A_rise,_A_shine] _DV_B: [_A_sleep,_B_rise,_B_shine,_B_twinkle] file.ic file.lir # data section.data.align 4 _DV_A:.long _A_sleep.long _A_rise.long _A_shine _DV_B:.long _A_sleep.long _B_rise.long _B_shine.long _B_twinkle file.s PA4 PA5

30 Runtime checks Insert code to check attempt to perform illegal operations Null pointer check MoveField, MoveArray, ArrayLength, VirtualCall Reference arguments to library functions should not be null Array bounds check MoveArray Array allocation size check __allocateArray(size) # size needs to be >0 Do we need to check argument of __allocateObject ? Division by zero Mul, Mod If check fails jump to error handler code that prints a message and gracefully exists program

31 Null pointer check # null pointer check cmp $0,%eax je labelNPE labelNPE: push $strNPE# error message call __println push $1# error code call __exit Single generated handler for entire program

32 Array bounds check # array bounds check mov -4(%eax),%ebx # ebx = length mov $0,%ecx # ecx = index cmp %ecx,%ebx jle labelABE # ebx <= ecx ? cmp $0,%ecx jl labelABE # ecx < 0 ? labelABE: push $strABE # error message call __println push $1 # error code call __exit Single generated handler for entire program

33 Array allocation size check # array size check cmp $0,%eax# eax == array size jle labelASE # eax <= 0 ? labelASE: push $strASE # error message call __println push $1 # error code call __exit Single generated handler for entire program

34 Division by zero check # division by zero check cmp $0,%eax# eax is divisor je labelDBE # eax == 0 ? labelDBE: push $strDBE # error message call __println push $1 # error code call __exit Single generated handler for entire program

35 Error handlers code.data.int 40 strNPE:.string "Runtime error: Null pointer dereference.".int 41 strABE:.string "Runtime error: Array index out of bounds!".int 56 strAAE:.string “Runtime error: Array allocation with negative array size!”.int 32 strDBE:.string “Runtime error: Division by zero!”.text # Runtime error handlers align 4 labelNPE: push $strNPE call __println push $1 call __exit.align 4 labelABE: push $strABE call __println push $1 call __exit.align 4 labelASE: push $strASE call __println push $1 call __exit.align 4 labelDBE: push $strDBE call __println push $1 call __exit

36 Optimizations More efficient register allocation for statements Allocate machine registers during translation Eliminate unnecessary labels and jumps Post-translation pass

37 Optimizing labels/jumps If we have subsequent labels: _label1: _label2: We can merge labels and redirect jumps to the merged label After translation (easier) Map old labels to new labels If we have jump label1 _label1: Can eliminate jump Eliminate labels not mentioned by any instruction

38 Optimizing register allocation Goal: associate machine registers with LIR registers as much as possible Optimization done only for sequence of instructions translated from single statement See more details on web siteweb site

39 See you next week