scoped dynamic rewrite rules

23
Scoped Dynamic Rewrite Rules Program Transformation 2004–2005 Eelco Visser Institute of Information & Computing Sciences Utrecht University, The Netherlands February 29, 2005

Upload: eelco-visser

Post on 05-Dec-2014

399 views

Category:

Technology


0 download

DESCRIPTION

A couple of basic applications of dynamic rewrite rules in Stratego: constant propagation, variable renaming, function inlining, common-subexpression elimination

TRANSCRIPT

Page 1: Scoped dynamic rewrite rules

Scoped Dynamic Rewrite RulesProgram Transformation 2004–2005

Eelco Visser

Institute of Information & Computing SciencesUtrecht University,The Netherlands

February 29, 2005

Page 2: Scoped dynamic rewrite rules

Limitations of Rewriting

Lack of control over application of rules

Non-terminationNon-confluenceCommon solution: encode with extra rulesStratego: programmable rewriting strategies

Context-free nature of rewrite rules

InliningBound variable renamingDead code eliminationCommon solution: encode with extra rulesStratego: scoped dynamic rewrite rules

For details see paper:

Program Transformation with Scoped Dynamic Rewrite Rules

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 3: Scoped dynamic rewrite rules

Limitations of Rewriting

Lack of control over application of rules

Non-terminationNon-confluenceCommon solution: encode with extra rulesStratego: programmable rewriting strategies

Context-free nature of rewrite rules

InliningBound variable renamingDead code eliminationCommon solution: encode with extra rulesStratego: scoped dynamic rewrite rules

For details see paper:

Program Transformation with Scoped Dynamic Rewrite Rules

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 4: Scoped dynamic rewrite rules

Contextual Rules

UnfoldCall :|[ let function f(x) = e1 in e2[f(e3)] end ]| ->|[ let function f(x) = e1

in e2[let var x := e3 in e1 end] end ]|

Implementation

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Problems

Local traversal

One rule at a time

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 5: Scoped dynamic rewrite rules

Contextual Rules

UnfoldCall :|[ let function f(x) = e1 in e2[f(e3)] end ]| ->|[ let function f(x) = e1

in e2[let var x := e3 in e1 end] end ]|

Implementation

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Problems

Local traversal

One rule at a time

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 6: Scoped dynamic rewrite rules

Contextual Rules

UnfoldCall :|[ let function f(x) = e1 in e2[f(e3)] end ]| ->|[ let function f(x) = e1

in e2[let var x := e3 in e1 end] end ]|

Implementation

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Problems

Local traversal

One rule at a time

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 7: Scoped dynamic rewrite rules

Idea

Contextual Rule

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Observation: Local rule inherits variable bindings from context

Dynamic Rule

define-unfold =?|[ let function f(x) = e1 in e2 end ]|; rules(

UnfoldCall : |[f(e3)]| -> |[let var x := e3 in e1 end]|)

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 8: Scoped dynamic rewrite rules

Idea

Contextual Rule

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Observation: Local rule inherits variable bindings from context

Dynamic Rule

define-unfold =?|[ let function f(x) = e1 in e2 end ]|; rules(

UnfoldCall : |[f(e3)]| -> |[let var x := e3 in e1 end]|)

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 9: Scoped dynamic rewrite rules

Idea

Contextual Rule

UnfoldCall :|[ let function f(x) = e1 in e2 end ]| ->|[ let function f(x) = e1 in e2’ end ]|where <oncetd({e3 :

(|[f(e3)]| -> |[let var x := e3 in e1 end]|)})> e2 => e2’

Observation: Local rule inherits variable bindings from context

Dynamic Rule

define-unfold =?|[ let function f(x) = e1 in e2 end ]|; rules(

UnfoldCall : |[f(e3)]| -> |[let var x := e3 in e1 end]|)

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 10: Scoped dynamic rewrite rules

Dynamic Rewrite Rules

Properties

Defined at run-time

Multiple rules with the same name can be defined

Rules can be redefined

Rules can be undefined

The scope in which a rule is applicable can be limited

Scope labels provide fine grained control over the scope inwhich a rule is defined

Rules can be extended to rewrite to multiple right-hand sides

Rule sets can be forked and later joined again withintersection or union operations

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 11: Scoped dynamic rewrite rules

Example: Constant Propagation

(b := 1;c := b + 3;b := b + 1;b := z + b;a := b + c)

b -> 1b -> 1, c -> 4b -> 2, c -> 4b-, c -> 4b-, c -> 4, a-

⇒(b := 1;c := 4;b := 2;b := z + 2;a := b + 4)

prop-const =PropConst<+ prop-const-assign<+ (all(prop-const); try(EvalBinOp <+ EvalRelOp))

prop-const-assign =|[ x := <prop-const => e> ]|; if <is-value> e then

rules( PropConst : |[ x ]| -> |[ e ]| )elserules( PropConst :- |[ x ]| ) end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 12: Scoped dynamic rewrite rules

Example: Constant Propagation

(b := 1;c := b + 3;b := b + 1;b := z + b;a := b + c)

b -> 1b -> 1, c -> 4b -> 2, c -> 4b-, c -> 4b-, c -> 4, a-

⇒(b := 1;c := 4;b := 2;b := z + 2;a := b + 4)

prop-const =PropConst<+ prop-const-assign<+ (all(prop-const); try(EvalBinOp <+ EvalRelOp))

prop-const-assign =|[ x := <prop-const => e> ]|; if <is-value> e then

rules( PropConst : |[ x ]| -> |[ e ]| )elserules( PropConst :- |[ x ]| ) end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 13: Scoped dynamic rewrite rules

