CS 701, Project 3
Global Code Optimizations

Due: Tuesday, November 29, 2005 (midnight)

Not accepted after: Tuesday, December 6, 2005 (midnight)

Overview

For this project, you will implement (up to) three related optimizations:
  1. Moving the computation of loop-invariant expressions out of the loop.
  2. Copy propagation.
  3. Removing useless assignments.

Moving Loop-Invariant Computations

For this part of the project you will identify loop-invariant expressions, and move their computations out of the loop. This involves the following steps:
  1. Build a control-flow graph.
  2. Find all natural loops (using using the same technique as in Project 2).
  3. Find loop-invariant expressions, and move their computations out of the loop.

The computations of loop-invariant expressions should be moved to the loop's preheader. The preheader of a loop is a CFG node that is the (unique) immediate predecessor of the loop header from outside the loop. If a loop does not have a preheader (i.e., the header node has more than one predecessor from outside the loop), you will need to add one (initially empty).

Note that Suif temporaries are only valid within a basic block, and that the only instructions involving literals are "load constant" instructions. Therefore, you will only be able to move expressions whose operands are pseudo registers (not temporary registers, and not literals). Look for instructions of the form

or where: and you will move the computation of the right-hand side of the assignment out of loop L into its preheader. This means creating two new instructions in the loop's preheader: where temp and pseudo are new temporary and pseudo registers, allocated using the new_register function (Suif does not permit instructions of the form pseudo = y op z; the only instruction that can assign to a pseudo register is a copy instruction). The code generator requires that every register correspond to a variable in the current function's symbol table, so when you allocate a new pseudo register you must also create a corresponding simple_sym and enter it into the symbol table using the function LVvar (as well as setting the var field of the new register to point to the new symbol).

You do not need to worry about profitability (is moving the invariant a guaranteed improvement), but you do need to worry about safety, so, as noted above, you should not move any computation that might cause a run-time error. This means that you should not move computations in which the opcode is DIV_OP, REM_OP, or MOD_OP. Also, an instruction that involves a pointer dereference (e.g., x = *z) should not be considered loop invariant.

Think about the order in which you process loops; an expression that is nested inside several loops should be moved out of as many of those loops as possible.

Copy Propagation

For this part of the project you will perform copy propagation. You will look for instructions of the form where y is a pseudo register, and you will replace later uses of x with y as appropriate. (Since temporary registers are only valid within a basic block, copy assignments in which y is a temporary cannot be propagated. Also, since the only instructions involving literals are "load constant" instructions, it is not possible to propagate x = literal.)

Remember that copy propagation can create opportunities for loop-invariant code motion, so think about iterating these two optimizations for maximum effect.

Removing Useless Assignments

Recall that an assignment is useless if the variable being assigned to is not live immediately after the assignment. Useless assignments can be created when copy propagation succeeds in propagating x = y to all later uses of x. For this part of the project you will identify and remove all instructions that correspond to useless assignments.

Command-Line Flags

To help make grading easier, you must implement the following command-line flags:
  1. -loopOpt
  2. -reportLoop
  3. -copyOpt
  4. -reportCopy
  5. -uselessOpt
  6. -reportUseless

Grading Criteria

Your grade will be based on the correctness of your implementation, a subjective evaluation of the quality of your code, and on the features you implement: For students working alone, 90 points will be considered perfect (and there will be no extra credit for additional points).

What to Hand In

As for previous assignments, please copy the following files to your subdirectory of the handin directory (~cs701-1/public/proj3/handin):
  1. All of the files that are needed to create your executable code generator (including your Makefile).
  2. A file named README that tells which features you implemented.

The executable created by your Makefile must be named gen.

Please do not create any subdirectories in your handin directory, and be sure not to copy any object files or executable files (they take up a lot of space and may cause the directory to exceed its quota).

Late Policy

This project is due by midnight on Tuesday, November 29. If handed in late, but prior to midnight Friday, December 2, a late penalty of 10% will be assessed. The project may handed in as late as midnight on Tuesday December 6, with a late penalty of 20%. This assignment will not be accepted after midnight on Tuesday, December 6.


Wed Oct 19 13:49:45 CDT 2005