Table of Contents
This chapter is work in progress. Not all parts have been finished yet. The latest revision of this manual may contain more material. Refer to the online version.
This chapter shows examples of data-flow transformations
Figure 7.1. file: til/opt/til-opt-lib.str
module til-opt-lib
imports liblib TIL til-eval
strategies
contains(|x) = // should be in stratego-lib
oncetd(?x)
elem-of(|xs) = // should be in stratego-lib
?x; where(<fetch(?x)> xs)
get-var-names =
collect(?Var(<id>))
get-var-dependencies =
collect(?Var(<!(<id>,<id>)>))
EvalExp =
EvalAdd <+ EvalMul <+ EvalSub <+ EvalDiv <+ EvalMod
<+ EvalLt <+ EvalGt <+ EvalEqu <+ EvalNeq
is-var =
?Var(_)
is-value =
?Int(_) <+ ?String(_)
is-pure-exp =
?Var(_) <+ ?Int(_) <+ ?String(_)
<+ is-bin-op#([is-pure-exp, is-pure-exp])
is-bin-op =
?"Or" <+ ?"And" <+ ?"Neq" <+ ?"Equ" <+ ?"Gt" <+ ?"Lt" <+ ?"Sub"
<+ ?"Add" <+ ?"Mod" <+ ?"Div" <+ ?"Mul"
Figure 7.2. file: til/xmpl/propconst-test2
sglri -p ../syn/TIL.tbl -i propconst-test2.til |\ ../sim/til-simplify |\ ../opt/til-propconst |\ ast2text -p ../pp/TIL-pretty.pp -o propconst-test2.txt
Table 7.1. files: til/xmpl/propconst-test2.til, til/xmpl/propconst-test2.txt
| before | after |
|---|---|
var x; var y; var z; var a; var b; z := readint(); x := 1; // constant value y := 2; // not constant x := 3; // override a := x + 4; // compute constant y := x + z; // not constant if y then z := 8; x := z - 5; // constant else x := a - 4; // constant z := a + z; // z is not constant end b := a + z; // a still constant, z not z := a + x; writeint(b + z); | var x : int; var y : int; var z : int; var a : int; var b : int; z := string2int(read()); x := 1; y := 2; x := 3; a := 7; y := 3 + z; if y then z := 8; x := 3; else x := 3; z := 7 + z; end b := 7 + z; z := 10; write(int2string(b + 10)); |
Figure 7.3. file: til/opt/til-propconst.str
module til-propconst
imports til-opt-lib
strategies
io-til-propconst =
io-wrap(propconst)
propconst =
PropConst
<+ propconst-declaration
<+ propconst-assign
<+ propconst-block
<+ propconst-if
<+ propconst-while
<+ all(propconst); try(EvalExp)
propconst-block =
Block({| PropConst : map(propconst) |})
propconst-declaration =
(?Declaration(x) <+ ?DeclarationTyped(x, t))
; rules( PropConst+x :- Var(x) )
propconst-assign =
Assign(?x, propconst => e)
; if <is-value> e then
rules( PropConst.x : Var(x) -> e )
else
rules( PropConst.x :- Var(x) )
end
propconst-if =
IfElse(propconst, id, id)
; (EvalIf; propconst
<+ IfElse(id, propconst, id) /PropConst\ IfElse(id,id,propconst))
propconst-while =
?While(_, _)
; (/PropConst\* While(propconst, propconst))
Figure 7.4. file: til/xmpl/copyprop-test2
sglri -p ../syn/TIL.tbl -i copyprop-test2.til |\ ../sim/til-simplify |\ ../opt/til-copyprop |\ ast2text -p ../pp/TIL-pretty.pp -o copyprop-test2.txt
Table 7.2. files: til/xmpl/copyprop-test2.til, til/xmpl/copyprop-test2.txt
| before | after |
|---|---|
var x : int; var y : int; x := string2int(read()); y := x; y := y + 1; x := y; write(int2string(x)); | var x : int; var y : int; x := string2int(read()); y := x; y := x + 1; x := y; write(int2string(y)); |
Figure 7.5. file: til/opt/til-copyprop.str
module til-copyprop
imports til-opt-lib
strategies
io-til-copyprop =
io-wrap(copyprop)
copyprop =
CopyProp
<+ copyprop-declaration
<+ copyprop-assign
<+ copyprop-block
<+ copyprop-if
<+ copyprop-while
<+ all(copyprop)
copyprop-block =
Block({| CopyProp : map(copyprop) |})
copyprop-declaration =
(?Declaration(x) <+ ?DeclarationTyped(x, t))
; new-CopyProp(|x, x)
copyprop-assign =
Assign(?x, copyprop => e)
; undefine-CopyProp(|x)
; where( innermost-scope-CopyProp => z )
; if <?Var(y)> e then
rules( CopyProp.z : Var(x) -> Var(y) depends on [(x,x),(y,y)] )
end
copyprop-if =
IfElse(copyprop, id, id)
; (IfElse(id, copyprop, id) /CopyProp\ IfElse(id,id,copyprop))
copyprop-while =
?While(_, _)
; (/CopyProp\* While(copyprop, copyprop))
innermost-scope-CopyProp =
get-var-names => vars
; innermost-scope-CopyProp(elem-of(|vars))
Figure 7.6. file: til/opt/til-copyprop-rev.str
module til-copyprop-rev
imports til-opt-lib
strategies
io-til-copyprop-rev =
io-wrap(copyprop-rev)
copyprop-rev =
CopyPropRev
<+ copyprop-rev-declaration
<+ copyprop-rev-assign
<+ copyprop-rev-block
<+ copyprop-rev-if
<+ copyprop-rev-while
<+ all(copyprop-rev)
copyprop-rev-block =
Block({| CopyPropRev : map(copyprop-rev) |})
copyprop-rev-declaration =
(?Declaration(x) <+ ?DeclarationTyped(x, t))
; new-CopyPropRev(|x, x)
copyprop-rev-assign =
Assign(?x, copyprop-rev => e)
; undefine-CopyPropRev(|x)
; where( innermost-scope-CopyPropRev => z )
; if <?Var(y)> e then
rules( CopyPropRev.z : Var(y) -> Var(x) depends on [(x,x),(y,y)] )
end
copyprop-rev-if =
IfElse(copyprop-rev, id, id)
; (IfElse(id, copyprop-rev, id) /CopyPropRev\ IfElse(id,id,copyprop-rev))
copyprop-rev-while =
?While(_, _)
; (/CopyPropRev\* While(copyprop-rev, copyprop-rev))
innermost-scope-CopyPropRev =
get-var-names => vars
; innermost-scope-CopyPropRev(elem-of(|vars))
Figure 7.7. file: til/xmpl/cse-test2
sglri -p ../syn/TIL.tbl -i cse-test2.til |\ ../sim/til-simplify |\ ../opt/til-cse |\ ast2text -p ../pp/TIL-pretty.pp -o cse-test2.txt
Table 7.3. files: til/xmpl/cse-test2.til, til/xmpl/cse-test2.txt
| before | after |
|---|---|
var a; var b; var x; a := readint(); b := readint(); x := a + b; writeint(a + b); a := 23; x := a + b; writeint(a + b); | var a : int; var b : int; var x : int; a := string2int(read()); b := string2int(read()); x := a + b; write(int2string(x)); a := 23; x := a + b; write(int2string(x)); |
Figure 7.8. file: til/opt/til-cse.str
module til-cse
imports til-opt-lib
strategies
io-til-cse =
io-wrap(cse)
cse =
CSE
<+ cse-declaration
<+ cse-assign
<+ cse-if
<+ cse-block
<+ cse-while
<+ all(cse)
cse-block =
Block({| CSE : map(cse) |})
cse-declaration =
(?Declaration(x) <+ ?DeclarationTyped(x, t))
; new-CSE(|x, x)
cse-assign =
Assign(?x, cse => e)
; undefine-CSE(|x)
; if <not(contains(|Var(x)))> e then
where( innermost-scope-CSE => z )
; where( get-var-dependencies => deps )
; rules( CSE.z : e -> Var(x) depends on deps )
end
cse-if =
IfElse(cse, id, id)
; (IfElse(id, cse, id) /CSE\ IfElse(id,id,cse))
cse-while =
?While(_, _)
; (/CSE\* While(cse, cse))
innermost-scope-CSE =
get-var-names => vars
; innermost-scope-CSE(elem-of(|vars))
Figure 7.9. file: til/opt/til-forward-subst.str
module til-forward-subst
imports til-opt-lib
strategies
io-til-forward-subst =
io-wrap(forward-subst)
forward-subst =
ForwardSubst
<+ forward-subst-declaration
<+ forward-subst-assign
<+ forward-subst-if
<+ forward-subst-block
<+ forward-subst-while
<+ all(forward-subst)
forward-subst-block =
Block({| ForwardSubst : map(forward-subst) |})
forward-subst-declaration =
(?Declaration(x) <+ ?DeclarationTyped(x, t))
; new-ForwardSubst(|x, x)
forward-subst-assign =
Assign(?x, forward-subst => e)
; undefine-ForwardSubst(|x)
; if <not(is-var); is-pure-exp; not(contains(|Var(x)))> e then
where( innermost-scope-ForwardSubst => z )
; where( get-var-dependencies => deps )
; rules( ForwardSubst.z : Var(x) -> e depends on deps )
end
forward-subst-if =
IfElse(forward-subst, id, id)
; (IfElse(id, forward-subst, id) /ForwardSubst\ IfElse(id,id,forward-subst))
forward-subst-while =
?While(_, _)
; (/ForwardSubst\* While(forward-subst, forward-subst))
innermost-scope-ForwardSubst =
get-var-names => vars
; innermost-scope-ForwardSubst(elem-of(|vars))
Figure 7.10. file: til/xmpl/dce-test2
sglri -p ../syn/TIL.tbl -i dce-test2.til |\ ../sim/til-simplify |\ ../opt/til-dce |\ ast2text -p ../pp/TIL-pretty.pp -o dce-test2.txt
Table 7.4. files: til/xmpl/dce-test2.til, til/xmpl/dce-test2.txt
| before | after |
|---|---|
var x; var y; var z; var a; var b; z := readint(); x := 1; y := 2; x := 3; a := 7; y := 3 + z; if y then z := 8; x := 3; else x := 3; z := 7 + z; end b := 7 + z; z := 10; writeint(b + 10); | var y : int; var z : int; var b : int; z := string2int(read()); y := 3 + z; if y then z := 8; else z := 7 + z; end b := 7 + z; write(int2string(b + 10)); |
Figure 7.11. file: til/opt/til-dce.str
module til-dce
imports TIL til-eval liblib
rules
ElimDecl :
[Declaration(x) | st*] -> st*
where <not(VarUsed)> Var(x)
ElimDecl :
[DeclarationTyped(x, t) | st*] -> st*
where <not(VarUsed)> Var(x)
ElimAssign :
Assign(x, e) -> Block([])
where <not(VarNeeded)> Var(x)
ElimIf :
IfElse(e, [], []) -> Block([])
strategies
io-til-dce =
io-wrap(dce-program)
dce-stat =
ElimAssign
<+ dce-assign
<+ dce-proccall
<+ dce-if; try(ElimIf)
<+ dce-block
<+ dce-while
dce-program =
Program(dce-stats)
dce-block =
Block(dce-stats)
dce-stats =
dce-stats-decl
<+ dce-stats-other
<+ []
dce-stats-decl =
(?[Declaration(x) | _] <+ ?[DeclarationTyped(x, t) | _])
; {| VarNeeded, VarUsed
: rules(
VarNeeded+x :- Var(x)
VarUsed+x :- Var(x)
)
; [id | dce-stats]
; try(ElimDecl)
|}
dce-stats-other =
[not(?Declaration(_) <+ ?DeclarationTyped(_, _)) | dce-stats]
; [dce-stat | id]
; try(?[Block([]) | <id>])
dce-assign =
?Assign(x, _)
; rules( VarNeeded.x :- Var(x) )
; Assign(id, declare-var-needed)
dce-proccall =
ProcCall(id, map(declare-var-needed))
declare-var-needed =
alltd({x :
?Var(x)
; rules(
VarNeeded.x : Var(x)
VarUsed.x : Var(x)
)
})
dce-if =
?IfElse(_,_,_)
; (IfElse(id,dce-stats,id) /VarNeeded,VarUsed\ IfElse(id,id,dce-stats))
; IfElse(declare-var-needed, id, id)
dce-while =
?While(_, _)
; (\VarNeeded,VarUsed/* While(declare-var-needed, dce-stats))
Figure 7.12. file: til/opt/maak
#! /bin/sh -e
INCL="-I ../sig -I ../sim"
# compile forward-subst
strc ${INCL} -i til-forward-subst.str -la stratego-lib -m io-til-forward-subst -O 2
# compile dce
strc ${INCL} -i til-dce.str -la stratego-lib -m io-til-dce -O 2
# compile cse
strc ${INCL} -i til-cse.str -la stratego-lib -m io-til-cse
# compile copyprop
strc -i til-copyprop.str ${INCL} -la stratego-lib -m io-til-copyprop
# compile copyprop-rev
strc -i til-copyprop-rev.str ${INCL} -la stratego-lib -m io-til-copyprop-rev
# compile propconst
strc -i til-propconst.str ${INCL} -la stratego-lib -m io-til-propconst