Download - Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Transcript
Page 1: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Composing Source-to-Source Data-FlowTransformations with Rewriting Strategies and

Dependent Dynamic Rewrite Rules

Karina Olmos & Eelco Visser

Institute of Information & Computing SciencesUtrecht UniversityThe Netherlands

April 5, 2005CC’05 Edinburgh

Page 2: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Source-to-Source

Data-Flow

Transformations

Goal: transformation tools for the working programmer

Transformations on various programming languages

I General-purpose languages

I (Embedded) domain-specific languages

Combine different types of transformations

I Program generation and meta-programming

I Simplification

I (Domain-specific) optimization

I Data-flow transformations

Source-to-source

I Transformations on abstract syntax trees

Concise and reusable

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

Page 3: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Source-to-Source Data-Flow Transformations

Goal: transformation tools for the working programmer

Transformations on various programming languages

I General-purpose languages

I (Embedded) domain-specific languages

Combine different types of transformations

I Program generation and meta-programming

I Simplification

I (Domain-specific) optimization

I Data-flow transformations

Source-to-source

I Transformations on abstract syntax trees

Concise and reusable

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

Page 4: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewriting Strategies and Dynamic Rewrite Rules

Stratego/XT: language + tools for program transformation

I XT: infrastructure for transformation systems

I Stratego: high-level language for program transformation

I Not tied to one type of transformation or language

Stratego paradigm

I Rewrite rules for basic transformation steps

I Programmable rewriting strategies for controlling rules

I Dynamic rules for context-sensitive transformation

I Concrete syntax for patterns

Contributions

I Dependent dynamic rules

I Generic data-flow strategies

I Combination of transformations

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

Page 5: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewriting Strategies and Dynamic Rewrite Rules

Stratego/XT: language + tools for program transformation

I XT: infrastructure for transformation systems

I Stratego: high-level language for program transformation

I Not tied to one type of transformation or language

Stratego paradigm

I Rewrite rules for basic transformation steps

I Programmable rewriting strategies for controlling rules

I Dynamic rules for context-sensitive transformation

I Concrete syntax for patterns

Contributions

I Dependent dynamic rules

I Generic data-flow strategies

I Combination of transformations

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

Page 6: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewriting Strategies and Dynamic Rewrite Rules

Stratego/XT: language + tools for program transformation

I XT: infrastructure for transformation systems

I Stratego: high-level language for program transformation

I Not tied to one type of transformation or language

Stratego paradigm

I Rewrite rules for basic transformation steps

I Programmable rewriting strategies for controlling rules

I Dynamic rules for context-sensitive transformation

I Concrete syntax for patterns

Contributions

I Dependent dynamic rules

I Generic data-flow strategies

I Combination of transformations

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

Page 7: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4) ⇒ y := x * 7

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 8: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4) ⇒ y := x * 7

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 9: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 10: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 11: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 12: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 13: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 14: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * (3 + 4)

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 15: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * 7

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 16: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * 7

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 17: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Rewrite Rules and Strategies

Constant folding

y := x * 7

Constant folding rules

EvalAdd : |[ i + j ]| -> |[ k ]| where <add>(i, j) => k

EvalMul : |[ i * j ]| -> |[ k ]| where <mul>(i, j) => k

AddZero : |[ 0 + e ]| -> |[ e ]|

Constant folding strategy (bottom-up)

EvalBinOp = EvalAdd <+ AddZero <+ EvalMul <+ EvalOther

try(s) = s <+ id

constfold = all(constfold); try(EvalBinOp)

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

Page 18: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Context-Sensitive Transformations

Problem: Rewrite Rules are Context-free

Rewrite rules can only access information in term that is matched

Many Transformations are Context-Sensitive

I Constant propagation

I Copy propagation

I Common-subexpression elimination

I Partial evaluation

I Function inlining

I Dead code elimination

Solution: Dynamic Rewrite Rules

Define rewrite rules during transformation

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

Page 19: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Context-Sensitive Transformations

Problem: Rewrite Rules are Context-free

Rewrite rules can only access information in term that is matched

Many Transformations are Context-Sensitive

I Constant propagation

I Copy propagation

I Common-subexpression elimination

I Partial evaluation

I Function inlining

I Dead code elimination

Solution: Dynamic Rewrite Rules

Define rewrite rules during transformation

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

Page 20: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Context-Sensitive Transformations

Problem: Rewrite Rules are Context-free

Rewrite rules can only access information in term that is matched

Many Transformations are Context-Sensitive

I Constant propagation

