+ All Categories
Home > Documents > Program analysis & Synthesis

Program analysis & Synthesis

Date post: 17-Feb-2016
Category:
Upload: bevan
View: 45 times
Download: 0 times
Share this document with a friend
Description:
Lecture 06 – Inter-procedural Analysis. Program analysis & Synthesis. Eran Yahav. Previously. Verifying absence of buffer overruns (requires) Heap abstractions (requires) Combining heap and numerical information. Today. LFP computation and join-over-all-paths I nter-procedural analysis - PowerPoint PPT Presentation
Popular Tags:
93
1 PROGRAM ANALYSIS & SYNTHESIS Lecture 06 – Inter-procedural Analysis Eran Yahav
Transcript
Page 1: Program analysis & Synthesis

PROGRAM ANALYSIS & SYNTHESIS

Lecture 06 – Inter-procedural Analysis

Eran Yahav

Page 2: Program analysis & Synthesis

2

Previously

Verifying absence of buffer overruns (requires) Heap abstractions (requires) Combining heap and

numerical information

Page 3: Program analysis & Synthesis

Today

LFP computation and join-over-all-paths

Inter-procedural analysis

Acks Some slides adapted from

Noam Rinetzky and Mooly Sagiv DNA of some slides traces back to Tom

Reps3

Page 4: Program analysis & Synthesis

4

Join over all paths (JOP) Propagate analysis information along paths A path is a sequence of edges in the CFG [e1, e2, …, en] Can define the transfer function for a path via transformer

composition let fi denote f(ei) f[e1, e2, …, en] = fn … f2 f1

Consider the (potentially infinite) set of paths reaching a label in the program from entry. Denote by Paths-to-in(entry,l) the set of paths from entry to label l, similarly for paths-to-out

The result at program point l can be defined as JOPin (l) = { f[p](initial) | p paths-to-in(entry,l) } JOPout(l) = { f[p](initial) | p paths-to-out(entry,l) }

Page 5: Program analysis & Synthesis

5

The lfp computation approximates JOP

JOPout(l) = { f[p](initial) | p paths-to-out(entry,l) }

Set of paths potentially infinite (non computable)

The lfp computation take joins “earlier” Merging sub-paths

For a monotone function f(x y) f(x) f(y)

Page 6: Program analysis & Synthesis

6

lfp computation and JOP

e1

e2

e3

e4

e5

e6

e7

e8

Paths transformers:f[e1,e2,e3,e4]f[e1,e2,e7,e8]f[e5,e6,e7,e8]f[e5,e6,e3,e4]

JOP: f[e1,e2,e3,e4](initial) f[e1,e2,e7,e8](initial) f[e5,e6,e7,e8](initial) f[e5,e6,e3,e4](initial)

“lfp” computation:j1 =f[e1,e2](initial) f[e5,e6](initial)j2 = f[e3,e4](j1) f[e7,e8](j1)

(wrote “lfp” just to emphasize that no iteration is required here, no loops)

Page 7: Program analysis & Synthesis

7

Interprocedural Analysis

The effect of calling a procedure is the effect of executing its body

Call bar()

foo()

bar()

Page 8: Program analysis & Synthesis

Interprocedural Analysis

Stack can grow without a bound Matching of call/return

8

Page 9: Program analysis & Synthesis

9

Solution Attempt #1

Inline callees into callers End up with one big procedure CFGs of individual procedures

= duplicated many times Good: it is precise

distinguishes different calls to the same function

Bad exponential blow-up, not

efficient doesn’t work with recursion

Page 10: Program analysis & Synthesis

Simple Exampleint p(int a) {

return a + 1;

}

void main() {

int x ;

x = p(7);

x = p(9) ;

}

Page 11: Program analysis & Synthesis

Simple Examplevoid main() {

int x ;

x = 7; x = x + 1;

x = 9; x = x + 1;

}

[x 8]

[x 10]

Page 12: Program analysis & Synthesis

Inlining: Exponential Blowup

12

main() { f1(); f1(); }f1() { f2(); f2(); }…fn() { ... }

Page 13: Program analysis & Synthesis

13

Solution Attempt #2

