46
Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules Program Transformation 2004–2005 Eelco Visser Institute of Information & Computing Sciences Utrecht University, The Netherlands March 3, 2005

Dependent dynamic rules

Embed Size (px)

DESCRIPTION

Slides based on Compiler Construction 2005 paper by Karina Olmos and Eelco Visser

Citation preview

Page 1: Dependent dynamic rules

Composing Source-to-SourceData-Flow Transformations with

Dependent Dynamic Rewrite RulesProgram Transformation 2004–2005

Eelco Visser

Institute of Information & Computing SciencesUtrecht University,The Netherlands

March 3, 2005

Page 2: Dependent dynamic rules

Outline

1 Data-flow transformation strategies

2 Dependencies in data-flow transformation rules

3 Generic data-flow transformation strategies

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 3: Dependent dynamic rules

Part I

Data-Flow Transformation Strategies

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 4: Dependent dynamic rules

Flow-Sensitive Constant Propagation

(x := 3;y := x + 1;if foo(x) then

(y := 2 * x;x := y - 2)

else(x := y;y := 23);

z := x + y)

(x := 3;y := 4;if foo(3) then

(y := 6;x := 4)

else(x := 4;y := 23);

z := 4 + y)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 5: Dependent dynamic rules

x := 3x := 3

y := x + 1y := 4

x -> 3

if foo(x)if foo(3)

x -> 3y -> 4

y := 2 * xy := 6

x -> 3y -> 4

x := yx := 4

x -> 3y -> 4

x := y - 2x := 4

x -> 3y -> 6

x -> 4y -> 6

z := x + yz := 4 + y

x -> 4y -

y := 23y := 23

x -> 4y -> 4

x -> 4y -> 23

Page 6: Dependent dynamic rules
Page 7: Dependent dynamic rules

Strategy for Basic Constant Propagation

prop-const = PropConst <+ prop-const-assign<+ prop-const-declare <+ prop-const-let <+ prop-const-if<+ prop-const-while <+ (all(prop-const); try(EvalBinOp))

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

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

prop-const-let =?|[ let d* in e* end ]|; {| PropConst : all(prop-const) |}

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 8: Dependent dynamic rules

Intersection of Rule Sets