I Copy propagation

I Common-subexpression elimination

I Partial evaluation

I Function inlining

I Dead code elimination

Solution: Dynamic Rewrite Rules

Define rewrite rules during transformation

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

Page 21: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 22: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 23: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 24: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 25: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 26: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 27: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 28: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

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

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 29: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 30: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1

b -> 1 & c -> 4b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 31: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1

b -> 1 & c -> 4

b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 32: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1

b -> 1 & c -> 4

b - & c -> 4b - & c -> 4 & a -

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

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

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

end

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

Page 33: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1b -> 1 & c -> 4

b - & c -> 4

b - & c -> 4 & a -

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

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

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

end

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

Page 34: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + c

b -> 1b -> 1 & c -> 4

b - & c -> 4

b - & c -> 4 & a -

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

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

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

end

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

Page 35: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + 4

b -> 1b -> 1 & c -> 4

b - & c -> 4

b - & c -> 4 & a -

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

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

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

end

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

Page 36: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Defining and Undefining Rules Dynamically

Constant Propagation and Folding in Straight-Line Code

b := 1;c := 4;b := foo();a := b + 4

b -> 1b -> 1 & c -> 4b - & c -> 4

b - & c -> 4 & a -

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

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

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

end

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

Page 37: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Properties of Dynamic Rules

I Rules are defined dynamically

I Carry context information

I Multiple rules with same name can be defined

I Rules can be undefined

I Rules with same left-hand side override old rules

b := 3;...b := 4;

b -> 3b -> 3b -> 4

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

Page 38: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Properties of Dynamic Rules

I Rules are defined dynamically

I Carry context information

I Multiple rules with same name can be defined

I Rules can be undefined

I Rules with same left-hand side override old rules

b := 3;...b := 4;

b -> 3b -> 3b -> 4

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

Page 39: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Flow-Sensitive Transformations

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)

fork rule sets and combine at merge point

x := 3

x := 3

y := x + 1

y := 4

x -> 3

if foo(x)

if foo(3)

x -> 3 y -> 4

y := 2 * x

y := 6

x -> 3 y -> 4

x := y

x := 4

x -> 3 y -> 4

x := y - 2

x := 4

x -> 3 y -> 6

x -> 4 y -> 6

z := x + y

z := 4 + y

x -> 4 y -

y := 23

y := 23

x -> 4 y -> 4

x -> 4 y -> 23

Page 40: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Flow-Sensitive Transformations

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)

fork rule sets and combine at merge point

x := 3

x := 3

y := x + 1

y := 4

x -> 3

if foo(x)

if foo(3)

x -> 3 y -> 4

y := 2 * x

y := 6

x -> 3 y -> 4

x := y

x := 4

x -> 3 y -> 4

x := y - 2

x := 4

x -> 3 y -> 6

x -> 4 y -> 6

z := x + y

z := 4 + y

x -> 4 y -

y := 23

y := 23

x -> 4 y -> 4

x -> 4 y -> 23

Page 41: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Constant propagation in abstract syntax tree

x := 3

x := 3

y := x + 1

y := 4

if foo(x)

if foo(3)

;

x -> 3 y -> 4

;

x -> 3 y -> 4

y := 2 * x

y := 6

x := y - 2

x := 4

x := y

x := 4

y := 23

y := 23

z := x + y

z := 4 + y

;

;

x -> 3

x -> 3

;

x -> 3y -> 4

x -> 3 y -> 4

x -> 4 y -

x -> 3y -> 4

x -> 3 y -> 6

x -> 3 y -> 4

x -> 4 y -> 4

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

Page 42: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Forking and Intersecting Dynamic Rulesets

Flow-sensitive Constant Propagation

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>]|)

s1 /R\ s2: fork and intersect

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

Page 43: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Propagation through Loops

(a := 1;i := 0;while i < m do (j := a;a := f();a := j;i := i + 1

);print(a, i, j))

(a := 1;i := 0;while i < m do (j := 1;a := f();a := 1;i := i + 1

);print(1, i, j))

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

Page 44: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Fixpoint Iteration

Flow-sensitive Constant Propagation

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

/R\* s ≡ ((id /R\ s) /R\ s) /R\ ...)until fixedpoint of ruleset is reached

prop-const-while terminates:fewer rules defined each iteration

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

Page 45: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Fixpoint Iteration

Flow-sensitive Constant Propagation

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

/R\* s ≡ ((id /R\ s) /R\ s) /R\ ...)until fixedpoint of ruleset is reached

