Languages and Compilers SProg og Oversttere Code Generation

  • Slides: 16
Download presentation
Languages and Compilers (SProg og Oversættere) Code Generation 1

Languages and Compilers (SProg og Oversættere) Code Generation 1

Code Generation – Describe the purpose of the code generator – Code templates –

Code Generation – Describe the purpose of the code generator – Code templates – Back patching 2

The “Phases” of a Compiler Source Program Syntax Analysis Error Reports Abstract Syntax Tree

The “Phases” of a Compiler Source Program Syntax Analysis Error Reports Abstract Syntax Tree Contextual Analysis Error Reports Decorated Abstract Syntax Tree Code Generation Object Code 3

Multi Pass Compiler A multi pass compiler makes several passes over the program. The

Multi Pass Compiler A multi pass compiler makes several passes over the program. The output of a preceding phase is stored in a data structure and used by subsequent phases. Dependency diagram of a typical Multi Pass Compiler: Compiler Driver calls Syntactic Analyzer Contextual Analyzer Code Generator input output Source Text AST Decorated AST Object Code 4

Issues in Code Generation • Code Selection: Deciding which sequence of target machine instructions

Issues in Code Generation • Code Selection: Deciding which sequence of target machine instructions will be used to implement each phrase in the source language. • Storage Allocation Deciding the storage address for each variable in the source program. (static allocation, stack allocation etc. ) • Register Allocation (for register-based machines) How to use registers efficiently to store intermediate results. 5

Code Generation Source Program let var n: integer; var c: char in begin c

Code Generation Source Program let var n: integer; var c: char in begin c : = ‘&’; n : = n+1 end ~ Source and target program must be “semantically equivalent” Target program PUSH 2 LOADL 38 STORE 1[SB] LOAD 0 LOADL 1 CALL add STORE 0[SB] POP 2 HALT Semantic specification of the source language is structured in terms of phrases in the SL: expressions, commands, etc. => Code generation follows the same “inductive” structure. Q: Can you see the connection with formal semantics? 6

Specifying Code Generation with Code Templates Example: Code templates specification for Mini Triangle RECAP:

Specifying Code Generation with Code Templates Example: Code templates specification for Mini Triangle RECAP: The mini triangle AST Program : : = Command : : = V-name : = Expression | let Declaration in Command. . . Expression : : = Integer-Literal | V-name | Operator Expression | Expression Op Expression Declaration : : =. . . V-name: : = Identifier Program Assign. Cmd Let. Cmd Integer. Exp Vname. Exp Unary. Exp Binary. Exp 7

Specifying Code Generation with Code Templates The code generation functions for Mini Triangle Phrase

Specifying Code Generation with Code Templates The code generation functions for Mini Triangle Phrase Class Function Effect of the generated code Program run P Run program P then halt. Starting and finishing with empty stack Command execute C Execute Command C. May update variables but does not shrink or grow the stack! Expres- evaluate E Evaluate E, net result is pushing the value of sion E on the stack. V-name Push value of constant or variable on the fetch V stack. V-name assign V Pop value from stack and store in variable V Declaelaborate Elaborate declaration, make space on the ration stack for constants and variables in the decl. D 8

Code Generation with Code Templates The code generation functions for Mini Triangle Programs: run

Code Generation with Code Templates The code generation functions for Mini Triangle Programs: run [C] = execute [C] HALT Commands: execute [V : = E] = evaluate [E] assign [V] execute [I ( E )] = evaluate [E] CALL p where p is address of the routine named I 9

Code Generation with Code Templates Commands: execute [C 1 ; C 2] = execute

Code Generation with Code Templates Commands: execute [C 1 ; C 2] = execute [C 1] execute [C 2] execute [if E then C 1 else C 2] = evaluate [E] E JUMPIF(0) g C 1 execute [C 1] JUMP h g: g: execute [C 2] C 2 h: h: 10

Code Generation with Code Templates While command execute [while E do C] = JUMP

Code Generation with Code Templates While command execute [while E do C] = JUMP h g: execute [C] h: evaluate[E] JUMPIF(1) g C E 11

Developing a Code Generator “Visitor” execute [C 1 ; C 2] = execute[C 1]

Developing a Code Generator “Visitor” execute [C 1 ; C 2] = execute[C 1] execute[C 2] public Object visit. Sequential. Command( Sequential. Command com, Object arg) { com. C 1. visit(this, arg); com. C 2. visit(this, arg); return null; } Let. Command, If. Command, While. Command => later. - Let. Command is more complex: memory allocation and addresses - If. Command While. Command: complications with jumps 12

Backpatching Example public Object While. Command ( While. Command com, Object arg) { short

Backpatching Example public Object While. Command ( While. Command com, Object arg) { short j = next. Instr. Addr; emit(Instruction. JUMPop, 0, Instruction. CBr, 0); dummy address short g = next. Instr. Addr; com. C. visit(this, arg); short h = next. Instr. Addr; backpatch code[j]. d = h; com. E. visit(this, arg); emit(Instruction. JUMPIFop, 1, Instruction. CBr, g); execute [while E do C] = return null; JUMP h } g: execute [C] h: evaluate[E] JUMPIF(1) g 13

Constants and Variables We have not yet discussed generation of Let. Command. This is

Constants and Variables We have not yet discussed generation of Let. Command. This is the place in Mini. Triangle where declarations are. Calculated during generation for execute [let D in C] = elaborate[D] execute [C] How to know these? POP(0) s if s>0 where s = amount of storage allocated by D fetch [V] = LOAD d[SB] assign [V] = STORE d[SB] where d = address of V relative to SB 14

Code Template: Global Procedure elaborate [proc I () ~ C] = JUMP g e:

Code Template: Global Procedure elaborate [proc I () ~ C] = JUMP g e: execute [C] C RETURN(0) 0 g: execute [I ()] = CALL(SB) e 15

Code Template: Global Procedure Example: let var n: Integer; proc double() ~ n :

Code Template: Global Procedure Example: let var n: Integer; proc double() ~ n : = n*2 in begin n : = 9; double() end 0: PUSH 1: JUMP 2: LOAD 3: LOADL 4: CALL 5: STORE 6: RETURN(0) 7: LOADL 8: STORE 9: CALL(SB) 10: POP(0) 11: HALT 1 7 0[SB] 2 mult 0[SB] 0 9 0[SB] 2 1 var n: Integer n : = n*2 proc double() ~ n : = n*2 n : = 9 double() 16