Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Composing Source-to-Source Data-Flow Transformations with Rewriting Strategies and Dependent Dynamic Rewrite Rules
1. 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
2. Source-to-Source
Transformations
Goal: transformation tools for the working programmer
Transformations on various programming languages
General-purpose languages
(Embedded) domain-specific languages
Combine different types of transformations
Program generation and meta-programming
Simplification
(Domain-specific) optimization
Data-flow transformations
Source-to-source
Transformations on abstract syntax trees
Concise and reusable
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
3. Source-to-Source Data-Flow Transformations
Goal: transformation tools for the working programmer
Transformations on various programming languages
General-purpose languages
(Embedded) domain-specific languages
Combine different types of transformations
Program generation and meta-programming
Simplification
(Domain-specific) optimization
Data-flow transformations
Source-to-source
Transformations on abstract syntax trees
Concise and reusable
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
4. Rewriting Strategies and Dynamic Rewrite Rules
Stratego/XT: language + tools for program transformation
XT: infrastructure for transformation systems
Stratego: high-level language for program transformation
Not tied to one type of transformation or language
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
5. Rewriting Strategies and Dynamic Rewrite Rules
Stratego/XT: language + tools for program transformation
XT: infrastructure for transformation systems
Stratego: high-level language for program transformation
Not tied to one type of transformation or language
Stratego paradigm
Rewrite rules for basic transformation steps
Programmable rewriting strategies for controlling rules
Dynamic rules for context-sensitive transformation
Concrete syntax for patterns
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
6. Rewriting Strategies and Dynamic Rewrite Rules
Stratego/XT: language + tools for program transformation
XT: infrastructure for transformation systems
Stratego: high-level language for program transformation
Not tied to one type of transformation or language
Stratego paradigm
Rewrite rules for basic transformation steps
Programmable rewriting strategies for controlling rules
Dynamic rules for context-sensitive transformation
Concrete syntax for patterns
Contributions
Dependent dynamic rules
Generic data-flow strategies
Combination of transformations
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
7. 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 ]
[
|
[
|
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
8. 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
9. 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
10. 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
11. 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
12. 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
13. 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
14. 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
15. 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
16. 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
17. 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
19. 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
Constant propagation
Copy propagation
Common-subexpression elimination
Partial evaluation
Function inlining
Dead code elimination
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
20. 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
Constant propagation
Copy propagation
Common-subexpression elimination
Partial evaluation
Function inlining
Dead code elimination
Solution: Dynamic Rewrite Rules
Define rewrite rules during transformation
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
21. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
22. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
23. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
24. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
25. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
26. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
b + 3;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
27. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
1 + 3;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
28. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
1 + 3;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
29. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
30. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -> 1
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
31. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -> 1 & c -> 4
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
32. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -> 1 & c -> 4
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
33. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -
& c -> 4
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
34. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + c
b -
& c -> 4
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
35. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + 4
b -
& c -> 4
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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
36. Defining and Undefining Rules Dynamically
Constant Propagation and Folding in Straight-Line Code
b
c
b
a
:=
:=
:=
:=
1;
4;
foo();
b + 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 ] )
[
|
[
|
else
rules( PropConst :- | x ] )
[
|
end
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
37. Properties of Dynamic Rules
Rules are defined dynamically
Carry context information
Multiple rules with same name can be defined
Rules can be undefined
Rules with same left-hand side override old rules
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
38. Properties of Dynamic Rules
Rules are defined dynamically
Carry context information
Multiple rules with same name can be defined
Rules can be undefined
Rules with same left-hand side override old rules
b := 3;
...
b := 4;
http://www.strategoxt.org
b -> 3
b -> 3
b -> 4
Dependent Dynamic Rewrite Rules
39. 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)
40. Flow-Sensitive Transformations
x := 3
x := 3
x -> 3
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)
y := x + 1
y := 4
x -> 3
y -> 4
if foo(x)
if foo(3)
x -> 3
y -> 4
x -> 3
y -> 4
y := 2 * x
y := 6
x := y
x := 4
x -> 3
y -> 6
x := y - 2
x := 4
x -> 4
y -> 4
y := 23
y := 23
x -> 4
y -> 6
x -> 4
y -> 23
fork rule sets and combine at merge point
x -> 4
y z := x + y
z := 4 + y
41. Constant propagation in abstract syntax tree
;
x -> 3
x := 3
;
x := 3
x -> 3
y := x + 1
x -> 3
y -> 4
;
y := 4
x -> 3
y -> 4
if foo(x)
z := x + y
if foo(3)
x -> 3
y -> 4
;
x -> 3 x -> 3
y -> 4 y -> 6
y := 2 * x
y := 6
x := y - 2
x := 4
http://www.strategoxt.org
x -> 4
y -
z := 4 + y
x -> 3
y -> 4
;
x -> 3
y -> 4
x -> 4
y -> 4
x := y
y := 23
x := 4
y := 23
Dependent Dynamic Rewrite Rules
42. 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
43. Propagation through Loops
(a := 1;
i := 0;
while i < m do (
j := a;
a := f();
a := j;
i := i + 1
);
print(a, i, j))
http://www.strategoxt.org
⇒
(a := 1;
i := 0;
while i < m do (
j := 1;
a := f();
a := 1;
i := i + 1
);
print(1, i, j))
Dependent Dynamic Rewrite Rules
44. 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
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
45. 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
46. Combining Analysis and Transformation
Unreachable code elimination
i := 1;
j := 2;
if j = 2
then i := 3;
else z := foo()
print(i)
http://www.strategoxt.org
⇒
i := 1;
j := 2;
i := 3;
print(3)
Dependent Dynamic Rewrite Rules
47. Combining Analysis and Transformation
Unreachable code elimination
i := 1;
j := 2;
if j = 2
then 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]
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
48. Combining Analysis and Transformation
Unreachable code elimination
i := 1;
j := 2;
if j = 2
then 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
49. Combining Analysis and Transformation
Unreachable code elimination
(x := 10;
while A do
if x = 10
then dosomething()
else (dosomethingelse();
x := x + 1);
y := x)
⇒
(x := 10;
while A do
dosomething();
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
50. Dynamic Rule Scope
let var x := 17
in let var y := x + 1
in let var x := y+1
in () end
end; print(x)
end
⇒
let var x := 17
in let var y := 18
in let var x := 19
in () end
end; print(17)
end
Transformation in presence of local variables
Dynamic rule scope restricts lifetime of dynamic rule
See paper
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
51. Other Issues
Interprocedural transformation
[Olmos & Visser 2003]
Type specialization for Octave
[Bravenboer, Van Dam, Olmos & Visser 2005]
Poly-variant online specialization and unfolding
[Olmos 2005 forthcoming]
Global variables
Mono-variant specialization (summaries)
Aliasing
[Olmos 2005 forthcoming]
Propagation with records and arrays
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
52. 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
53. Recapitulation
Rewrite rules for constant folding
Strategies for (generic) traversal
Dynamic rule propagates values
Fork and intersection (union) for flow-sensitive transformation
Dynamic rule scopes controls lifetime of rules
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
54. Recapitulation
Rewrite rules for constant folding
Strategies for (generic) traversal
Dynamic rule propagates values
Fork and intersection (union) for flow-sensitive transformation
Dynamic rule scopes controls lifetime of rules
can this be applied to other data-flow transformations?
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
55. Common-Subexpression Elimination
x := a + b;
y := a * b;
while y > a + b do (
a := a + 1;
x := a + b
)
http://www.strategoxt.org
⇒
x := a + b;
y := a * b;
while y > x do (
a := a + 1;
x := a + b
)
Dependent Dynamic Rewrite Rules
56. 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
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
57. 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
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
58. 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
59. Problem: Insufficient Dependency Information
x := a + b;
a := foo();
y := a + b
a + b -> x
http://www.strategoxt.org
x := a + b;
a := foo();
y := x // wrong!
Dependent Dynamic Rewrite Rules
60. 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
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
61. 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
62. 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
63. Hygienic Program Transformation
Respect variable bindings
Dependent rules avoid
free variable capture
escaping variables
See paper
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
64. Recapitulation
Rewrite rules for basic transformations
Strategies for control and (generic) traversal
Dynamic rule propagates context information
Fork and intersection (union) for flow-sensitive transformation
Dynamic rule scopes and dependent rules for control over
lifetime of rules
Examples
Constant propagation |[ x ]| -> |[ i ]|
Copy propagation |[ x ]| -> |[ y ]|
Common-subexpression elimination |[ e ]| -> |[ x ]|
Forward substitution |[ x ]| -> |[ e ]|
Partial redundancy elimination (down-safe, earliest)
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
65. Generic Data-Flow Strategies
Observation: most of data-flow strategy is boilerplate
Solution: generic data-flow strategy
Generalized operators
Intersection and union: /Rs1 Rs2 / and /Rs1 Rs2 /*
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
67. Experience with Dynamic Rules
Tiger compiler: sandbox for transformation techniques
bound 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, ...
Octave compiler
type specialization, partial evaluation, other data-flow
transformations, combined transformations, loop vectorization
Stratego compiler
inlining, specialization, bound-unbound variables analysis, ...
LVM optimizer (functional)
substitutions, inlining, (deforestation, warm fusion)
Java Compiler
name disambiguation, type propagation, assimilation of embedded
domain-specific languages
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
68. Related Work
[Wegman & Zadeck 1991]
SCC: special algorithm for conditional constant propagation
propagation through SSA edges
[Lerner et al. 2002]
integration of analysis and transformation for CFGs
combination of multiple analyses/transformations
[Lacey & de Moor 2001]
temporal logic : find context from occurrence
[Sittampalam, de Moor & Larsen 2004]
regular path queries
incremental analysis after applying transformation
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
69. Conclusion
Abstract interpretation style of data-flow transformation
combination of data-flow analysis and transformation
Hygienic: correct treatment of variable binding constructs
avoid free variable capture and escaping variables
scoped transformation rules
Generic data-flow strategies
concise specification specification of data-flow transformation
combination of multiple transformations
Combination of data-flow transformations with other
transformations
reuse of (elements of) transformations
alternative transformation strategies
Stratego/XT 0.14 (pre-release) from www.stratego-language.org
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
71. Correctness of Transformations
Invariant: rule set valid at current program point
Check: each rule maintains invariant
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules
72. Break and Continue
Only structured control-flow supported
Exit from loop: break-R
http://www.strategoxt.org
Dependent Dynamic Rewrite Rules