1====================
2Writing an LLVM Pass
3====================
4
5.. program:: opt
6
7.. contents::
8    :local:
9
10Introduction --- What is a pass?
11================================
12
13The LLVM pass framework is an important part of the LLVM system, because LLVM
14passes are where most of the interesting parts of the compiler exist. Passes
15perform the transformations and optimizations that make up the compiler, they
16build the analysis results that are used by these transformations, and they
17are, above all, a structuring technique for compiler code.
18
19Unlike passes under the legacy pass manager where the pass interface is
20defined via inheritance, passes under the new pass manager rely on
21concept-based polymorphism, meaning there is no explicit interface (see
22comments in ``PassManager.h`` for more details). All LLVM passes inherit from
23the CRTP mix-in ``PassInfoMixin<PassT>``. The pass should have a ``run()``
24method which returns a ``PreservedAnalyses`` and takes in some unit of IR
25along with an analysis manager. For example, a function pass would have a
26``PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);`` method.
27
28We start by showing you how to construct a pass, from setting up the build,
29creating the pass, to executing and testing it. Looking at existing passes is
30always a great way to learn details.
31
32Quick Start --- Writing hello world
33===================================
34
35Here we describe how to write the "hello world" of passes. The "HelloWorld"
36pass is designed to simply print out the name of non-external functions that
37exist in the program being compiled. It does not modify the program at all,
38it just inspects it.
39
40The code below already exists; feel free to create a pass with a different
41name alongside the HelloWorld source files.
42
43.. _writing-an-llvm-npm-pass-build:
44
45Setting up the build
46--------------------
47
48First, configure and build LLVM as described in :doc:`GettingStarted`.
49
50Next, we will reuse an existing directory (creating a new directory involves
51modifying more ``CMakeLists.txt``s than we want). For
52this example, we'll use ``llvm/lib/Transforms/HelloNew/HelloWorld.cpp``,
53which has already been created. If you'd like to create your own pass, add a
54new source file into ``llvm/lib/Transforms/HelloNew/CMakeLists.txt`` under
55``HelloWorld.cpp``:
56
57.. code-block:: cmake
58
59  add_llvm_component_library(LLVMHelloWorld
60    HelloWorld.cpp
61
62    DEPENDS
63    intrinsics_gen
64    )
65
66Now that we have the build set up for a new pass, we need to write the code
67for the pass itself.
68
69.. _writing-an-llvm-npm-pass-basiccode:
70
71Basic code required
72-------------------
73
74Now that the build is setup for a new pass, we just have to write it.
75
76First we need to define the pass in a header file. We'll create
77``llvm/include/llvm/Transforms/HelloNew/HelloWorld.h``. The file should
78contain the following boilerplate:
79
80.. code-block:: c++
81
82  #ifndef LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
83  #define LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
84
85  #include "llvm/IR/PassManager.h"
86
87  namespace llvm {
88
89  class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
90  public:
91    PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
92  };
93
94  } // namespace llvm
95
96  #endif // LLVM_TRANSFORMS_HELLONEW_HELLOWORLD_H
97
98This creates the class for the pass with a declaration of the ``run()``
99method which actually runs the pass. Inheriting from ``PassInfoMixin<PassT>``
100sets up some more boilerplate so that we don't have to write it ourselves.
101
102Our class is in the ``llvm`` namespace so that we don't pollute the global
103namespace.
104
105Next we'll create ``llvm/lib/Transforms/HelloNew/HelloWorld.cpp``, starting
106with
107
108.. code-block:: c++
109
110  #include "llvm/Transforms/HelloNew/HelloWorld.h"
111
112... to include the header file we just created.
113
114.. code-block:: c++
115
116  using namespace llvm;
117
118... is required because the functions from the include files live in the llvm
119namespace. This should only be done in non-header files.
120
121Next we have the pass's ``run()`` definition:
122
123.. code-block:: c++
124
125  PreservedAnalyses HelloWorldPass::run(Function &F,
126                                        FunctionAnalysisManager &AM) {
127    errs() << F.getName() << "\n";
128    return PreservedAnalyses::all();
129  }
130
131... which simply prints out the name of the function to stderr. The pass
132manager will ensure that the pass will be run on every function in a module.
133The ``PreservedAnalyses`` return value says that all analyses (e.g. dominator
134tree) are still valid after this pass since we didn't modify any functions.
135
136That's it for the pass itself. Now in order to "register" the pass, we need
137to add it to a couple places. Add the following to
138``llvm\lib\Passes\PassRegistry.def`` in the ``FUNCTION_PASS`` section
139
140.. code-block:: c++
141
142  FUNCTION_PASS("helloworld", HelloWorldPass())
143
144... which adds the pass under the name "helloworld".
145
146``llvm\lib\Passes\PassRegistry.def`` is #include'd into
147``llvm\lib\Passes\PassBuilder.cpp`` multiple times for various reasons. Since
148it constructs our pass, we need to also add the proper #include in
149``llvm\lib\Passes\PassBuilder.cpp``:
150
151.. code-block:: c++
152
153  #include "llvm/Transforms/HelloNew/HelloWorld.h"
154
155This should be all the code necessary for our pass, now it's time to compile
156and run it.
157
158Running a pass with ``opt``
159---------------------------
160
161Now that you have a brand new shiny pass, we can build :program:`opt` and use
162it to run some LLVM IR through the pass.
163
164.. code-block:: console
165
166  $ ninja -C build/ opt
167  # or whatever build system/build directory you are using
168
169  $ cat /tmp/a.ll
170  define i32 @foo() {
171    %a = add i32 2, 3
172    ret i32 %a
173  }
174
175  define void @bar() {
176    ret void
177  }
178
179  $ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld
180  foo
181  bar
182
183Our pass ran and printed the names of functions as expected!
184
185Testing a pass
186--------------
187
188Testing our pass is important to prevent future regressions. We'll add a lit
189test at ``llvm/test/Transforms/HelloNew/helloworld.ll``. See
190:doc:`TestingGuide` for more information on testing.
191
192.. code-block:: llvm
193
194  $ cat llvm/test/Transforms/HelloNew/helloworld.ll
195  ; RUN: opt -disable-output -passes=helloworld %s 2>&1 | FileCheck %s
196
197  ; CHECK: {{^}}foo{{$}}
198  define i32 @foo() {
199    %a = add i32 2, 3
200    ret i32 %a
201  }
202
203  ; CHECK-NEXT: {{^}}bar{{$}}
204  define void @bar() {
205    ret void
206  }
207
208  $ ninja -C build check-llvm
209  # runs our new test alongside all other llvm lit tests
210
211FAQs
212====
213
214Required passes
215---------------
216
217A pass that defines a static ``isRequired()`` method that returns true is a required pass. For example:
218
219.. code-block:: c++
220
221  class HelloWorldPass : public PassInfoMixin<HelloWorldPass> {
222  public:
223    PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
224
225    static bool isRequired() { return true; }
226  };
227
228A required pass is a pass that may not be skipped. An example of a required
229pass is ``AlwaysInlinerPass``, which must always be run to preserve
230``alwaysinline`` semantics. Pass managers are required since they may contain
231other required passes.
232
233An example of how a pass can be skipped is the ``optnone`` function
234attribute, which specifies that optimizations should not be run on the
235function. Required passes will still be run on ``optnone`` functions.
236
237For more implementation details, see
238``PassInstrumentation::runBeforePass()``.
239