Presentation is loading. Please wait.

Presentation is loading. Please wait.

Code Generation (Chapter 7) 1 Course Overview PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3Architecture.

Similar presentations


Presentation on theme: "Code Generation (Chapter 7) 1 Course Overview PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3Architecture."— Presentation transcript:

1 Code Generation (Chapter 7) 1 Course Overview PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3Architecture of a compiler PART II: inside a compiler 4Syntax analysis 5Contextual analysis 6Runtime organization 7Code generation PART III: conclusion 8Interpretation 9Review

2 Code Generation (Chapter 7) 2 Static Storage Allocation in the Code Generator public abstract class RuntimeEntity { public short size;... } public class KnownValue extends RuntimeEntity { public short value;... } public class UnknownValue extends RuntimeEntity { public short address;... } public class KnownAddress extends RuntimeEntity { public short address;... } public abstract class RuntimeEntity { public short size;... } public class KnownValue extends RuntimeEntity { public short value;... } public class UnknownValue extends RuntimeEntity { public short address;... } public class KnownAddress extends RuntimeEntity { public short address;... } Entitity Descriptions:

3 Code Generation (Chapter 7) 3 Static Storage Allocation in the Code Generator public abstract class AST { public RuntimeEntity entity; // mostly used for Decls... } public abstract class AST { public RuntimeEntity entity; // mostly used for Decls... } Entity Descriptions:

4 Code Generation (Chapter 7) 4 Static Storage Allocation in the Code Generator public Object visit...Command(...Command com, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by execute[com] return null; } public Object visit...Expression(...Expression expr, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by evaluate[expr] return new Short(size of expr result); } public Object visit...Declaration(...Declaration dec, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by elaborate[dec] return new Short(amount of memory allocated by dec); } public Object visit...Command(...Command com, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by execute[com] return null; } public Object visit...Expression(...Expression expr, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by evaluate[expr] return new Short(size of expr result); } public Object visit...Declaration(...Declaration dec, Object arg) { short gs = shortValueOf(arg); // global storage in use generate code as specified by elaborate[dec] return new Short(amount of memory allocated by dec); }

5 Code Generation (Chapter 7) 5 Static Storage Allocation in the Code Generator public void encode(Program prog) { prog.visit(this, new Short(0)); } public void encode(Program prog) { prog.visit(this, new Short(0)); } Amount of global storage previously allocated is initially = 0 The visitor is started …

6 Code Generation (Chapter 7) 6 Static Storage Allocation in the Code Generator public Object visitVarDeclaration( VarDeclaration decl, Object arg) { short gs = shortValueOf(arg); short s = shortValueOf(decl.T.visit(this, null)); decl.entity = new KnownAddress(s, gs); emit(Instruction.PUSHop, 0, 0, s); return new Short(s); } public Object visitVarDeclaration( VarDeclaration decl, Object arg) { short gs = shortValueOf(arg); short s = shortValueOf(decl.T.visit(this, null)); decl.entity = new KnownAddress(s, gs); emit(Instruction.PUSHop, 0, 0, s); return new Short(s); } Some specific examples of visitor methods elaborate [ var I : T ] = PUSH s where s = size of T Remember the size and address of the variable

7 Code Generation (Chapter 7) 7 Static Storage Allocation in the Code Generator public Object visitSequentialDeclaration( SequentialDeclaration decl, Object arg) { short gs = shortValueOf(arg); short s1 = shortValueOf(decl.D1.visit(this,arg)); short s2 = shortValueOf(decl.D2.visit(this, new Short(gs+s1))); return new Short(s1+s2); } public Object visitSequentialDeclaration( SequentialDeclaration decl, Object arg) { short gs = shortValueOf(arg); short s1 = shortValueOf(decl.D1.visit(this,arg)); short s2 = shortValueOf(decl.D2.visit(this, new Short(gs+s1))); return new Short(s1+s2); } elaborate [ D1 ; D2 ] = elaborate [ D1 ] elaborate [ D2 ]

8 Code Generation (Chapter 7) 8 Static Storage Allocation in the Code Generator public Object visitLetCommand( LetCommand com, Object arg) { short gs = shortValueOf(arg); short s = shortValueOf(com.D.visit(this,arg)); com.C.visit(this,new Short(gs+s)); if (s > 0) emit(Instruction.POPop, 0, 0, s); return null; } public Object visitLetCommand( LetCommand com, Object arg) { short gs = shortValueOf(arg); short s = shortValueOf(com.D.visit(this,arg)); com.C.visit(this,new Short(gs+s)); if (s > 0) emit(Instruction.POPop, 0, 0, s); return null; } execute [ let D in C ] = elaborate[ D ] execute [ C ] POP(0) s if s > 0 where s = amount of storage allocated by D

9 Code Generation (Chapter 7) 9 Static Storage Allocation in the Code Generator public void encodeFetch(Vname name, short s) { RuntimeEntity ent = VName.I.decl.entity; if (ent instanceof KnownValue) { short v = ((KnownValue)ent).value; emit(Instruction.LOADLop, 0, 0, v); } else { short d = (ent instanceof UnknownValue) ? ((UnknownValue)ent).address : ((KnownAddress)ent).address ; emit(Instruction.LOADop, 0, Instruction.SBr, d); } public void encodeFetch(Vname name, short s) { RuntimeEntity ent = VName.I.decl.entity; if (ent instanceof KnownValue) { short v = ((KnownValue)ent).value; emit(Instruction.LOADLop, 0, 0, v); } else { short d = (ent instanceof UnknownValue) ? ((UnknownValue)ent).address : ((KnownAddress)ent).address ; emit(Instruction.LOADop, 0, Instruction.SBr, d); } fetch [ I ] =special case if I is a known literal constant LOADL v where v is the known value of I fetch [ V ] = LOAD d[SB] where d = address of V relative to SB

10 Code Generation (Chapter 7) 10 Stack Allocation, Procedures and Functions So far we have seen how code generation works for Mini Triangle. Next we will extend code generation to handle remainder of Triangle: 1) How procedures and functions are compiled. 2) How to modify the code generator to compute addresses when we use a stack allocation model (instead of static allocation).

11 Code Generation (Chapter 7) 11 Recap: TAM Frame Layout Summary LB ST local variables and intermediate results dynamic link static link return address Local data (grows and shrinks during execution) Link data arguments Arguments for current procedure (these were put here by the caller)

12 Code Generation (Chapter 7) 12 Recap: Accessing global/local variables Example: Compute the addresses of the variables in this program let var a: array 3 of Integer; var b: Boolean; var c: Char; proc Y( ) ~ let var d: Integer; var e:... in... ; proc Z( ) ~ let var f: Integer; in begin...; Y( );... end in begin...; Y( );...; Z( ); end let var a: array 3 of Integer; var b: Boolean; var c: Char; proc Y( ) ~ let var d: Integer; var e:... in... ; proc Z( ) ~ let var f: Integer; in begin...; Y( );... end in begin...; Y( );...; Z( ); end Var Size Address abcdefabcdef 3 1 1 [0]SB [3]SB [4]SB 1 ? 1 [3]LB [4]LB [3]LB

13 Code Generation (Chapter 7) 13 Recap: TAM addressing schemas overview We now have a complete picture of the different kinds of addresses that are used for accessing variables and formal parameters stored on the stack. Type of variable Global Local Parameter Non-local, 1 level up Non-local, 2 levels up... Load instruction LOAD +offset[SB] LOAD +offset[LB] LOAD -offset[LB] LOAD +offset[L1] LOAD +offset[L2]

14 Code Generation (Chapter 7) 14 How To Characterize Addresses now? When we have a static allocation model only, an address can be characterized by a single positive integer (i.e. its offset from SB). Now we generalize this to stack allocation (for nested procedures). Q: How should we characterize an address for a variable/constant now? A: Each address can be characterized by two numbers: - offset (similar to static allocation) - nesting level Q: How do we compute the addresses to use in an instruction that loads a value from a variable, or stores a value to a variable?

15 Code Generation (Chapter 7) 15 How To Characterize Addresses of Vars/Constants Example: Compute the addresses of the variables in this program let var a: array 3 of Integer; var b: Boolean; proc foo( ) ~ let var d: array 2 of Integer; var e:... proc bar( ) ~ let var f: Integer; in...bar body... in...foo body... ; in... global code... let var a: array 3 of Integer; var b: Boolean; proc foo( ) ~ let var d: array 2 of Integer; var e:... proc bar( ) ~ let var f: Integer; in...bar body... in...foo body... ; in... global code... Var Size Addr Accessing 3 1 2 ? 1 (0, 0) (3, 0) (3, 1) (5, 1) (3, 2) 0[SB] 3[SB] 3[LB] ? How to access these depends on … where are you accessing from! accessing e from foo body => accessing e from bar body => 5[LB] 5[L1] abdefabdef

16 Code Generation (Chapter 7) 16 New Fetch and Assign Code Templates fetch [ I ] = LOAD(s) d[r] s = size of the type of I d from address of I is (d, l) r determined by l and cl (current level) How to determine r : l = 0 ==>r = SB l = cl==> r = LB otherwise==> r = L(cl-l)

17 Code Generation (Chapter 7) 17 How To Modify the Code Generator public class Frame { public byte level; public short size; } public class Frame { public byte level; public short size; } An info structure to pass as argument in the visitor (instead of “gs”)

18 Code Generation (Chapter 7) 18 How To Modify the Code Generator public class EntityAddress { public byte level; public short displacement; } public class EntityAddress { public byte level; public short displacement; } Different kind of “address” in entity descriptors public class UnknownValue extends RuntimeEntity { public EntityAddress address;... } public class KnownAddress extends RuntimeEntity { public EntityAddress address;... } public class UnknownValue extends RuntimeEntity { public EntityAddress address;... } public class KnownAddress extends RuntimeEntity { public EntityAddress address;... }

19 Code Generation (Chapter 7) 19 How To Modify the Code Generator Changes to code generator (visitor) Example: public Object visitVarDeclaration( VarDeclaration decl, Object arg) { Frame frame = (Frame)arg; short s = shortValueOf(decl.T.visit(this,null)); decl.entity = new KnownAddress(s,frame); emit(Instruction.PUSHop, 0, 0, s); return new Short(s); } public Object visitVarDeclaration( VarDeclaration decl, Object arg) { Frame frame = (Frame)arg; short s = shortValueOf(decl.T.visit(this,null)); decl.entity = new KnownAddress(s,frame); emit(Instruction.PUSHop, 0, 0, s); return new Short(s); } Q: When will the level of a frame be changed? Q: When will the size of a frame be changed?

20 Code Generation (Chapter 7) 20 Procedures and Functions We extend Mini Triangle with procedures: Declaration ::=... | proc Identifier ( ) ~ Command Command ::=... | Identifier ( ) Declaration ::=... | proc Identifier ( ) ~ Command Command ::=... | Identifier ( ) First, we will only consider global procedures (with no arguments).

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

22 Code Generation (Chapter 7) 22 Code Template: Global Procedure Example: let var n: Integer; proc double( ) ~ n := n*2 in begin n := 9; double( ) end let var n: Integer; proc double( ) ~ n := n*2 in begin n := 9; double( ) end 0:PUSH1 1:JUMP7 2:LOAD0[SB] 3:LOADL2 4:CALLmult 5:STORE0[SB] 6:RETURN(0)0 7:LOADL9 8:STORE0[SB] 9:CALL(SB)2 10:POP(0)1 11:HALT n := n*2 var n: Integer proc double( ) ~ n := n*2 n := 9 double( )

23 Code Generation (Chapter 7) 23 Procedures and Functions We extend Mini Triangle with functions: Declaration ::=... | func Identifier ( ) : TypeDenoter ~ Expression ::=... | Identifier ( ) Declaration ::=... | func Identifier ( ) : TypeDenoter ~ Expression ::=... | Identifier ( ) First, we will only consider global functions (with no arguments). This works nearly the same as procedures (except for the RETURN ).

24 Code Generation (Chapter 7) 24 Code Template: Global Function elaborate [ func I ( ) : T ~ E ] = JUMP g e: evaluate [ E ] RETURN(s) 0 g: E evaluate [ I ( ) ] = CALL(SB) e where s is the size of T

25 Code Generation (Chapter 7) 25 Nested Procedures and Functions We extend Mini Triangle with nested procedures and functions. Again, this works nearly the same except for static links. Recall the way this works from chapter 6. When calling a (nested) procedure we must tell the CALL where to find the static link. Revised code template: execute [ I ( ) ] = CALL(r) e evaluate [ I ( ) ] = CALL(r) e where address of I is (e, l) r determined by l and cl (current level)

26 Code Generation (Chapter 7) 26 Procedures and Functions: Parameters Parameters are pushed right before calling a procedure or function. They are addressed like locals, but with negative offsets (in TAM). LB ST local variables and intermediate results dynamic link static link return address arguments let proc double(var n:Integer) ~ n := n*2 in... let proc double(var n:Integer) ~ n := n*2 in... UnknownAddress address = (1, -1)

27 Code Generation (Chapter 7) 27 Procedures and Functions: Parameters We extend Mini Triangle with... Declaration ::=... | proc Identifier (Formal) ~ Command Command ::=... | Identifier (Actual) Formal ::= Identifier : TypeDenoter | var Identifier : TypeDenoter Actual ::= Expression | var VName Declaration ::=... | proc Identifier (Formal) ~ Command Command ::=... | Identifier (Actual) Formal ::= Identifier : TypeDenoter | var Identifier : TypeDenoter Actual ::= Expression | var VName

28 Code Generation (Chapter 7) 28 Code Templates: Parameters elaborate [ proc I (FP) ~ C ] = JUMP g e: execute [ C ] RETURN(0) d g: execute [ I (AP) ] = passArgument [ AP ] CALL(r) e passArgument [ E ] = evaluate [ E ] passArgument [var V] = fetch [ V ] where d is the size of FP

29 Code Generation (Chapter 7) 29 Code Templates: Parameters An “UnknownAddress” extra case for fetch and assign fetch [V] =if V bound to unknown address LOAD d[r] where (d,l) = address where the LOADI(s) unknown address will be stored at runtime. r determined by l and cl (current level). s is the size of the type of V. assign [ V ] = LOAD d[r] STOREI(s)

30 Code Generation (Chapter 7) 30 Runtime Entities Overview Known Unknown Value Address Routine const lucky ~ 888const foo ~ x + 10 value: 888 address: (offset, level) address where the value will be stored proc double( ) ~... address: (offset, level) address of the routine (label e in template) Proc or func parameter address: (offset, level) address where closure object will be stored var counter : Integer address: (offset, level) address of the variable Pass-by-ref (var) parameter address: (offset, level) address where the pointer will be stored


Download ppt "Code Generation (Chapter 7) 1 Course Overview PART I: overview material 1Introduction 2Language processors (tombstone diagrams, bootstrapping) 3Architecture."

Similar presentations


Ads by Google