1 / 92

Context-Sensitivity Analysis Literature Review

Context-Sensitivity Analysis Literature Review. by José Nelson Amaral (amaral@cs.ualberta.ca) University of Alberta. Dimensions of Pointer Analysis. Unification-based × Insertion-based Flow-sensitive × flow-insensitive Field-sensitive × field-insensitive × field-based

Download Presentation

Context-Sensitivity Analysis Literature Review

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

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.

More Related