SlideShare a Scribd company logo
Eelco Visser
CS4200 Compiler Construction
TU Delft
December 2018
Lecture 13: Code Generation and Optimization
Code Generation
- Compilation schemas

- Correctness

- Mechanics

Optimization of generated code
- Peephole optimization 

- Tail recursion elimination
!2
Code Generation and Optimization
Compilation Schemas
3
How do language constructs translate to target code?
Compilation schema
- Source language pattern

- Target language pattern

- Assuming translation for the pattern variables

Exploration
- Before constructing code generation rules

- Manually translate small fragments to understand schemas

Examples
- Some compilation schemas for Tiger constructs
!4
Compilation Schemas
Compilation Schema Schema
!5
[[ c e1 … en ]]
ins
[[ e1 ]]
ins
…
ins
[[ en ]]
ins
Translation of language construct c
with sub-expressions e1 … en
Combines translation of sub-
expressions with instruction pattern
Tiger Compilation Schemas: Arithmetic Expressions
!6
[[ x ]]
; type of x is int
; x is n-th variable
iload n
[[ e1 + e2 ]]
[[ e1 ]]
[[ e2 ]]
iadd
[[ e1 * e2 ]]
[[ e1 ]]
[[ e2 ]]
imul
Tiger Compilation Schemas: Control-Flow
!7
[[ e1 ]]
[[ e2 ]]
…
[[ en ]]
Sequential composition
[[
(
e1;
e2;
...
en
)
]]
To do: Pop elements from stack!
Tiger Compilation Schemas: Control-Flow
!8
[[ e1 ]]
ifeq else
[[ e2 ]]
goto end
else:
[[ e3 ]]
end:
Jump labels should be unique
[[ if e1 then e2 else e3 ]]
Tiger Compilation Schemas: Control-Flow
!9
goto check
body:
[[ e2 ]]
check:
ifeq else
[[ e1 ]]
ifne body
[[ while e1 do e2 ]]
Tiger Compilation Schemas: Function Definition and Call
!10
.method public static f(I…)I
[[ e ]]
ireturn
.end method
[[ function f(n: int, …): int = e ]]
[[ e ]]
...
invokestatic Program/f(I…)I
[[ f(e,…) ]]
Compilation schemas for other Tiger constructs
- Let bindings with local variables

- For loop with bound iteration variable

- Break statement in for/while loop

- Array types, creation and access

- Record types, creation and access
!11
Homework: More Tiger Schemas
Homework: Compiling Nested Functions
!12
let
function power(x: int, n: int): int =
let
function pow(n: int): int =
if n = 0 then 1 else x * pow(n - 1)
in pow(n)
in
power(3, 4)
Tiger has nested function definitions
Design a compilation schema for compiling
such functions to JVM byte code
Homework: Compiling Nested Functions
!13
let
function power(x: int, n: int): int =
let
var p : int := 1
function pow(n: int): int =
if n = 0 then p
else (
p := x * p;
pow(n - 1)
)
in pow(n)
in
power(3, 4)
That can also deal with programs like this one
Correctness of Code
Generation
14
!15
When is a code generator correct?
Target code should be
- Syntactically correct

- Type correct

- Other well-formedness criteria

- Ensures that generated code compiles / runs on target platform

Is that sufficient?
Target code should preserve
- Names: has the same interface

- Types: computed values have same type

- Semantics: compute same values

- Ensures that generated code has the same semantics
!16
Correctness of Code Generation
Testing
- Test suite of source language code, apply compiler

Verification
- Of generated code

- Of code generator

Type checking
- Building verification into type checker of the meta language

For all correctness criteria
- Different techniques apply to different criteria
!17
Guaranteeing Correctness of Generated Code
Byte Code Well-Formedness
18
Java Virtual Machine Specification 11
Format checking
- Magic number

- Predefined attributes have proper length 

- Not truncated or have extra bytes

- Satisfy constant pool constraints

- Field and method references have valid names, classes, descriptors
!19
JVM: Format Checking
Static Constraints
- Only valid instructions 

- First instruction at index 0

- Index of next instruction = index + length 

- Target of jump is opcode within method

- …

- The index operand of each iload, fload, aload, istore, fstore, astore,
iinc, and ret instruction must be a non-negative integer no greater
than max_locals - 1. 

- …

!20
JVM: Constraint on Class File
Structural Constraints
- Each instruction must only be executed with the appropriate type
and number of arguments in the operand stack and local variable
array, regardless of the execution path that leads to its invocation.

- Operand stack cannot grow to a depth greater than max_stack

- No more values can be popped from stack than it contains

- No local variable can be accessed before it is assigned a variable

- …

!21
JVM: Constraint on Class File
Class file verification guarantees
- No operand stack overflows or underflows 

- All local variable uses and stores are valid

- Arguments of all JVM instructions are of valid types 

Specification
- Using Prolog predicates
!22
JVM: Verification of class Files
Many non-trivial constraints on class files
JVM verifies all class files
- Compiler is not a trusted component

Compiler should generate correct class files
- Does not say anything about correctness of compiler

- Compiler generating byte code not necessarily semantics preserving
!23
JVM Verification Summary
Code Generation Mechanics
24
Code generation
- Input: AST of source language program

‣ with name and type annotations

- Output: machine instructions

Mechanics
- What techniques are available to define translation?

- What are the advantages and disadvantages of these techniques?