Build a “supergraph” = inter-procedural CFG Replace each call from P to Q with

An edge from point before the call (call point) to Q’s entry point An edge from Q’s exit point to the point after the call (return pt) Add assignments of actuals to formals, and assignment of return

value Good: efficient

Graph of each function included exactly once in the supergraph Works for recursive functions (although local variables need

additional treatment) Bad: imprecise, “context-insensitive”

The “unrealizable paths problem”: dataflow facts can propagate along infeasible control paths

Page 14: Program analysis & Synthesis

Simple Exampleint p(int a) {

return a + 1;

}

void main() {

int x ;

x = p(7);

x = p(9) ;

}

Page 15: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a 7]

return a + 1;

}

void main() {

int x ;

x = p(7);

x = p(9) ;

}

Page 16: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a 7]

return a + 1;

[a 7, $$ 8]

}

void main() {

int x ;

x = p(7);

x = p(9) ;

}

Page 17: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a 7]

return a + 1;

[a 7, $$ 8]

}

void main() {

int x ;

x = p(7);

[x 8]

x = p(9) ;

[x 8]

}

Page 18: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a 7]

return a + 1;

[a 7, $$ 8]

}

void main() {

int x ;

x =l p(7);

[x 8]

x = p(9) ;

[x 8]

}

Page 19: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a ]

return a + 1;

[a 7, $$ 8]

}

void main() {

int x ;

x = p(7);

[x 8]

x = p(9) ;

[x 8]

}

Page 20: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a ]

return a + 1;

[a , $$ ]

}

void main() {

int x ;

x = p(7);

[x 8]

x = p(9);

[x 8]

}

Page 21: Program analysis & Synthesis

Simple Exampleint p(int a) {

[a ]

return a + 1;

[a , $$ ]

}

void main() {

int x ;

x = p(7) ;

[x ]

x = p(9) ;

[x ]

}

Page 22: Program analysis & Synthesis

22

Unrealizable Paths

Call bar()

foo()

bar()

Call bar()

zoo()

Page 23: Program analysis & Synthesis

IVP: Interprocedural Valid Paths

( )

f1 f2 fk-1 fk

f3

f4

f5

fk-2

fk-3

callq

enterq exitq

ret

IVP: all paths with matching calls and returns And prefixes

Page 24: Program analysis & Synthesis

24

Valid Paths

Call bar()

foo()

bar()

Call bar()

zoo()

(1

)1

(2

)2

Page 25: Program analysis & Synthesis

Interprocedural Valid Paths

IVP set of paths Start at program entry

Only considers matching calls and returns aka, valid

Can be defined via context free grammar matched ::= matched (i matched )i | ε valid ::= valid (i matched | matched

paths can be defined by a regular expression

Page 26: Program analysis & Synthesis

The Join-Over-Valid-Paths (JVP)

vpaths(n) all valid paths from program start to n

JVP[n] = {e1, e2, …, e (initial) (e1, e2, …, e) vpaths(n)}

JVP JFP In some cases the JVP can be computed (Distributive problem)

Page 27: Program analysis & Synthesis

Sharir and Pnueli ‘82

Call String approach Blend interprocedural flow with intra

procedural flow Tag every dataflow fact with call history

Functional approach Determine the effect of a procedure

E.g., in/out map Treat procedure invocations as “super

ops”

Page 28: Program analysis & Synthesis

The Call String Approach

Record at every node a pair (l, c) where l L is the dataflow information and c is a suffix of unmatched calls

Use Chaotic iterations To guarantee termination limit the size

of c (typically 1 or 2) Emulates inline (but no code growth) Exponential in size of c

Page 29: Program analysis & Synthesis

begin proc p() is1 [x := a + 1]2

end3

[a=7]4

[call p()]56

[print x]7

[a=9]8

[call p()]910

[print a]11

end

proc p

x=a+1

end

a=7

call p5

call p6

print x

a=9

call p9

call p10

print a

[x0, a0][x0, a7] 5,[x0,

a7]5,[x0, a7]

5,[x8, a7]

[x8, a7]

[x8, a7]

[x8, a7]

[x8, a9]

9,[x8, a9] 9,[x8,

a9]9,[x10,

a9]

[x10, a9]

5,[x8, a7]

9,[x10, a9]

Page 30: Program analysis & Synthesis

begin0 proc p() is1

if [b]2 then ( [a := a -1]3

[call p()]45

[a := a + 1]6

) [x := -2* a + 5]7

end8

[a=7]9 ; [call p()]1011 ; [print(x)]12

end13

a=7

Call p10

Call p11

print(x)

p

If( … )

a=a-1

Call p4

Call p5

a=a+1

x=-2a+5

end

10:[x0, a7]

[x0, a7]

[x0, a0] 10:[x0, a7]

10:[x0, a6]

4:[x0, a6]

4:[x0, a6]

4:[x-7, a6]

10:[x-7, a6]4:[x-7, a6]4:[x-7,

a6]4:[x-7,

a7]4:[x, a]

Page 31: Program analysis & Synthesis

Simple Exampleint p(int a) {

return a + 1;

}

void main() {

int x ;

c1: x = p(7);

c2: x = p(9) ;

}

Page 32: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1: [a 7]

return a + 1;

}

