Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic...

72
Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules Karina Olmos & Eelco Visser Institute of Information & Computing Sciences Utrecht University The Netherlands April 5, 2005 CC’05 Edinburgh

description

Slides for talk at Compiler Construction 2005 in Edinburgh based on the paper with the same title by Karina Olmos and Eelco Visser

Transcript of Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic...

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