Managing data temporaries TopAnouncementsOperand Descriptors (cont.)

Operand Descriptors (cont.)

  1. In addition to providing a mechanism for communication between high-level code generation routines, the operand descriptor type is an essential component of the interface between the high and low level code-generation modules.

  2. The type used for operand descriptors should be flexible enough to handle several possibilities:

    registers
    Since access to values in registers is generally faster than access to memory, we would like the code we generate to keep intermediate results in registers whenever possible.

    memory locations
    Since we will eventually run out of registers, our compiler may have to store some intermediate results in memory. Even if this were not the case, other factors would make it necessary/desirable to have operand descriptors for memory locations.

    constants
    When processing an expression like x+1 we would like to produce the code:

    move x,D1
    add #1,D1

  3. There are several details we do have to consider at the high level if we want to produce decent code. For example, a more realistic version of the routine shown above might be:

       operand_desc *expr_gen(node * expr)
       { operand_desc *left_loc, *right_loc, *new_loc; 
    
         switch (expr->internal.type) {
            .  .   .
         case Nplus:
           left_loc = expr_gen(expr->internal.child[0]);
           right_loc = expr_gen(expr->internal.child[1]);
           
           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();
                output ``move left_loc,new_loc'';
                output ``add right_loc,new_loc'';
                freeOp(left_loc);
                freeOp(right_loc);
                return new_loc;
           }
           break;
           .
           .
           .
       

    As a result, the low-level code generator's interface must provide the means to determine various properties of the locations described by operand descriptors:

  4. This code illustrates the distinction between a high-level code generation routine and the low-level utility functions that allocate temporaries and actually output instructions.

  5. In this code we are assuming that the values returned by expr_gen, operand descriptors, provide both a mechanism for communication between high-level code generation routines, and an important component of the interface between the low-level and high-level code generation routines.

Computer Science 434
Department of Computer Science
Williams College

Managing data temporaries TopAnouncementsOperand Descriptors (cont.)