void main() {

int x ;

c1: x = p(7);

c2: x = p(9) ;

}

Page 33: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1: [a 7]

return a + 1;

c1:[a 7, $$ 8]

}

void main() {

int x ;

c1: x = p(7);

c2: x = p(9) ;

}

Page 34: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1: [a 7]

return a + 1;

c1:[a 7, $$ 8]

}

void main() {

int x ;

c1: x = p(7);

: x 8

c2: x = p(9) ;

}

Page 35: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1:[a 7]

return a + 1;

c1:[a 7, $$ 8]

}

void main() {

int x ;

c1: x = p(7);

: [x 8]

c2: x = p(9) ;

}

Page 36: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1:[a 7] c2:[a 9]

return a + 1;

c1:[a 7, $$ 8]

}

void main() {

int x ;

c1: x = p(7);

: [x 8]

c2: x = p(9) ;

}

Page 37: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1:[a 7] c2:[a 9]

return a + 1;

c1:[a 7, $$ 8] c2:[a 9, $$10]

}

void main() {

int x ;

c1: x = p(7);

: [x 8]

c2: x = p(9) ;

}

Page 38: Program analysis & Synthesis

Simple Exampleint p(int a) {

c1:[a 7] c2:[a 9]

return a + 1;

c1:[a 7, $$ 8] c2:[a 9, $$ 10]

}

void main() {

int x ;

c1: x = p(7);

: [x 8]

c2: x = p(9) ;

: [x 10]

}

Page 39: Program analysis & Synthesis

Another Exampleint p(int a) {

c1:[a 7] c2:[a 9]

return c3: p1(a + 1);

c1:[a 7, $$ ] c2:[a 9, $$ ]

}

void main() {

int x ;

c1: x = p(7);

: [x 8]

c2: x = p(9) ;

: [x 10]

}

int p1(int b) {

(c1|c2)c3:[b ]

return 2 * b;

(c1|c2)c3:[b , $$]

}

Page 40: Program analysis & Synthesis

int p(int a) {

c1: [a 7] c1.c2+: [a ]

if (…) {

c1: [a 7] c1.c2+: [a ]

a = a -1 ;

c1: [a 6] c1.c2+: [a ]

c2: p (a);

c1.c2*: [a ]

a = a + 1; c1.c2*: [a ] }c1.c2*: [a ]

x = -2*a + 5;c1.c2*: [a , x]

}

void main() {

c1: p(7);: [x ]

}

Recursion

Page 41: Program analysis & Synthesis

Summary: Call String

Simple Only feasible for very short call

strings exponential in call-string length

Often loses precision under recursion although can still be precise in some

cases

41

Page 42: Program analysis & Synthesis

The Functional Approach

The meaning of a procedure is mapping from states into states

The abstract meaning of a procedure is function from an abstract state to abstract states

Page 43: Program analysis & Synthesis

Functional Approach: Main Idea Iterate on the abstract domain of

functions from L to L Two phase algorithm

Compute the dataflow solution at the exit of a procedure as a function of the initial values at the procedure entry (functional values)

