97
Strategies for Rule-Based Program Transformation Software Engineering Techniques for Program Transformation Eelco Visser Center for Software Technology Department of Information & Computing Sciences Faculty of Science Utrecht University The Netherlands April 18, 2005 Dagstuhl Seminar Transformation Techniques in Software Engineering

Strategies for Rule-Based Program Transformation

Embed Size (px)

DESCRIPTION

Slides for invited talk at Seminar on Transformation Techniques in Software Engineering held in Dagstuhl in April 2005.

Citation preview

Page 1: Strategies for Rule-Based Program Transformation

Strategies for Rule-Based Program TransformationSoftware Engineering Techniques for Program Transformation

Eelco Visser

Center for Software TechnologyDepartment of Information & Computing Sciences

Faculty of ScienceUtrecht UniversityThe Netherlands

April 18, 2005Dagstuhl Seminar

Transformation Techniques in Software Engineering

Page 2: Strategies for Rule-Based Program Transformation

Sources

A Survey of Strategies in Rule-Based Program TransformationSystemsE. Visser (JSC 2005)

Program Transformation with Stratego/XTE. Visser (DSPG’03)

Program Transformation with Scoped Dynamic Rewrite RulesM. Bravenboer, A. van Dam, K. Olmos, and E. Visser (FI)

Composing Source-to-Source Data-Flow Transformations withRewriting Strategies and Dependent Dynamic Rewrite RulesK. Olmos and E. Visser. (CC’05)

Page 3: Strategies for Rule-Based Program Transformation

Sources

A Survey of Strategies in Rule-Based Program TransformationSystemsE. Visser (JSC 2005)

Program Transformation with Stratego/XTE. Visser (DSPG’03)

Program Transformation with Scoped Dynamic Rewrite RulesM. Bravenboer, A. van Dam, K. Olmos, and E. Visser (FI)

Composing Source-to-Source Data-Flow Transformations withRewriting Strategies and Dependent Dynamic Rewrite RulesK. Olmos and E. Visser. (CC’05)

Page 4: Strategies for Rule-Based Program Transformation

Sources

A Survey of Strategies in Rule-Based Program TransformationSystemsE. Visser (JSC 2005)

Program Transformation with Stratego/XTE. Visser (DSPG’03)

Program Transformation with Scoped Dynamic Rewrite RulesM. Bravenboer, A. van Dam, K. Olmos, and E. Visser (FI)

Composing Source-to-Source Data-Flow Transformations withRewriting Strategies and Dependent Dynamic Rewrite RulesK. Olmos and E. Visser. (CC’05)

Page 5: Strategies for Rule-Based Program Transformation

Outline

1 Program Transformation

2 Transformation Rules

3 Transformation Strategies

4 Dynamic Rules

Page 6: Strategies for Rule-Based Program Transformation

Part I

Program Transformation

Page 7: Strategies for Rule-Based Program Transformation

Computing with Programs

Program transformation is the domain of computing whereprograms are the data

Page 8: Strategies for Rule-Based Program Transformation

Improving Programs

Program transformation is the mechanical manipulation of aprogram in order to improve it relative to some cost function Csuch that

C (tr(P)) < C (P)

[Pettorossi 1996]

Dimensions of improvement

I Performance

I Memory usage

I Understandability

I Flexibility

I Maintainability

I Portability

I Correctness

I Satisfaction of requirements

Page 9: Strategies for Rule-Based Program Transformation

Improving Programs

Program transformation is the mechanical manipulation of aprogram in order to improve it relative to some cost function Csuch that

C (tr(P)) < C (P)

[Pettorossi 1996]

Dimensions of improvement

I Performance

I Memory usage

I Understandability

I Flexibility

I Maintainability

I Portability

I Correctness

I Satisfaction of requirements

Page 10: Strategies for Rule-Based Program Transformation

Application: Software Development

Software development is concerned with transformation fromrequirements to specification to implementation

Supporting abstraction

Approaches have varying degrees of automation

Page 11: Strategies for Rule-Based Program Transformation

Application: Software Development

