310 likes | 458 Views
Semantic Analysis III + Intermediate Representation I. Semantics Analysis Flow. IC Program. AST. Program file = …. class A { int x; int f(int x) { boolean y; ... } } class B extends A { boolean y; int t; } class C { A o; int z; }. classes[2]. classes[0].
E N D
IC Program AST Programfile = … class A { int x; int f(int x) { boolean y; ... }}class B extends A { boolean y; int t;}class C { A o; int z;} classes[2] classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = x … Methodname = f … body formals[0] LocalVariablevarName = yinitExpr = null … Formalname = x … 3
Types abstract class Type { String name;boolean subtypeof(Type t) {...}}class IntType extends Type {...}class BoolType extends Type {...}class ArrayType extends Type { Type elemType;}class MethodType extends Type { Type[] paramTypes; Type returnType;}class ClassType extends Type { ICClass classAST;} class A { int x; int f(int x) { boolean y; ... }}class B extends A { boolean y; int t;}class C { A o; int z;} TypeTable IntTypeBoolTypeABCint->int…
Type comparison • Use a unique object for each distinct type • Resolve each type expression to same object • Use reference equality for comparison (==)
Type table implementation class TypeTable { // Maps element types to array types private Map<Type,ArrayType> uniqueArrayTypes; private Map<String,ClassType> uniqueClassTypes; public static Type boolType = new BoolType(); public static Type intType = new IntType(); ... // Returns unique array type object public static ArrayType arrayType(Type elemType) { if (uniqueArrayTypes.containsKey(elemType)) { // array type object already created – return it return uniqueArrayTypes.get(elemType); } else { // object doesn’t exist – create and return it ArrayType arrt = new ArrayType(elemType); uniqueArrayTypes.put(elemType,ArrayType); return arrt; } } ... }
Types AST Programfile = … classes[2] classes[0] classes[1] … ICClassname = Bsuper = A ICClassname = C ICClassname = A TypeTable IntType BoolType ... fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … ClassTypename = C body formals[0] ClassTypename = B LocalVariablename = yinitExpr = nulltype = BoolType Formalname = xtype = IntType super ClassTypename = A MethodType retTypeparamTypes 7
Types • Data • Types Table • Subtyping relation • … • Partial Correctness • Acyclic Hierarchy • No Redefinitions • …
Symbol tables Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body formals[0] LocalVariablename = yinitExpr = nulltype = BoolType Formalname = xtype = IntType Resolve each id to a symbol … Locationname = xtype = ? check scope rules:illegal symbol re-definitions,illegal shadowing,illegal use of undefined symbols
Symbol tables Global symtab AST Programfile = … classes[2] classes[0] classes[1] … A symtab C symtab ICClassname = Bsuper = A ICClassname = C ICClassname = A fields[0] methods[0] … Fieldname = xtype = IntType Methodname = f … f symtab B symtab body formals[0] LocalVariablename = yinitExpr = nulltype = BoolType Formalname = xtype = IntType this belongs to method scope … Locationname = xtype = ? $ret can be used later for type-checking return statements
Miscellaneous semantic checks • Single main method • break/continue inside loops • return on every control path • …
x86 executable exe ICProgram ic IC compiler Compiler LexicalAnalysis Syntax Analysis Parsing AST SymbolTableetc. Inter.Rep.(IR) CodeGeneration
AddExpr AddExpr left left right right LocationExpr LocationExpr LocationExpr id=tomatoes id=carrots id=potatoes tomatoes + potatoes + carrots Lexical analyzer tomatoes,PLUS,potatoes,PLUS,carrots,EOF Parser Symtab hierarchy Global type table A E1 : T[] Additional semantic checks Type checking A E1.length : int Move tomatoes,R1 Move potatoes,R2 Add R2,R1 ... LIR
Low-level intermediate representation • Allows language-independent, machine-independent optimizations and transformations • Easy to translate from AST • Easy to translate to assembly • Narrow interface Pentium optimize Java bytecode AST LIR Sparc
Low-level IR (LIR) • Low-level representation is essentially an abstract machine language • Low-level language constructs • jumps, conditional jumps, … • Allows optimizations specific to these constructs
LIR instructions Immediate(constant) Memory(variable) Note 1: rightmost operand = operation destination Note 2: two register instr - second operand doubles as source and destination
Example Move 42,R1 Move R1,x _test_label: Move x,R1 Compare 0,R1 JumpLE _end_label Move x,R1 Move 1,R2 Sub R2,R1 Move R1,x Jump _test_label _end_label: x = 42; while (x > 0) { x = x - 1; }
Translation (IR lowering) • How to translate AST to LIR?(ignore non-computation nodes) • Define how each AST node is translated • Recursively translate AST (AST tree traversal) • TR[e] = LIR translation of AST construct e • A sequence of LIR instructions • Use temporary variables (LIR registers) to store intermediate values during translation
Translating expressions Fresh virtual (LIR) registergenerated by translation TR[e1 OP e2] Binary operations(arithmetic and comparisons) R1 := TR[e1] R2 := TR[e2] R3 := R1 OP R2 Shortcut notationto indicate target registerNOT LIR instruction Unary operations TR[OP e] R1 := TR[e] R2 := OP R1
LocationEx ValueExpr id = x val = 42 AddExpr left right Translating expressions – example TR[x + 42] visit Move x, R1 Add R2, R1 Move 42, R2 visit(right) visit(left) Add R2, R1 Move x, R1 Move 42, R2
Translating (short-circuit) OR TR[e1 OR e2] R1 := TR[e1] Compare 1,R1 JumpTrue _end_label R2 := T[e2] Or R2,R1 _end_label: Fresh labels generated during translation (OR can be replaced by Move operation since R1 is 0)
Translating (short-circuit) AND TR[e1 AND e2] R1 := TR[e1] Compare 0,R1 JumpTrue _end_label R2 := T[e2] And R2,R1 _end_label: (AND can be replaced by Move operation since R1 is 1)
Translating array and field access TR[e1[e2]] R1 := TR[e1] R2 := TR[e2] MoveArray R1[R2], R3 TR[e1.f] R1 := TR[e1] MoveField R1.cf,R3
Translating array and field access TR[e1[e2]] R1 := TR[e1] R2 := TR[e2] MoveArray R1[R2], R3 TR[e1.f] R1 := TR[e1] MoveField R1.cf,R3 Need to identify class type of e1 from semantic analysis phase
Translating array and field access TR[e1[e2]] R1 := TR[e1] R2 := TR[e2] MoveArray R1[R2], R3 Given class type of e1, need to compute offset of field f TR[e1.f] R1 := TR[e1] MoveField R1.cf,R3 Need to identify class type of e1 from semantic analysis phase
Translating array and field access TR[e1[e2]] R1 := TR[e1] R2 := TR[e2] MoveArray R1[R2], R3 Given class type of e1, need to compute offset of field f TR[e1.f] R1 := TR[e1] MoveField R1.cf,R3 Need to identify class type of e1 from semantic analysis phase Constant representing offset of field f in objects of class type of e1
Translating statement block TR[s1; s2; … ; sN] TR[s1] TR[s2] TR[s3] … TR[sN]
Translating if-then-else R1 := TR[e] Compare 0,R1 JumpTrue _false_label TR[s1] Jump _end_label _false_label: TR[s2] _end_label: TR[if (e) then s1 else s2]
Translating if-then TR[if (e) then s] R1 := TR[e] Compare 0,R1 JumpTrue _end_label TR[s] _end_label:
Translating while TR[while (e) s] _test_label: R1 := TR[e] Compare 0,R1 JumpTrue _end_label TR[s] Jump _test_label _end_label