Fine Slicing: Theory and Applications for Computation Extraction Aharon Abadi,Ran Ettinger,Yishai A. Feldman IBM Research – Haifa 1 Program Slicing Program Slice Start Slice x := exp The same sequence of values 2 Example x := 6 y := 3 f(x,y) x := 9 y:=2 w : = x*y w := 18 x := 6 y := 2 f(x,y) x := 9 y:=2 w : = x*y z := w x := 6 y := 3 x := 9 y:=2 w : = x*y w : = x*y w := 18 x := 9 y:=2 w : = x*y z := w z := w 3 Control-Flow Path Compression test X if-zero-go-to A . . . L:test Y if-zero- go-to B . . . go-to L A:Z0 . . . B: Work in two stages: - Compute the ‘traditional’ slice - Control dependences - Data Dependences - Compute the necessary branches to prevent infeasible control paths 4 Control-Flow Path Compression test X test X if-zero-go-to A if-zero-go-to A . . . go-to B A:Z0 L:test Y if-zero- go-to B B: . . . go-to L A:Z0 . . . B: This algorithm: - preserves behavior - yields a sub-program - one version may turn conditional branches into unconditional ones (“rhetorization”) 5 Data-Flow Path Compression Start:R2:=0 Start:R2:=0 R7:=exp1 Loop: R2:=R2 + 1 Loop: R2:=R2 + 1 compare R2, R9 compare R2, R9 R7:=exp1 if-not-less-go-to Out if-not-less-go-to Out Out: R0:=R7 + 1 Temp:=R7 use R7 R7:=Temp Temp:=R7; spill R7 to memory go-to Loop Out: R0:=R7 + 1 … ; code that uses R7:=exp1 ; all registers R7:=Temp; restore R7 go-to Loop Out: R0:= R7 + 1 The result is too large The value of R7 does not depend on the loop 6 Control-Flow Path Compression if (x<11) goto A4 F x := x+1 goto A2 A4: if (x<9) goto A3 x := x-1 A1: if (y<T) goto A2 x<11 T goto A4 x:=x+1 T goto A2 x<9 F goto A3 x:=x+2 x:=x-1 y := y–1 goto A1 T A3: x := x+2 y<T F goto A2 A2: print(x) print(x) y:=y-1 goto A 7 Compute the ‘Traditional’ Slice if (x<11) goto A4 F x := x+1 goto A2 A4: if (x<9) goto A3 x := x-1 A1: if (y<T) goto A2 x<11 T goto A4 x:=x+1 T goto A2 x<9 F goto A3 x:=x+2 y := y–1 x:=x-1 goto A1 T A3: x := x+2 y<T F goto A2 A2: print(x) print(x) y:=y-1 goto A 8 Completing Control Flow Paths: Main Lemma All paths from the same point in the slice enter the slice at a single point • precisely identifies the possible sets of branches that may be added to the slice • any path in the original program can be chosen • optimizations can be performed 9 Compute the Necessary Branches F if(x<11) goto A4 x:=x+1 goto A2 A4: if(x<9) goto A3 x:=x-1 A1: if(y<T) goto A2 x<11 T x:=x+1 goto A4 goto A2 T x<9 F goto A3 x:=x+2 x:=x-1 y:=y–1 goto A1 T A3: x:=x+2 y<T F goto A2 A2: print(x) print(x) y:=y-1 goto A 10 Data-Flow Path Compression Start:R2:=0 R7:=exp1 Loop: R2:=R2 + 1 compare R2, R9 if-not-less-go-to Out use R7 Temp:=R7; spill R7 to ;memory … ; code that uses ;all registers R7:=Temp; restore R7 go-to Loop Out: R0:=R7 + 1 R2:=0 R7:=exp1 R2:=R2+1 compare R2,R9 if-not-less use R7 go-to Out Temp:=R7 R7:=exp1 Out:R0:=R7 + 1 +1 R0:=R7+1 R7:=Temp goto Loop exit 11 Data-Flow Path Compression Start:R2:=0 R7:=exp1 Loop: R2:=R2 + 1 compare R2, R9 if-not-less-go-to Out use R7 Temp:=R7; spill R7 to ; memory … ; code that uses ; all registers R7:=Temp; restore R7 go-to Loop Out: R0:=R7+1 R2:=0 0 d1 d2 R7:=exp1 exp1 d1 R2:=R2+1 ++ in data port holds the next value compare R2,R9 out data port holds the last value if-not-less use R7 go-to Out Temp:=R7 • The Plan Calculus: The Programmer’s Apprentice, Rich and Waters, 1990 • R7,Temp carry the value of exp1 R7:=R7+1 ++ R7:=Temp • Use data edges instead of variables goto-Loop exit 12 Start:R2:=0 R7:=exp1 Loop: R2:=R2 + 1 compare R2, R9 if-not-less-go-to Out use R7 Temp:=R7; spill R7 to ; memory … ; code that uses ; all registers R7:=Temp; restore R7 go-to Loop Out: R0:=R7 + 1 entry exp1 0 R2 R9 R2 ++ R7 compare R2,R9 if-not-less R7:= exp1 R0:=R7 + 1 T F use R7 ++ R0 exit 13 Decompression Start:R2:=0 R7:=exp1 Loop:R2:=R2 + 1 compare R2, R9 if-not-less- go-to Out use R7 Temp:=R7; spill R7 to ; memory … ; code that uses ; all registers R7:=Temp; restore R7 go-to Loop Out: R0:=R7 + 1 entry exp1 0 R2 R9 R2 ++ R7 compare R2,R9 if-not-less T R7:=exp1 F use R7 go-to Out Out: R0:=R7 + 1 ++ R0 exit 14 If(q) goto Skip If(q) i := 0 x := 1 i := 0 i x := 1 Loop: If(i>10) goto Out i := i + 1 goto loop If(q) goto Skip 0 i := 0 x := 1 x := 1 goto Skip goto Out Skip: x := 2 Out: print(x) 2 Skip: x := 2 Out: print(x) x := 2 If(i>10) 1 + goto out x := 2 x := 1 print(x) 15 Fine Slicing Motivating Example Automatically extracts Out computation (The view model) out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; I < end; i++) { Picture picture = album.getPicture(i); pictures.add(picture); } display(out, start, end, pictures); void display(PrintStream out, int start, int end, Queue<Picture> pictures) { out.println("<table border=0>"); for (int i = start; i < end; i++) { printPicture(out,pictures.remove()); } out.println("</table>"); } 16 slice (v.): to cut with or as if with a knife slice (n.): a thin flat piece cut from something 17 Merriam-Webster Fine Slicing • A generalization of traditional program slicing • Fine slices can be precisely bounded – Slicing criteria include set of data and control dependences to ignore • Fine slices are executable and extractable • Complement slices (co-slices) are also fine slices • Oracle-based semantics for fine slices • Algorithm for computing data-structure representing the oracle 18 Extract Computation • • • • A new refactoring Extracts a fine slice into contiguous code Computes the co-slice Computation can then be extracted into a separate method using Extract Method • Passes necessary “oracle” variables between slice and co-slice • Generates new containers if series of values need to be passed 19 entry out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); "<table border=0>" out println page Token Semantics 20 * start + out album out getPictures i size end min getPicture p2 p1 end "</table>" out i out p2 p1 < println printPicture T ++ F exit 20 entry out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); "<table border=0>" out println page Fine Slicing 20 * start + out album out getPictures i size end min getPicture end "</table>" out i out < println printPicture T ++ F exit 21 entry out.println("<table border=0>"); for (int i = start; i < end; i++) { printPicture(out, picture); } out.println("</table>"); "<table border=0>" out println start picture p1 p2 p3 end The Fine Slice out out i "</table>" out i out < println printPicture T ++ F exit 22 entry out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); "<table border=0>" out println Co-Slicing page 20 * start + out album out getPictures i size end min getPicture end "</table>" out i out < println printPicture T ++ F exit 23 entry int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); } The CoSlice page 20 * start + album getPictures i size end min getPicture i start picture out < end T ++ F exit 24 entry Co-slice Fine slice page entry 20 "<table border=0>" * out start println + end start picture album getPictures i end size min getPicture p1 p2 p3 picture start i i out < "</table>" < printPicture end out T println T ++ F out exit ++ F A place for The call 25 exit How do we distinguish between sequence of values and single value? entry "<table border=0>" out println page 20 * start + out album out Every cycle of control that passes through entry out din does not pass through println dout Therefore din requires single value start picture getPictures "<table border=0>" end out out i i size end min getPicture end "</table>" "</table>" out i out i out out < printPicture < printPicture ++ println T T println F F exit ++ exit 26 How do we distinguish between sequence of values and single value? entry "<table border=0>" out println page 20 * start + out album out There is a cycle of control that passes through din and dout Therefore din may require multiple single value picture getPictures entry out "<table border=0>" println start end out out i i size end min getPicture end "</table>" "</table>" out i out i out out < printPicture < printPicture ++ println T T println F F exit ++ exit 27 Adding Container out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); void display(PrintStream out, int start, int end, Picture picture) { out.println("<table border=0>"); for (int i = start; i < end; i++) { printPicture(out,picture); } out.println("</table>"); } out.println("<table border=0>"); int start = page * 20; void display(PrintStream out, int start, int end = start + 20; int end, Queue<Picture> pictures) { end = Math.min(end, out.println("<table border=0>"); album.getPictures().size()); Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; i < end; i++) { for (int i = start; i < end; i++) { printPicture(out,pictures.remove()); Picture picture = album.getPicture(i); } pictures.add(picture); out.println("</table>"); printPicture(out,pictures.remove()); } } out.println("</table>"); 28 Adding Container out.println("<table border=0>"); void display(PrintStream out, int start, int start = page * 20; int end, Queue<Picture> pictures) { int end = start + 20; out.println("<table border=0>"); end = Math.min(end, for (int i = start; i < end; i++) { album.getPictures().size()); printPicture(out,pictures.remove()); Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; i < end; i++) { } Picture picture = album.getPicture(i); out.println("</table>"); pictures.add(picture); } printPicture(out,pictures.remove()); } out.println("</table>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; I < end; i++) { Picture picture = album.getPicture(i); pictures.add(picture); } display(out, start, end, pictures); 29 out.println("<table border=0>"); entry "<table border=0>" int start = page * 20; out int end = start + 20; println end = Math.min(end, album.getPictures().size()); page 20 Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; i < end; i++) { * Picture picture = album.getPicture(i); start pictures.add(picture); printPicture(out,pictures.remove()); } + out album out.println("</table>"); out Adding a Container getPictures i pictures size end min getPicture new pictures picture pictures add end pictures remove "</table>" out i out picture < println printPicture T ++ F exit 30 entry void display(PrintStream out, int start, int end, Queue<Picture> pictures){ out.println("<table border=0>"); for (int i = start; i < end; i++) { printPicture(out, pictures.remove()); } out.println("</table>"); } "<table border=0>" out The Fine Slice println end start pictures out out i pictures pictures "</table>" remove out i out picture < println printPicture T ++ F exit 31 out.println("<table border=0>"); entry "<table border=0>" int start = page * 20; out int end = start + 20; println end = Math.min(end, album.getPictures().size()); page 20 Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; i < end; i++) { * Picture picture = album.getPicture(i); start pictures.add(picture); printPicture(out,pictures.remove()); } + out album out.println("</table>"); out Program with Container getPictures i pictures size end min getPicture new pictures picture pictures add end pictures remove "</table>" out i out picture < println printPicture T ++ F exit 32 int start = page * 20; entry int end = start + 20; end = Math.min(end, album.getPictures().size()); Queue<Picture> pictures = new LinkedList<Picture>(); page for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); pictures.add(picture); } display(out, start, end, pictures); out The CoSlice 20 * start + album getPictures start i pictures size end min getPicture new pictures picture add pictures end pictures pictures i < display out T ++ F exit 33 Fine Slicing Motivating Example Automatically extracts Out computation (The view model) out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); Queue<Picture> pictures = new LinkedList<Picture>(); for (int i = start; I < end; i++) { Picture picture = album.getPicture(i); pictures.add(picture); } display(out, start, end, pictures); void display(PrintStream out, int start, int end, Queue<Picture> pictures) { out.println("<table border=0>"); for (int i = start; i < end; i++) { printPicture(out,pictures.remove()); } out.println("</table>"); } 34 Fine Slicing Algorithm • Compute the core slice by following unfiltered data and control dependence relations backwards in the plan. • (Semantic Restoration) Add necessary tests to make the slice executable. out.println("<table border=0>"); int start = page * 20; int end = start + 20; end = Math.min(end, album.getPictures().size()); for (int i = start; i < end; i++) { Picture picture = album.getPicture(i); printPicture(out, picture); } out.println("</table>"); 35 Fine Slicing Algorithm • Compute the core slice by following unfiltered data and control dependence relations backwards in the plan. • (Semantic Restoration) Add necessary tests to make the slice executable. Stat1; if(q){ x = x + 1;; }else{ y = x + 2; stat1; x = x + 1;; y = x + 2; } 36 Extract Computation • Get as input the program (P) and slicing criteria (SC) • Compute the fine slice (FS) corresponding to P and SC • Compute the Co-Slice: – Compute fine slice starting from P\FS – Disconnect the return values according to SC • Add containers to the fine slice and co-slice • Add the call from co-slice to the fine slice 37