Click here to load reader

Interprocedural Analysis Noam Rinetzky Mooly Sagiv

  • View
    216

  • Download
    0

Embed Size (px)

Text of Interprocedural Analysis Noam Rinetzky Mooly Sagiv

  • Slide 1
  • Interprocedural Analysis Noam Rinetzky Mooly Sagiv
  • Slide 2
  • Challenges in Interprocedural Analysis Respect call-return mechanism Handling recursion Local variables Parameter passing mechanisms The called procedure is not always known The source code of the called procedure is not always available Concurrency
  • Slide 3
  • Stack regime P() { R(); } R(){ } Q() { R(); } call return call return P R
  • Slide 4
  • Guiding light Exploit stack regime Precision Efficiency
  • Slide 5
  • Simplifying Assumptions Parameter passed by value No OO No nesting No concurrency Recursion is supported
  • Slide 6
  • Topics Covered The trivial approach Procedure Inlining The naive approach The call string approach Functional Approach Valid paths Interprocedural Analysis via Graph Reachability Beyond reachability [Demand analysis] [Advanced Topics] Karrs analysis Backward MOPED
  • Slide 7
  • Constant Propagation Find variables with constant value at a given program location int p(int x){ return x * x; void main()} { int z; if (...) z = p(5) + 5; else z = p(4) + 4; printf (z); }
  • Slide 8
  • Example Program x = 5; y = 7; if (...) y = x + 2; z = x +y;
  • Slide 9
  • Undecidability Issues It is undecidable if a program point is reachable in some execution Some static analysis problems are undecidable even if the program conditions are ignored
  • Slide 10
  • The Constant Propagation Example while (...) { if (...) x_1 = x_1 + 1; if (...) x_2 = x_2 + 1;... if (...) x_n = x_n + 1; } y = truncate (1/ (1 + p 2 (x_1, x_2,..., x_n)) /* Is y=0 here? */
  • Slide 11
  • Conservative Solution Every detected constant is indeed constant But may fail to identify some constants Every potential impact is identified Superfluous impacts
  • Slide 12
  • The extra cost of procedures Call return complicates the analysis Unbounded stack memory Increases asymptotic complexity But can be tolerable in practice Sometimes even cheaper/more precise than intraprocedural analysis
  • Slide 13
  • A trivial treatment of procedure Analyze a single procedure After every call continue with conservative information Global variables and local variables which may be modified by the call have unknown values Can be easily implemented Procedures can be written in different languages Procedure inline can help
  • Slide 14
  • Disadvantages of the trivial solution Modular (object oriented and functional) programming encourages small frequently called procedures Almost all information is lost
  • Slide 15
  • Procedure Inlining Inline called procedures Simple Does not handle recursion Exponential blow up p1 { call p2 call p2 } p2 { call p3 call p3 } p3{ }
  • Slide 16
  • A Naive Interprocedural solution Treat procedure calls as gotos Abstract call/return correlations Obtain a conservative solution Use chaotic iterations Usually fast
  • Slide 17
  • Simple Example int p(int a) { return a + 1; } void main() { int x ; x = p(7); x = p(9) ; }
  • Slide 18
  • Simple Example int p(int a) { [a 7] return a + 1; } void main() { int x ; x = p(7); x = p(9) ; }
  • Slide 19
  • Simple Example int p(int a) { [a 7] return a + 1; [a 7, $$ 8] } void main() { int x ; x = p(7); x = p(9) ; }
  • Slide 20
  • Simple Example int 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] }
  • Slide 21
  • Simple Example int 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] }
  • Slide 22
  • Simple Example int p(int a) { [a ] return a + 1; [a 7, $$ 8] } void main() { int x ; x = p(7); [x 8] x = p(9) ; [x 8] }
  • Slide 23
  • Simple Example int p(int a) { [a ] return a + 1; [a , $$ ] } void main() { int x ; x = p(7); [x 8] x = p(9); [x 8] }
  • Slide 24
  • Simple Example int p(int a) { [a ] return a + 1; [a , $$ ] } void main() { int x ; x = p(7) ; [x ] x = p(9) ; [x ] }
  • Slide 25
  • The Call String Approach The data flow value is associated with sequences of calls (call string) Use Chaotic iterations To guarantee termination limit the size of call string (typically 1 or 2) Represents tails of calls Abstract inline
  • Slide 26
  • Simple Example int p(int a) { return a + 1; } void main() { int x ; c1: x = p(7); c2: x = p(9) ; }
  • Slide 27
  • Simple Example int p(int a) { c1: [a 7] return a + 1; } void main() { int x ; c1: x = p(7); c2: x = p(9) ; }
  • Slide 28
  • Simple Example int 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) ; }
  • Slide 29
  • Simple Example int 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) ; }
  • Slide 30
  • Simple Example int 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) ; }
  • Slide 31
  • Simple Example int 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) ; }
  • Slide 32
  • Simple Example int 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) ; }
  • Slide 33
  • Simple Example int 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] }
  • Slide 34
  • Another Example int 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 , $$ ] }
  • Slide 35
  • Recursion int p(int a) { c1: [a 7] if () { c1: [a 7] a = a -1 ; c1: [a 6] c2: p (a); a = a + 1;{ x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 36
  • Recursion int p(int a) { c1: [a 7] c1.c2: [a 6] if () { c1: [a 7] a = a -1 ; c1: [a 6] c2: p (a); a = a + 1;} x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 37
  • Recursion int p(int a) { c1: [a 7] c1.c2: [a 6] if () { c1: [a 7] c1.c2: [a 6] a = a -1 ; c1: [a 6] c2: p (a); a = a + 1;} x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 38
  • Recursion int p(int a) { c1: [a 7] c1.c2: [a 6] if () { c1: [a 7] c1.c2: [a 6] a = a -1 ; c1: [a 6] c1.c2: [a 5] c2: p (a); a = a + 1;} x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 39
  • Recursion int p(int a) { c1: [a 7] c1.c2+: [a ] if () { c1: [a 7] c1.c2: [a 6] a = a -1 ; c1: [a 6] c1.c2: [a 5] c2: p (a); a = a + 1;} x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 40
  • Recursion 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 5] c2: p (a); a = a + 1;} x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 41
  • Recursion 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); a = a + 1; x = -2*a + 5; } void main() { c1: x = p(7); }
  • Slide 42
  • 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); a = a + 1;} c1: [a 7] c1.c2+: [a ] x = -2*a + 5; c1: [a 7, x -9] c1.c2+: [a , x ] } void main() { c1: x = p(7); }
  • Slide 43
  • 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 , x ] a = a + 1; } c1: [a 7] c1.c2+: [a ] x = -2*a + 5; c1: [a 7, x -9] c1.c2+: [a , x ] } void main() { c1: x = p(7); }
  • Slide 44
  • 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 , x ] a = a + 1; c1.c2+: [a , x ] } c1: [a 7] c1.c2+: [a ] x = -2*a + 5; c1: [a 7, x -9] c1.c2+: [a , x ] } void main() { c1: x = p(7); }
  • Slide 45
  • 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: [a , x ] a = a + 1; c1.c2+: [a , x ] c1: [a , x ] } c1: [a 7] c1.c2+: [a ] x = -2*a + 5; c1: [a , x ] c1.c2+: [a , x ] } void main() { c1: x = p(7); }
  • Slide 46
  • 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 ] }
  • Slide 47
  • Special cases and Extensions Finite distributive lattice There exists a bound on the call string which leads to join over all valid paths Solution seemingly unsafe Decomposable problem (Independent attributes) L = L 1 x L 2 x x L k F = F 1 x F 2 x x F k Cost is quadrat