| Handling Address Temporaries |
a[3*i+j]
operand_desc *expr_gen(node * expr, int useAddr)
{
operand_desc *left_loc, *right_loc, *new_loc;
switch (expr->internal.type) {
.
.
.
case Nplus:
left_loc = expr_gen(expr->internal.child[0],
useAddr);
right_loc = expr_gen(expr->internal.child[1],
useAddr && ! isAddr(left_loc));
if is_temporary(left_loc) {
output ``add right_loc,left_loc'';
freeOp(right_loc);
return left_loc;
} else if is_temporary(right_loc) {
output ``add left_loc,right_loc'';
freeOp(left_loc);
return right_loc;
} else {
new_loc = get_temporary( useAddr );
output ``move left_loc,new_loc'';
output ``add right_loc,new_loc'';
freeOp(left_loc);
freeOp(right_loc);
return new_loc;
}
break;
.
.
.
In this case, the routine that is eventually asked to generate an instruction referencing the operand may first have to generate instructions to load the needed static link pointer.
| move | static-link-pointer,a1 |
| code for big expression | |
| add | disp(a1),result-of-big-expr |
| code for big expression | |
| move | static-link-pointer,a1 |
| add | disp(a1),result-of-big-expr |
The second approach reduces the total demand for registers by reducing the range of instruction during which a register must be reserved for a base address.
a[i]+ (a[j] + (a[k] + ( a[l] + ( a[m] + a[n]))))
| Handling Address Temporaries |