Tim Sheard - PowerPoint PPT Presentation

About This Presentation
Title:

Tim Sheard

Description:

let val x = eval0 e env. in if x=1 then interpret0 s1 env else interpret0 s2 env end ... Code not very modular. What if we wanted to add 'print' or some other feature. ... – PowerPoint PPT presentation

Number of Views:25
Avg rating:3.0/5.0
Slides: 32
Provided by: markp77
Learn more at: http://web.cecs.pdx.edu
Category:
Tags: featurelet | sheard | tim

less

Transcript and Presenter's Notes

Title: Tim Sheard


1
Fundamentals of
Staged Computation
Lecture 4 Staging Interpreters
  • Tim Sheard
  • Oregon Graduate Institute

CSE 510 Section FSC Winter 2004
2
Languages and Calculation
  • The calculator language
  • datatype Exp
  • Var of string
  • Add of ExpExp
  • Mult of ExpExp
  • Const of int
  • Local of stringExpExp
  • The calculator program (un-staged)
  • fun calc term bindings
  • case term of
  • Var s gt lookup s bindings
  • Add(x,y) gt (calc x bindings) (calc y
    bindings)
  • Mult(x,y) gt (calc x bindings) (calc y
    bindings)
  • Const n gt n
  • Local(s,x,y) gt calc y ((s,calc x
    bindings)bindings)

3
Staged solution 1
  • Just add annoations
  • fun calc2 term bindings
  • case term of
  • Var s gt lookup s bindings
  • Add(x,y) gt lt (calc2 x bindings) (calc2 y
    bindings) gt
  • Mult(x,y) gt lt (calc2 x bindings) (calc2 y
    bindings) gt
  • Const n gt lift n
  • Local(s,x,y) gt calc2 y ((s,calc2 x
    bindings)bindings)

Note how the local let is inlined.
4
Results 1
  • val term
  • Local("x",Add(Const 3, Const 4),
  • Local("y",Mult(Const 6,Var "x"),
  • Add(Var "y",Const 12)))
  • val ans2 calc2 term
  • - ans2
  • val it
  • lt6 3 4 12gt
  • ltintgt

Note how the let structure has disappeared
5
Staged solution 2
  • fun calc3 term bindings
  • case term of
  • Var s gt lookup s bindings
  • Add(x,y) gt lt (calc3 x bindings) (calc3 y
    bindings) gt
  • Mult(x,y) gt lt (calc3 x bindings) (calc3 y
    bindings) gt
  • Const n gt lift n
  • Local(s,x,y) gt
  • ltlet val w (calc3 x bindings)
  • in (calc3 y ((s,ltwgt)bindings)) endgt
  • val ans3 calc3 term
  • val ans3
  • ltlet val a 3 4
  • val b 6 a
  • in b 12 endgt ltintgt

6
Why Stage Interpreters?
  • Interpreters are the classic example for using
    staging.
  • Interpreter takes a program, its data, and
    returns the result of applying the program to its
    data.
  • In transformer style
  • interp program -gt ltdatagt -gt ltresultgt
  • In generator style
  • interp program -gt ltdata -gt resultgt
  • Avoids the overhead of manipulating the data that
    represents the program each time it is applied.
  • Dramatic speedups are possible.
  • Abstract way of building a compiler.

7
Interpreter Characteristics
  • Recursive descent over the syntax of the
    language.
  • Ideally , the meaning of an expression in a
    language should depend only on the meaning of its
    constituent sub-expressions.
  • Structure of the syntax is what guides the
    interpreter.
  • One case for each kind of expression or
    statement
  • The use of an environment abstract datatype
  • encodes the meaning of variables
  • encodes the scope of binding constructs
  • The use of a value or semantic meaning type as
    the return type of the interpreter.

8
The Language
  • datatype Exp
  • Constant of int ( 5
    )
  • Variable of string ( x )
  • Minus of (Exp Exp) ( x - 5 )
  • Greater of (Exp Exp) ( x gt 1
    )
  • Times of (Exp Exp) ( x 4 )
  • datatype Com
  • Assign of (string Exp) ( x 1
    )
  • Seq of (Com Com) ( x 1 y
    2 )
  • Cond of (Exp Com Com) ( if x then x
    1 else y 0 )
  • While of (Exp Com) ( while xgt0 do x
    x - 1 )
  • Dec of (string Exp Com) ( Dec x 1 in x
    x - 1 )

