SlideShare a Scribd company logo
1 of 177
Download to read offline
Three-Address Code IR
Announcements
● Programming Project 3 due Monday at
11:59PM.
● OH today after lecture.
● Ask questions on Piazzza!
● Ask questions via email!
● Checkpoint feedback will be returned
soon.
Where We Are
Lexical Analysis
Semantic Analysis
Syntax Analysis
IR Generation
IR Optimization
Code Generation
Optimization
Source
Code
Machine
Code
Overview for Today
● The Final Assignment
● Introduction to TAC:
● TAC for simple expressions.
● TAC for functions and function calls.
● TAC for objects.
● TAC for arrays.
● Generating TAC.
● A few low-level details.
The Final Assignment
● Goal: Generate TAC IR for Decaf programs.
● We provide a code generator to produce MIPS assembly.
● You can run your programs using spim, the MIPS simulator.
● You must also take care of some low-level details:
● Assign all parameters, local variables, and temporaries positions
in a stack frame.
● Assign all global variables positions in the global memory
segment.
● Assign all fields in a class an offset from the base of the object.
● You should not need to know MIPS to do this; all details
will be covered in lecture.
● If you have any questions on MIPS, please feel to ask!
An Important Detail
● When generating IR at this level, you do
not need to worry about optimizing it.
● It's okay to generate IR that has lots of
unnecessary assignments, redundant
computations, etc.
● We'll see how to optimize IR code later
this week and at the start of next week.
● It's tricky, but extremely cool!
Three-Address Code
● Or “TAC”
● The IR that you will be using for the final
programming project.
● High-level assembly where each
operation has at most three operands.
● Uses explicit runtime stack for function
calls.
● Uses vtables for dynamic dispatch.
Sample TAC Code
int x;
int y;
int x2 = x * x;
int y2 = y * y;
int r2 = x2 + y2;
Sample TAC Code
int x;
int y;
int x2 = x * x;
int y2 = y * y;
int r2 = x2 + y2;
x2 = x * x;
y2 = y * y;
r2 = x2 + y2;
Sample TAC Code
int a;
int b;
int c;
int d;
a = b + c + d;
b = a * a + b * b;
Sample TAC Code
int a;
int b;
int c;
int d;
a = b + c + d;
b = a * a + b * b;
_t0 = b + c;
a = _t0 + d;
_t1 = a * a;
_t2 = b * b;
b = _t1 + _t2;
Sample TAC Code
int a;
int b;
int c;
int d;
a = b + c + d;
b = a * a + b * b;
_t0 = b + c;
a = _t0 + d;
_t1 = a * a;
_t2 = b * b;
b = _t1 + _t2;
Temporary Variables
● The “three” in “three-address code”
refers to the number of operands in any
instruction.
● Evaluating an expression with more than
three subexpressions requires the
introduction of temporary variables.
● This is actually a lot easier than you
might think; we'll see how to do it later
on.
Sample TAC Code
int a;
int b;
a = 5 + 2 * b;
Sample TAC Code
int a;
int b;
a = 5 + 2 * b;
_t0 = 5;
_t1 = 2 * b;
a = _t0 + _t1;
Sample TAC Code
int a;
int b;
a = 5 + 2 * b;
_t0 = 5;
_t1 = 2 * b;
a = _t0 + _t1;
TAC allows for
instructions with two
operands.
Simple TAC Instructions
● Variable assignment allows assignments of the
form
● var = constant;
● var1
= var2
;
● var1
= var2
op var3
;
● var1
= constant op var2
;
● var1
= var2
op constant;
● var = constant1
op constant2
;
● Permitted operators are +, -, *, /, %.
● How would you compile y = -x; ?
Simple TAC Instructions
● Variable assignment allows assignments of the
form
● var = constant;
● var1
= var2
;
● var1
= var2
op var3
;
● var1
= constant op var2
;
● var1
= var2
op constant;
● var = constant1
op constant2
;
● Permitted operators are +, -, *, /, %.
● How would you compile y = -x; ?
y = 0 – x; y = -1 * x;
One More with bools
int x;
int y;
bool b1;
bool b2;
bool b3;
b1 = x + x < y
b2 = x + x == y
b3 = x + x > y
One More with bools
int x;
int y;
bool b1;
bool b2;
bool b3;
b1 = x + x < y
b2 = x + x == y
b3 = x + x > y
_t0 = x + x;
_t1 = y;
b1 = _t0 < _t1;
_t2 = x + x;
_t3 = y;
b2 = _t2 == _t3;
_t4 = x + x;
_t5 = y;
b3 = _t5 < _t4;
TAC with bools
● Boolean variables are represented as
integers that have zero or nonzero
values.
● In addition to the arithmetic operator,
TAC supports <, ==, ||, and &&.
● How might you compile b = (x <= y) ?
TAC with bools
● Boolean variables are represented as
integers that have zero or nonzero
values.
● In addition to the arithmetic operator,
TAC supports <, ==, ||, and &&.
● How might you compile b = (x <= y) ?
_t0 = x < y;
_t1 = x == y;
b = _t0 || _t1;
Control Flow Statements
int x;
int y;
int z;
if (x < y)
z = x;
else
z = y;
z = z * z;
Control Flow Statements
int x;
int y;
int z;
if (x < y)
z = x;
else
z = y;
z = z * z;
_t0 = x < y;
IfZ _t0 Goto _L0;
z = x;
Goto _L1;
_L0:
z = y;
_L1:
z = z * z;
Control Flow Statements
int x;
int y;
int z;
if (x < y)
z = x;
else
z = y;
z = z * z;
_t0 = x < y;
IfZ _t0 Goto _L0;
z = x;
Goto _L1;
_L0:
z = y;
_L1:
z = z * z;
Control Flow Statements
int x;
int y;
int z;
if (x < y)
z = x;
else
z = y;
z = z * z;
_t0 = x < y;
IfZ _t0 Goto _L0;
z = x;
Goto _L1;
_L0:
z = y;
_L1:
z = z * z;
Labels
● TAC allows for named labels indicating
particular points in the code that can be
jumped to.
● There are two control flow instructions:
● Goto label;
● IfZ value Goto label;
● Note that IfZ is always paired with Goto.
Control Flow Statements
int x;
int y;
while (x < y) {
x = x * 2;
}
y = x;
Control Flow Statements
int x;
int y;
while (x < y) {
x = x * 2;
}
y = x;
_L0:
_t0 = x < y;
IfZ _t0 Goto _L1;
x = x * 2;
Goto _L0;
_L1:
y = x;
A Complete Decaf Program
void main() {
int x, y;
int m2 = x * x + y * y;
while (m2 > 5) {
m2 = m2 – x;
}
}
A Complete Decaf Program
void main() {
int x, y;
int m2 = x * x + y * y;
while (m2 > 5) {
m2 = m2 – x;
}
}
main:
BeginFunc 24;
_t0 = x * x;
_t1 = y * y;
m2 = _t0 + _t1;
_L0:
_t2 = 5 < m2;
IfZ _t2 Goto _L1;
m2 = m2 – x;
Goto _L0;
_L1:
EndFunc;
A Complete Decaf Program
void main() {
int x, y;
int m2 = x * x + y * y;
while (m2 > 5) {
m2 = m2 – x;
}
}
main:
BeginFunc 24;
_t0 = x * x;
_t1 = y * y;
m2 = _t0 + _t1;
_L0:
_t2 = 5 < m2;
IfZ _t2 Goto _L1;
m2 = m2 – x;
Goto _L0;
_L1:
EndFunc;
A Complete Decaf Program
void main() {
int x, y;
int m2 = x * x + y * y;
while (m2 > 5) {
m2 = m2 – x;
}
}
main:
BeginFunc 24;
_t0 = x * x;
_t1 = y * y;
m2 = _t0 + _t1;
_L0:
_t2 = 5 < m2;
IfZ _t2 Goto _L1;
m2 = m2 – x;
Goto _L0;
_L1:
EndFunc;
A Complete Decaf Program
void main() {
int x, y;
int m2 = x * x + y * y;
while (m2 > 5) {
m2 = m2 – x;
}
}
main:
BeginFunc 24;
_t0 = x * x;
_t1 = y * y;
m2 = _t0 + _t1;
_L0:
_t2 = 5 < m2;
IfZ _t2 Goto _L1;
m2 = m2 – x;
Goto _L0;
_L1:
EndFunc;
Compiling Functions
● Decaf functions consist of four pieces:
● A label identifying the start of the function.
– (Why?)
● A BeginFunc N; instruction reserving N
bytes of space for locals and temporaries.
● The body of the function.
● An EndFunc; instruction marking the end of
the function.
– When reached, cleans up stack frame and
returns.
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
g(a, …, m)
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
main:
BeginFunc 4;
_t0 = 137;
PushParam _t0;
LCall _SimpleFn;
PopParams 4;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
main:
BeginFunc 4;
_t0 = 137;
PushParam _t0;
LCall _SimpleFn;
PopParams 4;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
main:
BeginFunc 4;
_t0 = 137;
PushParam _t0;
LCall _SimpleFn;
PopParams 4;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
main:
BeginFunc 4;
_t0 = 137;
PushParam _t0;
LCall _SimpleFn;
PopParams 4;
EndFunc;
Compiling Function Calls
void SimpleFn(int z) {
int x, y;
x = x * y * z;
}
void main() {
SimpleFunction(137);
}
_SimpleFn:
BeginFunc 16;
_t0 = x * y;
_t1 = _t0 * z;
x = _t1;
EndFunc;
main:
BeginFunc 4;
_t0 = 137;
PushParam _t0;
LCall _SimpleFn;
PopParams 4;
EndFunc;
Stack Management in TAC
● The BeginFunc N; instruction only needs to
reserve room for local variables and
temporaries.
● The EndFunc; instruction reclaims the room
allocated with BeginFunc N;
● A single parameter is pushed onto the stack by
the caller using the PushParam var instruction.
● Space for parameters is reclaimed by the caller
using the PopParams N; instruction.
● N is measured in bytes, not number of arguments.
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M PushParam var;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
PushParam var;
PushParam var;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
PushParam var;
PushParam var;
PushParam var;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
PushParam var;
PushParam var;
PushParam var;
BeginFunc N;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
g(a, …, m)
PushParam var;
PushParam var;
PushParam var;
BeginFunc N;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
Storage for
Locals and
Temporaries
EndFunc;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Param M
…
Param 1
PopParams N;
A Logical Decaf Stack Frame
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Stack
frame for
function
f(a, …, n)
Storage Allocation
● As described so far, TAC does not specify
where variables and temporaries are
stored.
● For the final programming project, you
will need to tell the code generator where
each variable should be stored.
● This normally would be handled during
code generation, but Just For Fun we
thought you should have some experience
handling this. ☺
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
Param M
…
Param 1
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
Param M
…
Param 1
Storage for
Locals and
Temporaries
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
Param M
…
Param 1
Storage for
Locals and
Temporaries
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
Param M
…
Param 1
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
The Frame Pointer
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Frame
Pointer
Logical vs Physical Stack Frames
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Logical vs Physical Stack Frames
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Logical vs Physical Stack Frames
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
Param N
Param N – 1
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
fp of caller
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
fp of caller
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
fp of caller
Storage for
Locals and
Temporaries
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
fp of caller
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
fp of caller
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
Param N
...
Param 1
(Mostly) Physical Stack Frames
Param N
...
Param 1
Storage for
Locals and
Temporaries
fp of caller
Frame
Pointer
The Stored Return Address
● Internally, the processor has a special register
called the program counter (PC) that stores the
address of the next instruction to execute.
● Whenever a function returns, it needs to restore
the PC so that the calling function resumes
execution where it left off.
● The address of where to return is stored in MIPS
in a special register called ra (“return address.”)
● To allow MIPS functions to call one another, each
function needs to store the previous value of ra
somewhere.
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Param N
...
Param 1
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Param N
...
Param 1
fp of caller
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Param N
...
Param 1
fp of caller
ra of caller
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Param N
...
Param 1
fp of caller
ra of caller
Physical Stack Frames
Param N
...
Param 1
Locals and
Temporaries
fp of caller
Frame
Pointer
ra of caller
Param N
...
Param 1
fp of caller
ra of caller
Locals and
Temporaries
So What?
● In your code generator, you must assign each
local variable, parameter, and temporary
variable its own location.
● These locations occur in a particular stack
frame and are called fp-relative.
Param N
...
Param 1
Local 0
fp of caller
ra of caller
fp
● Parameters begin at address
fp + 4 and grow upward.
● Locals and temporaries begin
at address fp – 8 and grow
downward
...
Local M
fp + 0
fp + 4
...
fp + 4N
fp - 4
fp - 8
...
fp - 4 - 4M
From Your Perspective
Location* location =
new Location(fpRelative, +4, locName);
From Your Perspective
Location* location =
new Location(fpRelative, +4, locName);
From Your Perspective
Location* location =
new Location(fpRelative, +4, locName);
What variable does
this refer to?
And One More Thing...
int globalVariable;
int main() {
globalVariable = 137;
}
And One More Thing...
int globalVariable;
int main() {
globalVariable = 137;
}
And One More Thing...
int globalVariable;
int main() {
globalVariable = 137;
}
Where is this
stored?
The Global Pointer
● MIPS also has a register called the
global pointer (gp) that points to
globally accessible storage.
● Memory pointed at by the global pointer
is treated as an array of values that
grows upward.
● You must choose an offset into this array
for each global variable.
Global Variable 0
Global Variable 1
...
Global Variable N
gp gp + 0
gp + 4
...
gp + 4N
From Your Perspective
Location* global =
new Location(gpRelative, +8, locName);
From Your Perspective
Location* global =
new Location(gpRelative, +8, locName);
Summary of Memory Layout
● Most details abstracted away by IR
format.
● Remember:
● Parameters start at fp + 4 and grow upward.
● Locals start at fp – 8 and grow downward.
● Globals start at gp + 0 and grow upward.
● You will need to write code to assign
variables to these locations.
TAC for Objects, Part I
class A {
void fn(int x) {
int y;
y = x;
}
}
int main() {
A a;
a.fn(137);
}
TAC for Objects, Part I
class A {
void fn(int x) {
int y;
y = x;
}
}
int main() {
A a;
a.fn(137);
}
_A.fn:
BeginFunc 4;
y = x;
EndFunc;
main:
BeginFunc 8;
_t0 = 137;
PushParam _t0;
PushParam a;
LCall _A.fn;
PopParams 8;
EndFunc;
TAC for Objects, Part I
class A {
void fn(int x) {
int y;
y = x;
}
}
int main() {
A a;
a.fn(137);
}
_A.fn:
BeginFunc 4;
y = x;
EndFunc;
main:
BeginFunc 8;
_t0 = 137;
PushParam _t0;
PushParam a;
LCall _A.fn;
PopParams 8;
EndFunc;
A Reminder: Object Layout
Method 0
Field 0
Vtable*
Vtable*
...
Field N
Field 0
...
Field N
Field 0
...
Field M
Method 1
...
Method K
Method 0
Method 1
...
Method K
Method 0
...
Method L
TAC for Objects, Part II
class A {
int y;
int z;
void fn(int x) {
y = x;
x = z;
}
}
int main() {
A a;
a.fn(137);
}
TAC for Objects, Part II
class A {
int y;
int z;
void fn(int x) {
y = x;
x = z;
}
}
int main() {
A a;
a.fn(137);
}
_A.fn:
BeginFunc 4;
*(this + 4) = x;
x = *(this + 8);
EndFunc;
main:
BeginFunc 8;
_t0 = 137;
PushParam _t0;
PushParam a;
LCall _A.fn;
PopParams 8;
EndFunc;
TAC for Objects, Part II
class A {
int y;
int z;
void fn(int x) {
y = x;
x = z;
}
}
int main() {
A a;
a.fn(137);
}
_A.fn:
BeginFunc 4;
*(this + 4) = x;
x = *(this + 8);
EndFunc;
main:
BeginFunc 8;
_t0 = 137;
PushParam _t0;
PushParam a;
LCall _A.fn;
PopParams 8;
EndFunc;
TAC for Objects, Part II
class A {
int y;
int z;
void fn(int x) {
y = x;
x = z;
}
}
int main() {
A a;
a.fn(137);
}
_A.fn:
BeginFunc 4;
*(this + 4) = x;
x = *(this + 8);
EndFunc;
main:
BeginFunc 8;
_t0 = 137;
PushParam _t0;
PushParam a;
LCall _A.fn;
PopParams 8;
EndFunc;
Memory Access in TAC
● Extend our simple assignments with
memory accesses:
● var1
= *var2
● var1
= *(var2
+ constant)
● *var1
= var2
● *(var1
+ constant) = var2
● You will need to translate field accesses
into relative memory accesses.
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
_Base.hi:
BeginFunc 4;
_t0 = "Base";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Base = _Base.hi,
;
_Derived.hi:
BeginFunc 4;
_t0 = "Derived";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Derived = _Derived.hi,
;
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
_Base.hi:
BeginFunc 4;
_t0 = "Base";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Base = _Base.hi,
;
_Derived.hi:
BeginFunc 4;
_t0 = "Derived";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Derived = _Derived.hi,
;
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
_Base.hi:
BeginFunc 4;
_t0 = "Base";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Base = _Base.hi,
;
_Derived.hi:
BeginFunc 4;
_t0 = "Derived";
PushParam _t0;
LCall _PrintString;
PopParams 4;
EndFunc;
Vtable Derived = _Derived.hi,
;
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
TAC for Objects, Part III
class Base {
void hi() {
Print("Base");
}
}
class Derived extends Base{
void hi() {
Print("Derived");
}
}
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
What's going
on here?
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
hi
Derived Vtable
Code for
Derived.hi
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Param 1
4
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Param 1
4
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Param 1
4
(raw memory)
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
Param 1
4
(raw memory)
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
(raw memory)
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Allocate
Object
Set
Vtable
Load
Function
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable* Load
Function
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Param 1
Load
Function
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Param 1
Load
Function
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable*
Param 1
Load
Function
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable* Load
Function
Allocate
Object
Set
Vtable
Dissecting TAC
int main() {
Base b;
b = new Derived;
b.hi();
}
main:
BeginFunc 20;
_t0 = 4;
PushParam _t0;
b = LCall _Alloc;
PopParams 4;
_t1 = Derived;
*b = _t1;
_t2 = *b;
_t3 = *_t2;
PushParam b;
ACall _t3;
PopParams 4;
EndFunc;
fp of caller
ra of caller
hi
Derived Vtable
Code for
Derived.hi
_t0
_t1
_t2
_t3
b
4
VTable* Load
Function
Allocate
Object
Set
Vtable
OOP in TAC
● The address of an object's vtable can be
referenced via the name assigned to the vtable
(usually the object name).
● e.g. _t0 = Base;
● When creating objects, you must remember to
set the object's vtable pointer or any method
call will cause a crash at runtime.
● The ACall instruction can be used to call a
method given a pointer to the first instruction.
Generating TAC
TAC Generation
● At this stage in compilation, we have
● an AST,
● annotated with scope information,
● and annotated with type information.
● To generate TAC for the program, we do
(yet another) recursive tree traversal!
● Generate TAC for any subexpressions or
substatements.
● Using the result, generate TAC for the overall
expression.
TAC Generation for Expressions
● Define a function cgen(expr) that generates
TAC that computes an expression, stores it in a
temporary variable, then hands back the name
of that temporary.
●
Define cgen directly for atomic expressions
(constants, this, identifiers, etc.).
●
Define cgen recursively for compound
expressions (binary operators, function calls,
etc.)
cgen for Basic Expressions
cgen for Basic Expressions
cgen(k) = { // k is a constant
Choose a new temporary t
Emit( t = k );
Return t
}
cgen for Basic Expressions
cgen(k) = { // k is a constant
Choose a new temporary t
Emit( t = k );
Return t
}
cgen(id) = { // id is an identifier
Choose a new temporary t
Emit( t = id )
Return t
}
cgen for Binary Operators
cgen for Binary Operators
cgen(e1
+ e2
) = {
Choose a new temporary t
Let t1
= cgen(e1
)
Let t2
= cgen(e2
)
Emit( t = t1
+ t2
)
Return t
}
An Example
cgen(5 + x) = {
Choose a new temporary t
Let t1
= cgen(5)
Let t2
= cgen(x)
Emit (t = t1
+ t2
)
Return t
}
An Example
cgen(5 + x) = {
Choose a new temporary t
Let t1
= {
Choose a new temporary t
Emit( t = 5 )
return t
}
Let t2
= cgen(x)
Emit (t = t1
+ t2
)
Return t
}
An Example
cgen(5 + x) = {
Choose a new temporary t
Let t1
= {
Choose a new temporary t
Emit( t = 5 )
return t
}
Let t2
= {
Choose a new temporary t
Emit( t = x )
return t
}
Emit (t = t1
+ t2
)
Return t
}
An Example
cgen(5 + x) = {
Choose a new temporary t
Let t1
= {
Choose a new temporary t
Emit( t = 5 )
return t
}
Let t2
= {
Choose a new temporary t
Emit( t = x )
return t
}
Emit (t = t1
+ t2
)
Return t
}
_t0 = 5
_t1 = x
_t2 = _t0 + _t1
cgen for Statements
● We can extend the cgen function to
operate over statements as well.
● Unlike cgen for expressions, cgen for
statements does not return the name of a
temporary holding a value.
● (Why?)
cgen for Simple Statements
cgen for Simple Statements
cgen(expr;) = {
cgen(expr)
}
cgen for while loops
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
cgen for while loops
cgen(while (expr) stmt) = {
Let Lbefore
be a new label.
Let Lafter
be a new label.
Emit( Lbefore
:)
Let t = cgen(expr)
Emit( IfZ t Goto Lafter
)
cgen(stmt)
Emit( Goto Lbefore
)
Emit( Lafter
: )
}
Next Time
● Intro to IR Optimization
● Basic Blocks
● Control-Flow Graphs
● Local Optimizations