Compute the dataflow values at every point using the functional values

Computes JVP for distributive problems

Page 44: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 45: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

[a a0, x x0]

x = -2*a + 5;

}

void main() {

p(7);

}

Page 46: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

[a a0, x x0]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 47: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

[a a0-1, x x0]

p (a);

a = a + 1;

{

[a a0, x x0]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 48: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

[a a0-1, x x0]

p (a);

[a a0-1, x -2a0+7]

a = a + 1;

{

[a a0, x x0]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 49: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

[a a0-1, x x0]

p (a);

[a a0-1, x -2a0+7]

a = a + 1;

[a a0, x -2a0+7]

{

[a a0, x x0]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 50: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

[a a0-1, x x0]

p (a);

[a a0-1, x -2a0+7]

a = a + 1;

[a a0, x -2a0+7]

{

[a a0, x ]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 51: Program analysis & Synthesis

Phase 1int p(int a) {

[a a0, x x0]

if (…) {

a = a -1 ;

[a a0-1, x x0]

p (a);

[a a0-1, x -2a0+7]

a = a + 1;

[a a0, x -2a0+7]

{

[a a0, x ]

x = -2*a + 5;

[a a0, x -2a0 + 5]

}

void main() {

p(7);

}

Page 52: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

x = -2*a + 5;

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 53: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

[a 7, x 0]

x = -2*a + 5;

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 54: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

p (a);

a = a + 1;

{

[a 7, x 0]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 55: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

a = a + 1;

{

[a 7, x 0]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 56: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

{

[a 7, x 0]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 57: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x 0]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 58: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 59: Program analysis & Synthesis

int p(int a) {

[a 7, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 60: Program analysis & Synthesis

int p(int a) {

[a 7, x 0] [a 6, x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 61: Program analysis & Synthesis

int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a 6, x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 62: Program analysis & Synthesis

int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a , x 0]

p (a);

[a 6, x -9]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 63: Program analysis & Synthesis

int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a , x 0]

p (a);

[a , x ]

a = a + 1;

[a 7, x -9]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 64: Program analysis & Synthesis

Phase 2int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a , x 0]

p (a);

[a , x ]

a = a + 1;

[a , x ]

{

[a 7, x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Page 65: Program analysis & Synthesis

int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a , x 0]

p (a);

[a , x ]

a = a + 1;

[a , x ]

{

[a , x ]

x = -2*a + 5;

[a 7, x -9]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 66: Program analysis & Synthesis

int p(int a) {

[a , x 0]

if (…) {

a = a -1 ;

[a , x 0]

p (a);

[a , x ]

a = a + 1;

[a , x ]

{

[a , x ]

x = -2*a + 5;

[a , x ]

}

void main() {

p(7);

[x -9]

}

p(a0,x0) = [a a0, x -2a0 + 5]

Phase 2

Page 67: Program analysis & Synthesis

Issues in Functional Approach

How to guarantee finite height for functional lattice? Possible that L has finite height and yet the

lattice of monotonic function from L to L do not

Efficiently represent functions Functional join Functional composition Testing equality

Page 68: Program analysis & Synthesis

Tabulation

Special case: L is finite Data facts: d L L Initialization:

fstart,start= (,) ; otherwise (,) S[start, ] =

Propagation of (x,y) over edge e = (n,n’) Maintain summary: S[n’,x] = S[n’,x] n (y)) n intra-node: n’: (x, n (y)) n call-node: n’: (y,y) if S[n’,y] = and n’= entry

node n’: (y,z) if S[n’,y] = z and n’= rest-

site-of n n return-node: n’: (u,y) ; nc = call-site-of n’, S[nc,u]=x

Page 69: Program analysis & Synthesis

IFDS

IFDS Interprocedural Distributive Finite Subset Precise interprocedural dataflow analysis via graph reachability. Reps, Horowitz, and Sagiv, POPL’95

Page 70: Program analysis & Synthesis

IFDS Problems

Finite subset distributive Lattice L = (D) is is Transfer functions are distributive

Efficient solution through formulation as CFL reachability

Page 71: Program analysis & Synthesis

Possibly Uninitialized Variables Start

x = 3

if …

y = xy = w

w = 8

printf(y)

{w,x,y}

{w,y}

{w,y}{w,y}

{w}

{w,y}{}

{w,y}

{}

V.VV.V

V.V – { x }

V. { x, y, z }

V. if x V then V { y } else V – { y } V. if w V

then V { y } else V – { y }

V.V – { w }

Page 72: Program analysis & Synthesis

72

Encoding Transfer Functions Enumerate all input space and output space Represent functions as graphs with 2(D+1) nodes Special symbol “0” denotes empty sets

(sometimes denoted ) Example: D = { a, b, c }

f(S) = (S – {a}) U {b}

0 a b c

0 a b c

Page 73: Program analysis & Synthesis

Representing Dataflow FunctionsIdentity Function

VV .f

}{.f bVConstant Function

a b c

a b c

},{}),f({ baba

}{}),f({ bba

Page 74: Program analysis & Synthesis

}{}){.(f cbVV

}{ else }{ then

if .f

bVbV

VaV

“Gen/Kill” Function

Non-“Gen/Kill” Functiona b c

a b c

},{}),f({ caba

},{}),f({ baba

Representing Dataflow Functions

Page 75: Program analysis & Synthesis

Exploded Supergraph

Exploded supergraph Start with supergraph Replace each node by its graph

representation Add edges between corresponding elements

in D at consecutive program points CFL reachability

Finding MOVP solution is equivalent to computing CFL reachability over the exploded supergraph using the valid parentheses grammar.

Page 76: Program analysis & Synthesis

x = 3

p(x,y)

return from p

printf(y)

start main

exit main

start p(a,b)

if . . .b = a

p(a,b)

return from p

printf(b)

exit p

x y a b

Page 77: Program analysis & Synthesis

The Tabulation Algorithm

Worklist algorithm, start from entry of “main” Keep track of

Path edges: matched paren paths from procedure entry Summary edges: matched paren call-return paths

At each instruction Propagate facts using transfer functions; extend path edges

At each call Propagate to procedure entry, start with an empty path If a summary for that entry exits, use it

At each exit Store paths from corresponding call points as summary paths When a new summary is added, propagate to the return node

Page 78: Program analysis & Synthesis

else }{ then

if .f 2

cVbV

a b c}{ else }{then

if .f 1

bVbV

VaV

b ca

Composing Dataflow Functions

}{ else }{then

if .f 1

bVbV

VaV

b ca

else }{ then

if .f 2

cVbV

}),({ff 12 ca }{c

Page 79: Program analysis & Synthesis

x = 3

p(x,y)

return from p

start main

exit main

start p(a,b)

if . . .b = a

p(a,b)

return from p

exit p

x y a b

printf(y)

Might b beuninitializedhere?

printf(b) NO!

(

]

Might y beuninitializedhere?

YES!

(

)

Page 80: Program analysis & Synthesis

Interprocedural Dataflow Analysis via CFL-Reachability

Graph: Exploded control-flow graph L: L(unbalLeft)

unbalLeft = valid Fact d holds at n iff there is an

L(unbalLeft)-path from <Start main,> to <n,d>

Page 81: Program analysis & Synthesis

Asymptotic Running Time

CFL-reachability Exploded control-flow graph: ND nodes Running time: O(N3D3)

Exploded control-flow graph Special structure

Running time: O(ED3)

Typically: E l N, hence O(ED3) l O(ND3)

“Gen/kill” problems: O(ED)

Page 82: Program analysis & Synthesis

Recap

inter-procedural analysis inlining call-string approach functional approach

Page 83: Program analysis & Synthesis

83

Page 84: Program analysis & Synthesis

begin proc p() is1

if [b]2 then ( [a := a -1]3

[call p()]45

[a := a + 1]6

) [x := -2* a + 5]7

end8

[a=7]9 ; [call p()]1011 ; [print(x)]12

end

a=7

Call p10

Call p11

print(x)

p

If( … )

a=a-1

Call p4

Call p5

a=a+1

x=-2a+5

end

[x0, a7]

[x0, a0]

e.[x-2e(a)+5, a e(a)]

[x-9, a7][x-9, a7]

Page 85: Program analysis & Synthesis

begin proc p() is1

if [b]2 then ( [a := a -1]3

[call p()]45

[a := a + 1]6

) [x := -2* a + 5]7

end8

[read(a)]9 ; [call p()]1011 ; [print(x)]12

end

read(a)

Call p10

Call p11

print(x)

p

If( … )

a=a-1

Call p4

Call p5

a=a+1

x=-2a+5

end

[x0, a]

[x0, a0]

e.[x-2e(a)+5, a e(a)]

[x, a][x, a]

Page 86: Program analysis & Synthesis

Example: Constant propagation L = VarN {, } Domain: F:LL

(f1f2)(x) = f1(x)f2(x)

x=7

y=x+1

x=y

env.env[x7]

env.env[yenv(x)+1]

Id=envL.env

env.env[x7] env.env

env.env[yenv(x)+1] env.env[x7] env.env

Page 87: Program analysis & Synthesis

Example: Constant propagation

L = VarN {, } Domain: F:LL

(f1f2)(x) = f1(x)f2(x)

x=7 y=x+1

x=y

env.env[x7] env.env[yenv(x)+1]

Id=env.envId=env.env

env.env[yenv(x)+1] env.env[x7]

Page 88: Program analysis & Synthesis

init N Function0 e.[xe(x), ae(a)]=id1 e.[xe(x), ae(a)]=id3-13 e.

a=79

Call p10

Call p11

print(x)12

p1

If( … )2

a=a-13

Call p4

Call p5

a=a+16

x=-2a+57

end8

begin0

end13

Page 89: Program analysis & Synthesis

Solution (F)N Function1 e. [xe(x), ae(a)]=id

2 id

7 id8 e.[x-2e(a)+5, a e(a)]3 id

4 e.[xe(x), a e(a)-1]

5 f8 ○ e.[xe(x), a e(a)-1] =e.[x-2(e(a)-1)+5, a e(a)-1]

6 e.[x-2(e(a)-1)+ 5, a e(a)-1]

7 e.[x-2(e(a)-1)+5, a e(a)] e.[x e(x), a e(a)]

8 a, x.[x-2e(a)+5, a e(a)]

0 e.[xe(x), ae(a)]=id10 e.[xe(x), a7]11 a, x.[x-2e(a)+5, a e(a)] ○ f10

a=79

Call p10

Call p11

print(x)12

p1

If( … )2

a=a-13

Call p4

Call p5

a=a+16

x=-2a+57

end8

begin0

end13

Page 90: Program analysis & Synthesis

Solution (D)N Function1 [x0, a7]2 [x0, a7]7 [x0, a7]8 [x-9, a7]3 [x0, a7]4 [x0, a6]

1 [x-7, a6]

6 [x-7, a7]

7 [x, a7]

8 [x-9, a7]

1 [x, a]

0 [x0, a0]10 [x0, a7]11 [x-9, a7]

a=79

Call p10

Call p11

print(x)12

p1

If( … )2

a=a-13

Call p4

Call p5

a=a+16

x=-2a+57

end8

begin0

end13

Page 91: Program analysis & Synthesis

91

Interprocedural Analysis

Extend language with begin/end and with [call p()]clab

rlab Call label clab, and return label rlab

begin proc p() is1 [x := a + 1]2

end3

[a=7]4

[call p()]56

[print x]7

[a=9]8

[call p()]910

[print a]11

end

Page 92: Program analysis & Synthesis

92

Work-list AlgorithmChaotic(G(V, E): CFG, s: Node, L: Lattice, : L, f: E (L L)){ for each v in V to n do dfentry[v] := df[v] = WL = {s} while (WL ) do select and remove an element u WL for each v, such that (u, v) E do temp = f(e)(dfentry[u]) new := dfentry(v) temp if (new dfentry[v]) then dfentry[v] := new; WL := WL {v}

Page 93: Program analysis & Synthesis

93

Complexity of Chaotic Iterations

Parameters n the number of CFG nodes k is the maximum outdegree of edges A lattice of height h c is the maximum cost of

applying f(e) L comparisons

Complexity: O(n * h * c * k)(slide from Mooly Sagiv)


Recommended