Dynamic Computer Language Engineering
Prof. Michael Carbin
6.1120
Administrivia
What is a “Dynamic” Language?
1: x = “foo”;
2: print(x);
3:
4: x = 5;
5: print(x);
1: if (y > 0) :
2: x = “foo”;
3: else :
4: x = 5;
5: print(x);
1: x = new object();
2: x.f = 5;
Change the type of a variable
Variable may have different types at the same program point.
Data types themselves are flexible
Dynamic Languages?
The MITScript Project: Python -> x86
Registers
Control
CPU
ALU
fun(y) {
x = y - 2;
return x;
};
Language
Machine
Translation
fun(y) {
x = y - 2;
};
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
function __function_1 (y) : {
%x = alloca int64_t
%0 = %y
%1 = 2
%2 = sub %0 %1
store %x %2
%3 = 0
return %3
}
__function_1 :
sub 8 %rsp
mov %rsp %rbp
mov (%rbp, 2, 8) %rax
mov 2 %rcx
sub %rcx %rax
mov %rax (%rbp)
mov 0 %rax
ret
High-Level
VM
Low-Level
VM
Machine Code
Language
The MITScript Project: The Five Phases
Last day of class: Project Derby!
Each Phase
Project Organization (Groups)
More Information
6.1120: Coursework and Grading (Tentative)
Mini Quizzes
6.1120: Coursework and Grading (Tentative)
The MITScript Project: Python -> x86
Registers
Control
CPU
ALU
fun(y) {
x = y - 2;
return x;
};
Language
Machine
What a Language Environment Does (Typically)
Why Study Language Environments?
The MITScript Project: Python -> x86
Registers
Control
CPU
ALU
fun(y) {
x = y - 2;
return x;
};
Language
Machine
The MITScript Project: The Five Phases
MITScript Environment
Virtual Machine
Language
High-Level
VM
Machine Code
Low-Level
VM
Interpreter (Semantics)
x = 1 + 2 * 3;
Example: Semantics
multiply(string, int) -> string (and ruby coerces 2.2 to 2)
multiply(float, float) -> float (does what one expects)
test1.rb:
_____________________________
print ARGV[0] * 2.2
> ruby test1.rb 100
> 100100
test2.rb:
_____________________________
print 2.2 * ARGV[0]
> ruby test2.rb 100
> *': String can't be coerced into Float (TypeError)
MITScript Virtual Machine
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
f = fun(y) {
x = y - 2;
};
f(1);
Organization (Code, Stack, and Heaps)
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
Organization (Code, Stack, and Heaps)
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
MITScript VM
Op Stack |
|
|
|
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
|
Heap
Stack
Frame
Globals |
f |
Locals |
MITScript VM
Op Stack |
|
|
|
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
0 |
Heap
Stack
Frame
Globals |
f |
Locals |
MITScript VM
Op Stack |
|
|
0 |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
1 |
Heap
Stack
Frame
Globals |
f |
Locals |
MITScript VM
Op Stack |
|
0 |
|
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
2 |
Heap
Stack
Frame
Globals |
f |
Locals |
MITScript VM
Op Stack |
|
|
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
3 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Globals |
f |
MITScript VM
Globals |
f |
Op Stack |
|
|
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
4 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
|
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
5 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
|
1 |
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
6 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
7 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
1 |
|
1 |
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
8 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
9 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
|
|
Locals |
y : 1 |
x : . |
IP |
0 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
|
1 |
Locals |
y : 1 |
x : . |
IP |
1 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
1 |
2 |
Locals |
y : 1 |
x : . |
IP |
2 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
|
-1 |
Locals |
y : 1 |
x : . |
IP |
3 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
|
|
Locals |
y : 1 |
x : -1 |
IP |
4 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
1 |
1 |
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Op Stack |
|
None |
Locals |
y : 1 |
x : -1 |
IP |
5 |
Stack
Frame
MITScript VM
Globals |
f |
Op Stack |
|
|
None |
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
10 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
|
|
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
11 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
|
None |
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
12 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
MITScript VM
Globals |
f |
Op Stack |
|
|
None |
Locals |
function {
functions = [ ],
constants = [None, 0, 1],
names = [f],
instructions = [
load_const 1
load_func 0
alloc_closure
store_global 0
load_global 0
load_const 2
swap
load_const 2
swap
call
pop
load_const 0
return
]}
function {
local_vars = [y, x],
constants = [None, 2],
instructions = [
load_local 0
load_const 1
sub
store_local 1
load_const 0
return
]
}
IP |
12 |
Heap
Stack
Frame
Closure { f : , ctx : [ ]}
Dynamic Languages are Slow
In C:
//assuming y is in r1 and t is in r3
//puts the result in r2.
mov $r2, 7
add $r2 $r1
add $r2 $r3
In a dynamic language:
Check what type of value y is.
Get the integer value from the value object of y�Get the integer value from the value object of 7
Allocate a new object value to store y + 7
Check that the new value is an integer
Check that t is an integer
Allocate a new object value to store (y+7)+t
Make x point to new object
x = (y + 7) + t
Dynamic Languages are Slow
// t is in $r1, v is in $r3
allocate a block of sizeof(X) bytes of memory store address in $r1
$r2 = $r1 + offset(X, x)
mov addr($r2) 5
mov $r3, addr($r2)
Allocate a new map from strings to vals
Allocate a new value 5.
Check that t stores a map value
Perform an insert operation in map t with key “x” to store value 5.
Check that t stores a map value
Perform a lookup operation on map t with key “x”
Write value to v
struct X { int x; int y; }
t = new X();
t.x = 5;
v = t.x;
t = object { }
t.x = 5;
v = t.x
Code Generation and Optimization
For Dynamic Language
__function_1 :
push %rdi
call assert_integer
pop %rax
shr $3 %rax
mov $2 %rcx
sub %rcx %rax
ret
void execute() {
Frame f = ...;
push(f.locals[0]);
push(f.constants[1]);
Value* op2 = pop(stack);
assert_integer(op2);
Value* op1 = pop(stack);
assert_integer(op2);
auto* result =
new Integer((Int *) op1->value – ((Int *)op2)->value);
push(result);
Value* op3 = pop(stack);
f.locals[1] = op3;
push(f.constants[0]);
Value* op4 = pop(stack);
return op4;
}
Instructions: > 1000s -> 7
Function Calls: 10s -> 1
Memory Accesses: 100s -> 2
Allocations: > 1 -> 0
fun(y) {
x = y - 2;
};
Optimization Example
int sumcalc(int a, int b, int N)
{
int i;
int x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*y;
}
return x;
}
45
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl %edx, -12(%rbp)
movl $0, -20(%rbp)
movl $0, -24(%rbp)
movl $0, -16(%rbp)
.L2: movl -16(%rbp), %eax
cmpl -12(%rbp), %eax
jg .L3
movl -4(%rbp), %eax
leal 0(,%rax,4), %edx
leaq -8(%rbp), %rax
movq %rax, -40(%rbp)
movl %edx, %eax
movq -40(%rbp), %rcx
cltd
idivl (%rcx)
movl %eax, -28(%rbp)
movl -28(%rbp), %edx
imull -16(%rbp), %edx
movl -16(%rbp), %eax
incl %eax
imull %eax, %eax
addl %eax, %edx
leaq -20(%rbp), %rax
addl %edx, (%rax)
movl -8(%rbp), %eax
movl %eax, %edx
imull -24(%rbp), %edx
leaq -20(%rbp), %rax
addl %edx, (%rax)
leaq -16(%rbp), %rax
incl (%rax)
jmp .L2
.L3: movl -20(%rbp), %eax
leave
ret
Lets Optimize...
int sumcalc(int a, int b, int N)
{
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*y;
}
return x;
}
Constant Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*y;
}
return x;
Constant Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*y;
}
return x;
Constant Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*0;
}
return x;
Algebraic Simplification
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*0;
}
return x;
Algebraic Simplification
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x + b*0;
}
return x;
Algebraic Simplification
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x;
}
return x;
Copy Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x;
}
return x;
Copy Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
x = x;
}
return x;
Copy Propagation
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
}
return x;
Common Subexpression Elimination
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
}
return x;
Common Subexpression Elimination
int i, x, y;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
x = x + (4*a/b)*i + (i+1)*(i+1);
}
return x;
Common Subexpression Elimination
int i, x, y, t;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Dead Code Elimination
int i, x, y, t;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Dead Code Elimination
int i, x, y, t;
x = 0;
y = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Dead Code Elimination
int i, x, t;
x = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Loop Invariant Removal
int i, x, t;
x = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Loop Invariant Removal
int i, x, t;
x = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + (4*a/b)*i + t*t;
}
return x;
Loop Invariant Removal
int i, x, t, u;
x = 0;
u = (4*a/b);
for(i = 0; i <= N; i++) {
t = i+1;
x = x + u*i + t*t;
}
return x;
Strength Reduction
int i, x, t, u;
x = 0;
u = (4*a/b);
for(i = 0; i <= N; i++) {
t = i+1;
x = x + u*i + t*t;
}
return x;
Strength Reduction
int i, x, t, u;
x = 0;
u = (4*a/b);
for(i = 0; i <= N; i++) {
t = i+1;
x = x + u*i + t*t;
}
return x;
Strength Reduction
int i, x, t, u, v;
x = 0;
u = ((a<<2)/b);
v = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + v + t*t;
v = v + u;
}
return x;
Optimized Example
int sumcalc(int a, int b, int N)
{
int i, x, t, u, v;
x = 0;
u = ((a<<2)/b);
v = 0;
for(i = 0; i <= N; i++) {
t = i+1;
x = x + v + t*t;
v = v + u;
}
return x;
}
xorl %r8d, %r8d
xorl %ecx, %ecx
movl %edx, %r9d
cmpl %edx, %r8d
jg .L7
sall $2, %edi
.L5: movl %edi, %eax
cltd
idivl %esi
leal 1(%rcx), %edx
movl %eax, %r10d
imull %ecx, %r10d
movl %edx, %ecx
imull %edx, %ecx
leal (%r10,%rcx), %eax
movl %edx, %ecx
addl %eax, %r8d
cmpl %r9d, %edx
jle .L5
.L7: movl %r8d, %eax
ret
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
movl %edx, -12(%rbp)
movl $0, -20(%rbp)
movl $0, -24(%rbp)
movl $0, -16(%rbp)
.L2: movl -16(%rbp), %eax
cmpl -12(%rbp), %eax
jg .L3
movl -4(%rbp), %eax
leal 0(,%rax,4), %edx
leaq -8(%rbp), %rax
movq %rax, -40(%rbp)
movl %edx, %eax
movq -40(%rbp), %rcx
cltd
idivl (%rcx)
movl %eax, -28(%rbp)
movl -28(%rbp), %edx
imull -16(%rbp), %edx
movl -16(%rbp), %eax
incl %eax
imull %eax, %eax
addl %eax, %edx
leaq -20(%rbp), %rax
addl %edx, (%rax)
movl -8(%rbp), %eax
movl %eax, %edx
imull -24(%rbp), %edx
leaq -20(%rbp), %rax
addl %edx, (%rax)
leaq -16(%rbp), %rax
incl (%rax)
jmp .L2
.L3: movl -20(%rbp), %eax
leave
ret
Inner Loop:
10*mov + 5*lea + 5*add/inc �+ 4*div/mul + 5*cmp/br/jmp
= 29 instructions
4*mov + 2*lea + 1*add/inc+ �3*div/mul + 2*cmp/br/jmp
= 12 instructions
Unoptimized Code
Optimized Code
Execution time = 17 sec
Execution time = 43 sec
For Dynamic Language
__function_1 :
push %rdi
call assert_integer
pop %rax
shr $3 %rax
mov $2 %rcx
sub %rcx %rax
ret
void execute() {
Frame f = ...;
push(f.locals[0]);
push(f.constants[1]);
Value* op2 = pop(stack);
assert_integer(op2);
Value* op1 = pop(stack);
assert_integer(op2);
auto* result =
new Integer((Int *) op1->value – ((Int *)op2)->value);
push(result);
Value* op3 = pop(stack);
f.locals[1] = op3;
push(f.constants[0]);
Value* op4 = pop(stack);
return op4;
}
Instructions: > 1000s -> 7
Function Calls: 10s -> 1
Memory Accesses: 100s -> 2
Allocations: > 1 -> 0
fun(y) {
x = y - 2;
};
Optimize Programs for…
The MITScript Project: The Five Phases
Language Environment Construction touches �many topics in Computer Science