Software development is concerned with transformation fromrequirements to specification to implementation

Supporting abstraction

Approaches have varying degrees of automation

Page 12: Strategies for Rule-Based Program Transformation

Application: Software Development

Software development is concerned with transformation fromrequirements to specification to implementation

Supporting abstraction

Approaches have varying degrees of automation

Page 13: Strategies for Rule-Based Program Transformation

Application: Software Development

Transformational programming [Partsch 1986, Feather 1987]

Formal development of implementations from specifications

I Properties

I Mechanizable and traceableI ‘Correct by construction’

I Fold/Unfold [Burstall & Darlington 1977]

I Calculating efficient programs from general onesI Application-specific

I Program refinement [Green, Paige, Smith, ...]

I Kids: Specialization of solution theories to domain theories

I Pragmas [Peyton Jones et al. 2001]

I Programmer directives to compiler

I Draco, Popart, CIP, ...

Page 14: Strategies for Rule-Based Program Transformation

Application: Software Development

Compilation [ASU 1986, ...]

Fully automatic transformation from high-level language tolow-level language

I Instruction selection [Fraser et al. 1992]

I cost-driven translation from IR to machine instructions

I Compilation by transformation [Peyton Jones & Santos 1998]

I compilation as sequence of small transformation steps

I Program optimization [Appel 1998, Muchnik 1997, ...]

I improve run-time, memory usage, power consumptionI inlining, constant propagation, dead code elimination, ...

I Application generation [Smaragdakis & Batory 2000]

I Compilation for domain-specific languages

Page 15: Strategies for Rule-Based Program Transformation

Application: Software Evolution

Software evolution is concerned with the understanding andmaintenance of existing legacy programs

Recovering abstractions

Reverse Engineering [Chikofski & Cross 1990, V.d. Brand et al. 1997]

Extract from a low-level program a high-level program orspecification

I Decompilation

I Architecture extraction

I Documentation generation

I Software Visualization

Page 16: Strategies for Rule-Based Program Transformation

Application: Software Evolution

Software evolution is concerned with the understanding andmaintenance of existing legacy programs

Recovering abstractions

Reverse Engineering [Chikofski & Cross 1990, V.d. Brand et al. 1997]

Extract from a low-level program a high-level program orspecification

I Decompilation

I Architecture extraction

I Documentation generation

I Software Visualization

Page 17: Strategies for Rule-Based Program Transformation

Application: Software Evolution

Software evolution is concerned with the understanding andmaintenance of existing legacy programs

Recovering abstractions

Reverse Engineering [Chikofski & Cross 1990, V.d. Brand et al. 1997]

Extract from a low-level program a high-level program orspecification

I Decompilation

I Architecture extraction

I Documentation generation

I Software Visualization

Page 18: Strategies for Rule-Based Program Transformation

Application: Software Evolution

Software Renovation

Change the extensional behaviour of a program

I Error repair (Y2K)

I Changing requirements (Euro)

I Refactoring [Fowler 1999]

I improving the design of existing programs

I Obfuscation [Collberg et al. 1998]

I make a program harder to understand

Migration

Transformation to another language at the same level ofabstraction

I Dialect upgrading

