10 Introduction --- What is a pass?
11 ================================
14 This document deals with the new pass manager. LLVM uses the legacy pass
15 manager for the codegen pipeline. For more details, see
16 :doc:`WritingAnLLVMPass` and :doc:`NewPassManager`.
18 The LLVM pass framework is an important part of the LLVM system, because LLVM
19 passes are where most of the interesting parts of the compiler exist. Passes
20 perform the transformations and optimizations that make up the compiler, they
21 build the analysis results that are used by these transformations, and they
22 are, above all, a structuring technique for compiler code.
24 Unlike passes under the legacy pass manager where the pass interface is
25 defined via inheritance, passes under the new pass manager rely on
26 concept-based polymorphism, meaning there is no explicit interface (see
27 comments in ``PassManager.h`` for more details). All LLVM passes inherit from
28 the CRTP mix-in ``PassInfoMixin<PassT>``. The pass should have a ``run()``
29 method which returns a ``PreservedAnalyses`` and takes in some unit of IR
30 along with an analysis manager. For example, a function pass would have a
31 ``PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);`` method.
33 We start by showing you how to construct a pass, from setting up the build,
34 creating the pass, to executing and testing it. Looking at existing passes is
35 always a great way to learn details.
37 Quick Start --- Writing hello world
38 ===================================
40 Here we describe how to write the "hello world" of passes. The "HelloWorld"
41 pass is designed to simply print out the name of non-external functions that
42 exist in the program being compiled. It does not modify the program at all,
45 The code below already exists; feel free to create a pass with a different
46 name alongside the HelloWorld source files.
48 .. _writing-an-llvm-npm-pass-build:
53 First, configure and build LLVM as described in :doc:`GettingStarted`.
55 Next, we will reuse an existing directory (creating a new directory involves
56 messing around with more CMake files than we want). For this example, we'll use
57 ``llvm/lib/Transforms/Utils/HelloWorld.cpp``, which has already been created.
58 If you'd like to create your own pass, add a new source file into
59 ``llvm/lib/Transforms/Utils/CMakeLists.txt`` (assuming you want your pass in
60 the ``Transforms/Utils`` directory.
62 Now that we have the build set up for a new pass, we need to write the code
65 .. _writing-an-llvm-npm-pass-basiccode:
70 Now that the build is setup for a new pass, we just have to write it.
72 First we need to define the pass in a header file. We'll create
73 ``llvm/include/llvm/Transforms/Utils/HelloWorld.h``. The file should
74 contain the following boilerplate:
78 #ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
79 #define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
81 #include "llvm/IR/PassManager.h"
85 class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
87 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
92 #endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
94 This creates the class for the pass with a declaration of the ``run()``
95 method which actually runs the pass. Inheriting from ``PassInfoMixin<PassT>``
96 sets up some more boilerplate so that we don't have to write it ourselves.
98 Our class is in the ``llvm`` namespace so that we don't pollute the global
101 Next we'll create ``llvm/lib/Transforms/Utils/HelloWorld.cpp``, starting
106 #include "llvm/Transforms/Utils/HelloWorld.h"
108 ... to include the header file we just created.
112 using namespace llvm;
114 ... is required because the functions from the include files live in the llvm
115 namespace. This should only be done in non-header files.
117 Next we have the pass's ``run()`` definition:
121 PreservedAnalyses HelloWorldPass::run(Function &F,
122 FunctionAnalysisManager &AM) {
123 errs() << F.getName() << "\n";
124 return PreservedAnalyses::all();
127 ... which simply prints out the name of the function to stderr. The pass
128 manager will ensure that the pass will be run on every function in a module.
129 The ``PreservedAnalyses`` return value says that all analyses (e.g. dominator
130 tree) are still valid after this pass since we didn't modify any functions.
132 That's it for the pass itself. Now in order to "register" the pass, we need
133 to add it to a couple places. Add the following to
134 ``llvm/lib/Passes/PassRegistry.def`` in the ``FUNCTION_PASS`` section
138 FUNCTION_PASS("helloworld", HelloWorldPass())
140 ... which adds the pass under the name "helloworld".
142 ``llvm/lib/Passes/PassRegistry.def`` is #include'd into
143 ``llvm/lib/Passes/PassBuilder.cpp`` multiple times for various reasons. Since
144 it constructs our pass, we need to also add the proper #include in
145 ``llvm/lib/Passes/PassBuilder.cpp``:
149 #include "llvm/Transforms/Utils/HelloWorld.h"
151 This should be all the code necessary for our pass, now it's time to compile
154 Running a pass with ``opt``
155 ---------------------------
157 Now that you have a brand new shiny pass, we can build :program:`opt` and use
158 it to run some LLVM IR through the pass.
160 .. code-block:: console
162 $ ninja -C build/ opt
163 # or whatever build system/build directory you are using
175 $ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld
179 Our pass ran and printed the names of functions as expected!
184 Testing our pass is important to prevent future regressions. We'll add a lit
185 test at ``llvm/test/Transforms/Utils/helloworld.ll``. See
186 :doc:`TestingGuide` for more information on testing.
190 $ cat llvm/test/Transforms/Utils/helloworld.ll
191 ; RUN: opt -disable-output -passes=helloworld %s 2>&1 | FileCheck %s
193 ; CHECK: {{^}}foo{{$}}
199 ; CHECK-NEXT: {{^}}bar{{$}}
204 $ ninja -C build check-llvm
205 # runs our new test alongside all other llvm lit tests
213 A pass that defines a static ``isRequired()`` method that returns true is a required pass. For example:
217 class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
219 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
221 static bool isRequired() { return true; }
224 A required pass is a pass that may not be skipped. An example of a required
225 pass is ``AlwaysInlinerPass``, which must always be run to preserve
226 ``alwaysinline`` semantics. Pass managers are required since they may contain
227 other required passes.
229 An example of how a pass can be skipped is the ``optnone`` function
230 attribute, which specifies that optimizations should not be run on the
231 function. Required passes will still be run on ``optnone`` functions.
233 For more implementation details, see
234 ``PassInstrumentation::runBeforePass()``.
236 Registering passes as plugins
237 -----------------------------
239 LLVM provides a mechanism to register pass plugins within various tools like
240 ``clang`` or ``opt``. A pass plugin can add passes to default optimization
241 pipelines or to be manually run via tools like ``opt``. For more information,
242 see :doc:`NewPassManager`.
244 Create a CMake project at the root of the repo alongside
245 other projects. This project must contain the following minimal
248 .. code-block:: cmake
250 add_llvm_pass_plugin(MyPassName source.cpp)
252 See the definition of ``add_llvm_pass_plugin`` for more CMake details.
254 The pass must provide at least one of two entry points for the new pass manager,
255 one for static registration and one for dynamically loaded plugins:
257 - ``llvm::PassPluginLibraryInfo get##Name##PluginInfo();``
258 - ``extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() LLVM_ATTRIBUTE_WEAK;``
260 Pass plugins are compiled and linked dynamically by default. Setting
261 ``LLVM_${NAME}_LINK_INTO_TOOLS`` to ``ON`` turns the project into a statically
264 For an in-tree example, see ``llvm/examples/Bye/``.
266 To make ``PassBuilder`` aware of statically linked pass plugins:
270 // Declare plugin extension function declarations.
271 #define HANDLE_EXTENSION(Ext) llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
272 #include "llvm/Support/Extension.def"
276 // Register plugin extensions in PassBuilder.
277 #define HANDLE_EXTENSION(Ext) get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
278 #include "llvm/Support/Extension.def"
280 To make ``PassBuilder`` aware of dynamically linked pass plugins:
284 // Load plugin dynamically.
285 auto Plugin = PassPlugin::Load(PathToPlugin);
288 // Register plugin extensions in PassBuilder.
289 Plugin.registerPassBuilderCallbacks(PB);