9
Environment ADT
  • Lookup string -gt env -gt int
  • Set string -gt int -gt env -gt env
  • Ext string -gt int -gt env -gt env
  • Remove env -gt env
  • type env (string int) list
  • fun lookup x error ("variable not found
    "x)
  • lookup x ((y,v)zs) if xy then v else
    lookup x zs
  • fun set name v error ("name not found
    "name)
  • set name v ((z as (y,_))zs)
  • if namey then (y,v)zs else z(set name v
    zs)
  • fun ext nm v zs (nm,v)zs
  • fun remove (zzs) zs

10
Simple unstaged interpeters
  • Eval0 Exp -gt env -gt int
  • Value env -gt int
  • The meaning of an exp is a value
  • fun eval0 exp env
  • case exp of
  • Constant n gt n
  • Variable s gt lookup s env
  • Minus(x,y) gt let val a eval0 x env
  • val b eval0 y env
  • in a - b end
  • Greater(x,y) gt let val a eval0 x env
  • val b eval0 y env
  • in if a 'gt' b then 1 else 0 end
  • Times(x,y) gt let val a eval0 x env
  • val b eval0 y env in a
    b end

11
Interp0 Com -gt env -gt env
The meaning of a Com is an env transformer.
  • fun interpret0 stmt env
  • case stmt of
  • Assign(name,e) gt let val v eval0 e env in
    set name v env end
  • Seq(s1,s2) gt
  • let val env1 interpret0 s1 env
  • val env2 interpret0 s2 env1
  • in env2 end
  • If(e,s1,s2) gt
  • let val x eval0 e env
  • in if x1 then interpret0 s1 env else
    interpret0 s2 env end
  • While(e,body) gt
  • let val v eval0 e env
  • in if v0
  • then env
  • else interpret0 (While(e,body))(interpret
    0 body env) end
  • Declare(nm,e,stmt) gt
  • let val v eval0 e env
  • val env1 ext nm v env
  • in remove(interpret0 stmt env1) end

12
Getting ready to stage
  • What is the structure of the source language?
  • Exp and Com
  • What is the structure of the target language?
  • MetaML with let and operations on environments
    and arithmetic
  • What are the staging issues?
  • What is completely known at compile-time
  • Exp, Com, part of the environment (the names but
    not the values)
  • How do I connect the structure of the source and
    target languages.

13
Staging (Binding time) improvements
  • type env
  • (string int) list
  • Note the string and the spine of the list are
    known, but the ints are not.
  • Separate env into two parts. An index (the string
    and its position in the spine), and a stack (the
    ints)
  • type location int
  • type index string list
  • type stack int list
  • eval1 Exp -gt index -gt
  • stack -gt int
  • interp1 Com -gt index -gt
  • stack -gt stack

14
Recoding up environments
  • type location int
  • type index string list
  • type stack int list
  • pos string -gt index -gt location
  • get location -gt stack -gt value
  • put location -gt value -gt stack -gt stack
  • fun get 1 (xxs) x
  • get 0 _ error "No value at index 0."
  • get n (xxs) get (n-1) xs
  • get n error "Stack is empty"
  • fun put 1 v (xxs) (vxs)
  • put 0 v _ error "No value at index 0."
  • put n v (xxs) x (put (n-1) v xs)
  • put n v error "Stack is empty"

15
eval1
  • fun eval1 exp index stack
  • case exp of
  • Constant n gt n
  • Variable s gt get (pos s index) stack
  • Minus(x,y) gt let val a eval1 x index stack
  • val b eval1 y index stack
  • in a - b end
  • Greater(x,y) gt let val a eval1 x index stack
  • val b eval1 y index stack
  • in if a 'gt' b then 1 else 0 end
  • Times(x,y) gt let val a eval1 x index stack
  • val b eval1 y index stack
  • in a b end

16
interp1
  • fun interp1 stmt index stack
  • case stmt of
  • Assign(name,e) gt
  • let val v eval1 e index stack
  • val loc pos name index
  • in put loc v stack end
  • Seq(s1,s2) gt
  • let val stack1 interp1 s1 index stack
  • val stack2 interp1 s2 index stack1
  • in stack2 end
  • If(e,s1,s2) gt
  • let val x eval1 e index stack
  • in if x1
  • then interp1 s1 index stack
  • else interp1 s2 index stack
  • end

17
Interp1 (cont.)
  • fun interp1 stmt index stack
  • case stmt of
  • . . .
  • While(e,body) gt
  • let val v eval1 e index stack
  • in if v0
  • then stack
  • else interp1 (While(e,body)) index
  • (interp1 body index stack)
  • end
  • Declare(nm,e,stmt) gt
  • let val v eval1 e index stack
  • val stack1 v stack
  • in tl (interp1 stmt (nmindex) stack1) end

18
Adding staging annotations
  • fun eval2 exp index stack
  • case exp of
  • Constant n gt lift n
  • Variable s gt ltget (lift (pos s index))
    stackgt
  • Minus(x,y) gt ltlet val a (eval2 x index
    stack)
  • val b (eval2 y index
    stack)
  • in a - b endgt
  • Greater(x,y) gt ltlet val a (eval2 x index
    stack)
  • val b (eval2 y index
    stack)
  • in if a 'gt' b then 1 else 0
    endgt
  • Times(x,y) gt ltlet val a (eval2 x index
    stack)
  • val b (eval2 y index
    stack)
  • in a b endgt

19
interp2
  • fun interp2 stmt index stack
  • case stmt of
  • Assign(name,e) gt
  • ltlet val v (eval2 e index stack)
  • in put (lift (pos name index)) v stack endgt
  • Seq(s1,s2) gt
  • ltlet val stack1 (interp2 s1 index stack)
  • val stack2 (interp2 s2 index ltstack1gt)
  • in stack2 endgt
  • If(e,s1,s2) gt
  • ltlet val x (eval2 e index stack)
  • in if x1
  • then (interp2 s1 index stack)
  • else (interp2 s2 index stack)
  • endgt

20
Interp2 (cont)
  • fun interp2 stmt index stack
  • case stmt of
  • . . .
  • While(e,body) gt
  • ltlet val v (eval2 e index stack)
  • in if v0
  • then stack
  • else (interp2 (While(e,body)) index
  • (interp2 body index stack))
  • endgt
  • Declare(nm,e,stmt) gt
  • ltlet val v (eval2 e index stack)
  • val stack1 v stack
  • in tl (interp2 stmt (nmindex) ltstack1gt)
    endgt

21
Using the staged code
  • val s0
  • Declare("x",Constant 150,
  • Declare("y",Constant 200,
  • Seq(Assign("x",Minus(Variable "x",Constant
    1)),
  • Assign("y",Minus(Variable "y",Constant
    1)))))
  • val ans2 ltfn stack gt (interp2 s0 ltstackgt)gt

22
Results
  • - val ans2
  • lt(fn a gt
  • let val b 150 val c b a
  • in tl (let val d 200 val e d c
  • in tl (let val f get 1 e
  • val g 1
  • val h f - g
  • val i put 1 h e
  • val j get 0 i
  • val k 1
  • val l j - k
  • val m put 0 l i
  • in m end) end) end)gt
  • ltint list -gt int listgt

23
Beware
  • val s1
  • Declare("x",Constant 150,
  • Declare("y",Constant 200,
  • While(Greater(Variable "x",Constant 0),
  • Seq(Assign("x",Minus(Variable
    "x",Constant 1)),
  • Assign("y",Minus(Variable
    "y",Constant 1))))))
  • val ans3 ltfn stack gt (interp2 s1
    ltstackgt)gt

fun interp2 stmt index stack case stmt of . .
. While(e,body) gt ltlet val v (eval2 e
index stack) in if v0 then
stack else (interp2 (While(e,body))
index (interp2 body index
stack)) endgt
24
Compare
  • While(e,body) gt
  • ltlet fun loop stk0
  • let val v (eval2 e index ltstk0gt)
  • in if v0
  • then stk0
  • else let val stk1 (interp2
    body index ltstk0gt)
  • in loop stk1 end
  • end
  • in loop stack endgt
  • While(e,body) gt
  • ltlet val v (eval2 e index stack)
  • in if v0
  • then stack
  • else (interp2 (While(e,body)) index
  • (interp2 body index stack))
  • endgt

25
Finally, results!
  • - val ans3
  • lt(fn a gt
  • tl
  • (tl
  • (let fun b c
  • let val d get 1 c
  • val e if d 'gt' 0 then 1 else 0
  • in if e 0
  • then c
  • else let val f get 1 c
  • val g f - 1
  • val h put 1 g c
  • val i get 0 h
  • val j i - 1
  • val k put 0 j h
  • in b k end end
  • in b (200 150 a) end)))gt
  • ltint list -gt int listgt

26
Generate and optimize vsGenerate optimal code
  • - dotprod' 3 0,1,2
  • val it
  • lt(fn a gt (0 nth 0 a)
  • (1 nth 1 a)
  • (2 nth 2 a) 0)gt
  • Rules
  • 1x x
  • 0x 0
  • x0 x

ltfn a gt 0 (nth 1 a)
(2 nth 2 a)gt
27
Writing an optimizer is not easy!
  • ( rule 1 x0 x )
  • ( rule 2 0x 0 )
  • ( rule 3 1x x )
  • fun opt ltfn x gt (g ltxgt) 0gt opt ltfn y gt (g
    ltygt)gt
  • opt ltfn x gt (g ltxgt) 0 (h ltxgt)gt
  • opt ltfn y gt (g ltygt) (h ltygt)gt
  • opt ltfn x gt 0 (g ltxgt)gt opt ltfn y gt (g
    ltygt)gt
  • opt ltfn x gt 0 (g ltxgt) (h ltxgt)gt opt
    ltfn y gt (h ltygt)gt
  • opt ltfn x gt (e ltxgt) 0 (g ltxgt)gt opt
    ltfn y gt (e ltygt)gt
  • opt ltfn x gt (e ltxgt) 0 (g ltxgt) (h
    ltxgt)gt
  • opt ltfn y gt (e ltygt) (h ltygt)gt
  • opt ltfn x gt 1 (g ltxgt) (h ltxgt)gt
  • opt ltfn y gt (g ltygt) (h ltygt)gt
  • opt ltfn x gt (e ltxgt) 1 (g ltxgt)gt
  • opt ltfn y gt (e ltygt) (g ltygt)gt
  • opt ltfn x gt (e ltxgt) 1 (g ltxgt) (h
    ltxgt)gt
  • opt ltfn y gt (e ltygt) (g ltygt) (h
    ltygt)gt
  • opt x x

28
Optimal Generation vs Post Generation Optimizing
  • Complexity from several sources.
  • Walking deep over the tree
  • Complexity of pattern matching against code (vs
    matching against values)
  • Dealing with binding occurrences
  • Optimal generation can be directed by values at
    generation time.

29
Better Approach
  • fun dpopt n ys lt0gt
  • dpopt n 0 ys lt0gt
  • dpopt n 1 ys ltnth (lift n) ysgt
  • dpopt n x ys lt (lift x) (nth (lift n)
    ys) gt
  • dpopt n (0xs) ys lt(dpopt (n1) xs ys)gt
  • dpopt n (1xs) ys
  • lt(nth (lift n) ys) (dpopt (n1) xs ys)gt
  • dpopt n (xxs) ys
  • lt((lift x) (nth (lift n) ys)) (dpopt
    (n1) xs ys)gt
  • fun gen n xs ltfn ys gt (dpopt n xs ltysgt)gt
  • val ans0 gen 5 2,0,1,0,4
  • lt(fn a gt 2 nth 5 a nth 7 a 4 nth
    9 a)gt

30
Conclusion
  • Interpreters need binding time improvements
  • Split partially static data structures into two
    parts. E.g. Env index stack
  • Split recursion so that it depends only on
    structure of the data being interpreted
  • Use transformer style for easy construction
  • Let lifting makes code look nice.

31
Things to think about
  • Code not very modular
  • What if we wanted to add print or some other
    feature.
Write a Comment
User Comments (0)
About PowerShow.com