Compiler Constructie - Activatierecords en Intermediaire Code

67
CompilerConstructie / Les 3 Activatierecords & Intermediaire Code Christophe Van Ginneken

Transcript of Compiler Constructie - Activatierecords en Intermediaire Code

Page 1: Compiler Constructie - Activatierecords en Intermediaire Code

CompilerConstructie / Les 3 Activatierecords & Intermediaire Code

Christophe Van Ginneken

Page 2: Compiler Constructie - Activatierecords en Intermediaire Code

les 3 in 1 [slide|minuut]

Front End Back End

(intermediaire code)*broncode machine code

mov edx,len ;message length Mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

CJUMP(LT,x,CONST(5), t, F) MEM(+(TEMP fp, CONST kn), S) SEQ(label z, s2(t, f)) CALL(NAME z, [sl,e1, e2,...,en])

... argument n

... argument 2 argument 1

statische link

locale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

locale variabelen ...

stack

vrij geheugen

heap

statische gegevens

code

CALL(NAME z, [sl,e1, e2,...,en])

procedure-oproep- en keer-terug-model oproep == activatie

activatierecord == stack frame

Page 3: Compiler Constructie - Activatierecords en Intermediaire Code

89 minuten te vullen ;-)

Page 4: Compiler Constructie - Activatierecords en Intermediaire Code

Proloog: jij && CC

Page 5: Compiler Constructie - Activatierecords en Intermediaire Code

• 38 jaar + vrouw & 2 kinderen

• (ex-)software consultant

• Open{Source,Mind}

!

• 1999 gbasic

• 2006 UML model “compiler”

• 2012 foo-lang

Proloog: jij && CC

Page 6: Compiler Constructie - Activatierecords en Intermediaire Code

Les 3 Activatierecords & Intermediaire Code

Page 7: Compiler Constructie - Activatierecords en Intermediaire Code

EN ➔ NL

Page 8: Compiler Constructie - Activatierecords en Intermediaire Code

EN ➔ NL

Page 9: Compiler Constructie - Activatierecords en Intermediaire Code

EN ➔ NL

Page 10: Compiler Constructie - Activatierecords en Intermediaire Code

EN ➔ NL

Intermediaire Code

Intermediaire Voorstelling

Page 11: Compiler Constructie - Activatierecords en Intermediaire Code

Les 3 Activatierecords & Intermediaire Code

Page 12: Compiler Constructie - Activatierecords en Intermediaire Code
Page 13: Compiler Constructie - Activatierecords en Intermediaire Code

Situering

Page 14: Compiler Constructie - Activatierecords en Intermediaire Code

Structuur van een compiler

Front End Back End

intermediaire code

fouten

broncode machine code

mov edx,len ;message length Mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel !mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel

Page 15: Compiler Constructie - Activatierecords en Intermediaire Code

Front End

Scanner & Parser

Semantisch Analyse &

IC generatie

tokens

fouten

broncode intermediaire code