prop-const-while terminates:fewer rules defined each iteration

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

Page 46: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Combining Analysis and Transformation

Unreachable code elimination

i := 1;j := 2;if j = 2then i := 3;else z := foo()

print(i)

⇒i := 1;j := 2;i := 3;print(3)

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

where <not(eq)>(i,|[0]|)

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>]|))

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

Page 47: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Combining Analysis and Transformation

Unreachable code elimination

i := 1;j := 2;if j = 2then i := 3;else z := foo()

print(i)

⇒i := 1;j := 2;i := 3;print(3)

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

where <not(eq)>(i,|[0]|)

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>]|))

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

Page 48: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Combining Analysis and Transformation

Unreachable code elimination

i := 1;j := 2;if j = 2then i := 3;else z := foo()

print(i)

⇒i := 1;j := 2;i := 3;print(3)

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

where <not(eq)>(i,|[0]|)

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>]|))

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

Page 49: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Combining Analysis and Transformation

Unreachable code elimination

(x := 10;while A doif x = 10

then dosomething()else (dosomethingelse();

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

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

y := 10)

Conditional Constant Propagation [Wegman & Zadeck 1991]Graph analysis + transformation in Vortex [Lerner et al. 2002]

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

Page 50: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Dynamic Rule Scope

let var x := 17in let var y := x + 1

in let var x := y+1in () end

end; print(x)end

let var x := 17in let var y := 18

in let var x := 19in () end

end; print(17)end

Transformation in presence of local variables

I Dynamic rule scope restricts lifetime of dynamic rule

I See paper

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

Page 51: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Other Issues

Interprocedural transformation

[Olmos & Visser 2003]

I Type specialization for Octave

[Bravenboer, Van Dam, Olmos & Visser 2005]

I Poly-variant online specialization and unfolding

[Olmos 2005 forthcoming]

I Global variables

I Mono-variant specialization (summaries)

Aliasing

[Olmos 2005 forthcoming]

I Propagation with records and arrays

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

Page 52: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Putting it all together

Conditional 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> e then rules( PropConst.x : |[ x ]| -> |[ e ]| )

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

prop-const-declare =

|[ var x := <prop-const => e> ]|

; if <is-value> e then rules( PropConst+x : |[ x ]| -> |[ e ]| )

else rules( PropConst+x :- |[ x ]| ) end

prop-const-let =

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

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> ]|))

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

Page 53: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Recapitulation

I Rewrite rules for constant folding

I Strategies for (generic) traversal

I Dynamic rule propagates values

I Fork and intersection (union) for flow-sensitive transformation

I Dynamic rule scopes controls lifetime of rules

can this be applied to other data-flow transformations?

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

Page 54: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Recapitulation

I Rewrite rules for constant folding

I Strategies for (generic) traversal

I Dynamic rule propagates values

I Fork and intersection (union) for flow-sensitive transformation

I Dynamic rule scopes controls lifetime of rules

can this be applied to other data-flow transformations?

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

Page 55: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Common-Subexpression Elimination

x := a + b;y := a * b;while y > a + b do (

a := a + 1;x := a + b

)

x := a + b;y := a * b;while y > x do (

a := a + 1;x := a + b

)

CSE with dynamic rule

cse-assign =|[ x := <cse => e> ]|; if <pure-and-not-trivial(|x)> |[ e ]| then

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

This works

, kind of

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

Page 56: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Common-Subexpression Elimination

x := a + b;y := a * b;while y > a + b do (

a := a + 1;x := a + b

)

x := a + b;y := a * b;while y > x do (

a := a + 1;x := a + b

)

CSE with dynamic rule

cse-assign =|[ x := <cse => e> ]|; if <pure-and-not-trivial(|x)> |[ e ]| then

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

This works

, kind of

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

Page 57: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Common-Subexpression Elimination

x := a + b;y := a * b;while y > a + b do (

a := a + 1;x := a + b

)

x := a + b;y := a * b;while y > x do (

a := a + 1;x := a + b

)

CSE with dynamic rule

cse-assign =|[ x := <cse => e> ]|; if <pure-and-not-trivial(|x)> |[ e ]| then

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

This works

, kind of

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

Page 58: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Common-Subexpression Elimination

x := a + b;y := a * b;while y > a + b do (

a := a + 1;x := a + b

)

x := a + b;y := a * b;while y > x do (

a := a + 1;x := a + b

)

CSE with dynamic rule

cse-assign =|[ x := <cse => e> ]|; if <pure-and-not-trivial(|x)> |[ e ]| then

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