I Porting (Pascal to C, Java to C#)

Page 19: Strategies for Rule-Based Program Transformation

Realizing Program Transformations

Transformations are useful in software engineering if they are

I Correct

I Reproducable

I Automatic

I Scalable

How to compose transformation systems that have theseproperties?

What are the right abstractions for building transformationsystems?

Goal

A component-based approach to program transformation in whichbasic transformation components can be reused in many differentcompositions.

Page 20: Strategies for Rule-Based Program Transformation

Realizing Program Transformations

Transformations are useful in software engineering if they are

I Correct

I Reproducable

I Automatic

I Scalable

How to compose transformation systems that have theseproperties?

What are the right abstractions for building transformationsystems?

Goal

A component-based approach to program transformation in whichbasic transformation components can be reused in many differentcompositions.

Page 21: Strategies for Rule-Based Program Transformation

Realizing Program Transformations

Transformations are useful in software engineering if they are

I Correct

I Reproducable

I Automatic

I Scalable

How to compose transformation systems that have theseproperties?

What are the right abstractions for building transformationsystems?

Goal

A component-based approach to program transformation in whichbasic transformation components can be reused in many differentcompositions.

Page 22: Strategies for Rule-Based Program Transformation

Realizing Program Transformations

Transformations are useful in software engineering if they are

I Correct

I Reproducable

I Automatic

I Scalable

How to compose transformation systems that have theseproperties?

What are the right abstractions for building transformationsystems?

Goal

A component-based approach to program transformation in whichbasic transformation components can be reused in many differentcompositions.

Page 23: Strategies for Rule-Based Program Transformation

Program Transformation Mechanics

Basic Components

Transformation rule: one step transformation of part of a program

Perspective

A high-level, language parametric, rule-based programtransformation system, which supports a wide range oftransformations, admitting efficient implementations that scale tolarge programs

Practice

Many different systems with different trade-offs

I expressivity of rule specification

I strategies for control

I efficiency of implementation

I object languages supported

I range of transformations

Page 24: Strategies for Rule-Based Program Transformation

Program Transformation Mechanics

Basic Components

Transformation rule: one step transformation of part of a program

Perspective

A high-level, language parametric, rule-based programtransformation system, which supports a wide range oftransformations, admitting efficient implementations that scale tolarge programs

Practice

Many different systems with different trade-offs

I expressivity of rule specification

I strategies for control

I efficiency of implementation

I object languages supported

I range of transformations

Page 25: Strategies for Rule-Based Program Transformation

Program Transformation Mechanics

Basic Components

Transformation rule: one step transformation of part of a program

Perspective

A high-level, language parametric, rule-based programtransformation system, which supports a wide range oftransformations, admitting efficient implementations that scale tolarge programs

Practice

Many different systems with different trade-offs

I expressivity of rule specification

I strategies for control

I efficiency of implementation

I object languages supported

I range of transformations

Page 26: Strategies for Rule-Based Program Transformation

Architecture of Transformation Systems

program

tree

program

transform

parse pretty-print

transformtree tree

Page 27: Strategies for Rule-Based Program Transformation

Part II

Transformation Rules

1 Program Transformation

2 Transformation Rules

3 Transformation Strategies

4 Dynamic Rules

Page 28: Strategies for Rule-Based Program Transformation

Example: Desugaring

for i := 1 to n dofor j := 1 to n doc[i,j] := sum k = 1 to n (a[i,k] * b[k,j])

for i := 1 to n dofor j := 1 to n do

c[i,j] := let var d := 0in for k := 1 to n do

d := d + a[i,k] * b[k,j];d

end

let var din for i := 1 to n do

for j := 1 to n do(d := 0;for k := 1 to n do d := d + a[i,k] * b[k,j];c[i,j] := d)

end

Page 29: Strategies for Rule-Based Program Transformation

Example: Desugaring

for i := 1 to n dofor j := 1 to n doc[i,j] := sum k = 1 to n (a[i,k] * b[k,j])

for i := 1 to n dofor j := 1 to n doc[i,j] := let var d := 0

in for k := 1 to n dod := d + a[i,k] * b[k,j];

dend

let var din for i := 1 to n do

for j := 1 to n do(d := 0;for k := 1 to n do d := d + a[i,k] * b[k,j];c[i,j] := d)

end

Page 30: Strategies for Rule-Based Program Transformation

Example: Desugaring

for i := 1 to n dofor j := 1 to n doc[i,j] := sum k = 1 to n (a[i,k] * b[k,j])

for i := 1 to n dofor j := 1 to n doc[i,j] := let var d := 0

in for k := 1 to n dod := d + a[i,k] * b[k,j];

dend

let var din for i := 1 to n do

for j := 1 to n do(d := 0;for k := 1 to n do d := d + a[i,k] * b[k,j];c[i,j] := d)

end

Page 31: Strategies for Rule-Based Program Transformation

Programs as Terms

Abstract Syntax

Programs can be represented as terms

sum k = 1 to n (a[i,k] * b[k,j])

Sum([Index("k",Int("1"),Var("n"))],Times(Subscript(Var("a"),[Var("i"),Var("k")]),

Subscript(Var("b"),[Var("k"),Var("j")])))

Page 32: Strategies for Rule-Based Program Transformation

Patterns

Term patterns can be used to analyze and compose programs

Sum([idx | idx*], e)

matches

Sum([Index("k",Int("1"),Var("n"))],Times(Subscript(Var("a"),[Var("i"),Var("k")]),

Subscript(Var("b"),[Var("k"),Var("j")])))

Page 33: Strategies for Rule-Based Program Transformation

Rewrite Rules

SumSplit :Sum([idx | idx*], e) -> Sum([idx], Sum(idx*, e))where <not([])> idx*

DefSum :Sum([Index(x, e1, e2)], e3) ->Let([VarDec(y, NoTp(), Int("0"))],

[For(Var(x), e1, e2,Assign(Var(y), Plus(Var(y), e3))),

Var(y)])where new => y

LetFromAssign :Assign(lv, Let(d*, e*)) ->Let(d*, [Assign(lv, Seq([e*]))])

Page 34: Strategies for Rule-Based Program Transformation

Term Rewriting

Term rewriting = normalization with respect to a set of rules

normalization = exhaustive application

normal form : no sub-term can be rewritten

Page 35: Strategies for Rule-Based Program Transformation

Patterns in Concrete Syntax

I Problem: terms are hard to read, especially larger terms

I Observation: one-to-one correspondence between abstractsyntax and concrete syntax

I Solution: use concrete syntax for patterns

SumSplit :|[ sum idx; idx* (e) ]| -> |[ sum idx(sum idx*(e)) ]|where <not([])> idx*

DefSum :|[ sum x = e1 to e2 ( e3 ) ]| ->|[ let var y := 0

in for x := e1 to e2 do y := y + e3; y

end ]|where new => y

Page 36: Strategies for Rule-Based Program Transformation

Systems that support Term Rewriting

I OBJ

I ASF+SDF

I Elan

I Maude

I TXL

I DMS

I ...

Page 37: Strategies for Rule-Based Program Transformation

Extensions of Term Rewriting

I Matching modulo equations

I Associative, commutative, identity, ...I List matchingI Combinations: A, AC, ACI, AI

I Object variable bindings

I De Bruijn indicesI Higher-order abstract syntaxI FreshML

Page 38: Strategies for Rule-Based Program Transformation

Part III

Transformation Strategies

1 Program Transformation

2 Transformation Rules

3 Transformation Strategies

4 Dynamic Rules

Page 39: Strategies for Rule-Based Program Transformation

Example: Compilation by Transformation

sum k = 1 to n(a[i,k] * b[k,j])

a_0 := 0;k := 1;d_0 := n;t_3 := k <= d_0;label f_0;i_0 := not(t_3);if i_0 goto g_0;t_1 := a[i,k];t_2 := b[k,j];t_0 := t_1 * t_2;a_0 := a_0 + t_0;k := k + 1;t_3 := k <= d_0;goto f_0;label g_0

a_0 := 0;for k := 1 to n do(t_1 := a[i,k];t_2 := b[k,j];t_0 := t_1 * t_2;a_0 := a_0 + t_0)

a_0 := 0;k := 1;d_0 := n;t_3 := k <= d_0;while t_3 do(t_1 := a[i,k];t_2 := b[k,j];t_0 := t_1 * t_2;a_0 := a_0 + t_0;k := k + 1;t_3 := k <= d_0)

Page 40: Strategies for Rule-Based Program Transformation

Controlling Application of Rules

Limitations of Term Rewriting

I Non-Termination

I Exhaustive application may not terminate

I Non-Confluence

I There may be diverging paths in rewrite relation

I Non-Selection

I All rules are applied everywhere

Program transformation requires control over application of rules

Page 41: Strategies for Rule-Based Program Transformation

Controlling Application of Rules

Common Solution: Functional Rewriting

Use extra constructors (called ‘functions’) to define control-point

I Traversal overhead: one rule for each constructor

I Tangling of rules and strategy: rules not reusable

Compile(e) ->CollectDecls(SimpleExpressions(ForToWhile(Desugar(e))))

Desugar(|[ sum idx; idx+ (e) ]|) ->Desugar(|[ sum idx(sum idx+ (e)) ]|)

Desugar(|[ sum x = e1 to e2 ( e3 ) ]|) ->Desugar(|[ ... ]|

Desugar(|[ let d1* in e1* ]|) -> |[ let d2* in e2* ]|where Desugar(d1*) => d2*; Desugar(e1*) => e2*

Page 42: Strategies for Rule-Based Program Transformation

Controlling Application of Rules

Strategic Control

I Application of rules controlled by strategies

I Select rules and strategy

I Separation of rules and strategies

I reuse of rules in multiple transformationsI instantiate strategies with different rules

TAMPR [Boyle et al. 1997]

I Transformation Assisted Multiple Program Realization

I Normalization with selection of rules

I Sequence of normal forms: divide transformation in stages

Similar to layered graph grammars?

Page 43: Strategies for Rule-Based Program Transformation

Staged Transformation

compile =for-with-while; return-value; mark-procedure-calls; simple-expressions; control-flow-to-goto; collect-declarations; use-return-register; vars-on-stack; add-stack-machine; flatten-sequences; unmark-procedure-calls

Compilation by sequence oftransformations

for-with-while =topdown(try(ForToWhile))

simple-expressions =innermost(Simplify <+ LiftNonAtomicArgument <+ Desugar

<+ LetSplit)

Page 44: Strategies for Rule-Based Program Transformation

Controlling Application of Rules

Strategic Rewriting [Luttik & Visser 1997]

I Application of rules controlled by strategies

I Select rules and strategy

I Separation of rules and strategies

I reuse of rules in multiple transformationsI instantiate strategies with different rules

I Strategies are composed using strategy combinators

I Generic traversal reduces traversal overhead

Strategic Programming [Laemmel, Visser & Visser 2003]

Language independent paradigm for programming with strategies,in particular, generic traversals.

Instantiated for rewriting, logic programming, functionalprograming, object-oriented programming

Page 45: Strategies for Rule-Based Program Transformation

Controlling Application of Rules

Strategic Rewriting [Luttik & Visser 1997]

I Application of rules controlled by strategies

I Select rules and strategy

I Separation of rules and strategies

I reuse of rules in multiple transformationsI instantiate strategies with different rules

I Strategies are composed using strategy combinators

I Generic traversal reduces traversal overhead

Strategic Programming [Laemmel, Visser & Visser 2003]

Language independent paradigm for programming with strategies,in particular, generic traversals.

Instantiated for rewriting, logic programming, functionalprograming, object-oriented programming

Page 46: Strategies for Rule-Based Program Transformation

Sequential Composition

Sequential Composition

I Syntax: s1; s2I Apply s1, then s2I Fails if either s1 or s2 fails

I Variable bindings are propagated

Plus(Var("a"),Int("3"))stratego> ?Plus(e1, e2); !Plus(e2, e1)Plus(Int("3"),Var("a"))

Page 47: Strategies for Rule-Based Program Transformation

Deterministic Choice

Deterministic Choice (Left Choice)

I Syntax: s1 <+s2I First apply s1, if that fails apply s2I Note: local backtracking

PlusAssoc :Plus(Plus(e1, e2), e3) -> Plus(e1, Plus(e2, e3))

EvalPlus :Plus(Int(i),Int(j)) -> Int(k) where <addS>(i,j) => k

Plus(Int("14"),Int("3"))stratego> PlusAssoccommand failedstratego> PlusAssoc <+ EvalPlusInt("17")

Page 48: Strategies for Rule-Based Program Transformation

Identity and Failure

Identity

I Syntax: id

I Always succeedI Some laws

I id ; s ≡ sI s ; id ≡ sI id <+ s ≡ idI s <+ id 6≡ s

Failure

I Syntax: fail

I Always failI Some laws

I fail <+ s ≡ sI s <+ fail ≡ sI fail ; s ≡ failI s ; fail 6≡ fail

Defined Combinators

try(s) = s <+ id

repeat(s) = try(s; repeat(s))

while(c, s) = if c then s; while(c,s) end

do-while(s, c) = s; if c then do-while(s, c) end

Page 49: Strategies for Rule-Based Program Transformation

Traversal

Traversal Styles

Full traversal

I Folds: functional programming

I Visitors: object-oriented programming

Strategic programming

I One-level traversal combinator

I descend to direct subterms

I Combine into multiple full traversal strategies

I Flavours

I Congruence operator: specific for signatureI Generic: independent of signature

Page 50: Strategies for Rule-Based Program Transformation

Traversal Strategies

Visiting All Subterms

I Syntax: all(s)

I Apply strategy s to all direct sub-terms

Plus(Int("14"),Int("3"))stratego> all(!Var("a"))Plus(Var("a"),Var("a"))

bottomup(s) = all(bottomup(s)); stopdown(s) = s; all(topdown(s))downup(s) = s; all(downup(s)); salltd(s) = s <+ all(alltd(s))innermost(s) = bottomup(try(s; innermost(s)))

for-with-while = topdown(try(ForToWhile))simple-expressions =

innermost(Simplify <+ LiftNonAtomicArgument <+ Desugar<+ LetSplit)

Page 51: Strategies for Rule-Based Program Transformation

Traversal Strategies

Visiting All Subterms

I Syntax: all(s)

I Apply strategy s to all direct sub-terms

Plus(Int("14"),Int("3"))stratego> all(!Var("a"))Plus(Var("a"),Var("a"))

bottomup(s) = all(bottomup(s)); stopdown(s) = s; all(topdown(s))downup(s) = s; all(downup(s)); salltd(s) = s <+ all(alltd(s))innermost(s) = bottomup(try(s; innermost(s)))

for-with-while = topdown(try(ForToWhile))simple-expressions =

innermost(Simplify <+ LiftNonAtomicArgument <+ Desugar<+ LetSplit)

Page 52: Strategies for Rule-Based Program Transformation

Traversal Strategies

Visiting All Subterms

I Syntax: all(s)

I Apply strategy s to all direct sub-terms

Plus(Int("14"),Int("3"))stratego> all(!Var("a"))Plus(Var("a"),Var("a"))

bottomup(s) = all(bottomup(s)); stopdown(s) = s; all(topdown(s))downup(s) = s; all(downup(s)); salltd(s) = s <+ all(alltd(s))innermost(s) = bottomup(try(s; innermost(s)))

for-with-while = topdown(try(ForToWhile))simple-expressions =innermost(Simplify <+ LiftNonAtomicArgument <+ Desugar

<+ LetSplit)

Page 53: Strategies for Rule-Based Program Transformation

Traversal Strategies

Congruence Operator: Data-type Specific Traversal

I Syntax: c(s1,...,sn)for each n-ary constructor c

I Apply strategies to direct sub-terms of a c term

Plus(Int("14"),Int("3"))stratego> Plus(!Var("a"), id)Plus(Var("a"),Int("3"))

mark-procedure-calls =rec mark(alltd(Assign(id, id)<+ While(id, mark)<+ For(id, id, id, mark)<+ If(id, mark, mark)<+ VarDec(id, id, id)<+ !Proc(<Call(id,id)>)))

Page 54: Strategies for Rule-Based Program Transformation

History of Strategies

A Slice of History

I LCF etc: tactics in theorem provers

I ASF+SDF language processing environment: rewriting(later added traversal functions)

I Rewriting logic

I ELAN specification system: rewriting & strategy expressions

I Stratego: generic traversal & dynamic rules

I Strafunski: generic traversal in Haskell

I JJTraveler: visitor combinators in Java

Other Slices

I TXL: generic traversal function

I DMS

I ...

Page 55: Strategies for Rule-Based Program Transformation

Part IV

Dynamic Rules

1 Program Transformation

2 Transformation Rules

3 Transformation Strategies

4 Dynamic Rules

Page 56: Strategies for Rule-Based Program Transformation

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

Page 57: Strategies for Rule-Based Program Transformation

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

Page 58: Strategies for Rule-Based Program Transformation

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

Page 59: Strategies for Rule-Based Program Transformation

Constant Folding

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)

Page 60: Strategies for Rule-Based Program Transformation

Constant Folding

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)