More Related Content

Similar to Slides13.pdf

11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class웅식 전
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Sheik Uduman Ali
 
Data structures notes for college students btech.pptx
Data structures notes for college students btech.pptxData structures notes for college students btech.pptx
Data structures notes for college students btech.pptxKarthikVijay59
 
Introduction to Algorithms
Introduction to AlgorithmsIntroduction to Algorithms
Introduction to Algorithmspppepito86
 
Workshop03.docx lap trinh C cho người mới bắt đầu
Workshop03.docx  lap trinh C cho người mới bắt đầuWorkshop03.docx  lap trinh C cho người mới bắt đầu
Workshop03.docx lap trinh C cho người mới bắt đầulinhtran111111111111
 
chapter1.ppt
chapter1.pptchapter1.ppt
chapter1.pptebinazer1
 
Microcontroller lec 3
Microcontroller  lec 3Microcontroller  lec 3
Microcontroller lec 3Ibrahim Reda
 
How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012Connor McDonald
 
Cs1123 8 functions
Cs1123 8 functionsCs1123 8 functions
Cs1123 8 functionsTAlha MAlik
 
06 Recursion in C.pptx
06 Recursion in C.pptx06 Recursion in C.pptx
06 Recursion in C.pptxMouDhara1
 
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...Positive Hack Days
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approachAlexander Granin
 
