Composing Dataflow Analyses and Transformations Sorin Lerner (University of Washington) David Grove...

download Composing Dataflow Analyses and Transformations Sorin Lerner (University of Washington) David Grove (IBM T.J. Watson) Craig Chambers (University of Washington)

of 58

  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    212
  • download

    0

Embed Size (px)

Transcript of Composing Dataflow Analyses and Transformations Sorin Lerner (University of Washington) David Grove...

  • Slide 1
  • Composing Dataflow Analyses and Transformations Sorin Lerner (University of Washington) David Grove (IBM T.J. Watson) Craig Chambers (University of Washington)
  • Slide 2
  • x := 11; if (x == 11) { DoSomething(); } else { DoSomethingElse(); x := x + 1; } y := x; // value of y? Phase ordering problem Optimizations can interact in mutually beneficial ways, and no order exploits all of these interactions. Classic example: constant propagation and unreachable code elimination. x := 11; DoSomething(); y := x; // value of y? x := 11; DoSomething(); y := 11; const prop followed by unreachable code elimination const prop again true
  • Slide 3
  • One known solution: Iterate individual analyses until the results dont change x := 11; do { if (x == 11) { DoSomething(); } else { DoSomethingElse(); x := x + 1; } } while (...) y := x; // value of y? Compiler is slow. In the presence of loops in the source program, might not yield best possible results.
  • Slide 4
  • Another known solution: hand written super-analysis Lose modularity: difficult to write, reuse, and extend such analyses Examples: conditional constant propagation [Wegman and Zadeck 91] class analysis, splitting and inlining [Chambers and Ungar 90] const prop and pointer analysis [Pioli and Hind 99] Monolithic Super-Analysis
  • Slide 5
  • Ideally...... we want to: Write analyses modularly Exploit mutually beneficial interactions Have a fast compiler We present a framework that achieves this. Composition Framework
  • Slide 6
  • The key to modular composition Traditionally, optimizations are defined in two parts: 1.A dataflow analysis. 2.Rules for transforming the program representation after the analysis is solved. The key insight is to merge these two parts: Dataflow functions return either a dataflow value OR a replacement graph with which to replace the current statement.
  • Slide 7
  • Roadmap Several small examples that show how flow functions work One large example that shows how modular analyses are automatically composed together Overview of the theory behind the framework Experimental validation
  • Slide 8
  • Flow function returning a dataflow value y := 5
  • Slide 9
  • Flow function returning a dataflow value y := 5 [... ] [..., y 5] PROPAGATE
  • Slide 10
  • Flow function returning a replacement graph y := x+2
  • Slide 11
  • [x 3] Flow function returning a replacement graph y := x+2 [x 3] REPLACE y := 5 Replacement graph Step 1: Initialize input edges with dataflow information
  • Slide 12
  • Flow function returning a replacement graph y := 5 [x 3] PROPAGATE [x 3, y 5] Step 2: Perform recursive dataflow analysis on the replacement graph
  • Slide 13
  • Flow function returning a replacement graph y := 5 [x 3] PROPAGATE [x 3, y 5] Step 3: Propagate dataflow information from output edges.
  • Slide 14
  • Flow function returning a replacement graph y := x+2 [x 3] [x 3, y 5] Replacement graphs: used to compute outgoing dataflow information for the current statement. Replacement graphs: used to compute outgoing dataflow information for the current statement. a convenient way of specifying what might otherwise be a complicated flow function.
  • Slide 15
  • Flow function returning a replacement graph y := x+2 [x 3] [x 3, y 5] Soundness requirement: Replacement graph must have the same concrete semantics as the original statement, but only on concrete inputs that are consistent with the current dataflow facts.
  • Slide 16
  • Flow function returning a replacement graph y := x+2 [x 3] [x 3, y 5] Lets assume weve reached a fixed point.
  • Slide 17
  • Flow function returning a replacement graph y := x+2 [x 3] [x 3, y 5] y := 5 Lets assume weve reached a fixed point.
  • Slide 18
  • Flow function returning a replacement graph y := 5 [x 3] [x 3, y 5] Replacement graphs: used to transform the program once a fixed point has been reached. Lets assume weve reached a fixed point.
  • Slide 19
  • Iterative analysis example y := x+2 [x 3, y 5] [x 3][x T ] Now, lets assume we havent reached a fixed point.
  • Slide 20
  • Iterative analysis example y := x+2 [x 3, y 5] PROPAGATE [x 3][x T ] [x T, y T ] Now, lets assume we havent reached a fixed point.
  • Slide 21
  • Branch folding example if (x == 11) FT
  • Slide 22
  • Branch folding example if (x == 11) REPLACE [x 11] FT
  • Slide 23
  • Branch folding example [x 11]
  • Slide 24
  • Branch folding example if (x == 11) [x 11] FT
  • Slide 25
  • Composing several analyses x := new C; do { b := x instanceof C; if (b) { x := x.foo(); } else { x := new D; } } while (...) class A { A foo() { return new A; } }; class C extends A { A foo() { return self; } }; class D extends A { }; Constant Propagation Class Analysis Inlining Unreachable code elimination
  • Slide 26
  • x := new C merge b := x instanceof C x := new Dx := x.foo() merge while() if (b) TF
  • Slide 27
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) PROPAGATE while() PROPAGATE [x T ] [x {C}] T merge TF PROPAGATE T
  • Slide 28
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) PROPAGATE while() PROPAGATE [x T ] [x {C}] T ([x T ], [x {C}], T, T ) merge PROPAGATE TF T
  • Slide 29
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) PROPAGATE ([x T ], [x {C}], T, T ) while() merge TF
  • Slide 30
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) while() PROPAGATE [x T, b T ] merge TF ([x T ], [x {C}], T, T )
  • Slide 31
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) ([x T ], [x {C}], T, T ) REPLACE b := true while() [x T, b T ] merge TF ([x T ], [x {C}], T, T )
  • Slide 32
  • b := true ([x T ], [x {C}], T, T ) ([x T, b true], [x {C}, b {Bool}], T, T ) PROPAGATE
  • Slide 33
  • ([x T, b true], [x {C}, b {Bool}], T, T ) ([x T, b true], [x {C}, b {Bool}], T, T ) b := true ([x T ], [x {C}], T, T )
  • Slide 34
  • ([x T, b true], [x {C}, b {Bool}], T, T ) x := new C b := x instanceof C x := new Dx := x.foo() if (b) Replacement graph is analyzed by composed analysis. When one analysis chooses a replacement graph, other analyses see it immediately. Analyses communicate implicitly through graph transformations while() merge TF ([x T ], [x {C}], T, T )
  • Slide 35
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) ([x T, b true], [x {C}, b {Bool}], T, T ) REPLACE while() merge TF ([x T ], [x {C}], T, T )
  • Slide 36
  • x := new C b := x instanceof C x := new Dx := x.foo() if (b) ([x T, b true], [x {C}, b {Bool}], T, T ) while() merge TF ([x T ], [x {C}], T, T )