Page 61: Strategies for Rule-Based Program Transformation

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

Page 62: Strategies for Rule-Based Program Transformation

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

Page 63: Strategies for Rule-Based Program Transformation

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

Page 64: Strategies for Rule-Based Program Transformation

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

Page 65: Strategies for Rule-Based Program Transformation

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

Page 66: Strategies for Rule-Based Program Transformation

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

Page 67: Strategies for Rule-Based Program Transformation

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

Page 68: Strategies for Rule-Based Program Transformation

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

Page 69: Strategies for Rule-Based Program Transformation

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

Page 70: Strategies for Rule-Based Program Transformation

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

Page 71: Strategies for Rule-Based Program Transformation

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

Page 72: Strategies for Rule-Based Program Transformation

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

Page 73: Strategies for Rule-Based Program Transformation

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

Page 74: Strategies for Rule-Based Program Transformation

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

Page 75: Strategies for Rule-Based Program Transformation

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

Page 76: Strategies for Rule-Based Program Transformation

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

Page 77: Strategies for Rule-Based Program Transformation

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

Page 78: Strategies for Rule-Based Program Transformation

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

Page 79: Strategies for Rule-Based Program Transformation

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 80: Strategies for Rule-Based Program Transformation

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 81: Strategies for Rule-Based Program Transformation

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