CJUMP(LT,x,CONST(5), t, F) MEM(+(TEMP fp, CONST kn), S) SEQ(label z, s2(t, f) CALL(NAME z, [sl,e1, e2,...,en])

AST

Page 16: Compiler Constructie - Activatierecords en Intermediaire Code

CJUMP(LT,x,CONST(5), t, F) MEM(+(TEMP fp, CONST kn), S) SEQ(label z, s2(t, f) CALL(NAME z, [sl,e1, e2,...,en])

mov edx,len ;message length Mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel !mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel

Back End

Instructie Selectie &

Flow Analyse

Register Allocatie &

Code Emissie

fouten

intermediaire code

machine code

Optimizer Optimizer

{code generatie

Page 17: Compiler Constructie - Activatierecords en Intermediaire Code

Waarom intermediaire code ?

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

IC

Page 18: Compiler Constructie - Activatierecords en Intermediaire Code

Intermediaire code

• IC = “abstracte machine” code

• moet handig zijn

• genereren (door front-end)

• om te zetten (door back-end)

• eenvoudig en duidelijk

Page 19: Compiler Constructie - Activatierecords en Intermediaire Code

CJUMP(LT,x,CONST(5), t, F) MEM(+(TEMP fp, CONST kn), S) SEQ(label z, s2(t, f) CALL(NAME z, [sl,e1, e2,...,en])

!

Back End!

Front End

Situering IC

Semantisch Analyse &

IC generatie

Code Generatie

Page 20: Compiler Constructie - Activatierecords en Intermediaire Code

Activatierecords ?

Page 21: Compiler Constructie - Activatierecords en Intermediaire Code

broncode

Acties @

run-time

Page 22: Compiler Constructie - Activatierecords en Intermediaire Code

broncode

Acties @

run-timenamen data

objecten

Page 23: Compiler Constructie - Activatierecords en Intermediaire Code

Terminologieprogram sort(input, output);! var a : array [0..10] of integer;! ! procedure readarray;! var i : integer;! begin! for i := 1 to 9 do read(a[i])! end;! ! function partition(y, z: integer) : integer;! var i, j, x, v: integer;! begin ... end;! ! procedure quicksort(m, n : integer);! var a : integer;! begin! if( n > m ) then begin! a := partition(m, n);! quicksort(m, a-1);! quicksort(a+1, n);! end! end;! ! begin! a[0] := -9999; a[10] := 9999;! readarray;! quicksort(1,9);! end.

formele parameters

actuele parameters

procedure body

procedure naam

niet-lokale scope & geneste diepte

niveau 1

niveau 2

lokale scope

Page 24: Compiler Constructie - Activatierecords en Intermediaire Code

Procedure-verloop & levensduur

1. sequentieel: uitvoeringsstappen 2. procedureel: oproep - uitvoering - terugkeer

procedure A

procedure B

procedure A

procedure B

procedure A

procedure A

procedure A

procedure BXactivatie

recursief

Page 25: Compiler Constructie - Activatierecords en Intermediaire Code

Activatiesboomsort

readarray qs(1, 9)

part(1, 9) qs(1, 3) qs(5, 9)

part(1, 3) qs(1, 0) qs(2, 3) part(5, 9) qs(5, 5) qs(7, 9)

part(7, 9) qs(7, 7) qs(9, 9)part(2, 3) qs(2, 1) qs(3, 3)

Page 26: Compiler Constructie - Activatierecords en Intermediaire Code

Controlestack

sort

readarray qs(1, 9)

part(1, 9) qs(1, 3)

part(1, 3) qs(1, 0) qs(2, 3) sort

qs(1, 9)

qs(1, 3)

qs(2, 3)

Page 27: Compiler Constructie - Activatierecords en Intermediaire Code

Scope van een declaratie

• zelfde naam op meerdere plaatsen➔ scope regels: lokaal, niet-lokaal

• “de scope van x”➔ “de scope van de declaratie van naam x die van toepassing is voor dit voorkomen van x”

• compilatie ➔ symbolen tabel voorkomen ➔ declaratie

program sort(input, output);! var a : array [0..10] of integer;! ! procedure readarray;! var i : integer;! begin! for i := 1 to 9 do read(a[i])! end;!...! procedure quicksort(m, n : integer);! var a : integer;! begin! if( n > m ) then begin! a := partition(m, n);! quicksort(m, a-1);! quicksort(a+1, n);! end! end;!...

Page 28: Compiler Constructie - Activatierecords en Intermediaire Code

Naambinding

naam plaats waardeomgeving status

pi 100 0

binding

pi:=3.14;pi 100 3.14

statisch / in code dynamisch / tijdens uitvoering

definitie van een procedure activatie van de procedure

declaratie van een naam binding van de naam

scope van een declaratie levensduur van de binding

status

“l-value” “r-value”

Page 29: Compiler Constructie - Activatierecords en Intermediaire Code

Organisatie van geheugen

stack

vrij geheugen

heap

statische gegevens

code

(voorbeeld MIPS)

hoge adressen

lage adressen

controlestack met activatierecords

“malloc”

Page 30: Compiler Constructie - Activatierecords en Intermediaire Code

Activatierecords

• Stack Frame

• procedure oproep == “activatie”

• alle info gaat op de stack in een “frame”

• ligt bijna volledig vast bij compilatie

• conventionele layout

Page 31: Compiler Constructie - Activatierecords en Intermediaire Code

Activatierecords...

argument n ...

argument 2 argument 1

statische link

lokale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

locale variabelen ...

frame pointer

stack pointer

vorig frame

huidig frame

volgend frame

Page 32: Compiler Constructie - Activatierecords en Intermediaire Code

Intermezzo: Registers

• 32

• lokale variabelen ➔ snelheid

• caller-save / callee-save

• doorgeven van parameters (4, 6)

http://en.wikipedia.org/wiki/Processor_register

Page 33: Compiler Constructie - Activatierecords en Intermediaire Code

Parameters & terugkeeradres

• Calling convention

• Call-by-reference

!

• CALL()

• stack / register

... argument n

... argument 2 argument 1 statische link

lokale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

Page 34: Compiler Constructie - Activatierecords en Intermediaire Code

Variabelen in het activatierecord

• register !

• by-reference

• geneste procedures

• > 1 register

• rij

• veel

!

• “escapes”

... argument n

... argument 2 argument 1

statische link

lokale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

Page 35: Compiler Constructie - Activatierecords en Intermediaire Code

Statische link

• blok structuur

• statische link

• “display”

• “lambda lifting”

sort

qs(1, 9)

qs(1, 3)

part()

program sort(input, output);! var a : array [0..10] of integer;! ...! procedure quicksort(m, n : integer);! var i : integer;! function partition() : integer;! var i, j, x, v: integer;! begin ... a[x] ... end;! begin! if( n > m ) then begin! i := partition();! quicksort(m, i-1);! quicksort(i+1, n);! end! end;

Page 36: Compiler Constructie - Activatierecords en Intermediaire Code

Display

• blok structuur

• statische link

• “display”

• “lambda lifting”

sort

qs(1, 9)

qs(1, 3)

part()

program sort(input, output);! var a : array [0..10] of integer;! ...! procedure quicksort(m, n : integer);! var i : integer;! function partition() : integer;! var i, j, x, v: integer;! begin ... a[x] ... end;! begin! if( n > m ) then begin! i := partition();! quicksort(m, i-1);! quicksort(i+1, n);! end! end;

d[3]d[2]d[1]

Page 37: Compiler Constructie - Activatierecords en Intermediaire Code

Lambda Lifting

• blok structuur

• statische link

• “display”

• “lambda lifting”

program sort(input, output);! var a : array [0..10] of integer;! ! procedure readarray(a : array[0..10] of integer);! var i : integer;! begin! for i := 1 to 9 do read(a[i])! end;! ! function partition(y, z: integer,! a : array[0..10] of integer)! : integer;! var i, j, x, v: integer;! begin ... end;! ! procedure quicksort(m, n : integer,! a : array[0..10] of integer);! var i : integer;! begin! if( n > m ) then begin! i := partition(m,n,a);! quicksort(m,i-1,a);! quicksort(i+1,n,a);! end! end;! ! begin! a[0] := -9999; a[10] := 9999;! readarray(a);! quicksort(1,9,a);! end.

Page 38: Compiler Constructie - Activatierecords en Intermediaire Code

Intermezzo: Hogere orde functies

fun f(x) = let fun g(y) = x+y in g

end !val h = f(3) val j = f(4) !val z = h(5) (* 8 *) val w = j(7) (* 11 *)

Kan niet op een stack !

geneste functiesresultaat = functie+hogere orde functie

Page 39: Compiler Constructie - Activatierecords en Intermediaire Code

Intermediaire Code Generatie

Page 40: Compiler Constructie - Activatierecords en Intermediaire Code

IC generatie

• meerdere iteraties

• optimaliserende algoritmes één per één

• onderlinge afhankelijkheid

!

AST !

boom

IC !

sequentieel

Page 41: Compiler Constructie - Activatierecords en Intermediaire Code

IC statements

• SEQ( stm, stm )

• LABEL( label )

• JUMP( exp )

• CJUMP( op, exp, exp, label, label )

• MOVE( exp, exp )

• EXP( exp )

Page 42: Compiler Constructie - Activatierecords en Intermediaire Code

IC expressies

• BINOP( binop, exp, exp )

• MEM( exp )

• TEMP( temp )

• ESEQ( stm, exp )

• NAME( label )

• CONST( int )

• CALL( exp, args )

Page 43: Compiler Constructie - Activatierecords en Intermediaire Code

Intermezzo: Expressies & Statements

“Expressies” = “evalueert” tot een waarde 1 + 2 ⇒ 3

“Statements” = “doet iets” x = 2 doSomething() !

Pascal expliciet function, procedure C* verwaterd doSomething(x = 2) Haskell géén statements, alleen expressies

Page 44: Compiler Constructie - Activatierecords en Intermediaire Code

AST ➔ IC

• AST expressie

• 3 soorten IC expressies

• expressie 2 + 1 Ex

• statement procedure Nx

• boolse expr. a < b Cx

Page 45: Compiler Constructie - Activatierecords en Intermediaire Code

Enkelvoudige variabeleMEM(BINOP(PLUS, TEMP(fp), CONST(k)))MEM

BINOP

PLUS TEMP fp CONST k MEM(+(TEMP(fp), CONST(k)))

... argument n

... argument 2 argument 1

statische link

locale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

locale variabelen ...

stack

vrij geheugen

heap

statische gegevens

code

stack pointerframe pointer

frame pointer

TEMP(fp)

MEM(...)variabele

CONST(k)+

=

+ statische link

uitwerken

Page 46: Compiler Constructie - Activatierecords en Intermediaire Code

Rijenvar a,b : array[1..12] of integer begin b := a;

end;

{ int a[12], b[12]; b = a;

}

{ int a[12], *b; b = a;

}

let type intArray = array of int var a := intArray[12] of 0 var b := intArray[12] of 7

in b := a

end

X ➔

Pascal

C

Tiger

Page 47: Compiler Constructie - Activatierecords en Intermediaire Code

RijenMEM(+(MEM(e),BINOP(MUL,i,CONST(W)))

MEM

BINOP

MUL i CONST W

MEM e

+

locale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

a’= MEM(+(TEMP(fp),CONST(ka)))

MEM(a’)

stack

vrij geheugen

heap

statische gegevens

code

MEM(a’+(i*W))

a[i]

Page 48: Compiler Constructie - Activatierecords en Intermediaire Code

Integers & Strings

• Integer IntExp(i) ➔ CONST(i)

• Operaties OpExp(i,...) ➔ BINOP(i,...)

!

• Strings lengte + “rij” van karakters

e l l o h w o r l d11

Page 49: Compiler Constructie - Activatierecords en Intermediaire Code

Boolse expressiesa>b | c<d

SEQ

CJUMP

GT a zb null t

SEQ

CJUMP

LT c d null t

LABEL(z)

null f

if a > b goto lbl_true goto z z: if c < d goto lbl_true goto lbl_false

Page 50: Compiler Constructie - Activatierecords en Intermediaire Code

Intermezzo: Conversie van IC expr.

• a < b boolse expressie CJUMP(LT, a, b, ..., ...)

• var x = a < b expressie MOVE(TEMP(x), ? )

0

1

expressie boolse

statement

unCx

unNx

unEx

Page 51: Compiler Constructie - Activatierecords en Intermediaire Code

Conditionele Expressiesif e1 then e2 else e3

if e1 goto t goto f t: r = e2 goto join f: r = e3 join:

unCx unEx unEx

SEQ

CJUMP

“e1” ft

SEQ

LABEL(t) MOVE

TEMP(r) “e3”

SEQ

LABEL(f)MOVE

TEMP(r) “e2”

SEQ

SEQ

LABEL(join)

join

SEQ

join

SEQ

Page 52: Compiler Constructie - Activatierecords en Intermediaire Code

Lussen

test: if not(condition) goto done <body> goto test done:

for i := low to high do <body>

let var i := low in while i <= high do <body> i := i + 1

end

while

maxint !

Page 53: Compiler Constructie - Activatierecords en Intermediaire Code

Functieoproepen

CALL(NAME(lf), [sl,e1,e2,...,en])

f(a1,a2,...,an)

lf LABEL voor f sl statische link ex adres voor ax

Page 54: Compiler Constructie - Activatierecords en Intermediaire Code

Functiedefinitiesfunction partition(y, z: integer) : integer;! var i, j, x, v: integer;! begin ... end;

FunctionDec

Symbol(“partition”) FieldList

Symbol(“y”)

Symbol(“integer”)

Symbol(“z”)

Symbol(“integer”)

Symbol(“integer”) LetExp

VarDec

Symbol(“i”)

Symbol(“integer”)

... DecList

...

AST

IC fragment

PROC(label “partition”, <IC code for body>, <frame layout info>)

Page 55: Compiler Constructie - Activatierecords en Intermediaire Code

Proloog / Epiloog• proloog

• aankondiging begin functie

• label voor functie naam

• aanpassen stack pointer

• escaping argumenten + statische link bewaren niet-escaping in registers

• callee-save registers & terugkeer adres

• epiloog

• resultaat naar register

• callee-save registers

• terugzetten stack pointer

• terugkeer instructie

• aankondiging einde functie

exacte grootte frame

is pas gekend NA register

allocatie

Page 56: Compiler Constructie - Activatierecords en Intermediaire Code

Managed - Unmanaged

Page 57: Compiler Constructie - Activatierecords en Intermediaire Code

Managed - Unmanaged

• IC == Java Bytecode ?

• .NET Common Intermediate Language ?

• javac == Front-End ?

• java == Back-End ?

Page 58: Compiler Constructie - Activatierecords en Intermediaire Code
Page 59: Compiler Constructie - Activatierecords en Intermediaire Code
Page 60: Compiler Constructie - Activatierecords en Intermediaire Code

Managed - Unmanaged

• Java, .NET, Perl 6,...

• Heeft unmanaged nog zin ?

• Run-Time optimalisaties verder dan machine code optimalisaties in compiler ?

Page 61: Compiler Constructie - Activatierecords en Intermediaire Code

Managed - UnmanagedConclusies groepsgesprek:

• Intermediare Code staat nog ver van Java bytecode:bvb. veel details (exacte adressering, machineafhankelijke constanten,...) ontbreken nog

• Unmanaged code kan zeker nog betekenis behouden in kader van bvb. embedded systemen.

• Tendens naar managed is zeker waar te nemen en wordt bvb. ondersteund door processoren die rechtstreeks Java bytecode kunnen uitvoeren. De vraag wordt dan wel of deze dan nog verschillend van klassieke machine code kan/moet gezien worden.

Page 62: Compiler Constructie - Activatierecords en Intermediaire Code

Wat hebben we geleerd vandaag ?

COMPILEERPLEZIER

CC

Page 63: Compiler Constructie - Activatierecords en Intermediaire Code

Front End Back End

(intermediaire code)*broncode machine code

mov edx,len ;message length Mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

CJUMP(LT,x,CONST(5), t, F) MEM(+(TEMP fp, CONST kn), S) SEQ(label z, s2(t, f)) CALL(NAME z, [sl,e1, e2,...,en])

... argument n

... argument 2 argument 1

statische link

locale variabelen terugkeer adres

tijdelijke variabelen opgeslagen registers

argument n ...

argument 2 argument 1

statische link

locale variabelen ...

stack

vrij geheugen

heap

statische gegevens

code

CALL(NAME z, [sl,e1, e2,...,en])

procedure-oproep- en keer-terug-model oproep == activatie

activatierecord == stack frame

Page 64: Compiler Constructie - Activatierecords en Intermediaire Code
Page 65: Compiler Constructie - Activatierecords en Intermediaire Code

Optimale Code Generatie is een onbeslisbaar probleem

• Doe het zo goed mogelijk

• correct

• gebruik machine architectuur

• efficiënte uitvoering

Page 66: Compiler Constructie - Activatierecords en Intermediaire Code

EndOfPresentationException

Page 67: Compiler Constructie - Activatierecords en Intermediaire Code

Mogelijke Examenvragen

• Wat is een “standaard activatierecord-layout” en waarom zou je dit al dan niet volgen ?

• Kan het FP register niet eenvoudig vervangen worden door en/of gebaseerd worden op het SP register ? Bespreek aan de hand van het principe van activatierecords en een stack.

• Wat is een “dangling reference” ? Geef een voorbeeld hoe deze kan ontstaan vanuit een activatierecord.

• Wat zijn de beperkingen van activatierecords en een stack ?

• Waarom gebruik je wel of niet één of meerdere intermediare codes ? Wat zijn de voordelen/nadelen ?

• Welke eigenschappen vertoont een goede intermediaire code ?