Bound Variable Renaming

let var a : int := xfunction foo(a : int) : int =let var a := a + 3

var z := 0in for a := a to a + 100 do

z := z + a endin foo(a) end

let var a : int := xfunction foo(b : int) : int =let var c := b + 3

var z := 0in for d := c to c + 100 do

z := z + d endin foo(a) end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 14: Scoped dynamic rewrite rules

Bound Variable Renaming

exprename = rec rn(RenameVar<+ RenameVarDec<+ |[ let <*id> in <*id> end ]|

; {| RenameVar : all(rn) |}<+ |[ for <id> := <rn> to <rn> do <id> ]|

; {| RenameVar: RenameFor; |[ for <id> := <id> to <id> do <rn> ]| |}

<+ |[ function <id>(<*id>) <id> = <id> ]|; {| RenameVar :

RenameArgs; |[ function <id>(<*id>) <id> = <rn> ]| |}

<+ all(rn))

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 15: Scoped dynamic rewrite rules

Bound Variable Renaming

RenameVarDec :|[ var x ta := e ]| -> |[ var y ta := e ]|where <NewVar> x => y

RenameFor :|[ for x := e1 to e2 do e3 ]| ->|[ for y := e1 to e2 do e3 ]|where <NewVar> x => y

RenameArgs :|[ function f(x1*) ta = e ]| ->|[ function f(x2*) ta = e ]|where <map(FArg|[ <NewVar> : <id> ]|)> x1* => x2*

NewVar :x -> y where new => y

; rules( RenameVar : |[ x ]| -> |[ y ]| )

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 16: Scoped dynamic rewrite rules

Function Inlining

let function fact(n : int) : int =let function f(n : int, acc : int) : int =

(while n > 0 do(acc := acc * n; n := n - 1)

; acc)in f(n, 1) end

in fact(10) end

let var n : int := 10var b : int := nvar acc : int := 1

in while b > 0 do(acc := acc * b;b := b - 1);

acc end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 17: Scoped dynamic rewrite rules

Function Inlining

inline = inline-call <+ inline-let <+ inline-fundecs<+ all(inline)

inline-call = UnfoldCall; exprename; inline

inline-let = |[ let <*id> in <*id> end ]|; {| UnfoldCall : all(inline) |}

inline-fundecs =|[ <fd*: map(if is-inlineable

then define-unfoldelse undefine-unfold end)

; map(inline); filter(if is-inlineable

then define-fold; failelse undefine-unfold end)> ]|

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 18: Scoped dynamic rewrite rules

Function Inlining

define-unfold =?|[ function f(x*) ta = e ]|; rules(

UnfoldCall :|[ f(a*) ]| -> |[ let d* in e end ]|where <zip(bind-arg)> (x*, a*) => d* )

bind-arg :(FArg|[ x ta ]|, e) -> |[ var x ta := e ]|

undefine-unfold =?|[ function f(x*) ta = e ]|; rules( UnfoldCall :- |[ f(a*) ]|)

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 19: Scoped dynamic rewrite rules

Scope Labels – Constant Propagation with Local Variables

let var a := 1 var b := 2 var c := 3in a := b + c;

let var c := a + 1in b := b + c;

a := a + b;b := z + b end;

a := c + b + a end

let var a := 1 var b := 2 var c := 3in a := 5;

let var c := 6in b := 8;

a := 13;b := z + 8 end;

a := 3 + b + 13 end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 20: Scoped dynamic rewrite rules

Constant Propagation with Local Variables

prop-const = PropConst <+ prop-const-assign<+ prop-const-let <+ prop-const-vardec<+ all(prop-const); try(EvalBinOp <+ EvalRelOp)

prop-const-let =|[ let <*id> in <*id> end ]|; {| PropConst : all(prop-const) |}

prop-const-vardec =|[ var x ta := <prop-const => e> ]|; if <is-value> ethen rules( PropConst+x : |[ x ]| -> |[ e ]| )else rules( PropConst+x :- |[ x ]| ) end

prop-const-assign =|[ x := <prop-const => e> ]|; if <is-value> ethen rules( PropConst.x : |[ x ]| -> |[ e ]| )else rules( PropConst.x :- |[ x ]| ) end

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 21: Scoped dynamic rewrite rules

Common-Subexpression Elimination

(x := a + b;y := a + b;z := a + c;a := 1;z := (a + c) + (a + b))

⇒(x := a + b;y := x;z := a + c;a := 1;z := (a + c) + (a + b))

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 22: Scoped dynamic rewrite rules

Common-Subexpression Elimination

cse = cse-assign <+ (all(cse); try(ReplaceExp))

cse-assign =|[ x := <cse => e> ]|; where(<undefine-subexpressions> |[ x ]|); if <not(is-subterm(||[ x ]|))> |[ e ]| then

rules(ReplaceExp : |[ e ]| -> |[ x ]|); where(<register-subexpressions(|e)> |[ x := e ]|)

end

register-subexpressions(|e) =get-vars; map({y : ?|[ y ]|

; rules(UsedInExp :+ |[ y ]| -> e)})

undefine-subexpressions =bagof-UsedInExp; map({?e; rules(ReplaceExp :- |[ e ]|)})

get-vars = collect({?|[ x ]|})

http://www.strategoxt.org Scoped Dynamic Rewrite Rules

Page 23: Scoped dynamic rewrite rules

Next

Flow-sensitive data-flow transformation

Intersection and union of rule sets

Dependent dynamic rules

http://www.strategoxt.org Scoped Dynamic Rewrite Rules