(a) 
double  u_m;
double  v_m;

typedef struct s {
  int     n_m;
  double* x_m;
  double* a_m;
  double* b_m;
} s;
void f(struct s* s)
{
  int i;
  for (i=0; i < s->n_m; ++i)
    s->x_m[i] = (u_m * s->a_m[i]) + (v_m * s->b_m[i]);
}

(b) 
 .L9:
      sll     $3,$5,3       	# Multiply i by 8
      addu    $2,$3,$2      	# Compute the address of s->a_m[i]
      l.d     $f1,0($2)     	# Load s->a_m[i]
      mul.d   $f1,$f3,$f1   	# Multiply u_m * s->a_m[i]
      lw      $2,12($4)     	# Load s->b_m
      addu    $2,$3,$2      	# Compute the address of s->b_m[i]
      l.d     $f0,0($2)     	# Load s->b_m[i]
      mul.d   $f0,$f2,$f0   	# Multiply v_m * s->b_m[i]
      lw      $2,4($4)      	# Load s->x_m
      add.d   $f1,$f1,$f0   	# Add (u_m * s->a_m[i]) + (v_m * s->b_m[i])
      addu    $3,$3,$2      	# Compute the address of s->x_m[i]
      s.d     $f1,0($3)     	# Store the sum into s->x_m[i]
      lw      $2,0($4)      	# Load s->n_m
      addu    $5,$5,1       	# Increment i
      slt     $2,$5,$2      	# Subtract s->n_m from i
      bnel    $2,$0,.L9     	# If i < s->n_m goto .L9
      lw      $2,8($4)      	# Load s->a_m

(c) 
 .L6:
      l.d     $f1,0(2,$$4)  	# Load s->a_m[i]
      mul.d   $f1,$f3,$f1  	# Multiply u_m * s->a_m[i]
      mul.d   $f0,$ff0  	# Multiply v_m * s->b_m[i]
      add.d   $f1,$f1,$f0  	# Add (u_m * s->a_m[i]) + (v_m * s->b_m[i])
      addu    $3,$3,8      	# Increment pointer to s->b_m[i]
      addu    $4,$4,8      	# Increment pointer to s->a_m[i]
      addu    $2,$2,-1     	# Decrement i
      s.d     $f1,0($5)    	# Store the sum into s->x_m[i]
      bne     $2,$0,.L6    	# If i < s->n_m goto .L6
      addu    $5,$5,8      	# Increment pointer to s->x_m[i]
      l.d     $f0,0($3)    	# Load s->b_m[i]

Example 7: Impact of type-based alias analysis on real code. (a) Source code; (b) assembly, without using type-based alias analysis; (c) assembly, using type-based alias analysis.

Back to Article