prop-const-if =|[ if <prop-const> then <id> else <id> ]|; (|[ if <id> then <prop-const> else <id> ]|

/PropConst\ |[ if <id> then <id> else <prop-const> ]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 9: Dependent dynamic rules

Intersection of Rule Sets

let var x := 1 var y := zvar z := 3 var a := 4

in x := x + z;a := 5;if y then(y := y + 5;z := 8)

else(x := a + 21;y := x + 1;z := a + z);

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

x y z a b1 - - - -1 - 3 4 -4 - 3 4 -4 - 3 5 -

4 - 3 5 -4 - 8 5 -

26 - 3 5 -26 27 3 5 -26 27 8 5 -- - 8 5 -- - 8 5 13- - 8 5 13

let var x := 1 var y := zvar z := 3 var a := 4

in x := 4;a := 5;if y then

(y := y + 5;z := 8)

else(x := 26;y := 27;z := 8);

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

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 10: Dependent dynamic rules

Fixed-Point Intersection of Rule Sets

let var w := 20 var x := 20var y := 20 var z := 10

in while SomethingUnknown() do(if x = 20 then w := 20 else w := 10;if y = 20 then x := 20 else x := 10;if z = 20 then y := 20 else y := 10);

w; x; y; z end

let var w := 20 var x := 20var y := 20 var z := 10

in while SomethingUnknown() do(if x = 20 then w := 20 else w := 10;if y = 20 then x := 20 else x := 10;y := 10);

w; x; y; 10 end

w x y z20 20 20 10

1 20 20 10 1020 20 - 10

2 20 - 10 1020 - - 10

3 - - 10 10- - - 10

4 - - 10 10- - - 10

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 11: Dependent dynamic rules

Fixed-Point Intersection of Rule Sets

prop-const-while =?|[ while e1 do e2 ]|; (/PropConst\* |[ while <prop-const> do <prop-const> ]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 12: Dependent dynamic rules

Unreachable Code Elimination

let var x := 0 var y := 0in x := 10;

while A do(if x = 10then dosomething()else (dosomethingelse();

x := x + 1));y := x

end

let var x := 0var y := 0

in x := 10;while A dodosomething();

y := 10end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 13: Dependent dynamic rules

Unreachable Code Elimination

prop-const-if =|[ if <prop-const> then <id> else <id> ]|; (EvalIf; prop-const

<+ (|[ if <id> then <prop-const> else <id> ]|/PropConst\

|[ if <id> then <id> else <prop-const> ]|))

prop-const-while =?|[ while e1 do e2 ]|; (|[ while <prop-const> do <id> ]|; EvalWhile

<+ (/PropConst\*|[ while <prop-const> do <prop-const> ]|))

EvalIf : |[ if 0 then e1 else e2 ]| -> |[ e2 ]|EvalIf : |[ if i then e1 else e2 ]| -> |[ e1 ]|

where <not(eq)>(|[ i ]|, |[ 0 ]|)EvalWhile : |[ while 0 do e ]| -> |[ () ]|

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 14: Dependent dynamic rules

Dead Code Elimination

(x := foo(b);y := bar(h);a := c + 23;if 4 > x then

(d := b + a;g := 4 + y)

else(b := 2;a := y + 3;a := 4 + x);

print(a))

{c,b}{x,c}{x,c}{x,a}{a}{a}

{x}{x}{x}{a}

(x := foo(b);

a := c + 23;if not(4> x) then

a := 4 + x;print(a))

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 15: Dependent dynamic rules

Dead Code Elimination

dce = VarNeeded <+ ElimAssign <+ dce-assign<+ dce-seq <+ dce-if <+ dce-while <+ all(dce)

ElimAssign :|[ x := e ]| -> |[ () ]|where <not(Needed)> |[ x ]|

VarNeeded =?|[ x ]|; rules(Needed : |[ x ]|)

dce-assign =?|[ x := e ]|; rules(Needed :- |[ x ]|); |[ <id> := <dce> ]|

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 16: Dependent dynamic rules

Dead Code Elimination – Control-Flow

dce-seq =|[ (<* reverse-filter(dce; not(?|[ () ]|)) >) ]|

dce-if =(|[ if <id> then <dce> else <id> ]|

\Needed/ |[ if <id> then <id> else <dce> ]|); |[ if <dce> then <id> else <id> ]|; try(ElimIf)

dce-while =|[ while <id> do <id> ]|; (\Needed/* |[ while <dce> do <dce> ]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 17: Dependent dynamic rules

Part II

Dependencies in Data-Flow Transformation Rules

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 18: Dependent dynamic rules

Copy Propagation

Replace copies x produced by assignments of the form x := y byoriginal y

a := b;c := d + a

a := b;c := d + b

First attempt using dynamic rules (wrong)

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 19: Dependent dynamic rules

Copy Propagation

Replace copies x produced by assignments of the form x := y byoriginal y

a := b;c := d + a

a := b;c := d + b

First attempt using dynamic rules (wrong)

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 20: Dependent dynamic rules

Problem: Insufficient Dependencies

(a := b;b := foo();c := d + a)

(a := b;b := foo();c := d + b)

Problem: rule not undefined when variable in rhs changed

Solution: undefine rule when any of its variables is modified

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 21: Dependent dynamic rules

Problem: Insufficient Dependencies

(a := b;b := foo();c := d + a)

(a := b;b := foo();c := d + b)

Problem: rule not undefined when variable in rhs changed

Solution: undefine rule when any of its variables is modified

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 22: Dependent dynamic rules

Problem: Free Variable Capture

let var a := bar()var b := baz()

in a := b;let var b := foo()in print(a)end

end

let var a := bar()var b := baz()

in a := b;let var b := foo()in print(b) // wrong!end

end

Problem: rule not undefined when variables become shadowed

Solution: undefine rule locally when some variable shadowed

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 23: Dependent dynamic rules

Problem: Free Variable Capture

let var a := bar()var b := baz()

in a := b;let var b := foo()in print(a)end

end

let var a := bar()var b := baz()

in a := b;let var b := foo()in print(b) // wrong!end

end

Problem: rule not undefined when variables become shadowed

Solution: undefine rule locally when some variable shadowed

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 24: Dependent dynamic rules

Problem: Escaping Variables (1)

let var a := bar()in let var b := foo()

in a := bend;print(a)

end

let var a := bar()in let var b := foo()

in a := bend;print(b) // wrong!

end

Problem: rule not undefined when a variable goes out of scope

Solution: (re)define rule in local scope

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 25: Dependent dynamic rules

Problem: Escaping Variables (1)

let var a := bar()in let var b := foo()

in a := bend;print(a)

end

let var a := bar()in let var b := foo()

in a := bend;print(b) // wrong!

end

Problem: rule not undefined when a variable goes out of scope

Solution: (re)define rule in local scope

copy-prop-assign =?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

elserules( CopyProp.x :- |[ x ]| )

end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 26: Dependent dynamic rules

Problem: Escaping Variables (2)

let var a := bar()var c := baz()

in let var b := foo()in a := b;

a := cend;print(a)

end

let var a := bar()var c := baz()

in let var b := foo()in a := b;

a := cend;print(c) // ok!

end

Problem: definition in local scope is too restricted

Solution: (re)define rule in innermost scope of all variablesinvolved

copy-prop-assign = ?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

else rules( CopyProp.x :- |[ x ]| ) end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 27: Dependent dynamic rules

Problem: Escaping Variables (2)

let var a := bar()var c := baz()

in let var b := foo()in a := b;

a := cend;print(a)

end

let var a := bar()var c := baz()

in let var b := foo()in a := b;

a := cend;print(c) // ok!

end

Problem: definition in local scope is too restricted

Solution: (re)define rule in innermost scope of all variablesinvolved

copy-prop-assign = ?|[ x := y ]|;if <not(eq)>(x,y) thenrules( CopyProp.x : |[ x ]| -> |[ y ]| )

else rules( CopyProp.x :- |[ x ]| ) end

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 28: Dependent dynamic 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))

Assignment

x := e

Propagation rule

|[ e ]| -> |[ x ]|

Dependencies in common-subexpression elimination

all variables in assignment x := e

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 29: Dependent dynamic 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))

Assignment

x := e

Propagation rule

|[ e ]| -> |[ x ]|

Dependencies in common-subexpression elimination

all variables in assignment x := e

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 30: Dependent dynamic 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 Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 31: Dependent dynamic rules

Dependent Dynamic Rules

Declare rule dependencies

R.lab : p1 -> p2depends on [(lab1,dep1),...,(labn,depn)]

Undefine all rules depending on dep

undefine-R(|dep)

Locally undefine all rules depending on dep

new-R(|lab, dep)

and label current scope with lab

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 32: Dependent dynamic rules

Copy Propagation – Assignments

copy-prop =repeat1(CopyProp)<+ copy-prop-assign<+ copy-prop-declare<+ copy-prop-let <+ copy-prop-if <+ copy-prop-while<+ all(copy-prop)

copy-prop-declare =|[ var x ta := <copy-prop => e> ]|; where( new-CopyProp(|x, x) ); where( try(<copy-prop-assign-aux> |[ x := e ]|) )

copy-prop-assign =|[ x := <copy-prop => e> ]|; where( undefine-CopyProp(|x) ); where( try(copy-prop-assign-aux) )

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 33: Dependent dynamic rules

Copy Propagation – Propagation Rule

copy-prop-assign-aux =? |[ x := y ]|; where( <not(eq)>(x,y) ); where( innermost-scope-CopyProp => z ); rules(

CopyProp.z : |[ x ]| -> |[ y ]|depends on [(x,x), (y,y)]

)

innermost-scope-CopyProp =get-var-names => vars; innermost-scope-CopyProp(elem-of(|vars))

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 34: Dependent dynamic rules

Copy Propagation – Control-Flow

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

copy-prop-if =|[ if <copy-prop> then <id> else <id> ]|; ( |[ if <id> then <copy-prop> else <id> ]|

/CopyProp\ |[ if <id> then <id> else <copy-prop> ]|)

copy-prop-while =|[ while <id> do <id> ]|; (/CopyProp\* |[ while <copy-prop> do <copy-prop> ]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 35: Dependent dynamic rules

Common-Subexpression Elimination – Assignments

cse =cse-assign <+ cse-vardec <+ cse-let <+ cse-if<+ cse-while <+ all(cse); try(CSE)

cse-vardec =|[ var x ta := <cse => e> ]|; new-CSE(|x, x); where( try(<cse-assign-aux> |[ x := e ]|) )

cse-assign =|[ x := <cse => e> ]|; undefine-CSE(|x); where(try(cse-assign-aux))

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 36: Dependent dynamic rules

Common-Subexpression Elimination – Propagation

cse-assign-aux =? |[ x := e ]|; where( <not(oncetd(?|[ x ]|)); pure> |[ e ]| ); where( get-var-names; map(!(<id>,<id>)) => xs ); where( innermost-scope-CSE => z ); rules( CSE.z : |[ e ]| -> |[ x ]| depends on xs )

pure =?|[ i ]| + ?|[ x ]| + |[ <bo:id>(<pure>, <pure>) ]|

innermost-scope-CSE =get-var-names => vars; innermost-scope-CSE(where(<elem>(<id>, vars)))

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 37: Dependent dynamic rules

Common-Subexpression Elimination – Control-Flow

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

cse-if =|[ if <cse> then <id> else <id> ]|; ( |[ if <id> then <cse> else <id> ]|

/CSE\ |[ if <id> then <id> else <cse> ]|)

cse-while =|[ while <id> do <id> ]|; (/CSE\* |[ while <cse> do <cse> ]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 38: Dependent dynamic rules

Part III

Generic Data-Flow Transformation Strategies

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 39: Dependent dynamic rules

Generic Data-Flow Transformation Strategies

Data-flow transformation strategies are similar

Factor out underlying strategy

Requires generalization over combinators

new-dynamic-rules(|Rs,x,x)undefine-dynamic-rules(|Rs,x)/~Rs1\~Rs2/

Allows very concise specifications for specific transformations

Combination of transformations

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 40: Dependent dynamic rules

Generic Strategy – Framework

forward-prop(transform, before, after | Rs1, Rs2, Rs3) =<conc>(Rs1, Rs2, Rs3) => RsSc;<conc>(Rs1, Rs2) => RsDf;letfp = prop-assign <+ prop-declare <+ prop-let

<+ prop-if <+ prop-while<+ transform(fp)<+ (before; all(fp); after)

prop-assign = ...prop-declare = ...prop-let = ...prop-if = ...prop-while = ...

in fpend

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 41: Dependent dynamic rules

Generic Strategy – Assignments

prop-assign =|[ <id> := <fp> ]|; (transform(fp)

<+ before; ?|[ x := e ]|; undefine-dynamic-rules(|RsDf,x); after)

prop-declare =|[ var <id> := <fp> ]|; (transform(fp)

<+ before; ?|[ var x := e ]|; new-dynamic-rules(|RsSc,x,x);after)

prop-let =?|[ let d* in e* end ]|; (transform(fp)

<+ {|~RsSc : before; all(fp); after |})

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 42: Dependent dynamic rules

Generic Strategy – Control Flow

prop-if =|[ if <fp> then <id> else <id> ]|; (transform(fp)

<+ before; (|[ if <id> then <fp> else <id> ]|

/~Rs1\~Rs2/ |[ if <id> then <id> else <fp> ]|); after)

prop-while =?|[ while e1 do e2 ]|; (transform(fp)

<+ before; /~Rs1\~Rs2/* |[ while <fp> do <fp> ]|; after)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 43: Dependent dynamic rules

Instantation: Constant Propagation

prop-const = forward-prop(prop-const-transform, id,prop-const-after | ["PropConst"],[],[])

prop-const-transform(recur) =EvalFor <+ EvalIf; recur<+ |[ while <recur> do <id> ]|; EvalWhile

prop-const-after =try(prop-const-assign <+ prop-const-declare

<+ PropConst <+ EvalBinOp)

prop-const-assign =?|[ x := e ]|; where( <is-value> e ); rules( PropConst.x : |[ x ]| -> |[ e ]|

depends on [(x,x)] )prop-const-declare =?|[var x ta := e]|; where(<prop-const-assign>|[x := e]|)

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 44: Dependent dynamic rules

Instantation: Copy Propagation

copy-prop =forward-prop(no-transform,id,copy-prop-after

|["CopyProp"],[],[])

copy-prop-after =try(copy-prop-assign <+ copy-prop-declare

<+ repeat1(CopyProp))

copy-prop-declare =? |[ var x ta := e ]|; where(try(<copy-prop-assign> |[ x := e ]|))

copy-prop-assign =? |[ x := y ]|; where( <not(eq)> (x, y) ); where( get-var-dependencies => xs ); where( innermost-scope-CopyProp => z ); rules( CopyProp.z : |[ x ]| -> |[ y ]| depends on xs )

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 45: Dependent dynamic rules

Instantation: Common-Subexpression Elimination

cse =forward-prop(no-transform, id, cse-after|["CSE"],[],[])

cse-after =try(cse-assign <+ cse-declare <+ CSE)

cse-declare =?|[ var x := e ]|; where( <cse-assign> |[ x := e ]| )

cse-assign = ?|[ x := e ]|; where( <pure-and-not-trivial(|x)> |[ e ]| ); where( get-var-dependencies => xs ); where( innermost-scope-CSE => z ); rules( CSE.z : |[ e ]| -> |[ x ]| depends on xs )

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules

Page 46: Dependent dynamic rules

Instantation: A Super Optimizer

super-opt =forward-prop(prop-const-transform, bvr-before, bvr-after; copy-prop-after; prop-const-after; cse-after

| ["PropConst", "CopyProp", "CSE"], [], ["RenameVar"])

Combination of

constant propagation

copy propagation

common-subexpression elimination

bound variable renaming

http://www.strategoxt.org Composing Source-to-Source Data-Flow Transformations with Dependent Dynamic Rewrite Rules