This is an FYI to all people who are writing LLVM passes (mostly 426
people) about a useful feature of LLVM.
The "Support/StatisticReporter.h" file provides two useful features that
you may want to make use of in your pass
1. Statistics output - Often you may run your pass on some big program,
and you're interested to see how many times it makes a certain
transformation. For example, you may be interested to see how many
alloca instructions are replaced with their elements (for MP1).
Although you can do this with hand inspection, or some ad-hoc method,
this is a real pain and not very useful for big programs.
Because this is such a common need, LLVM provides the Statistic<>
template class that can be used to keep track of this kind of
information. You can find various examples of statistic users, but
this basics of using it are as follows:
Define your statistic like this:
static Statistic<> Foo("mypassname\t- The # of times I did stuff");
Whenever you make a transformation, bump the counter:
That's all you have to do. To get 'opt' to print out the statistics
gathered, use the '-stats' option:
$ opt -stats -mypassname < program.bc > /dev/null
... statistic output ...
2. Debugging output support - Often when working on your pass you will put
a bunch of debugging printouts and other code into your pass. After
you get it working, you want to remove it... but you may need
it again in the future (to work out new bugs that you run across).
Naturally, because of this, you don't want to delete the debug
printouts, but you don't want them to always be noisy. A standard
compromise is to comment them out, allowing you to enable them if you
need them in the future.
The StatisticReporter.h file makes available a macro named DEBUG()
that is a much nicer solution [yes, this should be moved to a
different header file in the future, but that's irrelevant for this
MP]. Basically, you can put arbitrary code into the argument of the
DEBUG macro, and it is only executed if 'opt' is run with the '-debug'
command line argument:
... DEBUG(std::cerr << "I am here!\n"); ...
$ opt < a.bc > /dev/null -mypass
$ opt < a.bc > /dev/null -mypass -debug
I am here!
Anyway, hopefully you'll find these utilities useful. You obviously don't
need to use them to fulfill the requirements for the MP, but using them
makes your pass more polished and generally useful (and fit into the rest
of the LLVM framework better). I just thought I would point them out,
eventually the programmers manual will be updated to include them.