Download presentation
Presentation is loading. Please wait.
1
Program Analysis with Set Constraints Ravi Chugh
2
Set-constraint based analysis Another technique for computing information about program variables Phase 1: constraint generation – Create set variables corresponding to program – Add inclusion constraints between these sets – Usually a local, syntax-directed process (ASTs vs CFGs) Phase 2: constraint resolution – Solve for values of all set variables Extends naturally to inter-procedural analysis
3
Constant propagation int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Want to determine whether x and y are constant values when they are used We will build a flow- insensitive analysis
4
Set constraints Terms t := c (constant) | X (set variable) | C(t 1,...,t n )(constructed term) Constraints t 1 t 2 (set inclusion) Constructors – C(v 1,...,v n ) is an n-arg ctor C with variances v i – v i is either + (covariant) or – (contravariant) – Covariance corresponds to “forwards flow” – Contravariance corresponds to “backwards flow”
5
Additional constraints Implicit constraints added by following rules: 1) Transitivity if t 1 t 2 and t 2 t 3 then t 1 t 3 2) Variance through constructed terms if C(...,t i,...) C(...,u i,...) then t i u i for covariant positions of C u i t i for contravariant positions of C
6
Constraint graphs 1 X X Y Ctor(A,B,C) Ctor(D,E,F) where Ctor(+,-,+) X X 1 1 Y Y Ctor A A B B C C D D E E F F
7
Function calls Define ctor Fun(-,+) for one input/one output To encode a function def/call: int z = id(2); Fun(i,r) id Fun(2,z) By contravariance, the actual 2 flows to i By covariance, the return value of id flows to z Fun i i r r 2 2 z z id
8
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... }
9
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... }
10
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs Fun i i r1 abs
11
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs Fun i i r1 abs
12
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 Fun i i r1 abs
13
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 Fun i i r1 abs
14
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun i i r1 abs T T
15
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun i i r1 abs T T
16
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id Fun j j r2 id Fun i i r1 abs T T
17
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id Fun j j r2 id Fun i i r1 abs T T
18
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 Fun j j r2 id Fun i i r1 abs T T
19
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 Fun j j r2 id Fun i i r1 abs T T
20
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b Fun j j r2 id b b 2 2 Fun i i r1 abs a a 1 1 T T
21
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b Fun j j r2 id b b 2 2 Fun i i r1 abs a a 1 1 T T
22
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) Fun j j r2 id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T
23
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) Fun j j r2 id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T
24
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) id Fun(b,y) Fun j j r2 Fun y y id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T
25
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) id Fun(b,y) Fun j j r2 Fun y y id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T ?? x ?? y
26
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) id Fun(b,y) Fun j j r2 Fun y y id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T {1,T} x ?? y
27
int abs(int i) { if (...) { return i; } else { return –i; } } int id(int j) { return j; } void main() { int a = 1, b = 2; int x = abs(a); int y = id(b);... use x...... use y... } Fun(i,r1) abs i r1 T r1 Fun(j,r2) id j r2 1 a 2 b abs Fun(a,x) id Fun(b,y) Fun j j r2 Fun y y id b b 2 2 Fun i i r1 Fun x x abs a a 1 1 T T {1,T} x {2} y
28
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; 1 1 i i
29
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; Ref i i 1 1
30
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; Ref i i p p 1 1
31
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; Ref 2 2 i i p p 1 1
32
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; Ref 2 2 j j i i p p 1 1
33
Pointers Handle pointers with a Ref(-,+) constructor Two args correspond to set and get operations int i = 1; int *p = &i; *p = 2; int j = *p; Ref 2 2 j j i i p p 1 1
34
More on functions This encoding supports higher-order functions – Passing around Fun terms just like constants Function pointers also work int (*funcPtr)(int); int id(int j) { return j }; funcPtr = &id; int x = (*funcPtr)(0); Fun j j id
35
More on functions This encoding supports higher-order functions – Passing around Fun terms just like constants Function pointers also work int (*funcPtr)(int); int id(int j) { return j }; funcPtr = &id; int x = (*funcPtr)(0); Fun j j Ref id
36
More on functions This encoding supports higher-order functions – Passing around Fun terms just like constants Function pointers also work int (*funcPtr)(int); int id(int j) { return j }; funcPtr = &id; int x = (*funcPtr)(0); Fun j j funcPtr Ref id
37
Ref More on functions This encoding supports higher-order functions – Passing around Fun terms just like constants Function pointers also work int (*funcPtr)(int); int id(int j) { return j }; funcPtr = &id; int x = (*funcPtr)(0); Fun j j 0 0 x x Ref id funcPtr
38
Context (in)sensitivity Multiple call sites int x = id(1); int y = id(2); Fun 2 2 y y id Fun 1 1 x x j j r r {1,2} x{1,2} y
39
Context sensitivity Multiple call sites int x = id 1 (1); int y = id 2 (2); Option 1: Specialization Each call id i gets a new copy of id Eliminates smearing but increases graph size Fun 2 2 y y id 2 Fun j2j2 j2j2 r2r2 r2r2 1 1 x x id 1 Fun j1j1 j1j1 r1r1 r1r1 {1} x {2} y
40
Context sensitivity Option 2: Unique labeled edges for each call site Not using Fun constructor There is flow only if there is a path that spells a substring of a well-bracketed string – [ a [ b ] b ] a and [ a ] a [ b are valid; [ a [ b ] a ] b is not For both options, if there are higher-order functions or function pointers, need a first pass to compute pointer targets [1[1 ]1]1 [2[2 ]2]2 1 1 x x 2 2 y y j j r r
41
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); o o Fld f o.f Fld g o.g Fld f 3 3 Fld g 4 4 id Fun j j r r
42
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); o o Fld f o.f Fld g o.g Fld f 3 3 Fld g 4 4 id Fun j j r r
43
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); id Fun j j r r readG Fun p p r3r3 r3r3 Fld g Fld f o.f Fld g o.g o o Fld f 3 3 Fld g 4 4
44
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); id Fun j j r r readG Fun p p r3r3 r3r3 Fld g Fld f o.f Fld g o.g o o Fld f 3 3 Fld g 4 4 Fld f Fun w w
45
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); id Fun j j r r readG Fun p p r3r3 r3r3 Fld g Fld f o.f Fld g o.g o o Fld f 3 3 Fld g 4 4 Fld f Fun w w
46
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); id Fun j j r r readG Fun p p r3r3 r3r3 Fld g Fld f o.f Fld g o.g o o Fld f 3 3 Fld g 4 4 Fun z z Fld f Fun w w
47
Field sensitivity For each field f, define Fld f (-,+) constructor obj o = { f:3; g:4 }; int readG(obj p) { return p.g; } int w = id(o.f); int z = readG(o); id Fun j j r r readG Fun p p r3r3 r3r3 Fld g Fld f o.f Fld g o.g o o Fld f 3 3 Fld g 4 4 Fun z z Fld f Fun w w
48
Scalability Constraint graph for entire program is in memory Even for flow-insensitive analyses, this can become a bottleneck Even worse for flow-sensitive analyses Techniques for analyzing parts of program in isolation and storing summaries of their observable effects
49
Summary Set constraints a natural way to express various program analyses – Constant propagation, pointer analysis – Closure analysis – Receiver class analysis, prototype-based inheritance – Information flow Rich literature on solving systems of constraints Non-trivial to extend to flow-sensitive or summary-based analyses Interference between functions and references
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.