Integer security analysis using smt solver
Integer security analysis using smt solverInteger security analysis using smt solver
Integer security analysis using smt solverDharmalingam Ganesan
 
how to reuse code
how to reuse codehow to reuse code
how to reuse codejleed1
 

Similar to Slides13.pdf (20)

3.Loops_conditionals.pdf
3.Loops_conditionals.pdf3.Loops_conditionals.pdf
3.Loops_conditionals.pdf
 
11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class11 2. variable-scope rule,-storage_class
11 2. variable-scope rule,-storage_class
 
C++ in 10 Hours.pdf.pdf
C++ in 10 Hours.pdf.pdfC++ in 10 Hours.pdf.pdf
C++ in 10 Hours.pdf.pdf
 
Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0Let Us Learn Lambda Using C# 3.0
Let Us Learn Lambda Using C# 3.0
 
Data structures notes for college students btech.pptx
Data structures notes for college students btech.pptxData structures notes for college students btech.pptx
Data structures notes for college students btech.pptx
 
Introduction to Algorithms
Introduction to AlgorithmsIntroduction to Algorithms
Introduction to Algorithms
 
Workshop03.docx lap trinh C cho người mới bắt đầu
Workshop03.docx  lap trinh C cho người mới bắt đầuWorkshop03.docx  lap trinh C cho người mới bắt đầu
Workshop03.docx lap trinh C cho người mới bắt đầu
 
