]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lli/OrcLazyJIT.h
MFC r343601:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lli / OrcLazyJIT.h
1 //===- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Simple Orc-based JIT. Uses the compile-on-demand layer to break up and
11 // lazily compile modules.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H
16 #define LLVM_TOOLS_LLI_ORCLAZYJIT_H
17
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/ExecutionEngine/JITSymbol.h"
22 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
23 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
24 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
25 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
26 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
27 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
28 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
29 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
30 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
31 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
32 #include "llvm/IR/DataLayout.h"
33 #include "llvm/IR/GlobalValue.h"
34 #include "llvm/IR/Mangler.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include "llvm/Target/TargetMachine.h"
38 #include <algorithm>
39 #include <functional>
40 #include <memory>
41 #include <set>
42 #include <string>
43 #include <vector>
44
45 namespace llvm {
46
47 class OrcLazyJIT {
48 public:
49
50   using CompileCallbackMgr = orc::JITCompileCallbackManager;
51   using ObjLayerT = orc::RTDyldObjectLinkingLayer;
52   using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
53   using TransformFtor =
54           std::function<std::shared_ptr<Module>(std::shared_ptr<Module>)>;
55   using IRDumpLayerT = orc::IRTransformLayer<CompileLayerT, TransformFtor>;
56   using CODLayerT = orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr>;
57   using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
58   using ModuleHandleT = CODLayerT::ModuleHandleT;
59
60   OrcLazyJIT(std::unique_ptr<TargetMachine> TM,
61              std::unique_ptr<CompileCallbackMgr> CCMgr,
62              IndirectStubsManagerBuilder IndirectStubsMgrBuilder,
63              bool InlineStubs)
64       : TM(std::move(TM)), DL(this->TM->createDataLayout()),
65         CCMgr(std::move(CCMgr)),
66         ObjectLayer([]() { return std::make_shared<SectionMemoryManager>(); }),
67         CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
68         IRDumpLayer(CompileLayer, createDebugDumper()),
69         CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr,
70                  std::move(IndirectStubsMgrBuilder), InlineStubs),
71         CXXRuntimeOverrides(
72             [this](const std::string &S) { return mangle(S); }) {}
73
74   ~OrcLazyJIT() {
75     // Run any destructors registered with __cxa_atexit.
76     CXXRuntimeOverrides.runDestructors();
77     // Run any IR destructors.
78     for (auto &DtorRunner : IRStaticDestructorRunners)
79       if (auto Err = DtorRunner.runViaLayer(CODLayer)) {
80         // FIXME: OrcLazyJIT should probably take a "shutdownError" callback to
81         //        report these errors on.
82         report_fatal_error(std::move(Err));
83       }
84   }
85
86   Error addModule(std::shared_ptr<Module> M) {
87     if (M->getDataLayout().isDefault())
88       M->setDataLayout(DL);
89
90     // Rename, bump linkage and record static constructors and destructors.
91     // We have to do this before we hand over ownership of the module to the
92     // JIT.
93     std::vector<std::string> CtorNames, DtorNames;
94     {
95       unsigned CtorId = 0, DtorId = 0;
96       for (auto Ctor : orc::getConstructors(*M)) {
97         std::string NewCtorName = ("$static_ctor." + Twine(CtorId++)).str();
98         Ctor.Func->setName(NewCtorName);
99         Ctor.Func->setLinkage(GlobalValue::ExternalLinkage);
100         Ctor.Func->setVisibility(GlobalValue::HiddenVisibility);
101         CtorNames.push_back(mangle(NewCtorName));
102       }
103       for (auto Dtor : orc::getDestructors(*M)) {
104         std::string NewDtorName = ("$static_dtor." + Twine(DtorId++)).str();
105         Dtor.Func->setLinkage(GlobalValue::ExternalLinkage);
106         Dtor.Func->setVisibility(GlobalValue::HiddenVisibility);
107         DtorNames.push_back(mangle(Dtor.Func->getName()));
108         Dtor.Func->setName(NewDtorName);
109       }
110     }
111
112     // Symbol resolution order:
113     //   1) Search the JIT symbols.
114     //   2) Check for C++ runtime overrides.
115     //   3) Search the host process (LLI)'s symbol table.
116     if (!ModulesHandle) {
117       auto Resolver =
118         orc::createLambdaResolver(
119           [this](const std::string &Name) -> JITSymbol {
120             if (auto Sym = CODLayer.findSymbol(Name, true))
121               return Sym;
122             return CXXRuntimeOverrides.searchOverrides(Name);
123           },
124           [](const std::string &Name) {
125             if (auto Addr =
126                 RTDyldMemoryManager::getSymbolAddressInProcess(Name))
127               return JITSymbol(Addr, JITSymbolFlags::Exported);
128             return JITSymbol(nullptr);
129           }
130         );
131
132       // Add the module to the JIT.
133       if (auto ModulesHandleOrErr =
134           CODLayer.addModule(std::move(M), std::move(Resolver)))
135         ModulesHandle = std::move(*ModulesHandleOrErr);
136       else
137         return ModulesHandleOrErr.takeError();
138
139     } else if (auto Err = CODLayer.addExtraModule(*ModulesHandle, std::move(M)))
140       return Err;
141
142     // Run the static constructors, and save the static destructor runner for
143     // execution when the JIT is torn down.
144     orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames),
145                                               *ModulesHandle);
146     if (auto Err = CtorRunner.runViaLayer(CODLayer))
147       return Err;
148
149     IRStaticDestructorRunners.emplace_back(std::move(DtorNames),
150                                            *ModulesHandle);
151
152     return Error::success();
153   }
154
155   JITSymbol findSymbol(const std::string &Name) {
156     return CODLayer.findSymbol(mangle(Name), true);
157   }
158
159   JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
160     return CODLayer.findSymbolIn(H, mangle(Name), true);
161   }
162
163 private:
164   std::string mangle(const std::string &Name) {
165     std::string MangledName;
166     {
167       raw_string_ostream MangledNameStream(MangledName);
168       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
169     }
170     return MangledName;
171   }
172
173   static std::set<Function*> extractSingleFunction(Function &F) {
174     std::set<Function*> Partition;
175     Partition.insert(&F);
176     return Partition;
177   }
178
179   static TransformFtor createDebugDumper();
180
181   std::unique_ptr<TargetMachine> TM;
182   DataLayout DL;
183   SectionMemoryManager CCMgrMemMgr;
184
185   std::unique_ptr<CompileCallbackMgr> CCMgr;
186   ObjLayerT ObjectLayer;
187   CompileLayerT CompileLayer;
188   IRDumpLayerT IRDumpLayer;
189   CODLayerT CODLayer;
190
191   orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
192   std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners;
193   llvm::Optional<CODLayerT::ModuleHandleT> ModulesHandle;
194 };
195
196 int runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms,
197                   const std::vector<std::string> &Args);
198
199 } // end namespace llvm
200
201 #endif // LLVM_TOOLS_LLI_ORCLAZYJIT_H