680 likes | 912 Views
Spring 2014 Program Analysis and Verification Lecture 8: Static Analysis II. Roman Manevich Ben-Gurion University. Syllabus. Previously. Static Analysis by example Simple Available Expressions analysis Abstract transformer for assignments Three-address code
E N D
Spring 2014Program Analysis and Verification Lecture 8: Static Analysis II Roman Manevich Ben-Gurion University
Previously • Static Analysis by example • Simple Available Expressions analysis • Abstract transformer for assignments • Three-address code • Processing serial composition • Processing conditions • Processing loops
Defining an SAV abstract transformer { y=z+w} x:=a { y=z+w } { y=x+w} x:=a { } { y=w+x} x:=a { } {} x:= { x= } { x=} x:=a { } [kill-rhs-1] [kill-rhs-2] [kill-lhs] [preserve] [gen] Is either a variable v or an addition expression v+w Goal: define a function FSAV[x:=a] : s.t.if FSAV[x:=a](D) = D’then sp(x := a, Conj(D)) Conj(D’) Idea: define rules for individual factsand generalize to sets of facts by the conjunction rule
Defining a semantic reduction • Idea: make as many implicit facts explicit by • Using symmetry and transitivity of equality • Commutativity of addition • Meaning of equality – can substitute equal variables • For an SAV-predicate P=Conj(D) defineExplicate(D) = minimal set D* such that: • D D* • x=y D* implies y=x D* • x=y D*y=z D* implies x=z D* • x=y+z D* implies x=z+y D* • x=y D* and x=z+w D* implies y=z+w D* • x=y D* and z=x+w D* implies z=y+w D* • x=z+w D* and y=z+w D* implies x=y D* • Notice that Explicate(D) D • Explicate is a special case of a semantic reduction
Annotating assignments Define:F*[x:=aexpr] = Explicate FSAV[x:=aexpr] Annotate(P, x:=aexpr) = {P} x:=aexprF*[x:=aexpr](P)
Annotating composition Annotate(P, S1; S2) = let Annotate(P, S1) be {P} A1 {Q1} let Annotate(Q1, S2) be {Q1} A2 {Q2} return {P} A1; {Q1} A2 {Q2}
Simplifying conditions • Extend While with • Non-determinism (or) and • An assume statement assumeb, s sossif B b s = tt • Now, the following two statements are equivalent • if bthenS1elseS2 • (assumeb; S1) or (assumeb; S2)
assume transformer Define (bexpr) = if bexpr is factoid {bexpr}else {} Define F[assumebexpr](D) = D (bexpr) Can sharpenF*[assumebexpr] = Explicate FSAV[assumebexpr]
Annotating conditions letPt = F*[assumebexpr]P letPf = F*[assumebexpr]P let Annotate(Pt, S1) be {Pt} A1 {Q1} let Annotate(Pf, S2) be {Pf} A2 {Q2} return {P}ifbexprthen{Pt} A1 {Q1} else{Pf} A2 {Q2}{Q1 Q2}
k-loop unrolling { y=x+a, y=a+x, w=d, d=w } if (x z) x := x + 1 y := x + a d := x + aQ1 = { y=x+a, y=a+x } { P }Inv = { N }while (x z) do x := x + 1 y := x + a d := x + a { P }if (x z) x := x + 1 y := x + a d := x + aQ1 = { y=x+a, y=a+x } if (x z) x := x + 1 y := x + a d := x + aQ2 = { y=x+a, y=a+x } The following must hold:P NQ1 NQ2 N…Qk N… Observation 1: No need to explicitly unroll loop – we can reuse postcondition from unrolling k-1 for k We can compute the following sequence:N0 = PN1 = N1 Q1N2 = N1 Q2…Nk = Nk-1 Qk …
Annotating loops Annotate(P, whilebexprdo S) = Initialize N:= Nc := Prepeat let Annotate(P, if b then S else skip) be {Nc} if bexpr then S else skip {N}Nc := Nc Nuntil N= Nc return {P} INV= NwhilebexprdoF[assumebexpr](N)Annotate(F[assumebexpr](N),S)F[assumebexpr](N)
Annotating programs Annotate(P, S) = caseS is x:=aexpr return {P} x:=aexpr {F*[x:=aexpr] P} caseSisS1; S2 let Annotate(P, S1) be {P} A1 {Q1} let Annotate(Q1, S2) be {Q1} A2 {Q2} return {P} A1; {Q1} A2 {Q2} caseSisifbexprthenS1elseS2 letPt = F[assumebexpr]P letPf = F[assumebexpr]P let Annotate(Pt, S1) be {Pt} A1 {Q1} let Annotate(Pf, S2) be {Pf} A2 {Q2} return {P} ifbexprthen {Pt} A1 {Q1}else {Pf} A2 {Q2} {Q1 Q2} caseSiswhilebexprdoS N:= Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N}Nc := Nc N untilN= Nc return{P} INV= {N} whilebexprdo {Pt} Abody {F[assumebexpr](N)}
Today • Another static analysis example – constant propagation • Basic concepts in static analysis • Control flow graphs • Equation systems • Collecting semantics • (Trace semantics)
Second static analysis example simplifies constant expressions constantfolding { x=c } y := aexpr y := eval(aexpr[c/x]) • Optimization: constant folding • Example: x:=7; y:=x*9transformed to: x:=7; y:=7*9and then to: x:=7; y:=63 • Analysis: constant propagation (CP) • Infers facts of the form x=c
Plan Define domain – set of allowed assertions Handle assignments Handle composition Handle conditions Handle loops
CP semantic domain • Define CP-factoids: = { x = c | x Var, c Z } • How many factoids are there? • Define predicates as = 2 • How many predicates are there? • Do all predicates make sense? (x=5) (x=7) • Treat conjunctive formulas as sets of factoids {x=5, y=7} ~ (x=5) (y=7)
CP abstract transformer ? Goal: define a functionFCP[x:=aexpr] : such thatif FCP[x:=aexpr] P = P’then sp(x:=aexpr, P) P’
CP abstract transformer { x=c} x:=aexpr { } [kill] {} x:=c { x=c } [gen-1] { y=c1, z=c2} x:=y op z{ x=c} and c=c1op c2 [gen-2] { y=c } x:=aexpr{ y=c } [preserve] Goal: define a functionFCP[x:=aexpr] : such thatif FCP[x:=aexpr] P = P’then sp(x:=aexpr, P) P’
Gen-kill formulation of transformers • Suited for analysis propagating sets of factoids • Available expressions, • Constant propagation, etc. • For each statement, define a set of killed factoids and a set of generated factoids F[S] P = (P \ kill(S)) gen(S) • FCP[x:=aexpr] P = (P \ {x=c})aexpr is not a constant • FCP[x:=k] P = (P \ {x=c}) {x=k} • Used in dataflow analysis – a special case of abstract interpretation
Does this still work? Annotate(P, S1; S2) = let Annotate(P, S1) be {P} A1 {Q1} let Annotate(Q1, S2) be {Q1} A2 {Q2} return {P} A1; {Q1} A2 {Q2}
Handling conditional expressions We want to soundly approximate D bexprand D bexprin Define (bexpr) = if bexpr is CP-factoid {bexpr}else {} Define F[assumebexpr](D) = D (bexpr)
Does this still work? How do we define join for CP? letPt = F[assumebexpr]P letPf = F[assumebexpr]P let Annotate(Pt, S1) be {Pt} A1 {Q1} let Annotate(Pf, S2) be {Pf} A2 {Q2} return {P}ifbexprthen{Pt} A1 {Q1} else{Pf} A2 {Q2}{Q1 Q2}
Join example {x=5, y=7} {x=3, y=7, z=9} =
Does this still work? Annotate(P, whilebexprdoS) = N:= Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N}Nc := Nc N untilN= Nc return{P} INV= {N} whilebexprdo {Pt} Abody {F[assumebexpr](N)} What about correctness? What about termination?
Does this still work? Annotate(P, whilebexprdoS) = N:= Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N}Nc := Nc N untilN= Nc return{P} INV= {N} whilebexprdo {Pt} Abody {F[assumebexpr](N)} • What about correctness? • If loop terminates then is Na loop invariant? • What about termination?
A termination principle • g : X X is a function • How can we determine whether the sequencex0, x1 = g(x0), …, xk+1=g(xk),… stabilizes? • Technique: • Find ranking functionrank : X N(that is show that rank(x) 0 for all x) • Show that if xg(x)then rank(g(x)) < rank(x)
Rank function for available expressions rank(P) = ?
Rank function for available expressions Annotate(P, whilebexprdoS) = N:= Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N}Nc := Nc N untilN= Nc return{P} INV= {N} whilebexprdo {Pt} Abody {F[assumebexpr](N)} rank(P) = |P|number of factoids Prove that either Nc =Nc Nor rank(Nc N) <? rank(Nc)
Rank function for constant propagation Annotate(P, whilebexprdoS) = N:= Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N}Nc := Nc N untilN= Nc return{P} INV= {N} whilebexprdo {Pt} Abody {F[assumebexpr](N)} rank(P) = ? Prove that either Nc =Nc Nor rank(Nc) >? rank(Nc N)
Rank function for constant propagation Annotate(P, whilebexprdoS) = N’ := Nc := P // Initialize repeatletPt = F[assumebexpr] Nc let Annotate(Pt, S) be {Nc} Abody{N’}Nc := Nc N’ untilN’ = Nc return{P} INV= {N’} whilebexprdo {Pt} Abody {F[assumebexpr](N)} rank(P) = |P|number of factoids Prove that either Nc =Nc N’or rank(Nc) >? rank(Nc N’)
Generalizing AvailableExpressions ConstantPropagation By NMZ (Photoshop) [CC0], via Wikimedia Commons AbstractInterpretation 1
Towards a recipe for static analysis • Two static analyses • Available Expressions (extended with equalities) • Constant Propagation • Semantic domain – a family of formulas • Join operator approximates pairs of formulas • Abstract transformers for basic statements • Assignments • assume statements • Initial precondition
A technical issue • Unrolling loops is quite inconvenient and inefficient (but we can avoid it as we just saw) • How do we handle more complex control-flow constructs, e.g., goto , break, exceptions…? • The problem: non-inductive control flow constructs • Solution: model control-flow by labels and goto statements • Would like a dedicated data structure to explicitly encode control flow in support of the analysis • Solution:control-flow graphs (CFGs)
Modeling control flow with labels label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b while (x z) do x := x + 1 y := x + a d := x + a a := b
Control-flow graph example line number label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b 1 2 3 label0: 4 1 5 6 2 if x z 7 label1: x := x + 1 8 7 3 a := b y := x + a 8 4 d := x + a 5 goto label0 6
Control-flow graph example label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b 1 entry 2 3 label0: 4 1 5 6 2 if x z 7 label1: x := x + 1 8 7 3 a := b y := x + a 8 4 d := x + a exit 5 goto label0 6
Control-flow graph • Node are statements or labels • Special nodes for entry/exit • A edge from node v to node w means that after executing the statement of v control passes to w • Conditions represented by splits and join node • Loops create cycles • Can be generated from abstract syntax tree in linear time • Automatically taken care of by the front-end • Usage: store analysis results (assertions) in CFG nodes
Control-flow graph example label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b 1 entry 2 3 label0: 4 1 5 6 2 if x z 7 label1: x := x + 1 8 7 3 a := b y := x + a 8 4 d := x + a exit 5 goto label0 6
Eliminating labels We can use edges to point to the nodes following labels and remove all label nodes (other than entry/exit)
Control-flow graph example label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b 1 entry 2 3 label0: 4 1 5 6 2 if x z 7 label1: x := x + 1 8 7 3 a := b y := x + a 8 4 d := x + a exit 5 goto label0 6
Control-flow graph example label0: if x z goto label1 x := x + 1 y := x + a d := x + agoto label0label1: a := b 1 entry 2 3 4 5 6 2 if x z 7 x := x + 1 8 3 a := b y := x + a 8 4 d := x + a exit 5