Operand DescriptorsTopLowering Expression Sub-trees Code Generation for Expressions

Code Generation for Expressions

  1. First, I would like to give a quick overview of a simple, "ad hoc" approach to code generation in hopes of:

  2. To do this, we will limit our attention to expressions including simple arithmetic operators:
  3. When I speak of applying "code templates" I am basically talking about the fact that the correct code for an expression can be generated using very little information about the context in which the expression occurs.

    All one has to do is make sure that each code generation routine tells its caller where the results can be found.
  4. Each code generation routine will use the "attribute value" it returns to tell its caller where the result of the code it produces can be found.

    We will call these attributes operand descriptors.

  5. To illustrate the use of operand descriptors, consider the following skeleton of a very naive routine to generate code for the addition operator. It assumes that "operand_desc" is the type used to represent the attribute values returned during code generation for expressions.
       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]);
           
           new_loc = get_temporary();
           output ``move left_loc,new_loc'';
           output ``add right_loc,new_loc'';
    
           opFree(left_loc);
           opFree(right_loc);
    
           return new_loc;
           }
           .
           .
       
  6. When writing such a routine, we would rather not have to worry about
  7. The issues of allocation registers and other temporaries and actual instruction selection decisions that depend on the operand types should be handled by "low level" code generation routines (with names like get_temporary and output_instructions).
  8. Routines like the "expr_gen" function sketched above form the "high level" component of the code generator in that they are concerned with mapping the operations of the source language into the operations the hardware can perform, but not in the precise details of each instruction generated.
  9. Maintaining a clear distinction between high level and low level code generation tasks will both keep your code well organized and result in a code generator that could be revised to output code for a different target machine with minimal effort.

Computer Science 434
Department of Computer Science
Williams College

Operand DescriptorsTopLowering Expression Sub-trees Code Generation for Expressions