functions
functionsfunctions
functions
 
Loops
LoopsLoops
Loops
 
chapter1.ppt
chapter1.pptchapter1.ppt
chapter1.ppt
 
Microcontroller lec 3
Microcontroller  lec 3Microcontroller  lec 3
Microcontroller lec 3
 
How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012
 
Cs1123 8 functions
Cs1123 8 functionsCs1123 8 functions
Cs1123 8 functions
 
06 Recursion in C.pptx
06 Recursion in C.pptx06 Recursion in C.pptx
06 Recursion in C.pptx
 
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
The System of Automatic Searching for Vulnerabilities or how to use Taint Ana...
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 
Advanced C - Part 2
Advanced C - Part 2Advanced C - Part 2
Advanced C - Part 2
 
C Programming Homework Help
C Programming Homework HelpC Programming Homework Help
C Programming Homework Help
 
Integer security analysis using smt solver
Integer security analysis using smt solverInteger security analysis using smt solver
Integer security analysis using smt solver
 
how to reuse code
how to reuse codehow to reuse code
how to reuse code
 

Recently uploaded

Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104misteraugie
 
Q4-W6-Restating Informational Text Grade 3
Q4-W6-Restating Informational Text Grade 3Q4-W6-Restating Informational Text Grade 3
Q4-W6-Restating Informational Text Grade 3JemimahLaneBuaron
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhikauryashika82
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxiammrhaywood
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introductionMaksud Ahmed
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...Sapna Thakur
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityGeoBlogs
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdfSoniaTolstoy
 