Page 82: Strategies for Rule-Based Program Transformation

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

Page 83: Strategies for Rule-Based Program Transformation

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

Page 84: Strategies for Rule-Based Program Transformation

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

Page 85: Strategies for Rule-Based Program Transformation

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

Page 86: Strategies for Rule-Based Program Transformation

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

Page 87: Strategies for Rule-Based Program Transformation

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

Page 88: Strategies for Rule-Based Program Transformation

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

Page 89: Strategies for Rule-Based Program Transformation

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]

Page 90: Strategies for Rule-Based Program Transformation

Dependent Dynamic Rules

Dependent Dynamic Rules

Record all dependencies of dynamic rules in order to undefine allrules depending on a dependencyUse to define generic data-flow strategies

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)

Page 91: Strategies for Rule-Based Program Transformation

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

Page 92: Strategies for Rule-Based Program Transformation

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, aspect

weaving, ...

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

I Java Compilername disambiguation, type propagation, assimilation of embedded

domain-specific languages

Page 93: Strategies for Rule-Based Program Transformation

Other Approaches to Context-Sensitive Transformation

I Environments

I explicit threadingI dynamic rules abstract over environments, symbol tables, etc.

I Attribute grammars

I implicit scheduling of attribute evaluation (declarative)I incremental evaluation: interaction between analysis and

transformation

I Graph transformations

I Regular path queries [De Moor et al 2004]

I Side conditions are regular expressions over execution pathsreaching this node

Page 94: Strategies for Rule-Based Program Transformation

Conclusion

I Programmable rewriting strategies and dynamic rules

I Small set of abstractions

I Supports a wide range of transformations

I For a wide range of languages

Page 95: Strategies for Rule-Based Program Transformation

Challenges

I Integration

I equational matchingI object variable bindingsI regular path queries (De Moor)I combining rewriting and attribute grammars (JastAdd; Hedin)

I Extensibility of transformation systems

I domain-/application-specific optimization pluginsI language extensions and embeddings

I Higher level abstractions for transformation

I make transformations available to programmersI capture class of transformations for specific languageI compile to strategiesI example: aspects

Page 96: Strategies for Rule-Based Program Transformation

Expectations

I’m always looking for new transformation problems to applytransformation strategies to and interested in subsuming cooltransformation mechanisms

Page 97: Strategies for Rule-Based Program Transformation

The End