xref: /aosp_15_r20/external/llvm/docs/tutorial/BuildingAJIT2.rst (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker=====================================================================
2*9880d681SAndroid Build Coastguard WorkerBuilding a JIT: Adding Optimizations -- An introduction to ORC Layers
3*9880d681SAndroid Build Coastguard Worker=====================================================================
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker.. contents::
6*9880d681SAndroid Build Coastguard Worker   :local:
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker**This tutorial is under active development. It is incomplete and details may
9*9880d681SAndroid Build Coastguard Workerchange frequently.** Nonetheless we invite you to try it out as it stands, and
10*9880d681SAndroid Build Coastguard Workerwe welcome any feedback.
11*9880d681SAndroid Build Coastguard Worker
12*9880d681SAndroid Build Coastguard WorkerChapter 2 Introduction
13*9880d681SAndroid Build Coastguard Worker======================
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard WorkerWelcome to Chapter 2 of the "Building an ORC-based JIT in LLVM" tutorial. In
16*9880d681SAndroid Build Coastguard Worker`Chapter 1 <BuildingAJIT1.html>`_ of this series we examined a basic JIT
17*9880d681SAndroid Build Coastguard Workerclass, KaleidoscopeJIT, that could take LLVM IR modules as input and produce
18*9880d681SAndroid Build Coastguard Workerexecutable code in memory. KaleidoscopeJIT was able to do this with relatively
19*9880d681SAndroid Build Coastguard Workerlittle code by composing two off-the-shelf *ORC layers*: IRCompileLayer and
20*9880d681SAndroid Build Coastguard WorkerObjectLinkingLayer, to do much of the heavy lifting.
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard WorkerIn this layer we'll learn more about the ORC layer concept by using a new layer,
23*9880d681SAndroid Build Coastguard WorkerIRTransformLayer, to add IR optimization support to KaleidoscopeJIT.
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard WorkerOptimizing Modules using the IRTransformLayer
26*9880d681SAndroid Build Coastguard Worker=============================================
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard WorkerIn `Chapter 4 <LangImpl4.html>`_ of the "Implementing a language with LLVM"
29*9880d681SAndroid Build Coastguard Workertutorial series the llvm *FunctionPassManager* is introduced as a means for
30*9880d681SAndroid Build Coastguard Workeroptimizing LLVM IR. Interested readers may read that chapter for details, but
31*9880d681SAndroid Build Coastguard Workerin short: to optimize a Module we create an llvm::FunctionPassManager
32*9880d681SAndroid Build Coastguard Workerinstance, configure it with a set of optimizations, then run the PassManager on
33*9880d681SAndroid Build Coastguard Workera Module to mutate it into a (hopefully) more optimized but semantically
34*9880d681SAndroid Build Coastguard Workerequivalent form. In the original tutorial series the FunctionPassManager was
35*9880d681SAndroid Build Coastguard Workercreated outside the KaleidoscopeJIT and modules were optimized before being
36*9880d681SAndroid Build Coastguard Workeradded to it. In this Chapter we will make optimization a phase of our JIT
37*9880d681SAndroid Build Coastguard Workerinstead. For now this will provide us a motivation to learn more about ORC
38*9880d681SAndroid Build Coastguard Workerlayers, but in the long term making optimization part of our JIT will yield an
39*9880d681SAndroid Build Coastguard Workerimportant benefit: When we begin lazily compiling code (i.e. deferring
40*9880d681SAndroid Build Coastguard Workercompilation of each function until the first time it's run), having
41*9880d681SAndroid Build Coastguard Workeroptimization managed by our JIT will allow us to optimize lazily too, rather
42*9880d681SAndroid Build Coastguard Workerthan having to do all our optimization up-front.
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard WorkerTo add optimization support to our JIT we will take the KaleidoscopeJIT from
45*9880d681SAndroid Build Coastguard WorkerChapter 1 and compose an ORC *IRTransformLayer* on top. We will look at how the
46*9880d681SAndroid Build Coastguard WorkerIRTransformLayer works in more detail below, but the interface is simple: the
47*9880d681SAndroid Build Coastguard Workerconstructor for this layer takes a reference to the layer below (as all layers
48*9880d681SAndroid Build Coastguard Workerdo) plus an *IR optimization function* that it will apply to each Module that
49*9880d681SAndroid Build Coastguard Workeris added via addModuleSet:
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker  class KaleidoscopeJIT {
54*9880d681SAndroid Build Coastguard Worker  private:
55*9880d681SAndroid Build Coastguard Worker    std::unique_ptr<TargetMachine> TM;
56*9880d681SAndroid Build Coastguard Worker    const DataLayout DL;
57*9880d681SAndroid Build Coastguard Worker    ObjectLinkingLayer<> ObjectLayer;
58*9880d681SAndroid Build Coastguard Worker    IRCompileLayer<decltype(ObjectLayer)> CompileLayer;
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker    typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
61*9880d681SAndroid Build Coastguard Worker      OptimizeFunction;
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker    IRTransformLayer<decltype(CompileLayer), OptimizeFunction> OptimizeLayer;
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker  public:
66*9880d681SAndroid Build Coastguard Worker    typedef decltype(OptimizeLayer)::ModuleSetHandleT ModuleHandle;
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard Worker    KaleidoscopeJIT()
69*9880d681SAndroid Build Coastguard Worker        : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
70*9880d681SAndroid Build Coastguard Worker          CompileLayer(ObjectLayer, SimpleCompiler(*TM)),
71*9880d681SAndroid Build Coastguard Worker          OptimizeLayer(CompileLayer,
72*9880d681SAndroid Build Coastguard Worker                        [this](std::unique_ptr<Module> M) {
73*9880d681SAndroid Build Coastguard Worker                          return optimizeModule(std::move(M));
74*9880d681SAndroid Build Coastguard Worker                        }) {
75*9880d681SAndroid Build Coastguard Worker      llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
76*9880d681SAndroid Build Coastguard Worker    }
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard WorkerOur extended KaleidoscopeJIT class starts out the same as it did in Chapter 1,
79*9880d681SAndroid Build Coastguard Workerbut after the CompileLayer we introduce a typedef for our optimization function.
80*9880d681SAndroid Build Coastguard WorkerIn this case we use a std::function (a handy wrapper for "function-like" things)
81*9880d681SAndroid Build Coastguard Workerfrom a single unique_ptr<Module> input to a std::unique_ptr<Module> output. With
82*9880d681SAndroid Build Coastguard Workerour optimization function typedef in place we can declare our OptimizeLayer,
83*9880d681SAndroid Build Coastguard Workerwhich sits on top of our CompileLayer.
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard WorkerTo initialize our OptimizeLayer we pass it a reference to the CompileLayer
86*9880d681SAndroid Build Coastguard Workerbelow (standard practice for layers), and we initialize the OptimizeFunction
87*9880d681SAndroid Build Coastguard Workerusing a lambda that calls out to an "optimizeModule" function that we will
88*9880d681SAndroid Build Coastguard Workerdefine below.
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker  // ...
93*9880d681SAndroid Build Coastguard Worker  auto Resolver = createLambdaResolver(
94*9880d681SAndroid Build Coastguard Worker      [&](const std::string &Name) {
95*9880d681SAndroid Build Coastguard Worker        if (auto Sym = OptimizeLayer.findSymbol(Name, false))
96*9880d681SAndroid Build Coastguard Worker          return Sym.toRuntimeDyldSymbol();
97*9880d681SAndroid Build Coastguard Worker        return RuntimeDyld::SymbolInfo(nullptr);
98*9880d681SAndroid Build Coastguard Worker      },
99*9880d681SAndroid Build Coastguard Worker  // ...
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker  // ...
104*9880d681SAndroid Build Coastguard Worker  return OptimizeLayer.addModuleSet(std::move(Ms),
105*9880d681SAndroid Build Coastguard Worker                                    make_unique<SectionMemoryManager>(),
106*9880d681SAndroid Build Coastguard Worker                                    std::move(Resolver));
107*9880d681SAndroid Build Coastguard Worker  // ...
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Worker  // ...
112*9880d681SAndroid Build Coastguard Worker  return OptimizeLayer.findSymbol(MangledNameStream.str(), true);
113*9880d681SAndroid Build Coastguard Worker  // ...
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker  // ...
118*9880d681SAndroid Build Coastguard Worker  OptimizeLayer.removeModuleSet(H);
119*9880d681SAndroid Build Coastguard Worker  // ...
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard WorkerNext we need to replace references to 'CompileLayer' with references to
122*9880d681SAndroid Build Coastguard WorkerOptimizeLayer in our key methods: addModule, findSymbol, and removeModule. In
123*9880d681SAndroid Build Coastguard WorkeraddModule we need to be careful to replace both references: the findSymbol call
124*9880d681SAndroid Build Coastguard Workerinside our resolver, and the call through to addModuleSet.
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker  std::unique_ptr<Module> optimizeModule(std::unique_ptr<Module> M) {
129*9880d681SAndroid Build Coastguard Worker    // Create a function pass manager.
130*9880d681SAndroid Build Coastguard Worker    auto FPM = llvm::make_unique<legacy::FunctionPassManager>(M.get());
131*9880d681SAndroid Build Coastguard Worker
132*9880d681SAndroid Build Coastguard Worker    // Add some optimizations.
133*9880d681SAndroid Build Coastguard Worker    FPM->add(createInstructionCombiningPass());
134*9880d681SAndroid Build Coastguard Worker    FPM->add(createReassociatePass());
135*9880d681SAndroid Build Coastguard Worker    FPM->add(createGVNPass());
136*9880d681SAndroid Build Coastguard Worker    FPM->add(createCFGSimplificationPass());
137*9880d681SAndroid Build Coastguard Worker    FPM->doInitialization();
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker    // Run the optimizations over all functions in the module being added to
140*9880d681SAndroid Build Coastguard Worker    // the JIT.
141*9880d681SAndroid Build Coastguard Worker    for (auto &F : *M)
142*9880d681SAndroid Build Coastguard Worker      FPM->run(F);
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Worker    return M;
145*9880d681SAndroid Build Coastguard Worker  }
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard WorkerAt the bottom of our JIT we add a private method to do the actual optimization:
148*9880d681SAndroid Build Coastguard Worker*optimizeModule*. This function sets up a FunctionPassManager, adds some passes
149*9880d681SAndroid Build Coastguard Workerto it, runs it over every function in the module, and then returns the mutated
150*9880d681SAndroid Build Coastguard Workermodule. The specific optimizations are the same ones used in
151*9880d681SAndroid Build Coastguard Worker`Chapter 4 <LangImpl4.html>`_ of the "Implementing a language with LLVM"
152*9880d681SAndroid Build Coastguard Workertutorial series. Readers may visit that chapter for a more in-depth
153*9880d681SAndroid Build Coastguard Workerdiscussion of these, and of IR optimization in general.
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard WorkerAnd that's it in terms of changes to KaleidoscopeJIT: When a module is added via
156*9880d681SAndroid Build Coastguard WorkeraddModule the OptimizeLayer will call our optimizeModule function before passing
157*9880d681SAndroid Build Coastguard Workerthe transformed module on to the CompileLayer below. Of course, we could have
158*9880d681SAndroid Build Coastguard Workercalled optimizeModule directly in our addModule function and not gone to the
159*9880d681SAndroid Build Coastguard Workerbother of using the IRTransformLayer, but doing so gives us another opportunity
160*9880d681SAndroid Build Coastguard Workerto see how layers compose. It also provides a neat entry point to the *layer*
161*9880d681SAndroid Build Coastguard Workerconcept itself, because IRTransformLayer turns out to be one of the simplest
162*9880d681SAndroid Build Coastguard Workerimplementations of the layer concept that can be devised:
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker.. code-block:: c++
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker  template <typename BaseLayerT, typename TransformFtor>
167*9880d681SAndroid Build Coastguard Worker  class IRTransformLayer {
168*9880d681SAndroid Build Coastguard Worker  public:
169*9880d681SAndroid Build Coastguard Worker    typedef typename BaseLayerT::ModuleSetHandleT ModuleSetHandleT;
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker    IRTransformLayer(BaseLayerT &BaseLayer,
172*9880d681SAndroid Build Coastguard Worker                     TransformFtor Transform = TransformFtor())
173*9880d681SAndroid Build Coastguard Worker      : BaseLayer(BaseLayer), Transform(std::move(Transform)) {}
174*9880d681SAndroid Build Coastguard Worker
175*9880d681SAndroid Build Coastguard Worker    template <typename ModuleSetT, typename MemoryManagerPtrT,
176*9880d681SAndroid Build Coastguard Worker              typename SymbolResolverPtrT>
177*9880d681SAndroid Build Coastguard Worker    ModuleSetHandleT addModuleSet(ModuleSetT Ms,
178*9880d681SAndroid Build Coastguard Worker                                  MemoryManagerPtrT MemMgr,
179*9880d681SAndroid Build Coastguard Worker                                  SymbolResolverPtrT Resolver) {
180*9880d681SAndroid Build Coastguard Worker
181*9880d681SAndroid Build Coastguard Worker      for (auto I = Ms.begin(), E = Ms.end(); I != E; ++I)
182*9880d681SAndroid Build Coastguard Worker        *I = Transform(std::move(*I));
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker      return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
185*9880d681SAndroid Build Coastguard Worker                                  std::move(Resolver));
186*9880d681SAndroid Build Coastguard Worker    }
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker    void removeModuleSet(ModuleSetHandleT H) { BaseLayer.removeModuleSet(H); }
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker    JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
191*9880d681SAndroid Build Coastguard Worker      return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
192*9880d681SAndroid Build Coastguard Worker    }
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker    JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
195*9880d681SAndroid Build Coastguard Worker                           bool ExportedSymbolsOnly) {
196*9880d681SAndroid Build Coastguard Worker      return BaseLayer.findSymbolIn(H, Name, ExportedSymbolsOnly);
197*9880d681SAndroid Build Coastguard Worker    }
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker    void emitAndFinalize(ModuleSetHandleT H) {
200*9880d681SAndroid Build Coastguard Worker      BaseLayer.emitAndFinalize(H);
201*9880d681SAndroid Build Coastguard Worker    }
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker    TransformFtor& getTransform() { return Transform; }
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker    const TransformFtor& getTransform() const { return Transform; }
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker  private:
208*9880d681SAndroid Build Coastguard Worker    BaseLayerT &BaseLayer;
209*9880d681SAndroid Build Coastguard Worker    TransformFtor Transform;
210*9880d681SAndroid Build Coastguard Worker  };
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard WorkerThis is the whole definition of IRTransformLayer, from
213*9880d681SAndroid Build Coastguard Worker``llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h``, stripped of its
214*9880d681SAndroid Build Coastguard Workercomments. It is a template class with two template arguments: ``BaesLayerT`` and
215*9880d681SAndroid Build Coastguard Worker``TransformFtor`` that provide the type of the base layer and the type of the
216*9880d681SAndroid Build Coastguard Worker"transform functor" (in our case a std::function) respectively. This class is
217*9880d681SAndroid Build Coastguard Workerconcerned with two very simple jobs: (1) Running every IR Module that is added
218*9880d681SAndroid Build Coastguard Workerwith addModuleSet through the transform functor, and (2) conforming to the ORC
219*9880d681SAndroid Build Coastguard Workerlayer interface. The interface consists of one typedef and five methods:
220*9880d681SAndroid Build Coastguard Worker
221*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
222*9880d681SAndroid Build Coastguard Worker|     Interface    |                         Description                       |
223*9880d681SAndroid Build Coastguard Worker+==================+===========================================================+
224*9880d681SAndroid Build Coastguard Worker|                  | Provides a handle that can be used to identify a module   |
225*9880d681SAndroid Build Coastguard Worker| ModuleSetHandleT | set when calling findSymbolIn, removeModuleSet, or        |
226*9880d681SAndroid Build Coastguard Worker|                  | emitAndFinalize.                                          |
227*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
228*9880d681SAndroid Build Coastguard Worker|                  | Takes a given set of Modules and makes them "available    |
229*9880d681SAndroid Build Coastguard Worker|                  | for execution. This means that symbols in those modules   |
230*9880d681SAndroid Build Coastguard Worker|                  | should be searchable via findSymbol and findSymbolIn, and |
231*9880d681SAndroid Build Coastguard Worker|                  | the address of the symbols should be read/writable (for   |
232*9880d681SAndroid Build Coastguard Worker|                  | data symbols), or executable (for function symbols) after |
233*9880d681SAndroid Build Coastguard Worker|                  | JITSymbol::getAddress() is called. Note: This means that  |
234*9880d681SAndroid Build Coastguard Worker|   addModuleSet   | addModuleSet doesn't have to compile (or do any other     |
235*9880d681SAndroid Build Coastguard Worker|                  | work) up-front. It *can*, like IRCompileLayer, act        |
236*9880d681SAndroid Build Coastguard Worker|                  | eagerly, but it can also simply record the module and     |
237*9880d681SAndroid Build Coastguard Worker|                  | take no further action until somebody calls               |
238*9880d681SAndroid Build Coastguard Worker|                  | JITSymbol::getAddress(). In IRTransformLayer's case       |
239*9880d681SAndroid Build Coastguard Worker|                  | addModuleSet eagerly applies the transform functor to     |
240*9880d681SAndroid Build Coastguard Worker|                  | each module in the set, then passes the resulting set     |
241*9880d681SAndroid Build Coastguard Worker|                  | of mutated modules down to the layer below.               |
242*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
243*9880d681SAndroid Build Coastguard Worker|                  | Removes a set of modules from the JIT. Code or data       |
244*9880d681SAndroid Build Coastguard Worker|  removeModuleSet | defined in these modules will no longer be available, and |
245*9880d681SAndroid Build Coastguard Worker|                  | the memory holding the JIT'd definitions will be freed.   |
246*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
247*9880d681SAndroid Build Coastguard Worker|                  | Searches for the named symbol in all modules that have    |
248*9880d681SAndroid Build Coastguard Worker|                  | previously been added via addModuleSet (and not yet       |
249*9880d681SAndroid Build Coastguard Worker|    findSymbol    | removed by a call to removeModuleSet). In                 |
250*9880d681SAndroid Build Coastguard Worker|                  | IRTransformLayer we just pass the query on to the layer   |
251*9880d681SAndroid Build Coastguard Worker|                  | below. In our REPL this is our default way to search for  |
252*9880d681SAndroid Build Coastguard Worker|                  | function definitions.                                     |
253*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
254*9880d681SAndroid Build Coastguard Worker|                  | Searches for the named symbol in the module set indicated |
255*9880d681SAndroid Build Coastguard Worker|                  | by the given ModuleSetHandleT. This is just an optimized  |
256*9880d681SAndroid Build Coastguard Worker|                  | search, better for lookup-speed when you know exactly     |
257*9880d681SAndroid Build Coastguard Worker|                  | a symbol definition should be found. In IRTransformLayer  |
258*9880d681SAndroid Build Coastguard Worker|   findSymbolIn   | we just pass this query on to the layer below. In our     |
259*9880d681SAndroid Build Coastguard Worker|                  | REPL we use this method to search for functions           |
260*9880d681SAndroid Build Coastguard Worker|                  | representing top-level expressions, since we know exactly |
261*9880d681SAndroid Build Coastguard Worker|                  | where we'll find them: in the top-level expression module |
262*9880d681SAndroid Build Coastguard Worker|                  | we just added.                                            |
263*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
264*9880d681SAndroid Build Coastguard Worker|                  | Forces all of the actions required to make the code and   |
265*9880d681SAndroid Build Coastguard Worker|                  | data in a module set (represented by a ModuleSetHandleT)  |
266*9880d681SAndroid Build Coastguard Worker|                  | accessible. Behaves as if some symbol in the set had been |
267*9880d681SAndroid Build Coastguard Worker|                  | searched for and JITSymbol::getSymbolAddress called. This |
268*9880d681SAndroid Build Coastguard Worker| emitAndFinalize  | is rarely needed, but can be useful when dealing with     |
269*9880d681SAndroid Build Coastguard Worker|                  | layers that usually behave lazily if the user wants to    |
270*9880d681SAndroid Build Coastguard Worker|                  | trigger early compilation (for example, to use idle CPU   |
271*9880d681SAndroid Build Coastguard Worker|                  | time to eagerly compile code in the background).          |
272*9880d681SAndroid Build Coastguard Worker+------------------+-----------------------------------------------------------+
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard WorkerThis interface attempts to capture the natural operations of a JIT (with some
275*9880d681SAndroid Build Coastguard Workerwrinkles like emitAndFinalize for performance), similar to the basic JIT API
276*9880d681SAndroid Build Coastguard Workeroperations we identified in Chapter 1. Conforming to the layer concept allows
277*9880d681SAndroid Build Coastguard Workerclasses to compose neatly by implementing their behaviors in terms of the these
278*9880d681SAndroid Build Coastguard Workersame operations, carried out on the layer below. For example, an eager layer
279*9880d681SAndroid Build Coastguard Worker(like IRTransformLayer) can implement addModuleSet by running each module in the
280*9880d681SAndroid Build Coastguard Workerset through its transform up-front and immediately passing the result to the
281*9880d681SAndroid Build Coastguard Workerlayer below. A lazy layer, by contrast, could implement addModuleSet by
282*9880d681SAndroid Build Coastguard Workersquirreling away the modules doing no other up-front work, but applying the
283*9880d681SAndroid Build Coastguard Workertransform (and calling addModuleSet on the layer below) when the client calls
284*9880d681SAndroid Build Coastguard WorkerfindSymbol instead. The JIT'd program behavior will be the same either way, but
285*9880d681SAndroid Build Coastguard Workerthese choices will have different performance characteristics: Doing work
286*9880d681SAndroid Build Coastguard Workereagerly means the JIT takes longer up-front, but proceeds smoothly once this is
287*9880d681SAndroid Build Coastguard Workerdone. Deferring work allows the JIT to get up-and-running quickly, but will
288*9880d681SAndroid Build Coastguard Workerforce the JIT to pause and wait whenever some code or data is needed that hasn't
289*9880d681SAndroid Build Coastguard Workeralready been processed.
290*9880d681SAndroid Build Coastguard Worker
291*9880d681SAndroid Build Coastguard WorkerOur current REPL is eager: Each function definition is optimized and compiled as
292*9880d681SAndroid Build Coastguard Workersoon as it's typed in. If we were to make the transform layer lazy (but not
293*9880d681SAndroid Build Coastguard Workerchange things otherwise) we could defer optimization until the first time we
294*9880d681SAndroid Build Coastguard Workerreference a function in a top-level expression (see if you can figure out why,
295*9880d681SAndroid Build Coastguard Workerthen check out the answer below [1]_). In the next chapter, however we'll
296*9880d681SAndroid Build Coastguard Workerintroduce fully lazy compilation, in which function's aren't compiled until
297*9880d681SAndroid Build Coastguard Workerthey're first called at run-time. At this point the trade-offs get much more
298*9880d681SAndroid Build Coastguard Workerinteresting: the lazier we are, the quicker we can start executing the first
299*9880d681SAndroid Build Coastguard Workerfunction, but the more often we'll have to pause to compile newly encountered
300*9880d681SAndroid Build Coastguard Workerfunctions. If we only code-gen lazily, but optimize eagerly, we'll have a slow
301*9880d681SAndroid Build Coastguard Workerstartup (which everything is optimized) but relatively short pauses as each
302*9880d681SAndroid Build Coastguard Workerfunction just passes through code-gen. If we both optimize and code-gen lazily
303*9880d681SAndroid Build Coastguard Workerwe can start executing the first function more quickly, but we'll have longer
304*9880d681SAndroid Build Coastguard Workerpauses as each function has to be both optimized and code-gen'd when it's first
305*9880d681SAndroid Build Coastguard Workerexecuted. Things become even more interesting if we consider interproceedural
306*9880d681SAndroid Build Coastguard Workeroptimizations like inlining, which must be performed eagerly. These are
307*9880d681SAndroid Build Coastguard Workercomplex trade-offs, and there is no one-size-fits all solution to them, but by
308*9880d681SAndroid Build Coastguard Workerproviding composable layers we leave the decisions to the person implementing
309*9880d681SAndroid Build Coastguard Workerthe JIT, and make it easy for them to experiment with different configurations.
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker`Next: Adding Per-function Lazy Compilation <BuildingAJIT3.html>`_
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard WorkerFull Code Listing
314*9880d681SAndroid Build Coastguard Worker=================
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard WorkerHere is the complete code listing for our running example with an
317*9880d681SAndroid Build Coastguard WorkerIRTransformLayer added to enable optimization. To build this example, use:
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker.. code-block:: bash
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker    # Compile
322*9880d681SAndroid Build Coastguard Worker    clang++ -g toy.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core orc native` -O3 -o toy
323*9880d681SAndroid Build Coastguard Worker    # Run
324*9880d681SAndroid Build Coastguard Worker    ./toy
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard WorkerHere is the code:
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker.. literalinclude:: ../../examples/Kaleidoscope/BuildingAJIT/Chapter2/KaleidoscopeJIT.h
329*9880d681SAndroid Build Coastguard Worker   :language: c++
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Worker.. [1] When we add our top-level expression to the JIT, any calls to functions
332*9880d681SAndroid Build Coastguard Worker       that we defined earlier will appear to the ObjectLinkingLayer as
333*9880d681SAndroid Build Coastguard Worker       external symbols. The ObjectLinkingLayer will call the SymbolResolver
334*9880d681SAndroid Build Coastguard Worker       that we defined in addModuleSet, which in turn calls findSymbol on the
335*9880d681SAndroid Build Coastguard Worker       OptimizeLayer, at which point even a lazy transform layer will have to
336*9880d681SAndroid Build Coastguard Worker       do its work.
337