Grant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingGrant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingTechSoup
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)eniolaolutunde
 
The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13Steve Thomason
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Krashi Coaching
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAssociation for Project Management
 
Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfchloefrazer622
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactPECB
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationnomboosow
 
Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Disha Kariya
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphThiyagu K
 

Recently uploaded (20)

Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104Nutritional Needs Presentation - HLTH 104
Nutritional Needs Presentation - HLTH 104
 
Q4-W6-Restating Informational Text Grade 3
Q4-W6-Restating Informational Text Grade 3Q4-W6-Restating Informational Text Grade 3
Q4-W6-Restating Informational Text Grade 3
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
 
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptxSOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
SOCIAL AND HISTORICAL CONTEXT - LFTVD.pptx
 
microwave assisted reaction. General introduction
microwave assisted reaction. General introductionmicrowave assisted reaction. General introduction
microwave assisted reaction. General introduction
 
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
BAG TECHNIQUE Bag technique-a tool making use of public health bag through wh...
 
Paris 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activityParis 2024 Olympic Geographies - an activity
Paris 2024 Olympic Geographies - an activity
 
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdfBASLIQ CURRENT LOOKBOOK  LOOKBOOK(1) (1).pdf
BASLIQ CURRENT LOOKBOOK LOOKBOOK(1) (1).pdf
 
Grant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy ConsultingGrant Readiness 101 TechSoup and Remy Consulting
Grant Readiness 101 TechSoup and Remy Consulting
 
Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)Software Engineering Methodologies (overview)
Software Engineering Methodologies (overview)
 
The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13The Most Excellent Way | 1 Corinthians 13
The Most Excellent Way | 1 Corinthians 13
 
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
Kisan Call Centre - To harness potential of ICT in Agriculture by answer farm...
 
APM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across SectorsAPM Welcome, APM North West Network Conference, Synergies Across Sectors
APM Welcome, APM North West Network Conference, Synergies Across Sectors
 
Arihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdfArihant handbook biology for class 11 .pdf
Arihant handbook biology for class 11 .pdf
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
Interactive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communicationInteractive Powerpoint_How to Master effective communication
Interactive Powerpoint_How to Master effective communication
 
Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..Sports & Fitness Value Added Course FY..
Sports & Fitness Value Added Course FY..
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 

