Title: Activation Records
1Activation Records
- Mooly Sagiv
- msagiv_at_post.tau.ac.il
- Schrierber 317
- 03-640-7606
- Wed 1000-1200
- html//www.math.tau.ac.il/msagiv/courses/wcc01.ht
ml - Chapter 6
2Basic Compiler Phases
Source program (string)
lexical analysis
Tokens
syntax analysis
Abstract syntax tree
semantic analysis
Frame
Translate
Intermediate representation
Instruction selection
Assembly
Register Allocation
Fin. Assembly
3Example factorial
let function nfactor (n int) int
if n 0 then 1 else n
nfactor(n-1) in nfactor(10) end
4IR for Main
/ prologue of main starts with l1 / / body of
main / MOV(TEMP(RV), CALL(NAME(l2),
ExpList(CONST(10), null / next
argument /))) / epilogue of main /
5IR for nfact
/ Prologue of nfunc starts with l2 / / body of
nfunc / MOV(TEMP(RV), ESEQ(SEQ(
CJUMP(, n, CONST(0), NAME(l3), NAME(l4)),
LABEL(l3) / then-clause /,
MOV(TEMP(t1), CONST(1)),
JUMP(NAME(l5)), LABEL(l4), /
else-clause / MOV(TEMP(t1),
BINOP(MUL, n,
CALL(NAME(l2),
ExpList(BINOP(MINUS, n,
CONST(1)),
null / next argument /)))),
LABEL(l5)), TEMP(t1))) /
epilogue of nfunc /
Where to store the value of n?
6Pseudo IR for nfact
/ Prologue of nfunc starts with l2 / PUSH(TEMP
t128) MOVE(TEMP t128, TEMP t104) / body of nfunc
/ MOV(TEMP(RV), ESEQ(SEQ(
CJUMP(, TEMP t128, CONST(0), NAME(l3),
NAME(l4)), LABEL(l3) / then-clause
/, MOV(TEMP(t1), CONST(1)),
JUMP(NAME(l5)), LABEL(l4), /
else-clause / MOV(TEMP(t1),
BINOP(MUL, TEMP t128,
CALL(NAME(l2),
ExpList(BINOP(MINUS, TEMP
t128, CONST(1)),
null / next argument /)))),
LABEL(l5)),
TEMP(t1))) / epilogue of nfunc / POP(TEMP t128)
7 .globl nfactor .ent nfactor
nfactor_framesize40 .frame
sp,nfactor_framesize,31 nfactor addiu
sp,sp,-nfactor_framesize L6 sw
2,0nfactor_framesize(sp) or
25,0,4 save arg1
or 24,0,31 sw 24,-4nfactor_framesi
ze(sp) sw 30,-8nfactor_framesize(sp)
beq 25,0,L0 n
0? L1 or 30,0,25 lw
24,0nfactor_framesize(sp) or
2,0,24 addi 25,25,-1
n-1 or 4,0,25
arg1 n-1 jal nfactor or
25,0,2 r25 (n-1)!
mult 30,25
r30n(n-1)! mflo 30
L2 or 2,0,30
lw 30,-nfactor_framesize(sp) or
31,0,30 lw 30,-8nfactor_framesize(
sp) b L5 L0 addi 30,0,1
b L2 L5 addiu
sp,sp,nfactor_framesize j 31
.end nfactor
8Outline of this lecture
- Properties of variables
- Stack Frames
- The Frame Pointer and Frame Size
- The Static Pointers and Nesting Levels
- Machine Architectures
- Parameter Passing and return Address
- Limitations
- Memory Management in the Tiger Language
- Summary
9Compile-Time Information on Variables
- Name
- Type
- Scope
- when is it recognized
- Duration
- when does its value exist
- Size
- How many bytes are required at runtime
- Address
- Fixed
- Relative
- Dynamic
10Stack Frames
- Allocate a separate space for every procedure
incarnation - Relative addresses
- Provides a simple mean to achieve modularity
- Naturally supports recursion
- Efficient memory allocation policy
- Low overhead
- Hardware support may be available
- LIFO policy
- Not a pure stack
- Non local references
- Updated using arithmetic
11A Typical Stack Frame
previous frame
argument 2
argument 1
outgoing parameters
static link
locals
return address
temporaries
current frame
saved registers
argument 2
outgoing parameters
argument 1
static link
next frame
12Pseudo IR for nfact
LABEL L2 MOVE(TEMP SP, BINOP(MINUS, TEMP SP,
CONST framesize))) MOVE(MEM(BINOP(MINUS, TEMP
FP, CONST k)), TEMP t128) MOVE(TEMP t128, TEMP
t104) MOV(TEMP(RV), ESEQ(SEQ(
CJUMP(, TEMP t128, CONST(0), NAME(l3),
NAME(l4)), LABEL(l3) / then-clause
/, MOV(TEMP(t1), CONST(1)),
JUMP(NAME(l5)), LABEL(l4), /
else-clause / MOV(TEMP(t1),
BINOP(MUL, TEMP t128,
CALL(NAME(l2),
ExpList(BINOP(MINUS, TEMP
t128, CONST(1)),
null / next argument /)))),
LABEL(l5)),
TEMP(t1))) MOVE(TEMP t128, MEM(BINOP(MINUS, TEMP
FP, CONST k))) MOVE(TEMP SP, BINOP(PLUS, TEMP SP,
CONST framesize)))
13Pascal 80386 Frame
argument 1
previous frame
argument 2
static link
return address
previous bp
locals
temporaries
current frame
saved registers
argument 1
outgoing parameters
argument 2
static link
next frame
14Summary thus far
- The structure of the stack frame may depend on
- Machine
- Architecture
- Programming language
- Compiler Conventions
- The stack is updated by
- Emitted compiler instructions
- Designated hardware instructions
15The Frame Pointer
- The caller
- the calling routine
- The callee
- the called routine
- caller responsibilities
- Calculate arguments and save in the stack
- Store static link
- call instruction M--SP RA PC
callee - callee responsibilities
- FP SP
- SP SP - frame-size
- Why use both SP and FP?
16Variable Length Frame Size
- C allows allocating objects of unbounded size in
the heapvoid p() int i char p
scanf(d, i) p (char )
alloca(isizeof(int)) - Some versions of Pascal allows conformant array
value parameters
17Pascal Conformant Arrays
program foo const max 4 var m1, m2, m3
array 1..max, 1..max of integer var i, j
integer procedure mult(a, b array 1..l, 1..l
of integer var carray 1..l,
1..l of integer)) var i, j, k integer
begin mult for i 1 to l do
for j 1 to l do begin
ci, j 0 for k 1 to l
do ci, j ci, j ai,
k bk, j
end end mult begin foo
mult(m1, m2, m3) end. foo
18Supporting Static Scoping
- References to non-local variables
- Language rules
- No nesting of functions
- C, C, Java
- Non-local references are bounded to the most
recently enclosed declared procedure and die
when the procedure end - Algol, Pascal, Tiger
- Simplest implementation
- Pass the stack pointer as an extra argument to
functions - Scope rules guarantee that this can be done
- Generate code to traverse the frames
19/ prologue starts at t_main / MOVE(TEMP
t103, CALL(NAME fun1,
TEMP FP)) / epilogue /
let function fun1()int let var
d0 function fun2()int
d1 in fun2() end in
fun1() end
/ prologue starts at fun1 / ESEQ( MOVE(
MEM(BINOP(PLUS, TEMP FP, CONST -4)), CONST
0), CALL(NAME fun2, TEMP FP))) / epilogue /
/ prologue starts at fun2 / BINOP(PLUS,
MEM( BINOP(PLUS,
MEM(BINOP(PLUS, TEMP FP,
CONST 0)), CONST
-4)), CONST 1), / epilogue /
20Realistic Tiger Example
tree
type tree key string, left tree, right
tree function pretyprint(tree tree) string
let var output function write(s
string) output concat(output, s)
function show(n int, t tree) let
function indent(s string) (for i
1 to n do write( ) output
concat(output, s)) in if t nil then
indent(.) else (indent(t.key)
show(n1, t.left) show(n1,
t.right)) end show in show(0, tree)
output end
main
link
pretyprint
n
t
link
show
s
link
indent
21Realistic Tiger Example
tree
type tree key string, left tree, right
tree function pretyprint(tree tree) string
let var output function write(s
string) output concat(output, s)
function show(n int, t tree) let
function indent(s string) (for i
1 to n do write( ) output
concat(output, s)) in if t nil then
indent(.) else (indent(t.key)
show(n1, t.left) show(n1,
t.right)) end show in show(0, tree)
output end
main
link
pretyprint
n
t
link
n
show
t
link
show
22Other Implementations of Static Scoping
- Display
- An array of static links
- di is static link nesting level i
- Can be stored in the stack
- lambda-lifting
- Pass non-local variables as extra parameters
23Machine Registers
- Every year
- CPUs are improving by 50-60
- Main memory speed is improving 10
- Machine registers allow efficient accesses
- Utilized by the compiler
- Other memory units exist
- Cache
24RISC vs. CISC Machines
Feature RISC CISC
Registers ?32 6, 8, 16
Register Classes One Some
Arithmetic Operands Registers MemoryRegisters
Instructions 3-addr 2-addr
Addressing Modes r Mrc (l,s) several
Instruction Length 32 bits Variable
Side-effects None Some
Instruction-Cost Uniform Varied
25Caller-save vs. Callee-Save Registers
- Compile every procedure separately
- Partition the machine registers into two sets
- Caller-Save registers
- Callee-Save registers
- Hardware support may be available
- Register allocation algorithm will be described
later
26Parameter Passing
- 1960s
- In memory
- No recursion is allowed
- 1970s
- In stack
- 1980s
- In registers
- First k parameters are passed in registers (k4
or k6) - Where is time saved?
- Most procedures are leaf procedures
- Interprocedural register allocation
- Many of the registers may be dead before
another invocation - Register windows are allocated in some
architectures per call (e.g., sun Sparc)
27Modern Architectures
- return-address
- also normally saved in a register on a call
- a non leaf procedure saves this value on the
stack - No stack support in the hardware
- function-result
- Normally saved in a register on a call
- A non leaf procedure saves this value on the stack
28Limitations
- The compiler may be forced to store a value on a
stack instead of registers - The stack may not suffice to handle some language
features
29Frame-Resident Variables
- A variable x cannot be stored in register when
- x is passed by reference
- Address of x is taken (x)
- is addressed via pointer arithmetic on the
stack-frame (C varags) - x is accessed from a nested procedure
- The value is too big to fit into a single
register - The variable is an array
- The register of x is needed for other purposes
- Too many local variables
- An escape variable
- Passed by reference
- Address is taken
- Addressed via pointer arithmetic on the
stack-frame - Accessed from a nested procedure
30type tree key string, left tree, right
tree function pretyprint(tree tree) string
let var output function write(s
string) output concat(output, s)
function show(n int, t tree) let
function indent(s string) (for i
1 to n do write( ) output
concat(output, s)) in if t nil then
indent(.) else (indent(t.key)
show(n1, t.left) show(n1,
t.right)) end show in show(0, tree)
output end
31Limitations of Stack Frames
- A local variable of P cannot be stored in the
activation record of P if its duration exceeds
the duration of P - Example 1 Static variables in C (own variables
in Algol)void p(int x) static int y 6
y x - Example 2 Features of the C languageint f()
int x return x - Example 3 Dynamic allocationint f() return
(int ) malloc(sizeof(int))
32Higher Order Functions
int ()() f(int x) int g(int y)
return x y return g int
(h)() f(3) int (j)() f(4) int z
h(5) int w j(7)
fun f(x) let fun g(y) x y in g
end val h f(3) val j f(4) val z h(5) val
w j(7)
33Memory Management in the Tiger Compiler
- Isolate architecture dependent parts in a
separate module - Frame
- Isolate programming language dependent parts in a
separate module - Translate
- Isolate labels and register temporaries in a
separate module - Temp
34Two Layers of Abstraction
semant.c
translateh
translate.c
frame.h
temp.h
mipsframe.c
temp.c
35Temporaries and Labels
/ temp.h / typedef struct Temp_temp_
Temp_temp Temp_temp Temp_newtemp(void) typedef
struct Temp_tempList_ Temp_tempList struct
Temp_tempList_ Temp\_temp head Temp_tempList
tail Temp_tempList Temp_TempList(Temp_temp h,
Temp_tempList t) typedef S_symbol
Temp_label Temp_label Temp_newlabel(void) Temp_l
abel Temp_namedlabel(string name) string
Temp_labelstring(Temp_label s)
36Example frame invocations (translate.c)
- When a function g(x, y, z) where x escapes is
encounteredf F_newFrame (g,
U_BoolList(TRUE,
U_BoolList(FALSE,
U_BoolList(FALSE, NULL)))) - When a local variable v is encountereda
F_allocLocal(f, escape) - Causes to reserve a space for v in f or in
register - When a variable is accessed F_Exp(a, access)
returns the generated code - access is the code for computing the static link
- Ignored when f
37Hidden in ?frame.c
- Word size
- The location of the formals
- Machine instructions to implement
shift-of-view' (prologue) - The number of locals allocated so far
- The label in which the machine code starts
38The frame interface
/ frame.h / typedef struct F_frame_
F_Frame typedef struct F_access_ F_access
typedef struct F_accessList_ F_accessList stru
ct F_accessList_ F_access head F_accessList
tail F_frame F_newFrame(Temp_label name,
U_boolList formals) F_label F_name(F_frame
d) F_accessList F_formals(F_frame f) F_access
f_allocLocal(F_frame f, bool escape) Temp_temp
F_FP(void) extern const int F_wordsize T_exp
F_Exp(F_access acc, T_EXP static_link)
39MIPS frame implementation
/ frame.c / include temp.h include
frame.h struct F_frame_ Temp_label name
int formalsCount
int localsCount
F_accessList formals
typedef enum inFrame, inReg
F_access_kind struct F_access
F_access_kind kind union int offset /
frame offset / Temp_temp reg / register
/ u
F_access F_allocLocal(F_frame f,
bool escape)
assert(f) if (escape) return
F_allocInFrame(-1
F_wordSize
f?localsCount) else return F_allocInRegister()
40The Frames in Different Architectures
g(x, y, z) where x escapes
Pentium MIPS Sparc
InFrame(8) InFrame(0) InFrame(68)
InFrame(12) InReg(t157) InReg(t157)
InFrame(16) InReg(t158) InReg(t158)
Msp0?fp fp ?sp sp ?sp-K sp ?sp-K MspK0 ?r2 t157 ?r4 t158 ?r5 save sp, -K, sp Mfp68?i0 t157?i1 t158?i2
x
y
z
View Change
41The Need for Register Copies
function m(x int, y int) (h(y, y) h(x, x))
42Nesting Blocks in Tiger
function f() let var v 6 in
print(v) let var v 7
in print(v) end
print(v) let var v 8
in print(v) end
print(v) end
43Managing Static Links
- Implemented in the translate module (translate.c)
- The static pointer is passed as extra argument
- For every function records the frame of function
in which it is defined - Generate instruction sequences for non-local
references
44Summary
- Stack frames provide a simple compile-time memory
management - Locality of references is supported
- Can be complex
- What about procedure parameters?
- Memory allocation is one of most interesting areas