- To what extent do these techniques help with verification?
!25
Code Generation Mechanics
Code Generation by
String Manipulation
26
Printing Strings as Side Effect
!27
to-jbc = ?Nil() ; <printstring> "aconst_nulln"
to-jbc = ?NoVal() ; <printstring> "nopn"
to-jbc = ?Seq(es) ; <list-loop(to-jbc)> es
to-jbc =
?Int(i);
<printstring> "ldc ";
<printstring> i;
<printstring> "n"
to-jbc = ?Bop(op, e1, e2) ; <to-jbc> e1 ; <to-jbc> e2 ; <to-jbc> op
to-jbc = ?PLUS() ; <printstring> "iaddn"
to-jbc = ?MINUS() ; <printstring> "isubn"
to-jbc = ?MUL() ; <printstring> "imuln"
to-jbc = ?DIV() ; <printstring> "idivn"
String Concatenation
!28
to-jbc: Nil() -> "aconst_nulln"
to-jbc: NoVal() -> "nopn"
to-jbc: Seq(es) -> <concat-strings> <map(to-jbc)> es
to-jbc: Int(i) -> <concat-strings> ["ldc ", i, "n"]
to-jbc: Bop(op, e1, e2) -> <concat-strings> [ <to-jbc> e1,
<to-jbc> e2,
<to-jbc> op ]
to-jbc: PLUS() -> "iaddn"
to-jbc: MINUS() -> "isubn"
to-jbc: MUL() -> "imuln"
to-jbc: DIV() -> "idivn"
String Interpolation
!29
to-jbc: Nil() -> $[aconst_null]
to-jbc: NoVal() -> $[nop]
to-jbc: Seq(es) -> <map-to-jbc> es
map-to-jbc: [] -> $[]
map-to-jbc: [h|t] ->
$[[<to-jbc> h]
[<map-to-jbc> t]]
to-jbc: Int(i) -> $[ldc [i]]

to-jbc: Bop(op, e1, e2) ->
$[[<to-jbc> e1]
[<to-jbc> e2]
[<to-jbc> op]]
to-jbc: PLUS() -> $[iadd]
to-jbc: MINUS() -> $[isub]
to-jbc: MUL() -> $[imul]
to-jbc: DIV() -> $[idiv]
Printing strings
- Generated code depends on order of traversal of the AST

- Explicit layout (whitespace) management

- Verbose quotation and anti-quotation

- Escaping meta-variables

- Easy to make syntax errors

- Output needs to be parsed for further processing

String concatenation
- Makes generation order independent

String interpolation (templates)
- Makes quotation and anti-quotation more concise

- Layout (whitespace) from template layout
!30
Summary: Code Generation by String Manipulation
All bets are off
- Only guarantee is that you get some text

- String interpolation may help with producing readable code

- Very easy to make even trivial syntactic errors

Verification
- Use target code checker for verification

- No input independent guarantees
!31
Correctness of String-Based Code Generators
Code Generation by
Term Transformation
32
AST to AST translation
- input: source language AST

- output: target language AST

Defined using term rewrite rules
- Recognise AST pattern for language construct

- Recursively translate sub-terms

- Compose results with target code schema for language construct

Intermediate representation (IR)
!33
Code Generation by Transformation
Code Generation by Transformation: Example
!34
to-jbc: Nil() -> [ ACONST_NULL() ]
to-jbc: NoVal() -> [ NOP() ]
to-jbc: Seq(es) -> <mapconcat(to-jbc)> es
to-jbc: Int(i) -> [ LDC(Int(i)) ]
to-jbc: String(s) -> [ LDC(String(s)) ]
to-jbc: Bop(op, e1, e2) -> <mapconcat(to-jbc)> [ e1, e2, op ]
to-jbc: PLUS() -> [ IADD() ]
to-jbc: MINUS() -> [ ISUB() ]
to-jbc: MUL() -> [ IMUL() ]
to-jbc: DIV() -> [ IDIV() ]
to-jbc: Assign(lhs, e) -> <concat> [ <to-jbc> e, <lhs-to-jbc> lhs ]
to-jbc: Var(x) -> [ ILOAD(x) ] where <type-of> Var(x) => INT()
to-jbc: Var(x) -> [ ALOAD(x) ] where <type-of> Var(x) => STRING()
lhs-to-jbc: Var(x) -> [ ISTORE(x) ] where <type-of> Var(x) => INT()
lhs-to-jbc: Var(x) -> [ ASTORE(x) ] where <type-of> Var(x) => STRING()
to-jbc : Exp -> List(Instruction)
Code Generation by Transformation: Example
!35
to-jbc:
IfThenElse(e1, e2, e3) -> <concat> [ <to-jbc> e1
, [ IFEQ(LabelRef(else)) ]
, <to-jbc> e2
, [ GOTO(LabelRef(end)), Label(else) ]
, <to-jbc> e3
, [ Label(end) ]
]
where <newname> "else" => else
where <newname> "end" => end
to-jbc:
While(e1, e2) -> <concat> [ [ GOTO(LabelRef(check)), Label(body) ]
, <to-jbc> e2
, [ Label(check) ]
, <to-jbc> e1
, [ IFNE(LabelRef(body)) ]
]
where <newname> "test" => check
where <newname> "body" => body
Compiler component composition
- AST output can be consumed by compatible AST transformations

Example compilation pipeline
- Parse source language text => source language AST

- Desugar => source language AST

- Type-check => annotated source language AST

- Translate => target language AST

- Optimize => target language AST

- Pretty-print => target language text

Easy to extend with new components
!36
Code Generation by Transformation
Guaranteeing Syntactically
Correct Target Code
37
Property: Syntactically correct target code
- Guarantee that generated code parses

Type correct AST = syntactically correct code
- AST types represent syntactic categories

‣Plus: Exp * Exp -> Exp
- Type check translation patterns

