1 //===- KaleidoscopeJIT.h - A simple JIT for Kaleidoscope --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Contains a simple JIT definition for use in the kaleidoscope tutorials.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
14 #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
15 
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ExecutionEngine/JITSymbol.h"
18 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
19 #include "llvm/ExecutionEngine/Orc/Core.h"
20 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
21 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
22 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
23 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
24 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
25 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/IR/LegacyPassManager.h"
29 #include "llvm/Transforms/InstCombine/InstCombine.h"
30 #include "llvm/Transforms/Scalar.h"
31 #include "llvm/Transforms/Scalar/GVN.h"
32 #include <memory>
33 
34 namespace llvm {
35 namespace orc {
36 
37 class KaleidoscopeJIT {
38 private:
39   ExecutionSession ES;
40   RTDyldObjectLinkingLayer ObjectLayer;
41   IRCompileLayer CompileLayer;
42   IRTransformLayer OptimizeLayer;
43 
44   DataLayout DL;
45   MangleAndInterner Mangle;
46   ThreadSafeContext Ctx;
47 
48   JITDylib &MainJD;
49 
50 public:
KaleidoscopeJIT(JITTargetMachineBuilder JTMB,DataLayout DL)51   KaleidoscopeJIT(JITTargetMachineBuilder JTMB, DataLayout DL)
52       : ObjectLayer(ES,
53                     []() { return std::make_unique<SectionMemoryManager>(); }),
54         CompileLayer(ES, ObjectLayer,
55                      std::make_unique<ConcurrentIRCompiler>(std::move(JTMB))),
56         OptimizeLayer(ES, CompileLayer, optimizeModule), DL(std::move(DL)),
57         Mangle(ES, this->DL), Ctx(std::make_unique<LLVMContext>()),
58         MainJD(ES.createJITDylib("<main>")) {
59     MainJD.addGenerator(
60         cantFail(DynamicLibrarySearchGenerator::GetForCurrentProcess(
61             DL.getGlobalPrefix())));
62   }
63 
getDataLayout()64   const DataLayout &getDataLayout() const { return DL; }
65 
getContext()66   LLVMContext &getContext() { return *Ctx.getContext(); }
67 
Create()68   static Expected<std::unique_ptr<KaleidoscopeJIT>> Create() {
69     auto JTMB = JITTargetMachineBuilder::detectHost();
70 
71     if (!JTMB)
72       return JTMB.takeError();
73 
74     auto DL = JTMB->getDefaultDataLayoutForTarget();
75     if (!DL)
76       return DL.takeError();
77 
78     return std::make_unique<KaleidoscopeJIT>(std::move(*JTMB), std::move(*DL));
79   }
80 
addModule(std::unique_ptr<Module> M)81   Error addModule(std::unique_ptr<Module> M) {
82     return OptimizeLayer.add(MainJD, ThreadSafeModule(std::move(M), Ctx));
83   }
84 
lookup(StringRef Name)85   Expected<JITEvaluatedSymbol> lookup(StringRef Name) {
86     return ES.lookup({&MainJD}, Mangle(Name.str()));
87   }
88 
89 private:
90   static Expected<ThreadSafeModule>
optimizeModule(ThreadSafeModule TSM,const MaterializationResponsibility & R)91   optimizeModule(ThreadSafeModule TSM, const MaterializationResponsibility &R) {
92     TSM.withModuleDo([](Module &M) {
93       // Create a function pass manager.
94       auto FPM = std::make_unique<legacy::FunctionPassManager>(&M);
95 
96       // Add some optimizations.
97       FPM->add(createInstructionCombiningPass());
98       FPM->add(createReassociatePass());
99       FPM->add(createGVNPass());
100       FPM->add(createCFGSimplificationPass());
101       FPM->doInitialization();
102 
103       // Run the optimizations over all functions in the module being added to
104       // the JIT.
105       for (auto &F : M)
106         FPM->run(F);
107     });
108 
109     return std::move(TSM);
110   }
111 };
112 
113 } // end namespace orc
114 } // end namespace llvm
115 
116 #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H
117