Slides13.pdf

  • 2. Announcements ● Programming Project 3 due Monday at 11:59PM. ● OH today after lecture. ● Ask questions on Piazzza! ● Ask questions via email! ● Checkpoint feedback will be returned soon.
  • 3. Where We Are Lexical Analysis Semantic Analysis Syntax Analysis IR Generation IR Optimization Code Generation Optimization Source Code Machine Code
  • 4. Overview for Today ● The Final Assignment ● Introduction to TAC: ● TAC for simple expressions. ● TAC for functions and function calls. ● TAC for objects. ● TAC for arrays. ● Generating TAC. ● A few low-level details.
  • 5. The Final Assignment ● Goal: Generate TAC IR for Decaf programs. ● We provide a code generator to produce MIPS assembly. ● You can run your programs using spim, the MIPS simulator. ● You must also take care of some low-level details: ● Assign all parameters, local variables, and temporaries positions in a stack frame. ● Assign all global variables positions in the global memory segment. ● Assign all fields in a class an offset from the base of the object. ● You should not need to know MIPS to do this; all details will be covered in lecture. ● If you have any questions on MIPS, please feel to ask!
  • 6. An Important Detail ● When generating IR at this level, you do not need to worry about optimizing it. ● It's okay to generate IR that has lots of unnecessary assignments, redundant computations, etc. ● We'll see how to optimize IR code later this week and at the start of next week. ● It's tricky, but extremely cool!
  • 7. Three-Address Code ● Or “TAC” ● The IR that you will be using for the final programming project. ● High-level assembly where each operation has at most three operands. ● Uses explicit runtime stack for function calls. ● Uses vtables for dynamic dispatch.
  • 8. Sample TAC Code int x; int y; int x2 = x * x; int y2 = y * y; int r2 = x2 + y2;
  • 9. Sample TAC Code int x; int y; int x2 = x * x; int y2 = y * y; int r2 = x2 + y2; x2 = x * x; y2 = y * y; r2 = x2 + y2;
  • 10. Sample TAC Code int a; int b; int c; int d; a = b + c + d; b = a * a + b * b;
  • 11. Sample TAC Code int a; int b; int c; int d; a = b + c + d; b = a * a + b * b; _t0 = b + c; a = _t0 + d; _t1 = a * a; _t2 = b * b; b = _t1 + _t2;
  • 12. Sample TAC Code int a; int b; int c; int d; a = b + c + d; b = a * a + b * b; _t0 = b + c; a = _t0 + d; _t1 = a * a; _t2 = b * b; b = _t1 + _t2;
  • 13. Temporary Variables ● The “three” in “three-address code” refers to the number of operands in any instruction. ● Evaluating an expression with more than three subexpressions requires the introduction of temporary variables. ● This is actually a lot easier than you might think; we'll see how to do it later on.
  • 14. Sample TAC Code int a; int b; a = 5 + 2 * b;
  • 15. Sample TAC Code int a; int b; a = 5 + 2 * b; _t0 = 5; _t1 = 2 * b; a = _t0 + _t1;
  • 16. Sample TAC Code int a; int b; a = 5 + 2 * b; _t0 = 5; _t1 = 2 * b; a = _t0 + _t1; TAC allows for instructions with two operands.
  • 17. Simple TAC Instructions ● Variable assignment allows assignments of the form ● var = constant; ● var1 = var2 ; ● var1 = var2 op var3 ; ● var1 = constant op var2 ; ● var1 = var2 op constant; ● var = constant1 op constant2 ; ● Permitted operators are +, -, *, /, %. ● How would you compile y = -x; ?
  • 18. Simple TAC Instructions ● Variable assignment allows assignments of the form ● var = constant; ● var1 = var2 ; ● var1 = var2 op var3 ; ● var1 = constant op var2 ; ● var1 = var2 op constant; ● var = constant1 op constant2 ; ● Permitted operators are +, -, *, /, %. ● How would you compile y = -x; ? y = 0 – x; y = -1 * x;
  • 19. One More with bools int x; int y; bool b1; bool b2; bool b3; b1 = x + x < y b2 = x + x == y b3 = x + x > y
  • 20. One More with bools int x; int y; bool b1; bool b2; bool b3; b1 = x + x < y b2 = x + x == y b3 = x + x > y _t0 = x + x; _t1 = y; b1 = _t0 < _t1; _t2 = x + x; _t3 = y; b2 = _t2 == _t3; _t4 = x + x; _t5 = y; b3 = _t5 < _t4;
  • 21. TAC with bools ● Boolean variables are represented as integers that have zero or nonzero values. ● In addition to the arithmetic operator, TAC supports <, ==, ||, and &&. ● How might you compile b = (x <= y) ?
  • 22. TAC with bools ● Boolean variables are represented as integers that have zero or nonzero values. ● In addition to the arithmetic operator, TAC supports <, ==, ||, and &&. ● How might you compile b = (x <= y) ? _t0 = x < y; _t1 = x == y; b = _t0 || _t1;
  • 23. Control Flow Statements int x; int y; int z; if (x < y) z = x; else z = y; z = z * z;
  • 24. Control Flow Statements int x; int y; int z; if (x < y) z = x; else z = y; z = z * z; _t0 = x < y; IfZ _t0 Goto _L0; z = x; Goto _L1; _L0: z = y; _L1: z = z * z;
  • 25. Control Flow Statements int x; int y; int z; if (x < y) z = x; else z = y; z = z * z; _t0 = x < y; IfZ _t0 Goto _L0; z = x; Goto _L1; _L0: z = y; _L1: z = z * z;
  • 26. Control Flow Statements int x; int y; int z; if (x < y) z = x; else z = y; z = z * z; _t0 = x < y; IfZ _t0 Goto _L0; z = x; Goto _L1; _L0: z = y; _L1: z = z * z;
  • 27. Labels ● TAC allows for named labels indicating particular points in the code that can be jumped to. ● There are two control flow instructions: ● Goto label; ● IfZ value Goto label; ● Note that IfZ is always paired with Goto.
  • 28. Control Flow Statements int x; int y; while (x < y) { x = x * 2; } y = x;
  • 29. Control Flow Statements int x; int y; while (x < y) { x = x * 2; } y = x; _L0: _t0 = x < y; IfZ _t0 Goto _L1; x = x * 2; Goto _L0; _L1: y = x;
  • 30. A Complete Decaf Program void main() { int x, y; int m2 = x * x + y * y; while (m2 > 5) { m2 = m2 – x; } }
  • 31. A Complete Decaf Program void main() { int x, y; int m2 = x * x + y * y; while (m2 > 5) { m2 = m2 – x; } } main: BeginFunc 24; _t0 = x * x; _t1 = y * y; m2 = _t0 + _t1; _L0: _t2 = 5 < m2; IfZ _t2 Goto _L1; m2 = m2 – x; Goto _L0; _L1: EndFunc;
  • 32. A Complete Decaf Program void main() { int x, y; int m2 = x * x + y * y; while (m2 > 5) { m2 = m2 – x; } } main: BeginFunc 24; _t0 = x * x; _t1 = y * y; m2 = _t0 + _t1; _L0: _t2 = 5 < m2; IfZ _t2 Goto _L1; m2 = m2 – x; Goto _L0; _L1: EndFunc;
  • 33. A Complete Decaf Program void main() { int x, y; int m2 = x * x + y * y; while (m2 > 5) { m2 = m2 – x; } } main: BeginFunc 24; _t0 = x * x; _t1 = y * y; m2 = _t0 + _t1; _L0: _t2 = 5 < m2; IfZ _t2 Goto _L1; m2 = m2 – x; Goto _L0; _L1: EndFunc;
  • 34. A Complete Decaf Program void main() { int x, y; int m2 = x * x + y * y; while (m2 > 5) { m2 = m2 – x; } } main: BeginFunc 24; _t0 = x * x; _t1 = y * y; m2 = _t0 + _t1; _L0: _t2 = 5 < m2; IfZ _t2 Goto _L1; m2 = m2 – x; Goto _L0; _L1: EndFunc;
  • 35. Compiling Functions ● Decaf functions consist of four pieces: ● A label identifying the start of the function. – (Why?) ● A BeginFunc N; instruction reserving N bytes of space for locals and temporaries. ● The body of the function. ● An EndFunc; instruction marking the end of the function. – When reached, cleans up stack frame and returns.
  • 36. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n)
  • 37. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M
  • 38. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M …
  • 39. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1
  • 40. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries
  • 41. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries Stack frame for function g(a, …, m)
  • 42. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries
  • 43. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1
  • 44. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n)
  • 45. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); }
  • 46. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc;
  • 47. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc;
  • 48. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc;
  • 49. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc; main: BeginFunc 4; _t0 = 137; PushParam _t0; LCall _SimpleFn; PopParams 4; EndFunc;
  • 50. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc; main: BeginFunc 4; _t0 = 137; PushParam _t0; LCall _SimpleFn; PopParams 4; EndFunc;
  • 51. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc; main: BeginFunc 4; _t0 = 137; PushParam _t0; LCall _SimpleFn; PopParams 4; EndFunc;
  • 52. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc; main: BeginFunc 4; _t0 = 137; PushParam _t0; LCall _SimpleFn; PopParams 4; EndFunc;
  • 53. Compiling Function Calls void SimpleFn(int z) { int x, y; x = x * y * z; } void main() { SimpleFunction(137); } _SimpleFn: BeginFunc 16; _t0 = x * y; _t1 = _t0 * z; x = _t1; EndFunc; main: BeginFunc 4; _t0 = 137; PushParam _t0; LCall _SimpleFn; PopParams 4; EndFunc;
  • 54. Stack Management in TAC ● The BeginFunc N; instruction only needs to reserve room for local variables and temporaries. ● The EndFunc; instruction reclaims the room allocated with BeginFunc N; ● A single parameter is pushed onto the stack by the caller using the PushParam var instruction. ● Space for parameters is reclaimed by the caller using the PopParams N; instruction. ● N is measured in bytes, not number of arguments.
  • 55. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n)
  • 56. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M PushParam var;
  • 57. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … PushParam var; PushParam var;
  • 58. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 PushParam var; PushParam var; PushParam var;
  • 59. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries PushParam var; PushParam var; PushParam var; BeginFunc N;
  • 60. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries Stack frame for function g(a, …, m) PushParam var; PushParam var; PushParam var; BeginFunc N;
  • 61. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries
  • 62. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 Storage for Locals and Temporaries EndFunc;
  • 63. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1
  • 64. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n) Param M … Param 1 PopParams N;
  • 65. A Logical Decaf Stack Frame Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Stack frame for function f(a, …, n)
  • 66. Storage Allocation ● As described so far, TAC does not specify where variables and temporaries are stored. ● For the final programming project, you will need to tell the code generator where each variable should be stored. ● This normally would be handled during code generation, but Just For Fun we thought you should have some experience handling this. ☺
  • 67. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries
  • 68. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer
  • 69. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer Param M … Param 1
  • 70. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer Param M … Param 1 Storage for Locals and Temporaries
  • 71. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer Param M … Param 1 Storage for Locals and Temporaries
  • 72. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer Param M … Param 1
  • 73. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer
  • 74. The Frame Pointer Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Frame Pointer
  • 75. Logical vs Physical Stack Frames Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries
  • 76. Logical vs Physical Stack Frames Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries fp of caller
  • 77. Logical vs Physical Stack Frames Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries Param N Param N – 1 ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer
  • 78. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer
  • 79. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1
  • 80. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1 fp of caller
  • 81. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1 fp of caller
  • 82. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1 fp of caller Storage for Locals and Temporaries
  • 83. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1 fp of caller
  • 84. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1 fp of caller
  • 85. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer Param N ... Param 1
  • 86. (Mostly) Physical Stack Frames Param N ... Param 1 Storage for Locals and Temporaries fp of caller Frame Pointer
  • 87. The Stored Return Address ● Internally, the processor has a special register called the program counter (PC) that stores the address of the next instruction to execute. ● Whenever a function returns, it needs to restore the PC so that the calling function resumes execution where it left off. ● The address of where to return is stored in MIPS in a special register called ra (“return address.”) ● To allow MIPS functions to call one another, each function needs to store the previous value of ra somewhere.
  • 88. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller
  • 89. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller Param N ... Param 1
  • 90. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller Param N ... Param 1 fp of caller
  • 91. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller Param N ... Param 1 fp of caller ra of caller
  • 92. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller Param N ... Param 1 fp of caller ra of caller
  • 93. Physical Stack Frames Param N ... Param 1 Locals and Temporaries fp of caller Frame Pointer ra of caller Param N ... Param 1 fp of caller ra of caller Locals and Temporaries
  • 94. So What? ● In your code generator, you must assign each local variable, parameter, and temporary variable its own location. ● These locations occur in a particular stack frame and are called fp-relative. Param N ... Param 1 Local 0 fp of caller ra of caller fp ● Parameters begin at address fp + 4 and grow upward. ● Locals and temporaries begin at address fp – 8 and grow downward ... Local M fp + 0 fp + 4 ... fp + 4N fp - 4 fp - 8 ... fp - 4 - 4M
  • 95. From Your Perspective Location* location = new Location(fpRelative, +4, locName);
  • 96. From Your Perspective Location* location = new Location(fpRelative, +4, locName);
  • 97. From Your Perspective Location* location = new Location(fpRelative, +4, locName); What variable does this refer to?
  • 98. And One More Thing... int globalVariable; int main() { globalVariable = 137; }
  • 99. And One More Thing... int globalVariable; int main() { globalVariable = 137; }
  • 100. And One More Thing... int globalVariable; int main() { globalVariable = 137; } Where is this stored?
  • 101. The Global Pointer ● MIPS also has a register called the global pointer (gp) that points to globally accessible storage. ● Memory pointed at by the global pointer is treated as an array of values that grows upward. ● You must choose an offset into this array for each global variable. Global Variable 0 Global Variable 1 ... Global Variable N gp gp + 0 gp + 4 ... gp + 4N
  • 102. From Your Perspective Location* global = new Location(gpRelative, +8, locName);
  • 103. From Your Perspective Location* global = new Location(gpRelative, +8, locName);
  • 104. Summary of Memory Layout ● Most details abstracted away by IR format. ● Remember: ● Parameters start at fp + 4 and grow upward. ● Locals start at fp – 8 and grow downward. ● Globals start at gp + 0 and grow upward. ● You will need to write code to assign variables to these locations.
  • 105. TAC for Objects, Part I class A { void fn(int x) { int y; y = x; } } int main() { A a; a.fn(137); }
  • 106. TAC for Objects, Part I class A { void fn(int x) { int y; y = x; } } int main() { A a; a.fn(137); } _A.fn: BeginFunc 4; y = x; EndFunc; main: BeginFunc 8; _t0 = 137; PushParam _t0; PushParam a; LCall _A.fn; PopParams 8; EndFunc;
  • 107. TAC for Objects, Part I class A { void fn(int x) { int y; y = x; } } int main() { A a; a.fn(137); } _A.fn: BeginFunc 4; y = x; EndFunc; main: BeginFunc 8; _t0 = 137; PushParam _t0; PushParam a; LCall _A.fn; PopParams 8; EndFunc;
  • 108. A Reminder: Object Layout Method 0 Field 0 Vtable* Vtable* ... Field N Field 0 ... Field N Field 0 ... Field M Method 1 ... Method K Method 0 Method 1 ... Method K Method 0 ... Method L
  • 109. TAC for Objects, Part II class A { int y; int z; void fn(int x) { y = x; x = z; } } int main() { A a; a.fn(137); }
  • 110. TAC for Objects, Part II class A { int y; int z; void fn(int x) { y = x; x = z; } } int main() { A a; a.fn(137); } _A.fn: BeginFunc 4; *(this + 4) = x; x = *(this + 8); EndFunc; main: BeginFunc 8; _t0 = 137; PushParam _t0; PushParam a; LCall _A.fn; PopParams 8; EndFunc;
  • 111. TAC for Objects, Part II class A { int y; int z; void fn(int x) { y = x; x = z; } } int main() { A a; a.fn(137); } _A.fn: BeginFunc 4; *(this + 4) = x; x = *(this + 8); EndFunc; main: BeginFunc 8; _t0 = 137; PushParam _t0; PushParam a; LCall _A.fn; PopParams 8; EndFunc;
  • 112. TAC for Objects, Part II class A { int y; int z; void fn(int x) { y = x; x = z; } } int main() { A a; a.fn(137); } _A.fn: BeginFunc 4; *(this + 4) = x; x = *(this + 8); EndFunc; main: BeginFunc 8; _t0 = 137; PushParam _t0; PushParam a; LCall _A.fn; PopParams 8; EndFunc;
  • 113. Memory Access in TAC ● Extend our simple assignments with memory accesses: ● var1 = *var2 ● var1 = *(var2 + constant) ● *var1 = var2 ● *(var1 + constant) = var2 ● You will need to translate field accesses into relative memory accesses.
  • 114. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); }
  • 115. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); }
  • 116. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); } _Base.hi: BeginFunc 4; _t0 = "Base"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Base = _Base.hi, ; _Derived.hi: BeginFunc 4; _t0 = "Derived"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Derived = _Derived.hi, ;
  • 117. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); } _Base.hi: BeginFunc 4; _t0 = "Base"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Base = _Base.hi, ; _Derived.hi: BeginFunc 4; _t0 = "Derived"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Derived = _Derived.hi, ;
  • 118. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); } _Base.hi: BeginFunc 4; _t0 = "Base"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Base = _Base.hi, ; _Derived.hi: BeginFunc 4; _t0 = "Derived"; PushParam _t0; LCall _PrintString; PopParams 4; EndFunc; Vtable Derived = _Derived.hi, ;
  • 119. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc;
  • 120. TAC for Objects, Part III class Base { void hi() { Print("Base"); } } class Derived extends Base{ void hi() { Print("Derived"); } } int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; What's going on here?
  • 121. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc;
  • 122. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; hi Derived Vtable Code for Derived.hi
  • 123. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi
  • 124. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi
  • 125. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b
  • 126. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b
  • 127. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4
  • 128. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4
  • 129. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 Param 1 4
  • 130. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 Param 1 4
  • 131. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 Param 1 4 (raw memory)
  • 132. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 Param 1 4 (raw memory)
  • 133. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory)
  • 134. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory)
  • 135. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory) Allocate Object
  • 136. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory) Allocate Object
  • 137. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory) Allocate Object
  • 138. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 (raw memory) Allocate Object
  • 139. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object
  • 140. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object
  • 141. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 142. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 143. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 144. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 145. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 146. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable
  • 147. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Allocate Object Set Vtable Load Function
  • 148. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Load Function Allocate Object Set Vtable
  • 149. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Param 1 Load Function Allocate Object Set Vtable
  • 150. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Param 1 Load Function Allocate Object Set Vtable
  • 151. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Param 1 Load Function Allocate Object Set Vtable
  • 152. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Load Function Allocate Object Set Vtable
  • 153. Dissecting TAC int main() { Base b; b = new Derived; b.hi(); } main: BeginFunc 20; _t0 = 4; PushParam _t0; b = LCall _Alloc; PopParams 4; _t1 = Derived; *b = _t1; _t2 = *b; _t3 = *_t2; PushParam b; ACall _t3; PopParams 4; EndFunc; fp of caller ra of caller hi Derived Vtable Code for Derived.hi _t0 _t1 _t2 _t3 b 4 VTable* Load Function Allocate Object Set Vtable
  • 154. OOP in TAC ● The address of an object's vtable can be referenced via the name assigned to the vtable (usually the object name). ● e.g. _t0 = Base; ● When creating objects, you must remember to set the object's vtable pointer or any method call will cause a crash at runtime. ● The ACall instruction can be used to call a method given a pointer to the first instruction.
  • 156. TAC Generation ● At this stage in compilation, we have ● an AST, ● annotated with scope information, ● and annotated with type information. ● To generate TAC for the program, we do (yet another) recursive tree traversal! ● Generate TAC for any subexpressions or substatements. ● Using the result, generate TAC for the overall expression.
  • 157. TAC Generation for Expressions ● Define a function cgen(expr) that generates TAC that computes an expression, stores it in a temporary variable, then hands back the name of that temporary. ● Define cgen directly for atomic expressions (constants, this, identifiers, etc.). ● Define cgen recursively for compound expressions (binary operators, function calls, etc.)
  • 158. cgen for Basic Expressions
  • 159. cgen for Basic Expressions cgen(k) = { // k is a constant Choose a new temporary t Emit( t = k ); Return t }
  • 160. cgen for Basic Expressions cgen(k) = { // k is a constant Choose a new temporary t Emit( t = k ); Return t } cgen(id) = { // id is an identifier Choose a new temporary t Emit( t = id ) Return t }
  • 161. cgen for Binary Operators
  • 162. cgen for Binary Operators cgen(e1 + e2 ) = { Choose a new temporary t Let t1 = cgen(e1 ) Let t2 = cgen(e2 ) Emit( t = t1 + t2 ) Return t }
  • 163. An Example cgen(5 + x) = { Choose a new temporary t Let t1 = cgen(5) Let t2 = cgen(x) Emit (t = t1 + t2 ) Return t }
  • 164. An Example cgen(5 + x) = { Choose a new temporary t Let t1 = { Choose a new temporary t Emit( t = 5 ) return t } Let t2 = cgen(x) Emit (t = t1 + t2 ) Return t }
  • 165. An Example cgen(5 + x) = { Choose a new temporary t Let t1 = { Choose a new temporary t Emit( t = 5 ) return t } Let t2 = { Choose a new temporary t Emit( t = x ) return t } Emit (t = t1 + t2 ) Return t }
  • 166. An Example cgen(5 + x) = { Choose a new temporary t Let t1 = { Choose a new temporary t Emit( t = 5 ) return t } Let t2 = { Choose a new temporary t Emit( t = x ) return t } Emit (t = t1 + t2 ) Return t } _t0 = 5 _t1 = x _t2 = _t0 + _t1
  • 167. cgen for Statements ● We can extend the cgen function to operate over statements as well. ● Unlike cgen for expressions, cgen for statements does not return the name of a temporary holding a value. ● (Why?)
  • 168. cgen for Simple Statements
  • 169. cgen for Simple Statements cgen(expr;) = { cgen(expr) }
  • 170. cgen for while loops
  • 171. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 172. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 173. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 174. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 175. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 176. cgen for while loops cgen(while (expr) stmt) = { Let Lbefore be a new label. Let Lafter be a new label. Emit( Lbefore :) Let t = cgen(expr) Emit( IfZ t Goto Lafter ) cgen(stmt) Emit( Goto Lbefore ) Emit( Lafter : ) }
  • 177. Next Time ● Intro to IR Optimization ● Basic Blocks ● Control-Flow Graphs ● Local Optimizations