X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FWritingAnLLVMPass.rst;h=241066842b7bb792ac2a95a23e75268046bf9b9b;hb=e67b3e872170aa4f2cacf12cc7c6c3aed7373399;hp=db47fefd9300257b13c0b6b6b5c618359f0ce956;hpb=b64f020a30427e90a05530f8b20f1bddd1ab9e0a;p=oota-llvm.git diff --git a/docs/WritingAnLLVMPass.rst b/docs/WritingAnLLVMPass.rst index db47fefd930..241066842b7 100644 --- a/docs/WritingAnLLVMPass.rst +++ b/docs/WritingAnLLVMPass.rst @@ -5,9 +5,6 @@ Writing an LLVM Pass .. contents:: :local: -Written by `Chris Lattner `_ and -`Jim Laskey `_ - Introduction --- What is a pass? ================================ @@ -50,14 +47,11 @@ source tree in the ``lib/Transforms/Hello`` directory. Setting up the build environment -------------------------------- -.. FIXME: Why does this recommend to build in-tree? - -First, configure and build LLVM. This needs to be done directly inside the -LLVM source tree rather than in a separate objects directory. Next, you need -to create a new directory somewhere in the LLVM source base. For this example, -we'll assume that you made ``lib/Transforms/Hello``. Finally, you must set up -a build script (``Makefile``) that will compile the source code for the new -pass. To do this, copy the following into ``Makefile``: +First, configure and build LLVM. Next, you need to create a new directory +somewhere in the LLVM source base. For this example, we'll assume that you +made ``lib/Transforms/Hello``. Finally, you must set up a build script +(``Makefile``) that will compile the source code for the new pass. To do this, +copy the following into ``Makefile``: .. code-block:: make @@ -99,7 +93,7 @@ Start out with: .. code-block:: c++ #include "llvm/Pass.h" - #include "llvm/Function.h" + #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" Which are needed because we are writing a `Pass @@ -134,7 +128,7 @@ Next, we declare our pass itself: struct Hello : public FunctionPass { -This declares a "``Hello``" class that is a subclass of `FunctionPass +This declares a "``Hello``" class that is a subclass of :ref:`FunctionPass `. The different builtin pass subclasses are described in detail :ref:`later `, but for now, know that ``FunctionPass`` operates on a function at a time. @@ -149,7 +143,7 @@ to avoid using expensive C++ runtime information. .. code-block:: c++ - virtual bool runOnFunction(Function &F) { + bool runOnFunction(Function &F) override { errs() << "Hello: "; errs().write_escaped(F.getName()) << "\n"; return false; @@ -187,7 +181,7 @@ As a whole, the ``.cpp`` file looks like: .. code-block:: c++ #include "llvm/Pass.h" - #include "llvm/Function.h" + #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -197,7 +191,7 @@ As a whole, the ``.cpp`` file looks like: static char ID; Hello() : FunctionPass(ID) {} - virtual bool runOnFunction(Function &F) { + bool runOnFunction(Function &F) override { errs() << "Hello: "; errs().write_escaped(F.getName()) << '\n'; return false; @@ -209,9 +203,8 @@ As a whole, the ``.cpp`` file looks like: static RegisterPass X("hello", "Hello World Pass", false, false); Now that it's all together, compile the file with a simple "``gmake``" command -in the local directory and you should get a new file -"``Debug+Asserts/lib/Hello.so``" under the top level directory of the LLVM -source tree (not in the local directory). Note that everything in this file is +from the top level of your build directory and you should get a new file +"``Debug+Asserts/lib/Hello.so``". Note that everything in this file is contained in an anonymous namespace --- this reflects the fact that passes are self contained units that do not need external interfaces (although they can have them) to be useful. @@ -231,7 +224,7 @@ will work): .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -hello < hello.bc > /dev/null + $ opt -load ../../Debug+Asserts/lib/Hello.so -hello < hello.bc > /dev/null Hello: __main Hello: puts Hello: main @@ -248,7 +241,7 @@ To see what happened to the other string you registered, try running .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -help + $ opt -load ../../Debug+Asserts/lib/Hello.so -help OVERVIEW: llvm .bc -> .bc modular optimizer USAGE: opt [options] @@ -262,7 +255,6 @@ To see what happened to the other string you registered, try running -hello - Hello World Pass -indvars - Induction Variable Simplification -inline - Function Integration/Inlining - -insert-edge-profiling - Insert instrumentation for edge profiling ... The pass name gets added as the information string for your pass, giving some @@ -276,7 +268,7 @@ you queue up. For example: .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -hello -time-passes < hello.bc > /dev/null + $ opt -load ../../Debug+Asserts/lib/Hello.so -hello -time-passes < hello.bc > /dev/null Hello: __main Hello: puts Hello: main @@ -438,9 +430,8 @@ The ``doFinalization(CallGraph &)`` method virtual bool doFinalization(CallGraph &CG); The ``doFinalization`` method is an infrequently used method that is called -when the pass framework has finished calling :ref:`runOnFunction -` for every function in the program being -compiled. +when the pass framework has finished calling :ref:`runOnSCC +` for every SCC in the program being compiled. .. _writing-an-llvm-pass-FunctionPass: @@ -457,10 +448,10 @@ external functions. To be explicit, ``FunctionPass`` subclasses are not allowed to: -#. Modify a ``Function`` other than the one currently being processed. +#. Inspect or modify a ``Function`` other than the one currently being processed. #. Add or remove ``Function``\ s from the current ``Module``. #. Add or remove global variables from the current ``Module``. -#. Maintain state across invocations of:ref:`runOnFunction +#. Maintain state across invocations of :ref:`runOnFunction ` (including global data). Implementing a ``FunctionPass`` is usually straightforward (See the :ref:`Hello @@ -858,7 +849,7 @@ Example implementations of ``getAnalysisUsage`` // This example modifies the program, but does not modify the CFG void LICM::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); - AU.addRequired(); + AU.addRequired(); } .. _writing-an-llvm-pass-getAnalysis: @@ -875,7 +866,7 @@ you want, and returns a reference to that pass. For example: .. code-block:: c++ bool LICM::runOnFunction(Function &F) { - LoopInfo &LI = getAnalysis(); + LoopInfo &LI = getAnalysis().getLoopInfo(); //... } @@ -1097,7 +1088,7 @@ passes. Lets try it out with the gcse and licm passes: .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -gcse -licm --debug-pass=Structure < hello.bc > /dev/null + $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -licm --debug-pass=Structure < hello.bc > /dev/null Module Pass Manager Function Pass Manager Dominator Set Construction @@ -1134,7 +1125,7 @@ Lets see how this changes when we run the :ref:`Hello World .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null + $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null Module Pass Manager Function Pass Manager Dominator Set Construction @@ -1167,7 +1158,7 @@ all! To fix this, we need to add the following :ref:`getAnalysisUsage .. code-block:: c++ // We don't modify the program, so we preserve all analyses - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); } @@ -1175,7 +1166,7 @@ Now when we run our pass, we get this output: .. code-block:: console - $ opt -load ../../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null + $ opt -load ../../Debug+Asserts/lib/Hello.so -gcse -hello -licm --debug-pass=Structure < hello.bc > /dev/null Pass Arguments: -gcse -hello -licm Module Pass Manager Function Pass Manager