<b>(a) </b> 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>(b) </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 <b>(c) </b> .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.