350 likes | 466 Views
Alias Analysis. 2006 년 5 월 1 일 ADVANCED COMPILER 이정옥. p. n. 4. What Is Alias Analysis. Determination of Storage Locations That May Be Accessed in Two or More Ways. main() { int *p; int n; p=&n; n=4 printf(“%d<br>”,*p); }. simple pointer aliasing in C.
E N D
Alias Analysis 2006년 5월 1일 ADVANCED COMPILER 이정옥
p n 4 What Is Alias Analysis Determination of Storage Locations That May Be Accessed in Two or More Ways main() { int *p; int n; p=&n; n=4 printf(“%d\n”,*p); } simple pointer aliasing in C Relationship between the variable at the call to printf()
Important Important to Doing Most of Optimization ■ Example of the Importance of Alias Computation ■ exam1() { int a, k; extern int *q; . . . k = a + 5; f(a,&k); *q = 13; k = a + 5; /*redundant?*/ . . . } Interprocedural Alias To Chapter 19 Intraprocedural Alias In practice, usually more Important if and only if both the call to f() and the assignment *q=13 leave the values of both k and a unmodified
May Alias Information • p may point to y or z Must Alias Information • p must points to x Flow-Insensitive Information • p may points to x • (there is a path, p assigned the address of x) Flow-Sensitive Information • p points to x in block B7 p=&y p=&z p=&x Classification for Alias Information
Formal Characterization of Aliasing Flow-Insensitive May Information Flow-Insensitive Must Information • x alias y if and only if x and y may, possibly at different times, refer to the same storage location. • Symmetric . x alias y == y alias x • Intransitive . a alias b, and b alias c but not → a alias c. • x alias y if and only if x and y must, throughout the execution of a procedure, refer to the same storage location. • Symmetric . x alias y == y alias x • Transitive . a alias b and b alias c → a alias c
Formal Characterization of Aliasing Flow-Sensitive May Information Flow-Sensitive Must Information • Alias(p,v) = SL . at point p variable v may refer to any of the locations in SL • Alias(p,a) ∩ Alias(p,b) ≠ and Alias(p,b) ∩ Alias(p,c) ≠, then Alias(p,a) ∩ Alias(p,c) ≠ but not necessarily • Alias(p1,a) ∩ Alias(p2,a) ≠ and Alias(p2,a) ∩ Alias(p3,a) ≠, then Alias(p1,a) ∩ Alias(p3,a) ≠ but not necessarily • Alias(p,v) = l . at point p variable v must refer to location l • Alias(p,a) = Alias(p,b) and Alias(p,b) = Alias(p,c) → Alias(p,a) = Alias(p,c) • Alias(p1,a) = Alias(p2,a) and Alias(p2,a) = Alias(p3,a) → Alias(p1,a) = Alias(p3,a)
Example for Different Aliases exam2() { int a, b, c[100], d, i; extern int *q; . . . q = &a; a = 2; b = *q + 2; . . . q = &b; for( i = 0; i < 100; i++ ) { c[i] = c[i] + a; *q = i; /* can out loop ? */ } d = * q + a; } exam2() { int a, b, c[100], d, i; extern int *q; . . . q = &a; a = 2; b = *q + 2; . . . q = &b; for( i = 0; i < 100; i++ ) { c[i] = c[i] + a; } *q = 100; /* can ! */ d = * q + a; } If we were to do flow-insensitive may alias, q could point to a or b so not loop invariant If we were to do flow-sensitive must alias, q must point to b in this so loop invariant.
Divide to Two Pass • A language-specific Component, • called the alias gatherer • Compiler front end to provide us. A single component in the optimizer, called the alias propagator • Performs a data flow analysis
Fortran 77 Pascal C Fortran 90 Aliases in Various Real Programming Languages ☼ Because C is most popular and C is most difficult, I will explain only in C.
Aliases in C (ANSI-standard C) [union] Union type may have several fields declared, all of which overlap in storage. [Array] Array index : a[100], we have a = &a[0] [Pointer] Int *p, a[100]; p = a; [Parameter passing and returning a pointer] f(i,j) int *i, *j; { *i = *j + 1; }
The Alias Gatherer [P] denote a program point, [entry+] immediately follow the entry node [exit-] immediately precede the exit node [stmt(P)] the statement immediately preceding P
entry entry+ q = p 5 1 Y q = NIL 6 N 2 4 return NIL q = q -> np q -> elt == m N Y 3 return q exit- exit stmt(2) = stmt(6) = node(q =NIL) The Alias Gatherer_EXAMPLE
The Alias Gatherer [x] a scalar variable, an array, a structure, the value of a pointer,etc. [memp(x)] an abstarct memory location associated with object x.(at point P) [star(o)] a static or automatically allocated memory area occupied by linguistic object o.
The Alias Gatherer [anon(ty)] If x is dynamically allocated (ty is the type of x). [anon] If x is dynamically allocated and its type is not known. • ∀ty1,ty2, if ty1 ≠ ty2, then anon(ty1) ≠ anon(ty2)
entry entry+ receive p(val) B1 1 mem2(i) = star(i) i = 1 B2 2 B3 4 3 i <= 5 N Y q = q.next 8 B5 p = q B4 6 p = q B6 7 Y 5 N print (q.value) 9 B7 return q B8 mem5(q) = anon(ptr) exit- exit The Alias Gatherer_EXAMPLE
The Alias Gatherer [any(ty)] the set of all possible storage location of the type [any] the set of all possible storage location. [globals] all location in common storage (in c: includes all variables declared outside and declared with the extern).
The Alias Gatherer Define a Series of Function ovrp(x) = the set of abstract memory locations x may overlap with at point p ptr(x) = the set of abstract memory locations x may point to at point p
p1 p2 p3 p4 The Alias Gatherer refp(x) = the set of abstract memory locations reachable through arbitrarily many dereferences from x at point p. • We define refp1(x) = ptrp(x) , for i > 1, • refpi(x) = ptrp (felds(refpi-1(x))) • Where fields(x) = x (if x is a point) the set of pointer-valued fields (if x is a structure) • refp(x) = • ref(x) = the set of abstract memory locations reachable through • arbitrarily many dereferences from x in dependent of the • program point.
Rules for C Now assume that • p, q are pointers. • s is a structure • st is a structure type • ut is union type • a [] is array • i is integer-valued • if stmt(P) is as following…
1 P’ p=null ptrP(p) = P 2 P’ p=malloc() ptrp(p)=anon P 3 P’ p = &a ptrp(p)={memp(a)}={memp’(a)} P Rules for C
4 P’ p1=p2 P entry+ • ptrp(p1)=ptrp(p2)= mementry+(*p2) p1=p2 P 5 P’ p1=p2->p3 ptrp(p1)=ptrp’(p2->p3) P Rules for C • ptrp(p1)=ptrp(p2)= ptrp’(p2)
6 P’ p=&a[expr] prtp(p)=ovrp(a)=ovrp’(a)={memp’(a)} P 7 P’ p = p + i ptrp(p)=ptrp’(p) P 8 P’ ptrp(p)=ptrp’(p) and if *p is a pointer then ptrp(*p) = ptrp(a) = ptrp’(a) *p=a P Rules for C
9 P’ if(p==q) Y P Rules for C ptrp(p)=ptrp(q)=ptrp’(p) ∩ ptrp’(q) N struct st { type s1; … type sn; } s; 10 ovrp(s)={memp(s)}= {memp(s.si)} and for each i, {memp(s.si)}= ovrp(s.si) ⊂ ovrp(s) and for each j≠i, ovrp(s.si) ∩ ovrp(s.sj)=
Rules for C ptrp(p)={memp(*p)} = {memp(p->si)} and for each i {memp(p->si)}=ptrp(p->si)⊂ptrp(s) and for all i≠j, ptrp(p->si) ∩ ptrp(p->sj) = and for all other objects x, ptrp(p) ∩ {memp(x)}= 11 P’ p=&s P 12 union ut { type u1; … type un; } u; ovrp(u)={memp(u)}= {memp(u.ui)} for i=1,…,n
Rules for C 13 P’ ptrp(p)={memp(*p)} = {memp(p->ui)} and for each i and for all other objects x, ptrp(p) ∩ {memp(x)}= p=&u P 14 ptrp(p)=refp’(p) for all pointers p p are arguments to f(), p are global pointer, or p =f(). P’ f( ) P
Alias Propagator The Data-Flow Function in Alias Propagator Ovr() , Ptr() ovrp(x) if stmt(P) affects p Ovr(P’,x)= otherwise 1 Ovr(P,x)= P’ P ptrp(p) if stmt(P) affects p Ptr(P’,p)= otherwise Ptr(P,p)=
P1…Pn 2 Ovr(P,x)= Ovr(Pi,x) empty P Ptr(P,p)= Ptr(Pi,p) 3 P Ovr(Pi,x) = Ovr(P,x) test Ptr(Pi,p) = Ptr(P,p) P1…Pn alias propagator
Initial Values for Ovr() and Ptr() {star(x)} if P = entry+ otherwise Ovr(P,x) = if P = entry+ and p is local any if P = entry+ and p is global {mementry+(*p)} if P = entry+ and p is a parameter otherwise Ptr(P,p) =
First Example typedef struct {int i; char c;} struct_type; struct_type s, *ps, **pps1, **pps2, arr[100]; pps1 = &ps; pps2 = pps1; *pps2 = &s; ps->i = 13; func(ps); arr[1].i = 10; ptr1(pps1)={mementry+(ps)} ={star(ps)} ptr2(pps2)= ptr2(pps1)=ptr1(pps1) ptr3(pps2)=ptr2(pps2) ptr3(*pps2)=ptr3(&s)=ptr2(&s)=ovr2(s) ptr5(ps)=ref4(ps) entry entry+ pps1 = &ps 1 pps2 = pps1 2 *pps2 = &s 3 ps -> i = 13 Ovr(entry+,s) = {star(s)} Ovr(entry+,ps) = {star(ps)} Ovr(entry+,pps1) = {star(pps1)} Ovr(entry+,pps2) = {star(pps2)} Ovr(entry+,arr) = {star(arr)} 4 func(ps) 5 arr[1].i = 10 exit- exit
entry entry+ pps1 = &ps 1 pps2 = pps1 2 *pps2 = &s 3 ps -> i = 13 4 func(ps) 5 arr[1].i = 10 exit- exit First Example Ptr(1,pps1)={star(ps)} Ptr(2,pps2)={star(ps)} Ptr(3,ps) = {star(s)} Ptr(5,ps) = ref5(ps) ∪ ∪ ref(p) = {star(s)} p∈globals ptr1(pps1) ={star(ps)} ptr2(pps2)=ptr1(pps1) ptr3(pps2)=ptr2(pps2) ptr3(*pps2)=ovr2(s) ptr5(ps)=ref4(ps) Ovr(entry+,s) = {star(s)} Ovr(entry+,ps) = {star(ps)} Ovr(entry+,pps1) = {star(pps1)} Ovr(entry+,pps2) = {star(pps2)} Ovr(entry+,arr) = {star(arr)} Ovr() is identical
entry entry+ p = &i 1 i = n +1 2 q = &j 3 j = n * 2 4 k = *p + *q 5 return k exit- exit Second Example int arith(n) int n; { int i, j, k, *p, *q; p =&i: i = n +1; q = &j; j = n * 2; k = *p + *q; return k; } ptr1(p) ={mem1(i)}={star(i)} ptr3(q) ={mem3(j)}={star(j)} the pointers are only fetched and never stored, we can optimize k = *p + *q; k = i + j;
entry entry+ q = p 5 1 Y q == NIL 6 N 2 4 return NIL q = q → np q -> elt == m N Y 3 return q exit exit Third Example typedef struct {node * np; int elt;} node; node *find(p,m) node *p; int m; { node * q; for (q=p; q==NIL; q = q->np) if (q->elt ==m) return q; return NIL; }
entry entry+ q = p 5 1 Y q == NIL 6 N 2 4 return NIL q = q → np q → elt == m N Y 3 return q exit- exit Third Example Ptr(entry+,p)= {mementry+(*p)} Ptr(1,q)=ptr1(q) Ptr(2,q)=Ptr(1,q)∪Ptr(5,q) Ptr(3,q)=Ptr2(q) Ptr(4,q)=Ptr2(q) Ptr(5,q)=ptr5(q) Ptr(6,q)=ptr6(q) Ptr(exit-,q)=Ptr(3,q )∪Ptr(6,q) ptr1(q)=ptr(p)=mementry+(*p) ptr6(q)={nil} ptr5(q)=ptr5(q → np)=ptr4(q → np)
Third Example Ptr(entry+,p)={mementry+(*p)} Ptr(1,q)= {mementry+(*p)} Ptr(2,q)= {mementry+(*p)} ∪Ptr(5,q) Ptr(3,q)= {mementry+(*p)} ∪ Ptr(5,q) Ptr(4,q)= {mementry+(*p)} ∪Ptr(5,q) Ptr(5,q)=ptr4(q->np) =ref4(q) Ptr(6,q)={nil} Ptr(exit-,q)= {nil,mementry+(*p)} ∪Ptr(5,q)
Third Example Ptr(entry+,p)={mementry+(*p)} Ptr(1,q) = {mementry+(*p)} Ptr(2,q) = {mementry+(*p)} ∪ ref4(q) Ptr(3,q) = {mementry+(*p)} ∪ ref4(q) Ptr(4,q) = {mementry+(*p)} ∪ ref4(q) Ptr(5,q) = ref4(q) Ptr(6,q)={nil} Ptr(exit-,q)= {nil,mementry+(*p)} ∪ ref4(q)