Home

Awesome

Writing an LLVM Pass using the (kind of) new PassManager

This tutorial assumes you already have the LLVM project somewhere on your computer and that you are familiar with compiling it. If you don't, please refer to the official documentation [1].

In general this tutorial is based on the official tutorial Writing An LLVM Pass Tutorial [2] from the LLVM documentation and the blog posts by Bekket McClane which can be found here [3]. You should start with following those tutorials if you haven't already done that.
But as the former lacks any information about the new PassManager and the latter does not cover integration of "new-PassManager-passes" into the LLVM source tree, I dug into the sources of LLVM and compiled all the information into the following tutorial.

Writing a FunctionPass as a loadable shared library

Note that this should also apply to ModulePass.

This is the quickest way to write a pass and use it on LLVM bitcode (.bc) as it only requires one .cpp file and two small changes in the build environment of LLVM. Those changes can be done according to the official Writing An LLVM Pass Tutorial [2]:

Now you have written a simple FunctionPass and you can compile LLVM. The compilation process will generate a shared library LLVMMyPass.so in the build/libdirectory. To run your pass on a bitcode file you have to load the pass into opt:

opt -disable-output \
    -load-pass-plugin=build/lib/MyPass.so \
    -passes="my-pass" bar.bc

In-Tree Integration of an Analysis Pass

Integration of an analysis pass into the LLVM source-tree is quite simple with the new PassManager but I had to extract the necessary steps from already existing analyses in the source-tree. There it also seems to be common practice to separate analyses from passes that are actually invoked by e.g. opt. Therefore I will follow this approach in this tutorial.

Now again you can compile LLVM but this time there will be no need to load a shared library before being able to run the analysis pass:

opt -passes="my-analysis-pass" bar.bc

Note that the string that identifies our MyAnalysisPass in the pass pipeline has been defined in lib/Passes/PassRegisty.def.

References

[1] http://releases.llvm.org/6.0.0/docs/GettingStarted.html
[2] http://releases.llvm.org/6.0.0/docs/WritingAnLLVMPass.html
[3] https://medium.com/@mshockwave/writing-llvm-pass-in-2018-preface-6b90fa67ae82