next up previous contents
Next: Some Issues in SimpleSUIF Up: CMSC 731 (Spring 1998) Previous: Dead Code Elimination

Pitfalls encountered

Although, all the above optimizations described above are expected to be useful, there are certain cases where many of the optimizations would lead to incorrect code generation. Since in the project, we perform on alias analysis or interprocedural analysis, it was necessary to make a few conservative assumptions to begin with.

An interesting example of this is for global variables. Consider the following piece of C code fragment -

int a; /* global variable */

void main (void)
{
 a = 1;
 foo();
 return;
}

void foo (void)
{
 printf ("%d\n",a);
 return;
}

In this example, in the procedure main, without information about the use of the variable a, inside the procedure foo, it would be detected as unused. As a consequence, it might lead to the assignment of a being deleted in dead code elimination, which is clearly wrong. Hence, it was necessary to assume that any procedure call would lead to use of all global variables. However, in SimpleSUIF instructions, there is no way to differentiate between a global variable and a regular pointer variable. Both of them would be accessed using load and str operations, as pointer variables. Hence, to turn off optimizations for global variables would lead to turning off these optimizations for all pointers in general.

Another problem was of aliasing in C programs. The following C code fragment illustrates the point.

void main (void)
{
 int *pa;
 int x, y;

 pa = 0x234435;

 x = 1;
 *pa = 2;
 y = x + 1;
 printf ("%d\n",y);
 return;
}

In this example, it is possible the pa actually points to the address of the variable x. However, since the address of x is only determined at run time, at compile time we cannot realize that the statement (*pa = 2;) might actually be changing the value of x. Hence, if we use the value of x as 1 in constant folding to get the value of y, it might be incorrect.

However, the above kind of code is actually very rare, if not absent from programs, since the user is general will not be aware of the actual address of variables at run-time. But, for sake of correctness, it would lead to unsafe code, if such kind of issues are not taken care of. In my implementation I have such unsafe optimizations, having made the optimistic assumption that users will not write such kinds of code.

It may be noted, however, that such kind of code cannot be generated in Fortran code, and so this is not an issue for Fortran programs.

Another example of interest is for array variables. Consider the code fragment below -

void main (void)
{
 int A[10];
 int i;

 A[0] = 5;
 for (i = 1; i < 9; i++)
	{
	 A[i] = A[i-1];
 	 printf ("%d\n",A[i]);
	}
 return;
}

It is clear that A[0] assignment cannot be deleted as a dead instruction, since it is used as A[i-1]. However, the address of A[i-1] will not be a constant, while the address of A[0] is. The address of A[i-1] would be computed as -

ldc  (a.32)     t9 = &A + 0
ldc  (s.32)     t10 = 4
mul  (s.32)     t11 = r1, t10
ldc  (s.32)     t12 = 4
sub  (s.32)     t13 = t11, t12

where, r1 denotes the variable i. To ensure correctness, I treat all uses of any variable, whose address is expressed as some function of the address of A, as an use of the entire array A. Hence, references of t9, t11 and t13 are treated as references to the array A. This prevents A[0] assignment from being detected as dead code.


next up previous contents
Next: Some Issues in SimpleSUIF Up: CMSC 731 (Spring 1998) Previous: Dead Code Elimination

Suman Banerjee
Tue Jun 16 14:38:56 EDT 1998