CS 701, Program #3

CS 701, Program 3
Natural Loops and Loop-Invariant Code Motion

Due: Wednesday, November 5, 2014 (by midnight)

Not accepted after midnight Wednesday, November 12, 2014

Overview

For this project, you will write one LLVM Function Pass that creates the usual instruction map, finds natural loops, then iterates, finding loop-invariant instructions and moving them out of their loops. The iteration ends when no more loop-invariant instructions are found.

The name of the pass (used in the call to RegisterPass) will be loopInv. Everyone will write the same code, whether working alone or in pairs.

As for project 2, you will use the mem2reg optimization before running your own pass. You'll also have your program keep track of the number of loop-invariant instructions that are moved, and store them as the statistics that are displayed to stderr when opt is run with the -stats flag.

For example, you'll use commands like the following:

    clang -emit-llvm -O0 -c foo.c -o foo.bc           // create bitcode .bc
    opt -mem2reg foo.bc > foo.opt                     // MEM2REG OPTIMIZATION
    mv foo.opt foo.bc
    (opt -load Debug/lib/P3.so -loopInv -stats foo.bc > foo.opt) >& foo.stats  // new loop-inv pass
                                                                                // bitcode sent to .opt file
                                                                                // stats and other debugging output sent to .stats file
    mv foo.opt foo.bc
    llc  foo.bc                                       // create assembly .s
    gcc foo.s -o foo                                  // create executable "foo"

Finding Natural Loops

To find natural loops you will do the following:
  1. Implement the "dominators analysis" dataflow problem using basic blocks as the nodes of the CFG. Some C programs include unreachable code. To avoid doing dominators analysis on unreachable code, initialize the worklist with the successors of the entry block instead of with all blocks. (You should assume that the first block visited by a Function iterator is the entry block.)
  2. Use depth-first search to find all backedges.
  3. Find all natural loops. For each, keep track of both the loop header and the loop body. (I suggest defining a NaturalLoop class to keep track of the natural loops that you find.) Note that if the input program has an irreducible CFG, there will be at least one backedge whose target doesn't dominate its source. Simply ignore such backedges.
  4. Combine loops with the same header into a single loop.
  5. Sort the loops by size (from largest to smallest). This way, when looking for loop-invariant instructions, you will process outer loops before inner loops. This will avoid moving an instruction that is in an inner loop but is invariant with respect to the outer loop, multiple times. (If multiple loops have the same size body, then sort them using the lexicographic order of the headers' block names. This will ensure that your output is uniform.)

Moving Loop-Invariant Instructions

Once you've found and sorted all natural loops, process them in sorted order. Processing a loop means finding all loop-invariant instructions, and moving them out of the loop. Only move instructions that are safe to move, but won't worry about profitability. An instruction is loop-invariant, and is safe to move if all of the following apply:

See Instruction.def to identify the opcodes for division, remainder, memory operations, call, invoke, and phi. See Instruction.h for the isTerminator method.

Loop-invariant instructions need to be moved to the loop's preheader. If a loop has no (unique) preheader, you will need to add one. You should only add a preheader when you're processing a loop if (a) it needs one, and (b) you've found loop-invariant instructions in that loop.

To add a preheader, you can use the LLVM method SplitBlockPredecessors in BasicBlockUtils.h; the documentation is at the end of this file. However, the type for the second parameter given there is wrong (the actual code can be found in /unsup/llvm-3.3/include/llvm/Transforms/Utils/BasicBlockUtils.h ). To use the SplitBlockPredecessors method, you should create and fill in a Preds array as described in the documentation (an array of BasicBlock, i.e., Preds should be of type BasicBlock **). If the Preds array is of size asize, then the second argument to SplitBlockPredecessors should look like this:

The Making simple changes section of the Programmers Manual tells how to insert an instruction into a Basic Block (useful when moving loop-invariant instructions out of the loop and into the preheader). Use the insert method of the preheader block, and insert the loop-invariant instruction before that block's terminator (branch) instruction. You can get a (pointer to) the terminator using the preheader block's getTerminator method.

The Programmers Manual also tells you how to remove an instruction from its basic block.

Program Output

As for project 2, you should produce different kinds of output depending on the contents of the file flags.h. Test inputs and expected output can be found in

I suggest that you also check to be sure that your optimized code, when run, produces the same results as the original code. You might want to write your own tests for this, in which various different kinds of instructions are moved, in which you do/do-not create preheaders, etc.

Here are the different kinds of output that you should be able to produce:

Submit Your Work

To submit your work, copy all of your .cpp and .h files and your Makefile to your handin directory

~cs701-1/HANDIN/YOUR-LOGIN/P3

using your actual login in place of YOUR-LOGIN. If you are working with a partner, only one of you should submit your work. Inform us if you have changed who you're working with.

Late Policy

The project is due on Wednesday, Novemebr 5. It may be handed in late, with a penalty of 3% per day, up to Wednesday, November 12. The maximum late penalty is therefore 21% (the maximum possible grade becomes 79). This assignment will not be accepted after Wednesday, November 12.


Wed Sep 24 15:05:03 CDT 2014