This works, kind of

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

Page 59: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Problem: Insufficient Dependency Information

x := a + b;a := foo();y := a + b

a + b -> x x := a + b;a := foo();y := x // wrong!

Analysis

Rule should be undefined when any variable changes value

Solution: Dependent Dynamic Rules

Record all dependencies of dynamic rules

rules( R : p1 -> p2 depends on [x1,...,xn] )

Undefine all rules depending on dep

undefine-R(|dep)

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

Page 60: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Problem: Insufficient Dependency Information

x := a + b;a := foo();y := a + b

a + b -> x x := a + b;a := foo();y := x // wrong!

Analysis

Rule should be undefined when any variable changes value

Solution: Dependent Dynamic Rules

Record all dependencies of dynamic rules

rules( R : p1 -> p2 depends on [x1,...,xn] )

Undefine all rules depending on dep

undefine-R(|dep)

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

Page 61: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Problem: Insufficient Dependency Information

x := a + b;a := foo();y := a + b

a + b -> x x := a + b;a := foo();y := x // wrong!

Analysis

Rule should be undefined when any variable changes value

Solution: Dependent Dynamic Rules

Record all dependencies of dynamic rules

rules( R : p1 -> p2 depends on [x1,...,xn] )

Undefine all rules depending on dep

undefine-R(|dep)

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

Page 62: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

CSE with Dependent Dynamic Rules

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

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 Dependent Dynamic Rewrite Rules

Page 63: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Hygienic Program Transformation

Respect variable bindings

Dependent rules avoid

I free variable capture

I escaping variables

See paper

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

Page 64: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Recapitulation

I Rewrite rules for basic transformations

I Strategies for control and (generic) traversal

I Dynamic rule propagates context information

I Fork and intersection (union) for flow-sensitive transformation

I Dynamic rule scopes and dependent rules for control overlifetime of rules

Examples

I Constant propagation |[ x ]| -> |[ i ]|

I Copy propagation |[ x ]| -> |[ y ]|

I Common-subexpression elimination |[ e ]| -> |[ x ]|

I Forward substitution |[ x ]| -> |[ e ]|

I Partial redundancy elimination (down-safe, earliest)

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

Page 65: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Generic Data-Flow Strategies

I Observation: most of data-flow strategy is boilerplate

I Solution: generic data-flow strategy

I Generalized operators

I Intersection and union: /Rs1\Rs2/ and /Rs1\Rs2/*I Undefinition of multiple dynamic rules

Instantiation for common-subexpression elimination

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

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

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

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

Page 66: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Combining Transformations

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

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

)

Apply multiple data-flow transformations simultaneously

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

Page 67: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Experience with Dynamic Rules

I Tiger compiler: sandbox for transformation techniquesbound variable renaming, inlining, constant propagation, copy

propagation, common-subexpression elimination, dead assignment

elimination, partial redundancy elimination, online and offline partial

evaluation, loop normalization, loop vectorization, ...

I Octave compilertype specialization, partial evaluation, other data-flow

transformations, combined transformations, loop vectorization

I Stratego compilerinlining, specialization, bound-unbound variables analysis, ...

I LVM optimizer (functional)substitutions, inlining, (deforestation, warm fusion)

I Java Compilername disambiguation, type propagation, assimilation of embedded

domain-specific languages

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

Page 68: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Related Work

[Wegman & Zadeck 1991]

I SCC: special algorithm for conditional constant propagation

I propagation through SSA edges

[Lerner et al. 2002]

I integration of analysis and transformation for CFGs

I combination of multiple analyses/transformations

[Lacey & de Moor 2001]

I temporal logic : find context from occurrence

[Sittampalam, de Moor & Larsen 2004]

I regular path queries

I incremental analysis after applying transformation

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

Page 69: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Conclusion

I Abstract interpretation style of data-flow transformation

I combination of data-flow analysis and transformation

I Hygienic: correct treatment of variable binding constructs

I avoid free variable capture and escaping variablesI scoped transformation rules

I Generic data-flow strategies

I concise specification specification of data-flow transformationI combination of multiple transformations

I Combination of data-flow transformations with othertransformations

I reuse of (elements of) transformationsI alternative transformation strategies

Stratego/XT 0.14 (pre-release) from www.stratego-language.org

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

Page 70: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

The End

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

Page 71: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Correctness of Transformations

I Invariant: rule set valid at current program point

I Check: each rule maintains invariant

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

Page 72: Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules

Break and Continue

I Only structured control-flow supported

I Exit from loop: break-R

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