Language support
- Any programming language with a static type system

- And support for algebraic data types

Note: lexical syntax
!38
Syntactically Correct Target Code
Type Checking Transformation Rules
!39
Type checking terms in rules guarantees
syntactic correctness of generated code
:-(
Stratego
- Only checks arities of constructor applications, not types

- Transformation rules could be checked by the compiler

- Generic traversals make traditional type checking impossible

Research
- A static analysis for Stratego that guarantees syntactic correctness 

Workaround
- Meta-programming with concrete object syntax
!40
Guaranteeing Syntactically Correct Target Code in Stratego?
!41
This paper defines a generic technique for embedding the
concrete syntax of an object language into a meta-
programming language.

Applied to Stratego as meta-language and Tiger as object
language.

Combines two advantages

- guarantee syntactic correctness of match and build patterns

- make rules more readable
https://doi.org/10.1007/3-540-45821-2_19
Concrete Object Syntax
!42
Abstract syntax transformation
Concrete syntax transformation
Implementing Concrete Object Syntax
!43
Embedding of object language into meta language
From Concrete Syntax to Abstract Syntax
!44
parse
explode
pretty-print
Mixed AST
Pure AST
Meta Explode
!45
How do you type check that?
Find term embedding
Explode it
!46
The concrete syntax embedding techniques is not
specific to Stratego as meta-language. This paper
shows how to use it to embed DSLs into Java.
https://doi.org/10.1145/1035292.1029007
!47
This paper generalizes the concrete syntax techniques
to all sorts of host and guest languages, with an
application to preventing injection attacks.

Injection attacks are caused by unhygienic
construction of code through which user input can be
turned into executable code.
doi:10.1016/j.scico.2009.05.004
Hygienic
!48
A Generic Architecture
!49
Hygienic Transformations
50
Hygienic Transformations
!51
Does new variable in TraceProcedure not capture variables in e?
Guarantee that variables are not captured
- Which variables?

Object language name analysis for transformation rules
- E.g. apply Tiger constraint rules to patterns in rules

Existing approaches
- Hygienic macros in Scheme/Racket

- Higher-order abstract syntax

- Nominal abstract syntax

Research
- Hygienic transformations for more complex binding patterns
!52
Guaranteeing Hygiene
Guaranteeing Type Correct
Target Code
53
Property: Type correct target code
- Guarantee that generated code type checks

Intrinsically-typed ASTs
- Encode type system in algebraic signature

- Including binding structure

- Language support: Generalized ADTs 

Research
- Advanced type systems & binding patterns
!54
Guaranteeing Type Correct Code
Semantics Preservation
55
Generate code has same interface as source code
!56
Interface Preservation
Generated code produces values with the same type
Intrinsically-typed interpreters for imperative languages
- POPL18 paper

- Verify that interpreters are type preserving 

- Including non-lexical binding patterns

Research
- how to do this for other transformations?
!57
Type Preservation
Semantics preservation
- Generated code has the same behaviour as the source program 

CompCert
- Certified C compiler

- Defines operational semantics of source language (most of C) and all
intermediate languages

- Mechanically verify that translations between IR preserve behaviour 

‣ For all possible programs

- Or: verify that generated output has same behaviour as input

‣ For programs that compiler is applied to
!58
Dynamic Semantics Preservation
Optimizing (Virtual)
Machine Code
59
Reasons
- code overhead

- execution overhead

Inlining
- replace calls by body of the procedure 

- source code level

Tail recursion
- replace recursive calls by loops or jumps

- source or machine code level
!60
Optimizations
Peephole Optimization
61
Code Generation
!62
function fac0(n0: int): int =
if
n0 = 0
then
1
else
n0 * fac0(n0 - 1)
.method public static fac0(I)I
iload 1
ldc 0
if_icmpeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!63
.method public static fac0(I)I
iload_1
ifne else0
iconst_1
ireturn
else0: iload_1
dup
iconst_1
isub
invokestatic
Exp/fac0(I)I
imul
ireturn
.end method
.method public static fac0(I)I
iload 1
ldc 0
if_icmpeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!64
.method public static fac0(I)I
iload 1
ifeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ldc 0
if_icmpeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!65
.method public static fac0(I)I
iload 1
ifeq label0
ldc 0
ifeq else0
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!66
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifeq label0
ldc 0
ifeq else0
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!67
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!68
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!69
.method public static fac0(I)I
iload 1
ifneq else0
label0: ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifeq label0
goto else0
label0: ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!70
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifneq else0
label0: ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!71
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
ireturn
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!72
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
ireturn
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
ireturn
else0: iload 1
dup
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!73
.method public static fac0(I)I
iload_1
ifneq else0
ldc 1
ireturn
else0: iload_1
dup
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload 1
ifneq else0
ldc 1
ireturn
else0: iload 1
dup
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!74
.method public static fac0(I)I
iload_1
ifneq else0
iconst_1
ireturn
else0: iload_1
dup
iconst_1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
.method public static fac0(I)I
iload_1
ifneq else0
ldc 1
ireturn
else0: iload_1
dup
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Optimization
!75
.method public static fac0(I)I
iload_1
ifneq else0
iconst_1
ireturn
else0: iload_1
dup
iconst_1
isub
invokestatic
Exp/fac0(I)I
imul
ireturn
.end method
.method public static fac0(I)I
iload 1
ldc 0
if_icmpeq label0
ldc 0
goto label1
label0: ldc 1
label1: ifeq else0
ldc 1
goto end0
else0: iload 1
iload 1
ldc 1
isub
invokestatic
Exp/fac0(I)I
imul
end0: ireturn
.end method
Implementing Peephole Optimizations
!76
Tail Recursion Elimination
77
Recursive function
- creates a new stack frame for each invocation 

Tail recursion
- recursive call is last action 

Tail recursion elimination
- If function is tail recursive, reuse stack frame for recursive call
!78
Tail Recursion Elimination
Example: Non-Tail Recursive Function
!79
.class public Exp
.method public static fac(I)I
iload 1
ifne else
iconst_1
ireturn
else: iload 1
dup
iconst_1
isub
invokestatic Exp/fac(I)I
imul
ireturn
.end method
function fac(n : Int) =
if n = 1
then
1
else
n * fac(n - 1)
Example: Make Tail Recursive
!80
function fac(n : Int) =
if n = 1
then
1
else
n * fac(n - 1)
function fac(n : Int) =
fac2(n, 1)
function fac2(n : Int, acc: Int) =
if n = 1
then
acc
else
fac(n - 1, n * acc)
Use an accumulator argument to
build return value
Example: Make Tail Recursive (in Byte Code)
!81
.class public Exp
.method public static fac(I)I
iload 1
ifne else
iconst_1
ireturn
else: iload 1
dup
iconst_1
isub
invokestatic Exp/fac(I)I
imul
ireturn
.end method
.class public Exp
.method public static fac(II)I
iload 1
ifne else
iload 2
ireturn
else: iload 1
iconst_1
isub
iload 1
iload 2
imul
invokestatic Exp/fac(II)I
ireturn
.end method
Example: Tail Recursion Elimination
!82
.class public Exp
.method public static fac(II)I
iload 1
ifne else
iload 2
ireturn
else: iload 1
iconst_1
isub
iload 1
iload 2
imul
invokestatic Exp/fac(II)I
ireturn
.end method
.class public Exp
.method public static fac(II)I
strt: iload 1
ifne else
iload 2
ireturn
else: iload 1
iconst_1
isub
iload 1
iload 2
imul
istore 2
istore 1
goto strt
.end method
Next: Interpreters
83
!84
Except where otherwise noted, this work is licensed under

More Related Content

PDF
Compiler Construction | Lecture 10 | Data-Flow Analysis
PDF
Compiler Construction | Lecture 12 | Virtual Machines
PDF
Compiler Construction | Lecture 3 | Syntactic Editor Services
PPTX
Presentation on C++ Programming Language
PDF
Compiler Construction | Lecture 14 | Interpreters
PDF
Compiler Construction | Lecture 2 | Declarative Syntax Definition
PPT
Introduction to HDLs
Compiler Construction | Lecture 10 | Data-Flow Analysis
Compiler Construction | Lecture 12 | Virtual Machines
Compiler Construction | Lecture 3 | Syntactic Editor Services
Presentation on C++ Programming Language
Compiler Construction | Lecture 14 | Interpreters
Compiler Construction | Lecture 2 | Declarative Syntax Definition
Introduction to HDLs

What's hot (20)

PDF
CS4200 2019 | Lecture 3 | Parsing
PDF
Compiler Construction | Lecture 15 | Memory Management
PDF
Declarative Type System Specification with Statix
PDF
Intro to C++ - language
PDF
Introduction to cpp
PPT
Interm codegen
PPTX
Introduction of bison
PPTX
C Programming Language Tutorial for beginners - JavaTpoint
PPT
Lex and Yacc ppt
PDF
Day2 Verilog HDL Basic
PPTX
Intermediate code- generation
PDF
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
PPT
Yacc lex
PPT
Chapter Eight(3)
PDF
VHDL- gate level modelling
PPSX
Complete C++ programming Language Course
PPTX
Code generation
PPT
Assembler
PPTX
basics of c++
PPT
Verilog tutorial
CS4200 2019 | Lecture 3 | Parsing
Compiler Construction | Lecture 15 | Memory Management
Declarative Type System Specification with Statix
Intro to C++ - language
Introduction to cpp
Interm codegen
Introduction of bison
C Programming Language Tutorial for beginners - JavaTpoint
Lex and Yacc ppt
Day2 Verilog HDL Basic
Intermediate code- generation
Compiler Construction | Lecture 5 | Transformation by Term Rewriting
Yacc lex
Chapter Eight(3)
VHDL- gate level modelling
Complete C++ programming Language Course
Code generation
Assembler
basics of c++
Verilog tutorial
Ad

Similar to Compiler Construction | Lecture 13 | Code Generation (20)

PPT
458237.-Compiler-Design-Intermediate-code-generation.ppt
PDF
robert-kovacsics-part-ii-dissertation
ODP
Clojure made simple - Lightning talk
PPTX
Proposals for new function in Java SE 9 and beyond
PDF
Compiler Construction for DLX Processor
PDF
Polyglot Programming in the JVM - Øredev
PPT
Chapter 6 Intermediate Code Generation
PDF
Clojure - An Introduction for Java Programmers
PDF
Workshop Scala
PDF
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
PPTX
Kuliah07 TBK-Compiler 111111111111111111
PPTX
JVM: A Platform for Multiple Languages
PDF
12IRGeneration.pdf
PDF
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
PDF
TSR_CLASS CD-UNIT 4.pdf ewqhqhqhewhwiqhe
PDF
TSR_CLASS CD-UNIT 4.pdf ewqhqhqhewhwiqhe
PDF
Polyglot Programming in the JVM - 33rd Degree
PDF
Improving Java performance at JBCNConf 2015
PDF
Projects Panama, Valhalla, and Babylon: Java is the New Python v0.9
PDF
What is new and cool j2se & java
458237.-Compiler-Design-Intermediate-code-generation.ppt
robert-kovacsics-part-ii-dissertation
Clojure made simple - Lightning talk
Proposals for new function in Java SE 9 and beyond
Compiler Construction for DLX Processor
Polyglot Programming in the JVM - Øredev
Chapter 6 Intermediate Code Generation
Clojure - An Introduction for Java Programmers
Workshop Scala
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
Kuliah07 TBK-Compiler 111111111111111111
JVM: A Platform for Multiple Languages
12IRGeneration.pdf
Mixing Source and Bytecode: A Case for Compilation By Normalization (OOPSLA 2...
TSR_CLASS CD-UNIT 4.pdf ewqhqhqhewhwiqhe
TSR_CLASS CD-UNIT 4.pdf ewqhqhqhewhwiqhe
Polyglot Programming in the JVM - 33rd Degree
Improving Java performance at JBCNConf 2015
Projects Panama, Valhalla, and Babylon: Java is the New Python v0.9
What is new and cool j2se & java
Ad

More from Eelco Visser (20)

PDF
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
PDF
CS4200 2019 | Lecture 4 | Syntactic Services
PDF
CS4200 2019 | Lecture 2 | syntax-definition
PDF
CS4200 2019 Lecture 1: Introduction
PDF
A Direct Semantics of Declarative Disambiguation Rules
PDF
Compiler Construction | Lecture 17 | Beyond Compiler Construction
PDF
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
PDF
Compiler Construction | Lecture 11 | Monotone Frameworks
PDF
Compiler Construction | Lecture 9 | Constraint Resolution
PDF
Compiler Construction | Lecture 8 | Type Constraints
PDF
Compiler Construction | Lecture 7 | Type Checking
PDF
Compiler Construction | Lecture 6 | Introduction to Static Analysis
PDF
Compiler Construction | Lecture 4 | Parsing
PDF
Compiler Construction | Lecture 1 | What is a compiler?
PDF
Declare Your Language: Virtual Machines & Code Generation
PDF
Declare Your Language: Dynamic Semantics
PDF
Declare Your Language: Constraint Resolution 2
PDF
Declare Your Language: Constraint Resolution 1
PDF
Declare Your Language: Type Checking
PDF
Declare Your Language: Name Resolution
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 4 | Syntactic Services
CS4200 2019 | Lecture 2 | syntax-definition
CS4200 2019 Lecture 1: Introduction
A Direct Semantics of Declarative Disambiguation Rules
Compiler Construction | Lecture 17 | Beyond Compiler Construction
Domain Specific Languages for Parallel Graph AnalytiX (PGX)
Compiler Construction | Lecture 11 | Monotone Frameworks
Compiler Construction | Lecture 9 | Constraint Resolution
Compiler Construction | Lecture 8 | Type Constraints
Compiler Construction | Lecture 7 | Type Checking
Compiler Construction | Lecture 6 | Introduction to Static Analysis
Compiler Construction | Lecture 4 | Parsing
Compiler Construction | Lecture 1 | What is a compiler?
Declare Your Language: Virtual Machines & Code Generation
Declare Your Language: Dynamic Semantics
Declare Your Language: Constraint Resolution 2
Declare Your Language: Constraint Resolution 1
Declare Your Language: Type Checking
Declare Your Language: Name Resolution

Recently uploaded (20)

PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PDF
System and Network Administration Chapter 2
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Nekopoi APK 2025 free lastest update
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
medical staffing services at VALiNTRY
PPTX
L1 - Introduction to python Backend.pptx
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
System and Network Administration Chapter 2
Understanding Forklifts - TECH EHS Solution
Nekopoi APK 2025 free lastest update
CHAPTER 2 - PM Management and IT Context
How to Migrate SBCGlobal Email to Yahoo Easily
Design an Analysis of Algorithms I-SECS-1021-03
How Creative Agencies Leverage Project Management Software.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
medical staffing services at VALiNTRY
L1 - Introduction to python Backend.pptx
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Odoo Companies in India – Driving Business Transformation.pdf
Operating system designcfffgfgggggggvggggggggg
Design an Analysis of Algorithms II-SECS-1021-03
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx

Compiler Construction | Lecture 13 | Code Generation

  • 1. Eelco Visser CS4200 Compiler Construction TU Delft December 2018 Lecture 13: Code Generation and Optimization
  • 2. Code Generation - Compilation schemas - Correctness - Mechanics Optimization of generated code - Peephole optimization - Tail recursion elimination !2 Code Generation and Optimization
  • 4. How do language constructs translate to target code? Compilation schema - Source language pattern - Target language pattern - Assuming translation for the pattern variables Exploration - Before constructing code generation rules - Manually translate small fragments to understand schemas Examples - Some compilation schemas for Tiger constructs !4 Compilation Schemas
  • 5. Compilation Schema Schema !5 [[ c e1 … en ]] ins [[ e1 ]] ins … ins [[ en ]] ins Translation of language construct c with sub-expressions e1 … en Combines translation of sub- expressions with instruction pattern
  • 6. Tiger Compilation Schemas: Arithmetic Expressions !6 [[ x ]] ; type of x is int ; x is n-th variable iload n [[ e1 + e2 ]] [[ e1 ]] [[ e2 ]] iadd [[ e1 * e2 ]] [[ e1 ]] [[ e2 ]] imul
  • 7. Tiger Compilation Schemas: Control-Flow !7 [[ e1 ]] [[ e2 ]] … [[ en ]] Sequential composition [[ ( e1; e2; ... en ) ]] To do: Pop elements from stack!
  • 8. Tiger Compilation Schemas: Control-Flow !8 [[ e1 ]] ifeq else [[ e2 ]] goto end else: [[ e3 ]] end: Jump labels should be unique [[ if e1 then e2 else e3 ]]
  • 9. Tiger Compilation Schemas: Control-Flow !9 goto check body: [[ e2 ]] check: ifeq else [[ e1 ]] ifne body [[ while e1 do e2 ]]
  • 10. Tiger Compilation Schemas: Function Definition and Call !10 .method public static f(I…)I [[ e ]] ireturn .end method [[ function f(n: int, …): int = e ]] [[ e ]] ... invokestatic Program/f(I…)I [[ f(e,…) ]]
  • 11. Compilation schemas for other Tiger constructs - Let bindings with local variables - For loop with bound iteration variable - Break statement in for/while loop - Array types, creation and access - Record types, creation and access !11 Homework: More Tiger Schemas
  • 12. Homework: Compiling Nested Functions !12 let function power(x: int, n: int): int = let function pow(n: int): int = if n = 0 then 1 else x * pow(n - 1) in pow(n) in power(3, 4) Tiger has nested function definitions Design a compilation schema for compiling such functions to JVM byte code
  • 13. Homework: Compiling Nested Functions !13 let function power(x: int, n: int): int = let var p : int := 1 function pow(n: int): int = if n = 0 then p else ( p := x * p; pow(n - 1) ) in pow(n) in power(3, 4) That can also deal with programs like this one
  • 15. !15 When is a code generator correct?
  • 16. Target code should be - Syntactically correct - Type correct - Other well-formedness criteria - Ensures that generated code compiles / runs on target platform Is that sufficient? Target code should preserve - Names: has the same interface - Types: computed values have same type - Semantics: compute same values - Ensures that generated code has the same semantics !16 Correctness of Code Generation
  • 17. Testing - Test suite of source language code, apply compiler Verification - Of generated code - Of code generator Type checking - Building verification into type checker of the meta language For all correctness criteria - Different techniques apply to different criteria !17 Guaranteeing Correctness of Generated Code
  • 18. Byte Code Well-Formedness 18 Java Virtual Machine Specification 11
  • 19. Format checking - Magic number - Predefined attributes have proper length - Not truncated or have extra bytes - Satisfy constant pool constraints - Field and method references have valid names, classes, descriptors !19 JVM: Format Checking
  • 20. Static Constraints - Only valid instructions - First instruction at index 0 - Index of next instruction = index + length - Target of jump is opcode within method - … - The index operand of each iload, fload, aload, istore, fstore, astore, iinc, and ret instruction must be a non-negative integer no greater than max_locals - 1. - …
 !20 JVM: Constraint on Class File
  • 21. Structural Constraints - Each instruction must only be executed with the appropriate type and number of arguments in the operand stack and local variable array, regardless of the execution path that leads to its invocation. - Operand stack cannot grow to a depth greater than max_stack - No more values can be popped from stack than it contains - No local variable can be accessed before it is assigned a variable - …
 !21 JVM: Constraint on Class File
  • 22. Class file verification guarantees - No operand stack overflows or underflows - All local variable uses and stores are valid - Arguments of all JVM instructions are of valid types Specification - Using Prolog predicates !22 JVM: Verification of class Files
  • 23. Many non-trivial constraints on class files JVM verifies all class files - Compiler is not a trusted component Compiler should generate correct class files - Does not say anything about correctness of compiler - Compiler generating byte code not necessarily semantics preserving !23 JVM Verification Summary
  • 25. Code generation - Input: AST of source language program ‣ with name and type annotations - Output: machine instructions Mechanics - What techniques are available to define translation? - What are the advantages and disadvantages of these techniques? - To what extent do these techniques help with verification? !25 Code Generation Mechanics
  • 26. Code Generation by String Manipulation 26
  • 27. Printing Strings as Side Effect !27 to-jbc = ?Nil() ; <printstring> "aconst_nulln" to-jbc = ?NoVal() ; <printstring> "nopn" to-jbc = ?Seq(es) ; <list-loop(to-jbc)> es to-jbc = ?Int(i); <printstring> "ldc "; <printstring> i; <printstring> "n" to-jbc = ?Bop(op, e1, e2) ; <to-jbc> e1 ; <to-jbc> e2 ; <to-jbc> op to-jbc = ?PLUS() ; <printstring> "iaddn" to-jbc = ?MINUS() ; <printstring> "isubn" to-jbc = ?MUL() ; <printstring> "imuln" to-jbc = ?DIV() ; <printstring> "idivn"
  • 28. String Concatenation !28 to-jbc: Nil() -> "aconst_nulln" to-jbc: NoVal() -> "nopn" to-jbc: Seq(es) -> <concat-strings> <map(to-jbc)> es to-jbc: Int(i) -> <concat-strings> ["ldc ", i, "n"] to-jbc: Bop(op, e1, e2) -> <concat-strings> [ <to-jbc> e1, <to-jbc> e2, <to-jbc> op ] to-jbc: PLUS() -> "iaddn" to-jbc: MINUS() -> "isubn" to-jbc: MUL() -> "imuln" to-jbc: DIV() -> "idivn"
  • 29. String Interpolation !29 to-jbc: Nil() -> $[aconst_null] to-jbc: NoVal() -> $[nop] to-jbc: Seq(es) -> <map-to-jbc> es map-to-jbc: [] -> $[] map-to-jbc: [h|t] -> $[[<to-jbc> h] [<map-to-jbc> t]] to-jbc: Int(i) -> $[ldc [i]]
 to-jbc: Bop(op, e1, e2) -> $[[<to-jbc> e1] [<to-jbc> e2] [<to-jbc> op]] to-jbc: PLUS() -> $[iadd] to-jbc: MINUS() -> $[isub] to-jbc: MUL() -> $[imul] to-jbc: DIV() -> $[idiv]
  • 30. Printing strings - Generated code depends on order of traversal of the AST - Explicit layout (whitespace) management - Verbose quotation and anti-quotation - Escaping meta-variables - Easy to make syntax errors - Output needs to be parsed for further processing String concatenation - Makes generation order independent String interpolation (templates) - Makes quotation and anti-quotation more concise - Layout (whitespace) from template layout !30 Summary: Code Generation by String Manipulation
  • 31. All bets are off - Only guarantee is that you get some text - String interpolation may help with producing readable code - Very easy to make even trivial syntactic errors Verification - Use target code checker for verification - No input independent guarantees !31 Correctness of String-Based Code Generators
  • 32. Code Generation by Term Transformation 32
  • 33. AST to AST translation - input: source language AST - output: target language AST Defined using term rewrite rules - Recognise AST pattern for language construct - Recursively translate sub-terms - Compose results with target code schema for language construct Intermediate representation (IR) !33 Code Generation by Transformation
  • 34. Code Generation by Transformation: Example !34 to-jbc: Nil() -> [ ACONST_NULL() ] to-jbc: NoVal() -> [ NOP() ] to-jbc: Seq(es) -> <mapconcat(to-jbc)> es to-jbc: Int(i) -> [ LDC(Int(i)) ] to-jbc: String(s) -> [ LDC(String(s)) ] to-jbc: Bop(op, e1, e2) -> <mapconcat(to-jbc)> [ e1, e2, op ] to-jbc: PLUS() -> [ IADD() ] to-jbc: MINUS() -> [ ISUB() ] to-jbc: MUL() -> [ IMUL() ] to-jbc: DIV() -> [ IDIV() ] to-jbc: Assign(lhs, e) -> <concat> [ <to-jbc> e, <lhs-to-jbc> lhs ] to-jbc: Var(x) -> [ ILOAD(x) ] where <type-of> Var(x) => INT() to-jbc: Var(x) -> [ ALOAD(x) ] where <type-of> Var(x) => STRING() lhs-to-jbc: Var(x) -> [ ISTORE(x) ] where <type-of> Var(x) => INT() lhs-to-jbc: Var(x) -> [ ASTORE(x) ] where <type-of> Var(x) => STRING() to-jbc : Exp -> List(Instruction)
  • 35. Code Generation by Transformation: Example !35 to-jbc: IfThenElse(e1, e2, e3) -> <concat> [ <to-jbc> e1 , [ IFEQ(LabelRef(else)) ] , <to-jbc> e2 , [ GOTO(LabelRef(end)), Label(else) ] , <to-jbc> e3 , [ Label(end) ] ] where <newname> "else" => else where <newname> "end" => end to-jbc: While(e1, e2) -> <concat> [ [ GOTO(LabelRef(check)), Label(body) ] , <to-jbc> e2 , [ Label(check) ] , <to-jbc> e1 , [ IFNE(LabelRef(body)) ] ] where <newname> "test" => check where <newname> "body" => body
  • 36. Compiler component composition - AST output can be consumed by compatible AST transformations Example compilation pipeline - Parse source language text => source language AST - Desugar => source language AST - Type-check => annotated source language AST - Translate => target language AST - Optimize => target language AST - Pretty-print => target language text Easy to extend with new components !36 Code Generation by Transformation
  • 38. Property: Syntactically correct target code - Guarantee that generated code parses Type correct AST = syntactically correct code - AST types represent syntactic categories ‣Plus: Exp * Exp -> Exp - Type check translation patterns Language support - Any programming language with a static type system - And support for algebraic data types Note: lexical syntax !38 Syntactically Correct Target Code
  • 39. Type Checking Transformation Rules !39 Type checking terms in rules guarantees syntactic correctness of generated code
  • 40. :-( Stratego - Only checks arities of constructor applications, not types - Transformation rules could be checked by the compiler - Generic traversals make traditional type checking impossible Research - A static analysis for Stratego that guarantees syntactic correctness Workaround - Meta-programming with concrete object syntax !40 Guaranteeing Syntactically Correct Target Code in Stratego?
  • 41. !41 This paper defines a generic technique for embedding the concrete syntax of an object language into a meta- programming language. Applied to Stratego as meta-language and Tiger as object language. Combines two advantages - guarantee syntactic correctness of match and build patterns - make rules more readable https://doi.org/10.1007/3-540-45821-2_19
  • 42. Concrete Object Syntax !42 Abstract syntax transformation Concrete syntax transformation
  • 43. Implementing Concrete Object Syntax !43 Embedding of object language into meta language
  • 44. From Concrete Syntax to Abstract Syntax !44 parse explode pretty-print Mixed AST Pure AST
  • 45. Meta Explode !45 How do you type check that? Find term embedding Explode it
  • 46. !46 The concrete syntax embedding techniques is not specific to Stratego as meta-language. This paper shows how to use it to embed DSLs into Java. https://doi.org/10.1145/1035292.1029007
  • 47. !47 This paper generalizes the concrete syntax techniques to all sorts of host and guest languages, with an application to preventing injection attacks. Injection attacks are caused by unhygienic construction of code through which user input can be turned into executable code. doi:10.1016/j.scico.2009.05.004
  • 51. Hygienic Transformations !51 Does new variable in TraceProcedure not capture variables in e?
  • 52. Guarantee that variables are not captured - Which variables? Object language name analysis for transformation rules - E.g. apply Tiger constraint rules to patterns in rules Existing approaches - Hygienic macros in Scheme/Racket - Higher-order abstract syntax - Nominal abstract syntax Research - Hygienic transformations for more complex binding patterns !52 Guaranteeing Hygiene
  • 54. Property: Type correct target code - Guarantee that generated code type checks Intrinsically-typed ASTs - Encode type system in algebraic signature - Including binding structure - Language support: Generalized ADTs Research - Advanced type systems & binding patterns !54 Guaranteeing Type Correct Code
  • 56. Generate code has same interface as source code !56 Interface Preservation
  • 57. Generated code produces values with the same type Intrinsically-typed interpreters for imperative languages - POPL18 paper - Verify that interpreters are type preserving - Including non-lexical binding patterns Research - how to do this for other transformations? !57 Type Preservation
  • 58. Semantics preservation - Generated code has the same behaviour as the source program CompCert - Certified C compiler - Defines operational semantics of source language (most of C) and all intermediate languages - Mechanically verify that translations between IR preserve behaviour ‣ For all possible programs - Or: verify that generated output has same behaviour as input ‣ For programs that compiler is applied to !58 Dynamic Semantics Preservation
  • 60. Reasons - code overhead - execution overhead Inlining - replace calls by body of the procedure - source code level Tail recursion - replace recursive calls by loops or jumps - source or machine code level !60 Optimizations
  • 62. Code Generation !62 function fac0(n0: int): int = if n0 = 0 then 1 else n0 * fac0(n0 - 1) .method public static fac0(I)I iload 1 ldc 0 if_icmpeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 63. Optimization !63 .method public static fac0(I)I iload_1 ifne else0 iconst_1 ireturn else0: iload_1 dup iconst_1 isub invokestatic Exp/fac0(I)I imul ireturn .end method .method public static fac0(I)I iload 1 ldc 0 if_icmpeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 64. Optimization !64 .method public static fac0(I)I iload 1 ifeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ldc 0 if_icmpeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 65. Optimization !65 .method public static fac0(I)I iload 1 ifeq label0 ldc 0 ifeq else0 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 66. Optimization !66 .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifeq label0 ldc 0 ifeq else0 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 67. Optimization !67 .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 68. Optimization !68 .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 69. Optimization !69 .method public static fac0(I)I iload 1 ifneq else0 label0: ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifeq label0 goto else0 label0: ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 70. Optimization !70 .method public static fac0(I)I iload 1 ifneq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifneq else0 label0: ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 71. Optimization !71 .method public static fac0(I)I iload 1 ifneq else0 ldc 1 ireturn else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifneq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 72. Optimization !72 .method public static fac0(I)I iload 1 ifneq else0 ldc 1 ireturn else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifneq else0 ldc 1 ireturn else0: iload 1 dup ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 73. Optimization !73 .method public static fac0(I)I iload_1 ifneq else0 ldc 1 ireturn else0: iload_1 dup ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload 1 ifneq else0 ldc 1 ireturn else0: iload 1 dup ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 74. Optimization !74 .method public static fac0(I)I iload_1 ifneq else0 iconst_1 ireturn else0: iload_1 dup iconst_1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method .method public static fac0(I)I iload_1 ifneq else0 ldc 1 ireturn else0: iload_1 dup ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 75. Optimization !75 .method public static fac0(I)I iload_1 ifneq else0 iconst_1 ireturn else0: iload_1 dup iconst_1 isub invokestatic Exp/fac0(I)I imul ireturn .end method .method public static fac0(I)I iload 1 ldc 0 if_icmpeq label0 ldc 0 goto label1 label0: ldc 1 label1: ifeq else0 ldc 1 goto end0 else0: iload 1 iload 1 ldc 1 isub invokestatic Exp/fac0(I)I imul end0: ireturn .end method
  • 78. Recursive function - creates a new stack frame for each invocation Tail recursion - recursive call is last action Tail recursion elimination - If function is tail recursive, reuse stack frame for recursive call !78 Tail Recursion Elimination
  • 79. Example: Non-Tail Recursive Function !79 .class public Exp .method public static fac(I)I iload 1 ifne else iconst_1 ireturn else: iload 1 dup iconst_1 isub invokestatic Exp/fac(I)I imul ireturn .end method function fac(n : Int) = if n = 1 then 1 else n * fac(n - 1)
  • 80. Example: Make Tail Recursive !80 function fac(n : Int) = if n = 1 then 1 else n * fac(n - 1) function fac(n : Int) = fac2(n, 1) function fac2(n : Int, acc: Int) = if n = 1 then acc else fac(n - 1, n * acc) Use an accumulator argument to build return value
  • 81. Example: Make Tail Recursive (in Byte Code) !81 .class public Exp .method public static fac(I)I iload 1 ifne else iconst_1 ireturn else: iload 1 dup iconst_1 isub invokestatic Exp/fac(I)I imul ireturn .end method .class public Exp .method public static fac(II)I iload 1 ifne else iload 2 ireturn else: iload 1 iconst_1 isub iload 1 iload 2 imul invokestatic Exp/fac(II)I ireturn .end method
  • 82. Example: Tail Recursion Elimination !82 .class public Exp .method public static fac(II)I iload 1 ifne else iload 2 ireturn else: iload 1 iconst_1 isub iload 1 iload 2 imul invokestatic Exp/fac(II)I ireturn .end method .class public Exp .method public static fac(II)I strt: iload 1 ifne else iload 2 ireturn else: iload 1 iconst_1 isub iload 1 iload 2 imul istore 2 istore 1 goto strt .end method
  • 84. !84 Except where otherwise noted, this work is licensed under