Very busy expr.: kill and generate core of the intra-block flow specification { a ′ ∈ AExp ∗ | x ∈ fv ( a ′ ) } kill VB ([ x := a ] l ) = kill VB ([ skip ] l ) = ∅ kill VB ([ b ] l ) = ∅ gen VB ([ x := a ] l ) = AExp ( a ) gen VB ([ skip ] l ) = ∅ gen VB ([ b ] l ) = AExp ( b ) 24 / 157
Available expressions analysis: kill and generate core of the intra-block flow specification { a ′ ∈ AExp ∗ | x ∈ fv ( a ′ ) } kill AE ([ x := a ] l ) = kill AE ([ skip ] l ) = ∅ kill AE ([ b ] l ) = ∅ { a ′ ∈ AExp ( a ) | x / gen AE ([ x := a ] l ) ∈ fv ( a ′ ) } = gen AE ([ skip ] l ) = ∅ gen AE ([ b ] l ) = AExp ( b ) 25 / 157
Flow equations.: VB = split into • intra-block equations, using kill/generate • inter-block equations, using flow however: everything works backwards now Flow equations: VB VB exit ( l ) = VB entry ( l ) = where B l ∈ blocks ( S ∗ ) 26 / 157
Flow equations.: VB = split into • intra-block equations, using kill/generate • inter-block equations, using flow however: everything works backwards now Flow equations: VB � ∅ l = final ( S ∗ ) VB exit ( l ) = � { VB entry ( l ′ ) | ( l ′ , l ) ∈ flow R ( S ∗ ) } otherwise VB exit ( l ) \ kill VB ( B l ) ∪ gen VB ( B l ) VB entry ( l ) = where B l ∈ blocks ( S ∗ ) 26 / 157
Example 27 / 157
When can var’s be “thrown away”: Live variable analysis [ x := 2 ] 1 ; [ y := 4 ] 2 ; [ x := 1 ] 3 ; ( if [ y > x ] 4 then [ z := y ] 5 else [ z := y ∗ y ] 6 ); [ x := z ] 7 28 / 157
When can var’s be “thrown away”: Live variable analysis [ x := 2 ] 1 ; [ y := 4 ] 2 ; [ x := 1 ] 3 ; ( if [ y > x ] 4 then [ z := y ] 5 else [ z := y ∗ y ] 6 ); [ x := z ] 7 Live variable a variable is live (at exit of a label) = there exists a path from the mentioned exit to the use of that variable which does not assign to the variable (i.e., redefines its value) • use: dead code elimination, register allocation Goal for each program point: which variables may be live at the exit of that point. 28 / 157
Live variables: types • interested in sets of variables 2 Var ∗ • generation and killing: kill LV , gen LV : Blocks ∗ → 2 Var ∗ • analysis: pair of functions LV entry , LV exit : Lab ∗ → 2 Var ∗ 29 / 157
Live variables: kill and generate kill AE ([ x := a ] l ) = kill LV ([ skip ] l ) = kill LV ([ b ] l ) = gen LV ([ x := a ] l ) = gen LV ([ skip ] l ) = gen LV ([ b ] l ) = 30 / 157
Live variables: kill and generate kill AE ([ x := a ] l ) = { x } kill LV ([ skip ] l ) = ∅ kill LV ([ b ] l ) = ∅ gen LV ([ x := a ] l ) = fv ( a ) gen LV ([ skip ] l ) = ∅ gen LV ([ b ] l ) = fv ( b ) 30 / 157
Flow equations LV = split into • intra-block equations, using kill/generate • inter-block equations, using flow however: everything works backwards now Flow equations LV LV exit ( l ) = LV entry ( l ) = where B l ∈ blocks ( S ∗ ) 31 / 157
Flow equations LV = split into • intra-block equations, using kill/generate • inter-block equations, using flow however: everything works backwards now Flow equations LV � ∅ l ∈ final ( S ∗ ) LV exit ( l ) = � { LV entry ( l ′ ) | ( l ′ , l ) ∈ flow R ( S ∗ ) } otherwise LV exit ( l ) \ kill LV ( B l ) ∪ gen LV ( B l ) LV entry ( l ) = where B l ∈ blocks ( S ∗ ) 31 / 157
Example 32 / 157
Relating programs with analyses • analyses • intended as (static) abstraction/overapprox. of real program behavior • so far: without real connection to programs • soundness of the analysis: “safe” analysis • but: we have not defined yet the behavior/semantics of programs • here: “easiest” semantics: operational • more precisely: small-step SOS (structural operational semantics) 33 / 157
states, configs, and transitions fixing some data types • state σ : State = Var → Z • configuration: pair of statement × state or (terminal) just a state • transitions � S , σ � → � ´ � S , σ � → ´ σ S , ´ σ � or 34 / 157
Semantics of expressions ] A : AExp → ( State → Z ) [ [ ] ] B : BExp → ( State → T ) [ [ ] simplifying assumption: no errors ] A [ [ x ] = σ ( x ) σ ] A [ [ n ] = N ( n ) σ ] A ] A ] A [ a 1 op a a 2 ] [ = [ [ a 1 ] σ op a [ [ a 2 ] σ σ ] B ] B [ not b ] [ = ¬ [ [ b ] σ σ ] B ] B ] B [ b 1 op b b 2 ] [ = [ [ b 1 ] σ op b [ [ b 2 ] σ σ ] B ] A ] A [ a 1 op r a 2 ] [ = [ [ a 1 ] σ op r [ [ a 2 ] σ σ clearly: ] A ] A ∀ x ∈ fv ( a ) . σ 1 ( x ) = σ 2 ( x ) then [ [ a ] σ 1 = [ [ a ] σ 2 35 / 157
SOS � [ x := a ] l , σ � → σ [ x �→ [ ] A � [ skip ] l , σ � → σ [ a ] σ ] A SS SKIP � S 1 , σ � → � ´ S 1 , ´ σ � � S 1 , σ � → ´ σ S EQ 1 S EQ 2 � S 1 ; S 2 , σ � → � ´ σ � � S 1 ; S 2 , σ � → � S 2 , ´ σ � S 1 ; S 2 , ´ ] B [ b ] [ σ = ⊤ I F 1 � if [ b ] l then S 1 else S 2 , σ � → � S 1 , σ � ] B [ [ b ] σ = ⊤ W HILE 1 � while [ b ] l do S , σ � → � S ; while [ b ] l do S , σ � ] B [ [ b ] σ = ⊥ W HILE 2 � while [ b ] l do S , σ � → σ 36 / 157
Derivation sequences • derivation sequence: “completed” execution: • finite sequence: � S 1 , σ 1 � , . . . , � S n , σ n � , σ n + 1 • infinite sequence: � S 1 , σ 1 � , . . . , � S i , σ i � , . . . • note: labels do not influence the semantics Lemma 1. � S , σ � → σ ′ , then final ( S ) = { init ( S ) } 2. � S , σ � → � ´ σ � , then final ( S ) ⊇ { final (´ S , ´ S ) } 3. � S , σ � → � ´ σ � , then flow ( S ) ⊇ { flow (´ S ) } S , ´ 4. � S , σ � → � ´ σ � , then blocks ( S ) ⊇ blocks (´ S , ´ S ) ; if S is label consistent, then so is ´ S 37 / 157
Correctness of live analysis • LV as example • given as constraint system (not as equational system) LV constraint system � ∅ l ∈ final ( S ∗ ) LV exit ( l ) ⊇ � { LV entry ( l ′ ) | ( l ′ , l ) ∈ flow R ( S ∗ ) } otherwise LV exit ( l ) \ kill LV ( B l ) ∪ gen LV ( B l ) ⊇ LV entry ( l ) live entry , live exit : Lab ∗ → 2 Var ∗ “ live solves constraint system LV ⊆ ( S ) ” = LV ⊆ ( S ) live | (analogously for equations LV = ( S ) ) 38 / 157
When can var’s be “thrown away”: Live variable analysis [ x := 2 ] 1 ; [ y := 4 ] 2 ; [ x := 1 ] 3 ; ( if [ y > x ] 4 then [ z := y ] 5 else [ z := y ∗ y ] 6 ); [ x := z ] 7 Live variable a variable is live (at exit of a label) = there exists a path from the mentioned exit to the use of that variable which does not assign to the variable (i.e., redefines its value) • use: dead code elimination, register allocation Goal for each program point: which variables may be live at the exit of that point. 39 / 157
Equational vs. constraint analysis Lemma = LV = , then live | = LV ⊆ • If live | = LV = and live | = LV ⊆ coincide. • The least solutions of live | 40 / 157
Intermezzo: orders, lattices. etc. as a reminder: • partial order ( L , ⊑ ) • upper bound l of Y ⊆ L : • least upper bound (lub): � Y (or join ) • dually: lower bounds and greatest lower bounds: � Y (or meet ) • complete lattice L = ( L , ⊑ ) = ( L , ⊑ , � , � , ⊥ , ⊤ ) : po-set where meets and joins exist for all subsets, furthermore ⊥ = � ∅ and ⊤ = � ∅ . 41 / 157
Fixpoints given complete lattice L and monotone f : L → L . • fixpoint: f ( l ) = l Fix ( f ) = { l | f ( l ) = l } • f reductive at l , l is a pre-fixpoint of f : f ( l ) ⊑ l : Red ( f ) = { l | f ( l ) ⊑ l } • f extensive at l , l is a post-fixpoint of f : f ( l ) ⊒ l : Ext ( f ) = { l | f ( l ) ⊒ l } � � lfp ( f ) � Fix ( f ) and gfp ( f ) � Fix ( f ) 42 / 157
Tarski’s theorem Theorem L: complete lattice, f : L → L monotone. � Red ( f ) � lfp ( f ) ∈ Fix ( f ) (6) � Ext ( f ) � gfp ( f ) ∈ Fix ( f ) 43 / 157
Fixpoint iteration • often: iterate, approximate least fixed point from below ( f n ( ⊥ )) n : ⊥ ⊑ f ( ⊥ ) ⊑ f 2 ( ⊥ ) ⊑ . . . • not assured that we “reach” the fixpoint (“within” ω ) ⊥ ⊑ f n ( ⊥ ) ⊑ � n f n ( ⊥ ) ⊑ lfp ( f ) n f n ( ⊤ ) ⊑ f n ( ⊤ ) ⊑ ( ⊤ ) gfp ( f ) ⊑ � • additional requirement: continuity on f for all ascending chains ( l n ) n � � f ( ( l n )) = ( f ( l n )) n • ascending chain condition: f n ( ⊥ ) = f n + 1 ( ⊥ ) , i.e., lfp ( f ) = f n ( ⊥ ) • descending chain condition: dually 44 / 157
Equational vs. constraint analysis Lemma = LV = , then live | = LV ⊆ • If live | = LV = and live | = LV ⊆ coincide. • The least solutions of live | 45 / 157
Basic preservation results Lemma (“Smaller” graph → less constraints) = LV ⊆ ( S 1 ) . If flow ( S 1 ) ⊇ flow ( S 2 ) and Assume live | = LV ⊆ ( S 2 ) . blocks ( S 1 ) ⊇ blocks ( S 2 ) , then live | Corollary (“subject reduction”) = LV ⊆ ( S ) and � S , σ � → � ´ = LV ⊆ (´ If live | S , ´ σ � , then live | S ) Lemma (Flow) = LV ⊆ ( S ) . If l → flow l ′ , then Assume live | live exit ( l ) ⊇ live entry ( l ′ ) . 46 / 157
� � � � Correctness relation • basic intuitition: only live variables influence the program • proof by induction Correctness relation on states: Given V = set of variables: a σ 1 ∼ V σ 2 iff ∀ x ∈ V .σ 1 ( x ) = σ 2 ( x ) (7) a V is intended to be “live variables” but in ∼ V just set of vars. ⇒ � � S ′′ , σ ′′ � S ′ , σ ′ σ ′′′ � S , σ 1 � 1 � 1 � . . . 1 ∼ V ′ ∼ V ′′ ∼ X ( l ) ∼ V � � S ′ , σ ′ � � S ′′ , σ ′′ � σ ′′′ � S , σ 2 � 2 � . . . 2 � 2 Notation: • N ( l ) = live entry ( l ) , X ( l ) = live exit ( l ) 47 / 157
Example 48 / 157
Correctness (1) Lemma (Preservation inter-block flow) = LV ⊆ . If σ 1 ∼ X ( l ) σ 2 and l → flow l ′ , then Assume live | σ 1 ∼ N ( l ′ ) σ 2 . 49 / 157
� � � � Correctness Theorem (Correctness) = LV ⊆ ( S ) . Assume live | • If � S , σ 1 � → � ´ S , ´ σ 1 � and σ 1 ∼ N ( init ( S )) σ 2 , then there exists σ 2 s.t. � S , σ 2 � → � ´ ´ S , ´ σ 2 � and ´ σ 1 ∼ N ( init (´ S )) ´ σ 2 . • If � S , σ 1 � → ´ σ 1 and σ 1 ∼ N ( init ( S )) σ 2 , then there exists ´ σ 2 s.t. � S , σ 2 � → ´ σ 2 and ´ σ 1 ∼ X ( init ( S )) ´ σ 2 . ∼ N ( init ( S )) ∼ N ( init ( S )) � S , σ 1 � � S , σ 2 � � S , σ 1 � � S , σ 2 � ∼ X ( init ( S )) ∼ N ( init ( S )) � ´ � ´ σ 1 ´ ´ σ 2 S , ´ σ 1 � S , ´ σ 2 � 50 / 157
Correctness (many steps) = LV ⊆ ( S ) Assume live | • If � S , σ 1 � → ∗ � ´ S , ´ σ 1 � and σ 1 ∼ N ( init ( S )) σ 2 , then there exists σ 2 s.t. � S , σ 2 � → ∗ � ´ ´ S , ´ σ 2 � and ´ σ 1 ∼ N ( init (´ S )) ´ σ 2 . • If � S , σ 1 � → ∗ ´ σ 1 and σ 1 ∼ N ( init ( S )) σ 2 , then there exists ´ σ 2 s.t. � S , σ 2 � → ∗ ´ σ 2 and ´ σ 1 ∼ X ( l ) ´ σ 2 for some l ∈ final ( S ) . 51 / 157
Monotone framework: general pattern � ι if l ∈ E Analysis ◦ ( l ) = � { Analysis • ( l ′ ) | ( l ′ , l ) ∈ F } otherwise Analysis • ( l ) = f l ( Analysis ◦ ( l )) (8) • � : either � or � • F : either flow ( S ∗ ) or flow R ( S ∗ ) . • E : either { init ( S ∗ ) } or final ( S ∗ ) • ι : either the initial or final information • f l : transfer function for [ B ] l ∈ blocks ( S ∗ ) . 52 / 157
Monotone frameworks • direction of flow: • forward analysis: • F = flow ( S ∗ ) • Analysis ◦ for entry and Analysis • for exits • assumption: isolated entries • backward analysis: dually • F = flow R ( S ∗ ) • Analysis ◦ for exit and Analysis • for entry • assumption: isolated exits • sort of solution • may analysis • properties for some path • smallest solution • must analysis • properties of all paths • greatest solution 53 / 157
Without isolated entries E ⊔ � { Analysis • ( l ′ ) | ( l ′ , l ) ∈ F } ι l Analysis ◦ ( l ) = (9) � ι if l ∈ E where ι l E = ⊥ if l / ∈ E Analysis • ( l ) = f l ( Analysis ◦ ( l )) where l ⊔ ⊥ = l 54 / 157
Basic definitions: property space • property space L , often complete lattice • combination operator: � : 2 L → L ( ⊔ : binary case). • ⊥ = � ∅ • often: ascending chain condition (stabilization) 55 / 157
Transfer functions f l : L → L with l ∈ Lab ∗ • associated with the blocks 3 • requirements: monotone • F : monotone functions over L : • containing all transfer functions • containing identity • closed under composition 3 One can do it also other way (but not in this lecture). 56 / 157
Framework (summary) • complete lattice L , ascending chain condition • F monotone functions, closed as stated • distributive framework f ( l 1 ∨ l 2 ) = f ( l 1 ) ∨ f ( l 2 ) (or rather f ( l 1 ∨ l 2 ) ⊑ f ( l 1 ) ∨ f ( l 2 ) ) 57 / 157
Our 4 classical examples • for a label consistent program S ∗ , all a instances of a monotone, distributive, framework: • conditions: • lattice of properties: immediate (subset/superset) • ascending chain condition: finite set of syntactic entities • closure conditions on F • monotone • closure under identity and composition • distributive: assured by using the kill- and generate-formulation 58 / 157
Instances: overview avail. epxr. reach. def’s very busy expr. live var’s 2 Var ∗ × Lab ? 2 AExp ∗ 2 AExp ∗ 2 Var ∗ L ∗ ⊑ ⊇ ⊆ ⊇ ⊆ � � � � � ⊥ ∅ ∅ AExp ∗ AExp ∗ ∅ { ( x , ?) | x ∈ fv ( S ∗ ) } ∅ ∅ ι E { init ( S ∗ ) } { init ( S ∗ ) } final ( S ∗ ) final ( S ∗ ) flow R ( S ∗ ) flow R ( S ∗ ) F flow ( S ∗ ) flow ( S ∗ ) F { f : L → L | ∃ l k , l g . f ( l ) = ( l \ l k ) ∪ l g } f l ( l ) = ( l \ kill ([ B ] l ) ∪ gen ([ B ] l )) where [ B ] l ∈ blocks ( S ∗ ) f l 59 / 157
Solving the analyses • given: set of equations (or constraints) over finite sets of variables • domain of variables: complete lattices + ascending chain condition • 2 solutions for the monotone frameworks 1. MFP: “maximal fix point” 2. MOP: “meet over all paths” 60 / 157
MFP • terminology: historically “MFP” stands for maximal fix point (not minimal) • iterative worklist algorithm: • central data structure: worklist • list (or container) of pairs • related to chaotic iteration 61 / 157
Chaotic iteration Input: example equations for reaching definitions � RD = ( RD 1 , . . . , RD 12 ) Output: least solution: Method: step 1: initialization RD 1 := ∅ ; . . . ; RD 12 := ∅ step 2: iteration while RD j � = F j ( RD 1 , . . . , RD 12 ) for some j do RD j := F j ( RD 1 , . . . , RD 12 ) 62 / 157
Worklist algorithms • fixpoint iteration algorithm • general kind of algorithms, for DFA, CFA, . . . • same for equational and constraint systems • “specialization”/determinization of chaotic iteration ⇒ worklist: central data structure, “container” containing “the work still to be done” • for more details (different traversal strategies): see [2, Chap. 6] 63 / 157
WL-algo for DFA • WL-algo for monotone frameworks ⇒ input: instance of monotone framework • two central data structures • worklist: flow-edges yet to be (re-)considered: 1. removed when effect of transfer function has been taken care of 2. (re-)added, when point 1 endangers satisfaction of (in-)equations • array to store the “current state” of Analysis ◦ • one central control structure (after initialization): loop until worklist empty 64 / 157
( L , F , F , E , ι, f ) Input: Output: MFP ◦ , MFP • Method: step 1: initialization W := nil ; for all ( l , l ′ ) ∈ F do W := ( l , l ′ ) :: W ; for all l ∈ F or ∈ E do if l ∈ E then Analysis [ l ] := ι else Analysis [ l ] := ⊥ L ; step 2: iteration while W � = nil do ( l , l ′ ) := ( fst(head(W)), snd(head(W))); W := tail W; if f l ( Analysis [ l ]) �⊑ Analysis [ l ′ ] Analysis [ l ′ ] := Analysis [ l ′ ] ⊔ f l ( Analysis [ l ]) ; then for all l ′′ with ( l ′ , l ′′ ) ∈ F do W := ( l ′ , l ′′ ) :: W ; step 3: presenting the result: for all l ∈ F or ∈ E do MFP ◦ ( l ) := Analysis [ l ] ; MFP • ( l ) := f l ( Analysis [ l ]) 65 / 157
66 / 157
MFP: properties Lemma The algo • terminates and • calculates the least solution Proof. • termination: ascending chain condition & loop is enlarging • least FP: • invariant: array always below Analysis ◦ • at loop exit: array “solves” (in-)equations 67 / 157
Time complexity • estimation of upper bound of number basic steps • at most b different labels in E • at most e ≥ b pairs in the flow F • height of the lattice: at most h • non-loop steps: O ( b + e ) • loop: at most h times addition to the WL ⇒ O ( e · h ) (10) or ≤ O ( b 2 h ) 68 / 157
MOP: paths • terminoloy: historically: MOP stands for “meet over all paths” • here: dually joins • 2 versions of a path: 1. path to entry of a block: blocks traversed from the “extremal block” of the program, but not including it 2. path to exit of a block • { [ l 1 , . . . l n − 1 ] | l i → flow l i + 1 ∧ l n = l ∧ l 1 ∈ E } path ◦ ( l ) = path • ( l ) = { [ l 1 , . . . l n ] | l i → flow l i + 1 ∧ l n = l ∧ l 1 ∈ E } • transfer function for paths � l l = f l n ◦ . . . f l 1 ◦ id f � 69 / 157
MOP • paths: • forward analyses: paths from init block to entry of a block • backward analyses: paths from exits of a block to a final block • two components of the MOP solution (for given l ): • up-to but not including l • up-to including l l ( ι ) | � MOP ◦ ( l ) = � { f l ∈ path ◦ l } � l ( ι ) | � MOP • ( l ) = � { f l ∈ path • l } � 70 / 157
MOP vs. MFP • MOP: can be undecidable • MFP approximates MOP (“ MFP ⊒ MOP ”) Lemma MFP ◦ ⊒ MOP ◦ and MFP • ⊒ MOP • (11) In case of a distributive framework MFP ◦ = MOP ◦ and MFP • = MOP • (12) 71 / 157
Adding procedures • so far: very simplified language: • minimalistic imperative language • reading and writing to variables plus • simple controlflow, given as flow graph • now: procedures: interprocedural analysis • (possible) complications: • calls/returns (i.e., control flow) • parameter passing (call-by-value vs. call-by-reference) • scopes • potential aliasing (with call-by-reference) • higher-order functions/procedures • here: top-level procedures, mutual recursion, call-by-value parameter + call-by-result 72 / 157
Syntax • program: begin D ∗ S ∗ end l n l x D ∗ ::= proc p ( val x , res y ) is S end | D D • procedure names p • statements S ::= . . . [ call p ( a , z )] l c l r • note: call statement with 2 labels • statically scoped language, CBV parameter passing (1st parameter), and CBN for second • mutal recursion possible • assumption: unique labelling, only declared procedures are called, all procedures have different names. 73 / 157
Example proc fib ( val z , u , res v ) is 1 begin [ z < 3 ] 2 if [ v := u + 1 ] 3 then [ call fib ( z − 1 , u , v )] 4 5 ; else [ call fib ( z − 2 , v , v )] 6 7 end 8 ; [ call fib ( x , 0 , y )] 9 10 end 74 / 157
Blocks, labels, etc init ([ call p ( a , z )] l c l r ) = l c final ([ call p ( a , z )] l c { l r } l r ) = blocks ([ call p ( a , z )] l c { [ call p ( a , z )] l c l r ) = l r } labels ([ call p ( a , z )] l c l r ) = { l c , l r } flow ([ call p ( a , z )] l c l r ) = 75 / 157
Blocks, labels, etc init ([ call p ( a , z )] l c l r ) = l c final ([ call p ( a , z )] l c { l r } l r ) = blocks ([ call p ( a , z )] l c { [ call p ( a , z )] l c l r ) = l r } labels ([ call p ( a , z )] l c l r ) = { l c , l r } flow ([ call p ( a , z )] l c { ( l c ; l n ) , ( l x ; l r ) } l r ) = where proc p ( val x , res y ) is l n S end l x is in D ∗ . • two new kinds of flows: 4 calling and returning • static dispatch only 4 written slightly different(!) 75 / 157
For procedure declaration init ( p ) = final ( p ) = blocks ( p ) = ∪ blocks ( S ) labels ( p ) = flow ( p ) = 76 / 157
For procedure declaration init ( p ) = l n final ( p ) = { l x } { is l n , end l x } ∪ blocks ( S ) blocks ( p ) = labels ( p ) = { l n , l x } ∪ labels ( S ) flow ( p ) = { ( l n , init ( S )) } ∪ flow ( S ) ∪ { ( l , l x ) | l ∈ final ( S ) } 76 / 157
Flow graph of complete program init ∗ = init ( S ∗ ) final ∗ = final ( S ∗ ) � { blocks ( p ) | proc p ( val x , res y ) is l n S end l x ∈ D ∗ } blocks ∗ = ∪ blocks ( S ∗ ) � { labels ( p ) | proc p ( val x , res y ) is l n S end l x ∈ D ∗ } labels ∗ = ∪ labels ( S ∗ ) � { flow ( p ) | proc p ( val x , res y ) is l n S end l x ∈ D ∗ } flow ∗ = ∪ flow ( S ∗ ) 77 / 157
Interprocedural flow • inter-procedural: from call-site to procedure, and back: ( l c ; l n ) and ( l x ; l r ) . • more precise (=better) capture of flow: inter - flow ∗ = { ( l c , l n , l x , l r ) | P ∗ contains [ call p ( a , z )] l c l r and proc ( val x , res y ) is l n S end abbreviation: IF for inter - flow ∗ or inter - flow R ∗ 78 / 157
Example: fibonacci flow 79 / 157
Semantics: stores, locations,. . . • not only new syntax • new semantical concept: local data! • different “incarnations” of a variable ⇒ locations • remember: σ ∈ State = Var ∗ → Z ξ ∈ Loc locations ∈ Env = Var ∗ → Loc ρ environment ς ∈ Store = Loc → fin Z (partial functions) store • σ = ς ◦ ρ : total ⇒ ran ( ρ ) ⊆ dom ( ς ) • top-level environment: ρ ∗ : all var’s are mapped to unique locations 80 / 157
Steps • steps relative to environment ρ ρ ⊢ ∗ � S , ς � → � ´ S , ´ ς � or ρ ⊢ ∗ � S , ς � → ´ ς • old rules needs to be adapted ξ 1 , ξ 2 / ∈ dom ( ς ) v ∈ Z proc p ( val x , res y ) is l n S end l x ∈ D ∗ ´ ς = ρ ⊢ ∗ � [ call p ( a , z )] l c l r , ς � → � bind ρ [ x �→ ξ 1 ][ y �→ ξ 2 ] in S then z := y , ´ ς � 81 / 157
Steps • steps relative to environment ρ ρ ⊢ ∗ � S , ς � → � ´ S , ´ ς � or ρ ⊢ ∗ � S , ς � → ´ ς • old rules needs to be adapted ξ 1 , ξ 2 / ∈ dom ( ς ) v ∈ Z proc p ( val x , res y ) is l n S end l x ∈ D ∗ ] A ς = ς [ ξ 1 �→ [ ς ◦ ρ ][ ξ 2 �→ v ] ´ [ a ] ρ ⊢ ∗ � [ call p ( a , z )] l c l r , ς � → � bind ρ [ x �→ ξ 1 ][ y �→ ξ 2 ] in S then z := y , ´ ς � 81 / 157
Bind-construct ρ ⊢ ∗ � S , ς � → � ´ ´ S , ´ ς � B IND 1 ρ ⊢ ∗ � bind ´ ρ in S then z := y , ς � → ρ ⊢ ∗ � S , ς � → ´ ´ ς B IND 2 ρ ⊢ ∗ � bind ´ ρ in S then z := y , ς � → • bind-syntax: “runtime syntax” ⇒ formulation of correctness must be adapted, too (Chap. 3) 82 / 157
Bind-construct ρ ⊢ ∗ � S , ς � → � ´ ´ S , ´ ς � B IND 1 ρ in ´ ρ ⊢ ∗ � bind ´ ρ in S then z := y , ς � → � bind ´ ς � S then z := y , ´ ρ ⊢ ∗ � S , ς � → ´ ´ ς B IND 2 ρ ⊢ ∗ � bind ´ ρ in S then z := y , ς � → ´ ς [ ρ ( z ) �→ ´ ς (´ ρ ( y ))] • bind-syntax: “runtime syntax” ⇒ formulation of correctness must be adapted, too (Chap. 3) 82 / 157
Naive formulation • first attempt • assumptions: • for each proc. call: 2 transfer functions: f l c (call) and f l r (return) • for each proc. definition: 2 transfer functions: f l n (enter) and f l x (exit) • given: mon. framework ( L , F , F , E , ι, f ) • inter-proc. edges ( l c ; l n ) and ( l x ; l r ) = ordinary flow edges ( l 1 , l 2 ) • ignore parameter passing: transfer functions for proc. calls/proc definitions are identity 83 / 157
Equation system A • ( l ) = f l ( A ◦ ( l )) � { A • ( l ′ ) | ( l ′ , l ) ∈ F or ( l ′ ; l ) ∈ F }∨ ι l A ◦ ( l ) = E with � ι if l ∈ E ι l = E ⊥ if l / ∈ E • analysis: safe • unnecessary unprecise/too abstract 84 / 157
Recommend
More recommend