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"
entry
block instead of with all blocks.
(You should assume that the first block visited by a Function
iterator is the entry
block.)
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.
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
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
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
The Programmers Manual also tells you how to remove an instruction
from its basic block.
As for project 2, you should produce different kinds of output
depending on the contents of the file
Here are the different kinds of output that you should be able
to produce:
To submit your work,
copy all of your 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.
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.
Moving Loop-Invariant Instructions
Instruction.def
to identify the opcodes for division, remainder, memory operations,
call, invoke, and phi.
See
Instruction.h
for the isTerminator
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:
ArrayRef
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.
Program Output
flags.h
.
Test inputs and expected output can be found in
~cs701-1/public/proj3/TESTS
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.
flags.h
contains
#define PRINTDOM 1
, you should
print the results of the dominators
analysis.
The sets of basic-block names in the dominators sets should be
printed in sorted order.
Print empty sets for both the dominator-before and
dominator-after sets of unreachable blocks.
flags.h
contains #define PRINTMERGE 1
, then
each time you merge a set of loops with the same header you should print
where merging N loops with header XXX
N
is the number of loops being merged, and
XXX
is the name of the basic block that is the (common)
header.
We will sort this output before comparing it to the expected
output, so don't worry about the order in which loops are merged.
flags.h
contains #define PRINTLOOPS 1
you should print the loops in sorted order, longest to shortest.
If there are two loops with the same length, print the loop
whose header block's name come first in lexigraphical order.
The basic block names in the loop body should also be printed in
sorted order.
Print the loops before adding preheaders but after merging
loops with the same header.
flags.h
contains #define PRINTPRE 1
, then
each time you add a loop preheader, print
where adding preheader for loop with header XXX
XXX
is the name of the basic block that is
the header of the loop.
We will sort this output before comparing it to the expected
output, so don't worry about the order in which these messages
are printed.
flags.h
contains #define PRINTMOVING 1
,
then each time you move a loop-invariant instruction, print
where moving instruction %xx
xx
is the instruction number.
I will sort this output before comparing it to the expected
output, so don't worry about the order in which these messages
are printed.
STATISTIC
macro with the string "Number of loop-invariant instructions
moved".
Submit Your Work
.cpp
and .h
files
and your Makefile
to your handin directory
~cs701-1/HANDIN/YOUR-LOGIN/P3
Late Policy
Wed Sep 24 15:05:03 CDT 2014