Download
context sensitivity analysis literature review n.
Skip this Video
Loading SlideShow in 5 Seconds..
Context-Sensitivity Analysis Literature Review PowerPoint Presentation
Download Presentation
Context-Sensitivity Analysis Literature Review

Context-Sensitivity Analysis Literature Review

131 Views Download Presentation
Download Presentation

Context-Sensitivity Analysis Literature Review

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Context-Sensitivity AnalysisLiterature Review by José Nelson Amaral (amaral@cs.ualberta.ca) University of Alberta

  2. Dimensions of Pointer Analysis • Unification-based × Insertion-based • Flow-sensitive × flow-insensitive • Field-sensitive × field-insensitive × field-based • Context-sensitive × context-insensitive

  3. a Andersen’s X Steensgaard’s (Example) Insertion X Unification Program: Steensgaard: a = &b; S = {(a,b)} b Andersen: S = {(a,b)} b a CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  4. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; S = {(a,b); (b,c)} b c Andersen: S = {(a,b); (b,c)} b c a CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  5. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; if(cond) a = &d; S = {(a,b); (b,c)} b c Andersen: What should happen in each analysis? S = {(a,b); (b,c)} b c a CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  6. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; if(cond) a = &d; S = {(a,b); (b,c); (a,d); (d,c)} (b,d) c Andersen: S = {(a,b); (b,c); (a,d)} b c a d CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  7. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; if(cond) a = &d; d = &e; S = {(a,b); (b,c); (a,d); (d,c)} (b,d) c Andersen: And now? S = {(a,b); (b,c); (a,d)} b c a d CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  8. a Andersen’s X Steensgaard’s (Example) Program: Steensgaard: a = &b; b = &c; if(cond) a = &d; d = &e; S = {(a,b); (b,c); (a,d); (d,c); (d,e); (b,e)} (b,d) (c,e) Andersen: S = {(a,b); (b,c); (a,d); (d,e)} b c a e d CMPUT 680 - Compiler Design and Optimization After (Shapiro/Horwitz, PPL97)

  9. a a a Flow-sensitive X Flow-insensitive (Example) Strong update: Not only a now points to d, but also a no longer points to b b b c Program: a = &b;  b = &c;  if(cond)  a = &d;   d = &e;  a b c d Insertion based Unification based a b,d c d b c a b c a b,d c,e e d CMPUT 680 - Compiler Design and Optimization

  10. Flow-sensitivity in SSA(incomplete slide) All variables that had their address taken must have an “access path” which is their address. They can only be referenced through their access paths. pb = &b; pc = &c; pd = &d; pe = &e; a0 = pb; *pb = pc; if(cond) a1 = pd; a2 = phi(a0, a1, FALSE, TRUE); *pd = pe; pb pc Program: b c a0 a2 e a1 d pd pe In SSA flow-sensitive information can be obtained from the single graph above. CMPUT 680 - Compiler Design and Optimization

  11. Field-insensitive × Field-based × Field-sensitive analysis • Field insensitive: Each aggregate object modeled by a single abstract variable. • Field-based: An abstract variable models all instances of a field of an aggregate type. • Field-sensitive: Unique abstract variable models each field of each aggregate object. (PearceKellyHankinTOPLAS07)

  12. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; Program: af1 d f1 d d (PearceKellyHankinTOPLAS07)

  13. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; Program: af1 d f1 d d f f f (PearceKellyHankinTOPLAS07)

  14. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; Program: af1 d f1 d d f af2 f2 f f (PearceKellyHankinTOPLAS07)

  15. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; b.f1 = &e; af1 d f1 d d e f af2 e f2 f f e (PearceKellyHankinTOPLAS07)

  16. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. b a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; b.f1 = &e; af1 d f1 d d e f af2 e f2 f f bf1 e (PearceKellyHankinTOPLAS07)

  17. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. c b a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; b.f1 = &e; c = a.f1; af1 d f1 d d c e f c af2 e f2 f f bf1 e (PearceKellyHankinTOPLAS07)

  18. Field Sensitivity (Example) Assume a flow insensitive, insertion-based analysis. c b a Program: Field Insensitive Field Based Field Sensitive typedef struct{ int *f1; int *f2; } aggr; aggr a,b; int *c, d, e, f; a.f1 = &d; a.f2 = &f; b.f1 = &e; c = a.f1; af1 d f1 d d c e f c af2 e f2 f f bf1 e (PearceKellyHankinTOPLAS07)

  19. Field Sensitivity in C • A field-sensitive analysis for C is fundamentally harder than a field-sensitive analysis for Java: • C allows the address of a field to be taken • Existing field-sensitive analysis for C: • YongHorwitzRepsPLDI99; • ChandraRepsPASTE99; • JohnsonWagnerUSENIX04; • PearceKellyHankinTOPLAS07;

  20. What context-sensitivity means? • Context-sensitive analysis: “the effects of a procedure call are estimated within a specific calling context” • Context-insensitive analysis: “the effects of a procedure call summarizes the information for all calling contexts.” (EmamiGhyaHendrenPLDI94)

  21. Another definition • “A context-insensitive (CI) algorithm does not distinguish the different calling contexts of a procedure, whereas a context-sensitive (CS) does.” (ZhuCalmanPLDI04) • “CS treats multiple calls to a single procedure independently.” (RufPLDI95) • “CI constructs a single approximation to a procedure’s effect on all of its callers.” (RufPLDI95)

  22. Alternative definition:The calling context problem • The calling context problem is “the problem of correctly accounting for the calling context of a called procedure.” HorowitzRepsBlinkeyTOPLAS90

  23. A more strict definition • “A precise CS analysis yields results as precise as if they were computed on a modified program with all method calls inlined.” • Requires a context-sensitive heap abstraction: • a separate abstraction is needed for each copy of an allocation statement • Virtual call targets must be computed context-sensitively • separately for each calling context; • using precise points-to information; SridharanBodikPLDI06

  24. Context-Sensitive Example • Two calls to a function foo produce different return values because of the points-to set at the point immediately before each call to foo. • In other words, the return value of foo changes depending on the context within which foo is invoked.

  25. #include <stdlib.h> typedefintarr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(intargc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example

  26. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo Is there an algorithm that “gets” this example? Emami, Ghiya, and Hendren (PLDI94) should get it. We need to study the points-to sets that the algorithm computes at points P1, P2, and P3. P1 P2 P3

  27. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo In the following animation: y x x definitely points to y (variable x contains the address of variable y) x probably points to y (arrowsare colored red only for convenience in the animation, they represent new points-to relations that were not in the previous slide) P1 P2 P3

  28. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo x1 x2 x3 a1 a2 a3 y1 y2 y3 P1?

  29. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo x1 x2 x3 a1 a2 a3 y1 y2 y3 P1

  30. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  31. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  32. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA’? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  33. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA’ p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  34. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA”? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  35. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA” p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  36. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA” p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  37. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA’’’? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  38. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA’’’? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  39. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PB? p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  40. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PB p2 p3 t x1 x2 x3 a1 a2 a3 y1 y2 y3

  41. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo lp x1 x2 x3 a1 a2 a3 y1 y2 y3 P2?

  42. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo lp x1 x2 x3 a1 a2 a3 y1 y2 y3 P2

  43. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA? p2 lp p3 t x2 x3 x1 a2 a3 a1 y1 y3 y2

  44. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PA p2 lp p3 t x2 x3 x1 a2 a3 a1 y1 y3 y2

  45. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PB? t lp p2 p3 x3 x1 x2 a2 a3 a1 y3 y1 y2

  46. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo PB t lp p2 p3 x3 x1 x2 a2 a3 a1 y3 y1 y2

  47. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo lp lq x1 x2 x3 a1 a2 a3 y1 y2 y3 P3?

  48. #include <stdlib.h> typedef int arr[10000]; arr a1, a2, a3; int cond1, cond2; int *foo (int **p2, int **p3){ int *t; if(cond2){ t = *p2; *p2 = *p3; *p3 = t; } return *p2; } int main(int argc, char *argv[]){ int *x1, *x2, *x3, *y1, *y2, *y3; int *lp, *lq, r; cond1 = argc-1; cond2 = argc-2; a1[0] = argc; a2[0] = argc+1; a3[0] = argc+2; x1 = a1; x2 = a2; x3 = a3; y1 = a1; y2 = a2; y3 = a3; if(cond1){ x1 = a2; x2 = a1; } lp = foo(&x2, &x3); lq = foo(&y2, &y3); return (*lp + *lq); } Context-sensitive example foo lp lq x1 x2 x3 a1 a2 a3 y1 y2 y3 P3

  49. Solutions to the context-sensitive problem • Create a context for each acyclic path from the root of the call graph to the current invocation (EmamiGhyaHendrenPLDI94). • Create a context for each set of “relevant” alias set on entry of procedure --- also known as partial transfer functions (PTF) (WilsonLamPLDI95) • “to answer simple queries (PTF) requires all the results to be computed.” (WhaleyLamPLDI04) (Descriptions taken from RufPLDI95)

  50. Solutions to the context-sensitive problem (cont.) • Tag each alias to allow a procedure to propagate only appropriate aliases to its callers: • uses aliases on entry to the enclosing procedure (LandiRyderPLDI93) • Augment summary with abstraction of call stack (Cooper89MScThesis, ChoiBurkeCarinePoPL93) • A fully context-sensitive analysis is exponential on the size of the input program --- unless the number of contexts considered is limited somehow.