llvm.org GIT mirror llvm / 1aeb111
[Orc] Reapply r236465 with fixes for the MSVC bots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236506 91177308-0d34-0410-b5e6-96231b3b80d8 Lang Hames 4 years ago
9 changed file(s) with 599 addition(s) and 567 deletion(s). Raw diff Collapse all Expand all
12131213 void removeModule(ModuleHandleT H) { LazyEmitLayer.removeModuleSet(H); }
12141214
12151215 JITSymbol findSymbol(const std::string &Name) {
1216 return LazyEmitLayer.findSymbol(Name, true);
1216 return LazyEmitLayer.findSymbol(Name, false);
12171217 }
12181218
12191219 JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
1220 return LazyEmitLayer.findSymbolIn(H, Name, true);
1220 return LazyEmitLayer.findSymbolIn(H, Name, false);
12211221 }
12221222
12231223 JITSymbol findUnmangledSymbol(const std::string &Name) {
12751275 makeStub(*F, *FunctionBodyPointer);
12761276
12771277 // Step 4) Add the module containing the stub to the JIT.
1278 auto H = addModule(C.takeM());
1278 auto StubH = addModule(C.takeM());
12791279
12801280 // Step 5) Set the compile and update actions.
12811281 //
12881288 // The update action will update FunctionBodyPointer to point at the newly
12891289 // compiled function.
12901290 std::shared_ptr Fn = std::move(FnAST);
1291 CallbackInfo.setCompileAction([this, Fn]() {
1291 CallbackInfo.setCompileAction([this, Fn, BodyPtrName, StubH]() {
12921292 auto H = addModule(IRGen(Session, *Fn));
1293 return findUnmangledSymbolIn(H, Fn->Proto->Name).getAddress();
1293 auto BodySym = findUnmangledSymbolIn(H, Fn->Proto->Name);
1294 auto BodyPtrSym = findUnmangledSymbolIn(StubH, BodyPtrName);
1295 assert(BodySym && "Missing function body.");
1296 assert(BodyPtrSym && "Missing function pointer.");
1297 auto BodyAddr = BodySym.getAddress();
1298 auto BodyPtr = reinterpret_cast(
1299 static_cast(BodyPtrSym.getAddress()));
1300 memcpy(BodyPtr, &BodyAddr, sizeof(uintptr_t));
1301 return BodyAddr;
12941302 });
1295 CallbackInfo.setUpdateAction(
1296 getLocalFPUpdater(LazyEmitLayer, H, mangle(BodyPtrName)));
1297
1298 return H;
1303
1304 return StubH;
12991305 }
13001306
13011307 SessionContext &Session;
+0
-60
include/llvm/ExecutionEngine/Orc/CloneSubModule.h less more
None //===-- CloneSubModule.h - Utilities for extracting sub-modules -*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Contains utilities for extracting sub-modules. Useful for breaking up modules
10 // for lazy jitting.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_CLONESUBMODULE_H
15 #define LLVM_EXECUTIONENGINE_ORC_CLONESUBMODULE_H
16
17 #include "llvm/ADT/DenseSet.h"
18 #include "llvm/Transforms/Utils/ValueMapper.h"
19 #include
20
21 namespace llvm {
22
23 class Function;
24 class GlobalVariable;
25 class Module;
26
27 namespace orc {
28
29 /// @brief Functor type for describing how CloneSubModule should mutate a
30 /// GlobalVariable.
31 typedef std::function
32 ValueToValueMapTy &)> HandleGlobalVariableFtor;
33
34 /// @brief Functor type for describing how CloneSubModule should mutate a
35 /// Function.
36 typedef std::function
37 HandleFunctionFtor;
38
39 /// @brief Copies the initializer from Orig to New.
40 ///
41 /// Type is suitable for implicit conversion to a HandleGlobalVariableFtor.
42 void copyGVInitializer(GlobalVariable &New, const GlobalVariable &Orig,
43 ValueToValueMapTy &VMap);
44
45 /// @brief Copies the body of Orig to New.
46 ///
47 /// Type is suitable for implicit conversion to a HandleFunctionFtor.
48 void copyFunctionBody(Function &New, const Function &Orig,
49 ValueToValueMapTy &VMap);
50
51 /// @brief Clone a subset of the module Src into Dst.
52 void CloneSubModule(Module &Dst, const Module &Src,
53 HandleGlobalVariableFtor HandleGlobalVariable,
54 HandleFunctionFtor HandleFunction, bool KeepInlineAsm);
55
56 } // End namespace orc.
57 } // End namespace llvm.
58
59 #endif // LLVM_EXECUTIONENGINE_ORC_CLONESUBMODULE_H
1414 #ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
1515 #define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
1616
17 //#include "CloneSubModule.h"
1718 #include "IndirectionUtils.h"
1819 #include "LambdaResolver.h"
1920 #include "llvm/ADT/STLExtras.h"
2021 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
22 #include "llvm/Transforms/Utils/Cloning.h"
2123 #include
24 #include
25
26 #include "llvm/Support/Debug.h"
2227
2328 namespace llvm {
2429 namespace orc {
2530
2631 /// @brief Compile-on-demand layer.
2732 ///
28 /// Modules added to this layer have their calls indirected, and are then
29 /// broken up into a set of single-function modules, each of which is added
30 /// to the layer below in a singleton set. The lower layer can be any layer that
31 /// accepts IR module sets.
32 ///
33 /// It is expected that this layer will frequently be used on top of a
34 /// LazyEmittingLayer. The combination of the two ensures that each function is
35 /// compiled only when it is first called.
33 /// When a module is added to this layer a stub is created for each of its
34 /// function definitions. The stubs and other global values are immediately
35 /// added to the layer below. When a stub is called it triggers the extraction
36 /// of the function body from the original module. The extracted body is then
37 /// compiled and executed.
3638 template
3739 class CompileOnDemandLayer {
3840 private:
39 /// @brief Lookup helper that provides compatibility with the classic
40 /// static-compilation symbol resolution process.
41 ///
42 /// The CompileOnDemand (COD) layer splits modules up into multiple
43 /// sub-modules, each held in its own llvm::Module instance, in order to
44 /// support lazy compilation. When a module that contains private symbols is
45 /// broken up symbol linkage changes may be required to enable access to
46 /// "private" data that now resides in a different llvm::Module instance. To
47 /// retain expected symbol resolution behavior for clients of the COD layer,
48 /// the CODScopedLookup class uses a two-tiered lookup system to resolve
49 /// symbols. Lookup first scans sibling modules that were split from the same
50 /// original module (logical-module scoped lookup), then scans all other
51 /// modules that have been added to the lookup scope (logical-dylib scoped
52 /// lookup).
53 class CODScopedLookup {
41
42 // Utility class for MapValue. Only materializes declarations for global
43 // variables.
44 class GlobalDeclMaterializer : public ValueMaterializer {
45 public:
46 GlobalDeclMaterializer(Module &Dst) : Dst(Dst) {}
47 Value* materializeValueFor(Value *V) final {
48 if (auto *GV = dyn_cast(V))
49 return cloneGlobalVariableDecl(Dst, *GV);
50 else if (auto *F = dyn_cast(V))
51 return cloneFunctionDecl(Dst, *F);
52 // Else.
53 return nullptr;
54 }
5455 private:
55 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
56 typedef std::vector SiblingHandlesList;
57 typedef std::list PseudoDylibModuleSetHandlesList;
58
56 Module &Dst;
57 };
58
59 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
60 class UncompiledPartition;
61
62 // Logical module.
63 //
64 // This struct contains the handles for the global values and stubs (which
65 // cover the external symbols of the original module), plus the handes for
66 // each of the extracted partitions. These handleds are used for lookup (only
67 // the globals/stubs module is searched) and memory management. The actual
68 // searching and resource management are handled by the LogicalDylib that owns
69 // the LogicalModule.
70 struct LogicalModule {
71 LogicalModule() {}
72
73 LogicalModule(LogicalModule &&Other)
74 : SrcM(std::move(Other.SrcM)),
75 GVsAndStubsHandle(std::move(Other.GVsAndStubsHandle)),
76 ImplHandles(std::move(ImplHandles)) {}
77
78 std::unique_ptr SrcM;
79 BaseLayerModuleSetHandleT GVsAndStubsHandle;
80 std::vector ImplHandles;
81 };
82
83 // Logical dylib.
84 //
85 // This class handles symbol resolution and resource management for a set of
86 // modules that were added together as a logical dylib.
87 //
88 // A logical dylib contains one-or-more LogicalModules plus a set of
89 // UncompiledPartitions. LogicalModules support symbol resolution and resource
90 // management for for code that has already been emitted. UncompiledPartitions
91 // represent code that has not yet been compiled.
92 class LogicalDylib {
93 private:
94 friend class UncompiledPartition;
95 typedef std::list LogicalModuleList;
5996 public:
60 /// @brief Handle for a logical module.
61 typedef typename PseudoDylibModuleSetHandlesList::iterator LMHandle;
62
63 /// @brief Construct a scoped lookup.
64 CODScopedLookup(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
65
66 virtual ~CODScopedLookup() {}
67
68 /// @brief Start a new context for a single logical module.
97
98 typedef unsigned UncompiledPartitionID;
99 typedef typename LogicalModuleList::iterator LMHandle;
100
101 // Construct a logical dylib.
102 LogicalDylib(CompileOnDemandLayer &CODLayer) : CODLayer(CODLayer) { }
103
104 // Delete this logical dylib, release logical module resources.
105 virtual ~LogicalDylib() {
106 releaseLogicalModuleResources();
107 }
108
109 // Get a reference to the containing layer.
110 CompileOnDemandLayer& getCODLayer() { return CODLayer; }
111
112 // Get a reference to the base layer.
113 BaseLayerT& getBaseLayer() { return CODLayer.BaseLayer; }
114
115 // Start a new context for a single logical module.
69116 LMHandle createLogicalModule() {
70 Handles.push_back(SiblingHandlesList());
71 return std::prev(Handles.end());
72 }
73
74 /// @brief Add a concrete Module's handle to the given logical Module's
75 /// lookup scope.
117 LogicalModules.push_back(LogicalModule());
118 return std::prev(LogicalModules.end());
119 }
120
121 // Set the global-values-and-stubs module handle for this logical module.
122 void setGVsAndStubsHandle(LMHandle LMH, BaseLayerModuleSetHandleT H) {
123 LMH->GVsAndStubsHandle = H;
124 }
125
126 // Return the global-values-and-stubs module handle for this logical module.
127 BaseLayerModuleSetHandleT getGVsAndStubsHandle(LMHandle LMH) {
128 return LMH->GVsAndStubsHandle;
129 }
130
131 // Add a handle to a module containing lazy function bodies to the given
132 // logical module.
76133 void addToLogicalModule(LMHandle LMH, BaseLayerModuleSetHandleT H) {
77 LMH->push_back(H);
78 }
79
80 /// @brief Remove a logical Module from the CODScopedLookup entirely.
81 void removeLogicalModule(LMHandle LMH) { Handles.erase(LMH); }
82
83 /// @brief Look up a symbol in this context.
84 JITSymbol findSymbol(LMHandle LMH, const std::string &Name) {
85 if (auto Symbol = findSymbolIn(LMH, Name))
134 LMH->ImplHandles.push_back(H);
135 }
136
137 // Create an UncompiledPartition attached to this LogicalDylib.
138 UncompiledPartition& createUncompiledPartition(LMHandle LMH,
139 std::shared_ptr SrcM);
140
141 // Take ownership of the given UncompiledPartition from the logical dylib.
142 std::unique_ptr
143 takeUPOwnership(UncompiledPartitionID ID);
144
145 // Look up a symbol in this context.
146 JITSymbol findSymbolInternally(LMHandle LMH, const std::string &Name) {
147 if (auto Symbol = getBaseLayer().findSymbolIn(LMH->GVsAndStubsHandle,
148 Name, false))
86149 return Symbol;
87150
88 for (auto I = Handles.begin(), E = Handles.end(); I != E; ++I)
151 for (auto I = LogicalModules.begin(), E = LogicalModules.end(); I != E;
152 ++I)
89153 if (I != LMH)
90 if (auto Symbol = findSymbolIn(I, Name))
154 if (auto Symbol = getBaseLayer().findSymbolIn(I->GVsAndStubsHandle,
155 Name, false))
91156 return Symbol;
92157
93158 return nullptr;
94159 }
95160
96 /// @brief Find an external symbol (via the user supplied SymbolResolver).
97 virtual RuntimeDyld::SymbolInfo
98 externalLookup(const std::string &Name) const = 0;
99
100 private:
101
102 JITSymbol findSymbolIn(LMHandle LMH, const std::string &Name) {
103 for (auto H : *LMH)
104 if (auto Symbol = BaseLayer.findSymbolIn(H, Name, false))
161 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
162 for (auto &LM : LogicalModules)
163 if (auto Symbol = getBaseLayer().findSymbolIn(LM.GVsAndStubsHandle,
164 Name,
165 ExportedSymbolsOnly))
105166 return Symbol;
106167 return nullptr;
107168 }
108169
109 BaseLayerT &BaseLayer;
110 PseudoDylibModuleSetHandlesList Handles;
170 // Find an external symbol (via the user supplied SymbolResolver).
171 virtual RuntimeDyld::SymbolInfo
172 findSymbolExternally(const std::string &Name) const = 0;
173
174 private:
175
176 void releaseLogicalModuleResources() {
177 for (auto I = LogicalModules.begin(), E = LogicalModules.end(); I != E;
178 ++I) {
179 getBaseLayer().removeModuleSet(I->GVsAndStubsHandle);
180 for (auto H : I->ImplHandles)
181 getBaseLayer().removeModuleSet(H);
182 }
183 }
184
185 CompileOnDemandLayer &CODLayer;
186 LogicalModuleList LogicalModules;
187 std::vector> UncompiledPartitions;
111188 };
112189
113190 template
114 class CODScopedLookupImpl : public CODScopedLookup {
191 class LogicalDylibImpl : public LogicalDylib {
115192 public:
116 CODScopedLookupImpl(BaseLayerT &BaseLayer, ResolverPtrT Resolver)
117 : CODScopedLookup(BaseLayer), Resolver(std::move(Resolver)) {}
193 LogicalDylibImpl(CompileOnDemandLayer &CODLayer, ResolverPtrT Resolver)
194 : LogicalDylib(CODLayer), Resolver(std::move(Resolver)) {}
118195
119196 RuntimeDyld::SymbolInfo
120 externalLookup(const std::string &Name) const override {
197 findSymbolExternally(const std::string &Name) const override {
121198 return Resolver->findSymbol(Name);
122199 }
123200
126203 };
127204
128205 template
129 static std::shared_ptr
130 createCODScopedLookup(BaseLayerT &BaseLayer,
131 ResolverPtrT Resolver) {
132 typedef CODScopedLookupImpl Impl;
133 return std::make_shared(BaseLayer, std::move(Resolver));
134 }
135
136 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerModuleSetHandleT;
137 typedef std::vector BaseLayerModuleSetHandleListT;
138
139 struct ModuleSetInfo {
140 // Symbol lookup - just one for the whole module set.
141 std::shared_ptr Lookup;
142
143 // Logical module handles.
144 std::vector LMHandles;
145
146 // List of vectors of module set handles:
147 // One vector per logical module - each vector holds the handles for the
148 // exploded modules for that logical module in the base layer.
149 BaseLayerModuleSetHandleListT BaseLayerModuleSetHandles;
150
151 ModuleSetInfo(std::shared_ptr Lookup)
152 : Lookup(std::move(Lookup)) {}
153
154 void releaseResources(BaseLayerT &BaseLayer) {
155 for (auto LMH : LMHandles)
156 Lookup->removeLogicalModule(LMH);
157 for (auto H : BaseLayerModuleSetHandles)
158 BaseLayer.removeModuleSet(H);
159 }
206 static std::unique_ptr
207 createLogicalDylib(CompileOnDemandLayer &CODLayer,
208 ResolverPtrT Resolver) {
209 typedef LogicalDylibImpl Impl;
210 return llvm::make_unique(CODLayer, std::move(Resolver));
211 }
212
213 // Uncompiled partition.
214 //
215 // Represents one as-yet uncompiled portion of a module.
216 class UncompiledPartition {
217 public:
218
219 struct PartitionEntry {
220 PartitionEntry(Function *F, TargetAddress CallbackID)
221 : F(F), CallbackID(CallbackID) {}
222 Function *F;
223 TargetAddress CallbackID;
224 };
225
226 typedef std::vector PartitionEntryList;
227
228 // Creates an uncompiled partition with the list of functions that make up
229 // this partition.
230 UncompiledPartition(LogicalDylib &LD, typename LogicalDylib::LMHandle LMH,
231 std::shared_ptr SrcM)
232 : LD(LD), LMH(LMH), SrcM(std::move(SrcM)), ID(~0U) {}
233
234 ~UncompiledPartition() {
235 // FIXME: When we want to support threaded lazy compilation we'll need to
236 // lock the callback manager here.
237 auto &CCMgr = LD.getCODLayer().CompileCallbackMgr;
238 for (auto PEntry : PartitionEntries)
239 CCMgr.releaseCompileCallback(PEntry.CallbackID);
240 }
241
242 // Set the ID for this partition.
243 void setID(typename LogicalDylib::UncompiledPartitionID ID) {
244 this->ID = ID;
245 }
246
247 // Set the function set and callbacks for this partition.
248 void setPartitionEntries(PartitionEntryList PartitionEntries) {
249 this->PartitionEntries = std::move(PartitionEntries);
250 }
251
252 // Handle a compile callback for the function at index FnIdx.
253 TargetAddress compile(unsigned FnIdx) {
254 // Take ownership of self. This will ensure we delete the partition and
255 // free all its resources once we're done compiling.
256 std::unique_ptr This = LD.takeUPOwnership(ID);
257
258 // Release all other compile callbacks for this partition.
259 // We skip the callback for this function because that's the one that
260 // called us, and the callback manager will already have removed it.
261 auto &CCMgr = LD.getCODLayer().CompileCallbackMgr;
262 for (unsigned I = 0; I < PartitionEntries.size(); ++I)
263 if (I != FnIdx)
264 CCMgr.releaseCompileCallback(PartitionEntries[I].CallbackID);
265
266 // Grab the name of the function being called here.
267 Function *F = PartitionEntries[FnIdx].F;
268 std::string CalledFnName = Mangle(F->getName(), SrcM->getDataLayout());
269
270 // Extract the function and add it to the base layer.
271 auto PartitionImplH = emitPartition();
272 LD.addToLogicalModule(LMH, PartitionImplH);
273
274 // Update body pointers.
275 // FIXME: When we start supporting remote lazy jitting this will need to
276 // be replaced with a user-supplied callback for updating the
277 // remote pointers.
278 TargetAddress CalledAddr = 0;
279 for (unsigned I = 0; I < PartitionEntries.size(); ++I) {
280 auto F = PartitionEntries[I].F;
281 std::string FName(F->getName());
282 auto FnBodySym =
283 LD.getBaseLayer().findSymbolIn(PartitionImplH,
284 Mangle(FName, SrcM->getDataLayout()),
285 false);
286 auto FnPtrSym =
287 LD.getBaseLayer().findSymbolIn(LD.getGVsAndStubsHandle(LMH),
288 Mangle(FName + "$orc_addr",
289 SrcM->getDataLayout()),
290 false);
291 assert(FnBodySym && "Couldn't find function body.");
292 assert(FnPtrSym && "Couldn't find function body pointer.");
293
294 auto FnBodyAddr = FnBodySym.getAddress();
295 void *FnPtrAddr = reinterpret_cast(
296 static_cast(FnPtrSym.getAddress()));
297
298 // If this is the function we're calling record the address so we can
299 // return it from this function.
300 if (I == FnIdx)
301 CalledAddr = FnBodyAddr;
302
303 memcpy(FnPtrAddr, &FnBodyAddr, sizeof(uintptr_t));
304 }
305
306 // Finally, clear the partition structure so we don't try to
307 // double-release the callbacks in the UncompiledPartition destructor.
308 PartitionEntries.clear();
309
310 return CalledAddr;
311 }
312
313 private:
314
315 BaseLayerModuleSetHandleT emitPartition() {
316 // Create the module.
317 std::string NewName(SrcM->getName());
318 for (auto &PEntry : PartitionEntries) {
319 NewName += ".";
320 NewName += PEntry.F->getName();
321 }
322 auto PM = llvm::make_unique(NewName, SrcM->getContext());
323 PM->setDataLayout(SrcM->getDataLayout());
324 ValueToValueMapTy VMap;
325 GlobalDeclMaterializer GDM(*PM);
326
327 // Create decls in the new module.
328 for (auto &PEntry : PartitionEntries)
329 cloneFunctionDecl(*PM, *PEntry.F, &VMap);
330
331 // Move the function bodies.
332 for (auto &PEntry : PartitionEntries)
333 moveFunctionBody(*PEntry.F, VMap);
334
335 // Create memory manager and symbol resolver.
336 auto MemMgr = llvm::make_unique();
337 auto Resolver = createLambdaResolver(
338 [this](const std::string &Name) {
339 if (auto Symbol = LD.findSymbolInternally(LMH, Name))
340 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
341 Symbol.getFlags());
342 return LD.findSymbolExternally(Name);
343 },
344 [this](const std::string &Name) {
345 if (auto Symbol = LD.findSymbolInternally(LMH, Name))
346 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
347 Symbol.getFlags());
348 return RuntimeDyld::SymbolInfo(nullptr);
349 });
350 std::vector> PartMSet;
351 PartMSet.push_back(std::move(PM));
352 return LD.getBaseLayer().addModuleSet(std::move(PartMSet),
353 std::move(MemMgr),
354 std::move(Resolver));
355 }
356
357 LogicalDylib &LD;
358 typename LogicalDylib::LMHandle LMH;
359 std::shared_ptr SrcM;
360 typename LogicalDylib::UncompiledPartitionID ID;
361 PartitionEntryList PartitionEntries;
160362 };
161363
162 typedef std::list<ModuleSetInfo> ModuleSetInfoListT;
364 typedef std::list<std::unique_ptr> LogicalDylibList;
163365
164366 public:
165367 /// @brief Handle to a set of loaded modules.
166 typedef typename ModuleSetInfoListT::iterator ModuleSetHandleT;
368 typedef typename LogicalDylibList::iterator ModuleSetHandleT;
167369
168370 /// @brief Construct a compile-on-demand layer instance.
169371 CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
179381 assert(MemMgr == nullptr &&
180382 "User supplied memory managers not supported with COD yet.");
181383
182 // Create a lookup context and ModuleSetInfo for this module set.
183 // For the purposes of symbol resolution the set Ms will be treated as if
184 // the modules it contained had been linked together as a dylib.
185 auto DylibLookup = createCODScopedLookup(BaseLayer, std::move(Resolver));
186 ModuleSetHandleT H =
187 ModuleSetInfos.insert(ModuleSetInfos.end(), ModuleSetInfo(DylibLookup));
188 ModuleSetInfo &MSI = ModuleSetInfos.back();
384 LogicalDylibs.push_back(createLogicalDylib(*this, std::move(Resolver)));
189385
190386 // Process each of the modules in this module set.
191 for (auto &M : Ms)
192 partitionAndAdd(*M, MSI);
193
194 return H;
387 for (auto &M : Ms) {
388 std::vector> Partitioning;
389 for (auto &F : *M) {
390 if (F.isDeclaration())
391 continue;
392 Partitioning.push_back(std::vector());
393 Partitioning.back().push_back(&F);
394 }
395 addLogicalModule(*LogicalDylibs.back(),
396 std::shared_ptr(std::move(M)),
397 std::move(Partitioning));
398 }
399
400 return std::prev(LogicalDylibs.end());
195401 }
196402
197403 /// @brief Remove the module represented by the given handle.
199405 /// This will remove all modules in the layers below that were derived from
200406 /// the module represented by H.
201407 void removeModuleSet(ModuleSetHandleT H) {
202 H->releaseResources(BaseLayer);
203 ModuleSetInfos.erase(H);
408 LogicalDylibs.erase(H);
204409 }
205410
206411 /// @brief Search for the given named symbol.
215420 /// below this one.
216421 JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
217422 bool ExportedSymbolsOnly) {
218
219 for (auto &BH : H->BaseLayerModuleSetHandles) {
220 if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly))
221 return Symbol;
222 }
223 return nullptr;
423 return (*H)->findSymbol(Name, ExportedSymbolsOnly);
224424 }
225425
226426 private:
227427
228 void partitionAndAdd(Module &M, ModuleSetInfo &MSI) {
229 const char *AddrSuffix = "$orc_addr";
230 const char *BodySuffix = "$orc_body";
231
232 // We're going to break M up into a bunch of sub-modules, but we want
233 // internal linkage symbols to still resolve sensibly. CODScopedLookup
234 // provides the "logical module" concept to make this work, so create a
235 // new logical module for M.
236 auto DylibLookup = MSI.Lookup;
237 auto LogicalModule = DylibLookup->createLogicalModule();
238 MSI.LMHandles.push_back(LogicalModule);
239
240 // Partition M into a "globals and stubs" module, a "common symbols" module,
241 // and a list of single-function modules.
242 auto PartitionedModule = fullyPartition(M);
243 auto StubsModule = std::move(PartitionedModule.GlobalVars);
244 auto CommonsModule = std::move(PartitionedModule.Commons);
245 auto FunctionModules = std::move(PartitionedModule.Functions);
246
247 // Emit the commons stright away.
248 auto CommonHandle = addModule(std::move(CommonsModule), MSI, LogicalModule);
249 BaseLayer.emitAndFinalize(CommonHandle);
250
251 // Map of definition names to callback-info data structures. We'll use
252 // this to build the compile actions for the stubs below.
253 typedef std::map
254 typename CompileCallbackMgrT::CompileCallbackInfo>
255 StubInfoMap;
256 StubInfoMap StubInfos;
257
258 // Now we need to take each of the extracted Modules and add them to
259 // base layer. Each Module will be added individually to make sure they
260 // can be compiled separately, and each will get its own lookaside
261 // memory manager that will resolve within this logical module first.
262 for (auto &SubM : FunctionModules) {
263
264 // Keep track of the stubs we create for this module so that we can set
265 // their compile actions.
266 std::vector NewStubInfos;
267
268 // Search for function definitions and insert stubs into the stubs
269 // module.
270 for (auto &F : *SubM) {
271 if (F.isDeclaration())
272 continue;
273
274 std::string Name = F.getName();
275 Function *Proto = StubsModule->getFunction(Name);
276 assert(Proto && "Failed to clone function decl into stubs module.");
277 auto CallbackInfo =
278 CompileCallbackMgr.getCompileCallback(Proto->getContext());
279 GlobalVariable *FunctionBodyPointer =
280 createImplPointer(*Proto->getType(), *Proto->getParent(),
281 Name + AddrSuffix,
282 createIRTypedAddress(*Proto->getFunctionType(),
283 CallbackInfo.getAddress()));
284 makeStub(*Proto, *FunctionBodyPointer);
285
286 F.setName(Name + BodySuffix);
287 F.setVisibility(GlobalValue::HiddenVisibility);
288
289 auto KV = std::make_pair(std::move(Name), std::move(CallbackInfo));
290 NewStubInfos.push_back(StubInfos.insert(StubInfos.begin(), KV));
428 void addLogicalModule(LogicalDylib &LD, std::shared_ptr SrcM,
429 std::vector> Partitions) {
430
431 // Bump the linkage and rename any anonymous/privote members in SrcM to
432 // ensure that everything will resolve properly after we partition SrcM.
433 makeAllSymbolsExternallyAccessible(*SrcM);
434
435 // Create a logical module handle for SrcM within the logical dylib.
436 auto LMH = LD.createLogicalModule();
437
438 // Create the GVs-and-stubs module.
439 auto GVsAndStubsM = llvm::make_unique(
440 (SrcM->getName() + ".globals_and_stubs").str(),
441 SrcM->getContext());
442 GVsAndStubsM->setDataLayout(SrcM->getDataLayout());
443 ValueToValueMapTy VMap;
444
445 // Process partitions and create stubs.
446 // We create the stubs before copying the global variables as we know the
447 // stubs won't refer to any globals (they only refer to their implementation
448 // pointer) so there's no ordering/value-mapping issues.
449 for (auto& Partition : Partitions) {
450 auto &UP = LD.createUncompiledPartition(LMH, SrcM);
451 typename UncompiledPartition::PartitionEntryList PartitionEntries;
452 for (auto &F : Partition) {
453 assert(!F->isDeclaration() &&
454 "Partition should only contain definitions");
455 unsigned FnIdx = PartitionEntries.size();
456 auto CCI = CompileCallbackMgr.getCompileCallback(SrcM->getContext());
457 PartitionEntries.push_back(
458 typename UncompiledPartition::PartitionEntry(F, CCI.getAddress()));
459 Function *StubF = cloneFunctionDecl(*GVsAndStubsM, *F, &VMap);
460 GlobalVariable *FnBodyPtr =
461 createImplPointer(*StubF->getType(), *StubF->getParent(),
462 StubF->getName() + "$orc_addr",
463 createIRTypedAddress(*StubF->getFunctionType(),
464 CCI.getAddress()));
465 makeStub(*StubF, *FnBodyPtr);
466 CCI.setCompileAction([&UP, FnIdx]() { return UP.compile(FnIdx); });
291467 }
292468
293 auto H = addModule(std::move(SubM), MSI, LogicalModule);
294
295 // Set the compile actions for this module:
296 for (auto &KVPair : NewStubInfos) {
297 std::string BodyName = Mangle(KVPair->first + BodySuffix,
298 M.getDataLayout());
299 auto &CCInfo = KVPair->second;
300 CCInfo.setCompileAction(
301 [=](){
302 return BaseLayer.findSymbolIn(H, BodyName, false).getAddress();
303 });
304 }
305
306 }
307
308 // Ok - we've processed all the partitioned modules. Now add the
309 // stubs/globals module and set the update actions.
310 auto StubsH =
311 addModule(std::move(StubsModule), MSI, LogicalModule);
312
313 for (auto &KVPair : StubInfos) {
314 std::string AddrName = Mangle(KVPair.first + AddrSuffix,
315 M.getDataLayout());
316 auto &CCInfo = KVPair.second;
317 CCInfo.setUpdateAction(
318 getLocalFPUpdater(BaseLayer, StubsH, AddrName));
319 }
320 }
321
322 // Add the given Module to the base layer using a memory manager that will
323 // perform the appropriate scoped lookup (i.e. will look first with in the
324 // module from which it was extracted, then into the set to which that module
325 // belonged, and finally externally).
326 BaseLayerModuleSetHandleT addModule(
327 std::unique_ptr M,
328 ModuleSetInfo &MSI,
329 typename CODScopedLookup::LMHandle LogicalModule) {
330
331 // Add this module to the JIT with a memory manager that uses the
332 // DylibLookup to resolve symbols.
333 std::vector> MSet;
334 MSet.push_back(std::move(M));
335
336 auto DylibLookup = MSI.Lookup;
337 auto Resolver =
338 createLambdaResolver(
339 [=](const std::string &Name) {
340 if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
469 UP.setPartitionEntries(std::move(PartitionEntries));
470 }
471
472 // Now clone the global variable declarations.
473 GlobalDeclMaterializer GDMat(*GVsAndStubsM);
474 for (auto &GV : SrcM->globals())
475 if (!GV.isDeclaration())
476 cloneGlobalVariableDecl(*GVsAndStubsM, GV, &VMap);
477
478 // Then clone the initializers.
479 for (auto &GV : SrcM->globals())
480 if (!GV.isDeclaration())
481 moveGlobalVariableInitializer(GV, VMap, &GDMat);
482
483 // Build a resolver for the stubs module and add it to the base layer.
484 auto GVsAndStubsResolver = createLambdaResolver(
485 [&LD](const std::string &Name) {
486 if (auto Symbol = LD.findSymbol(Name, false))
341487 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
342488 Symbol.getFlags());
343 return DylibLookup->externalLookup(Name);
489 return LD.findSymbolExternally(Name);
344490 },
345 [=](const std::string &Name) -> RuntimeDyld::SymbolInfo {
346 if (auto Symbol = DylibLookup->findSymbol(LogicalModule, Name))
347 return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
348 Symbol.getFlags());
349 return nullptr;
491 [&LD](const std::string &Name) {
492 return RuntimeDyld::SymbolInfo(nullptr);
350493 });
351494
352 BaseLayerModuleSetHandleT H =
353 BaseLayer.addModuleSet(std::move(MSet),
354 make_unique(),
355 std::move(Resolver));
356 // Add this module to the logical module lookup.
357 DylibLookup->addToLogicalModule(LogicalModule, H);
358 MSI.BaseLayerModuleSetHandles.push_back(H);
359
360 return H;
495 std::vector> GVsAndStubsMSet;
496 GVsAndStubsMSet.push_back(std::move(GVsAndStubsM));
497 auto GVsAndStubsH =
498 BaseLayer.addModuleSet(std::move(GVsAndStubsMSet),
499 llvm::make_unique(),
500 std::move(GVsAndStubsResolver));
501 LD.setGVsAndStubsHandle(LMH, GVsAndStubsH);
361502 }
362503
363504 static std::string Mangle(StringRef Name, const DataLayout &DL) {
372513
373514 BaseLayerT &BaseLayer;
374515 CompileCallbackMgrT &CompileCallbackMgr;
375 ModuleSetInfoListT ModuleSetInfos;
516 LogicalDylibList LogicalDylibs;
376517 };
518
519 template
520 typename CompileOnDemandLayer::
521 UncompiledPartition&
522 CompileOnDemandLayer::LogicalDylib::
523 createUncompiledPartition(LMHandle LMH, std::shared_ptr SrcM) {
524 UncompiledPartitions.push_back(
525 llvm::make_unique(*this, LMH, std::move(SrcM)));
526 UncompiledPartitions.back()->setID(UncompiledPartitions.size() - 1);
527 return *UncompiledPartitions.back();
528 }
529
530 template
531 std::unique_ptr::
532 UncompiledPartition>
533 CompileOnDemandLayer::LogicalDylib::
534 takeUPOwnership(UncompiledPartitionID ID) {
535
536 std::swap(UncompiledPartitions[ID], UncompiledPartitions.back());
537 UncompiledPartitions[ID]->setID(ID);
538 auto UP = std::move(UncompiledPartitions.back());
539 UncompiledPartitions.pop_back();
540 return UP;
541 }
377542
378543 } // End namespace orc.
379544 } // End namespace llvm.
2020 #include "llvm/IR/IRBuilder.h"
2121 #include "llvm/IR/Mangler.h"
2222 #include "llvm/IR/Module.h"
23 #include "llvm/Transforms/Utils/ValueMapper.h"
2324 #include
2425
2526 namespace llvm {
3132 public:
3233
3334 typedef std::function CompileFtor;
34 typedef std::function UpdateFtor;
3535
3636 /// @brief Handle to a newly created compile callback. Can be used to get an
3737 /// IR constant representing the address of the trampoline, and to set
38 /// the compile and update actions for the callback.
38 /// the compile action for the callback.
3939 class CompileCallbackInfo {
4040 public:
41 CompileCallbackInfo(TargetAddress Addr, CompileFtor &Compile,
42 UpdateFtor &Update)
43 : Addr(Addr), Compile(Compile), Update(Update) {}
41 CompileCallbackInfo(TargetAddress Addr, CompileFtor &Compile)
42 : Addr(Addr), Compile(Compile) {}
4443
4544 TargetAddress getAddress() const { return Addr; }
4645 void setCompileAction(CompileFtor Compile) {
4746 this->Compile = std::move(Compile);
4847 }
49 void setUpdateAction(UpdateFtor Update) {
50 this->Update = std::move(Update);
51 }
5248 private:
5349 TargetAddress Addr;
5450 CompileFtor &Compile;
55 UpdateFtor &Update;
5651 };
5752
5853 /// @brief Construct a JITCompileCallbackManagerBase.
7065
7166 /// @brief Execute the callback for the given trampoline id. Called by the JIT
7267 /// to compile functions on demand.
73 TargetAddress executeCompileCallback(TargetAddress TrampolineID) {
74 TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID);
68 TargetAddress executeCompileCallback(TargetAddress TrampolineAddr) {
69 auto I = ActiveTrampolines.find(TrampolineAddr);
7570 // FIXME: Also raise an error in the Orc error-handler when we finally have
7671 // one.
7772 if (I == ActiveTrampolines.end())
8378 // Moving the trampoline ID back to the available list first means there's at
8479 // least one available trampoline if the compile action triggers a request for
8580 // a new one.
86 AvailableTrampolines.push_back(I->first);
87 auto CallbackHandler = std::move(I->second);
81 auto Compile = std::move(I->second);
8882 ActiveTrampolines.erase(I);
89
90 if (auto Addr = CallbackHandler.Compile()) {
91 CallbackHandler.Update(Addr);
83 AvailableTrampolines.push_back(TrampolineAddr);
84
85 if (auto Addr = Compile())
9286 return Addr;
93 }
87
9488 return ErrorHandlerAddress;
9589 }
9690
97 /// @brief Get/create a compile callback with the given signature.
91 /// @brief Reserve a compile callback.
9892 virtual CompileCallbackInfo getCompileCallback(LLVMContext &Context) = 0;
9993
94 /// @brief Get a CompileCallbackInfo for an existing callback.
95 CompileCallbackInfo getCompileCallbackInfo(TargetAddress TrampolineAddr) {
96 auto I = ActiveTrampolines.find(TrampolineAddr);
97 assert(I != ActiveTrampolines.end() && "Not an active trampoline.");
98 return CompileCallbackInfo(I->first, I->second);
99 }
100
101 /// @brief Release a compile callback.
102 ///
103 /// Note: Callbacks are auto-released after they execute. This method should
104 /// only be called to manually release a callback that is not going to
105 /// execute.
106 void releaseCompileCallback(TargetAddress TrampolineAddr) {
107 auto I = ActiveTrampolines.find(TrampolineAddr);
108 assert(I != ActiveTrampolines.end() && "Not an active trampoline.");
109 ActiveTrampolines.erase(I);
110 AvailableTrampolines.push_back(TrampolineAddr);
111 }
112
100113 protected:
101
102 struct CallbackHandler {
103 CompileFtor Compile;
104 UpdateFtor Update;
105 };
106
107114 TargetAddress ErrorHandlerAddress;
108115 unsigned NumTrampolinesPerBlock;
109116
110 typedef std::mapallbackHandler> TrampolineMapT;
117 typedef std::mapompileFtor> TrampolineMapT;
111118 TrampolineMapT ActiveTrampolines;
112119 std::vector AvailableTrampolines;
113120 };
139146 /// @brief Get/create a compile callback with the given signature.
140147 CompileCallbackInfo getCompileCallback(LLVMContext &Context) final {
141148 TargetAddress TrampolineAddr = getAvailableTrampolineAddr(Context);
142 auto &CallbackHandler =
143 this->ActiveTrampolines[TrampolineAddr];
144
145 return CompileCallbackInfo(TrampolineAddr, CallbackHandler.Compile,
146 CallbackHandler.Update);
149 auto &Compile = this->ActiveTrampolines[TrampolineAddr];
150 return CompileCallbackInfo(TrampolineAddr, Compile);
147151 }
148152
149153 private:
217221 TargetAddress ResolverBlockAddr;
218222 };
219223
220 /// @brief Get an update functor that updates the value of a named function
221 /// pointer.
222 template
223 JITCompileCallbackManagerBase::UpdateFtor
224 getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H,
225 std::string Name) {
226 // FIXME: Move-capture Name once we can use C++14.
227 return [=,&JIT](TargetAddress Addr) {
228 auto FPSym = JIT.findSymbolIn(H, Name, true);
229 assert(FPSym && "Cannot find function pointer to update.");
230 void *FPAddr = reinterpret_cast(
231 static_cast(FPSym.getAddress()));
232 memcpy(FPAddr, &Addr, sizeof(uintptr_t));
233 };
234 }
235
236224 /// @brief Build a function pointer of FunctionType with the given constant
237225 /// address.
238226 ///
249237 /// indirect call using the given function pointer.
250238 void makeStub(Function &F, GlobalVariable &ImplPointer);
251239
252 typedef std::map> ModulePartitionMap;
253
254 /// @brief Extract subsections of a Module into the given Module according to
255 /// the given ModulePartitionMap.
256 void partition(Module &M, const ModulePartitionMap &PMap);
257
258 /// @brief Struct for trivial "complete" partitioning of a module.
259 class FullyPartitionedModule {
260 public:
261 std::unique_ptr GlobalVars;
262 std::unique_ptr Commons;
263 std::vector> Functions;
264
265 FullyPartitionedModule() = default;
266 FullyPartitionedModule(FullyPartitionedModule &&S)
267 : GlobalVars(std::move(S.GlobalVars)), Commons(std::move(S.Commons)),
268 Functions(std::move(S.Functions)) {}
269 };
270
271 /// @brief Extract every function in M into a separate module.
272 FullyPartitionedModule fullyPartition(Module &M);
240 /// @brief Raise linkage types and rename as necessary to ensure that all
241 /// symbols are accessible for other modules.
242 ///
243 /// This should be called before partitioning a module to ensure that the
244 /// partitions retain access to each other's symbols.
245 void makeAllSymbolsExternallyAccessible(Module &M);
246
247 /// @brief Clone a function declaration into a new module.
248 ///
249 /// This function can be used as the first step towards creating a callback
250 /// stub (see makeStub), or moving a function body (see moveFunctionBody).
251 ///
252 /// If the VMap argument is non-null, a mapping will be added between F and
253 /// the new declaration, and between each of F's arguments and the new
254 /// declaration's arguments. This map can then be passed in to moveFunction to
255 /// move the function body if required. Note: When moving functions between
256 /// modules with these utilities, all decls should be cloned (and added to a
257 /// single VMap) before any bodies are moved. This will ensure that references
258 /// between functions all refer to the versions in the new module.
259 Function* cloneFunctionDecl(Module &Dst, const Function &F,
260 ValueToValueMapTy *VMap = nullptr);
261
262 /// @brief Move the body of function 'F' to a cloned function declaration in a
263 /// different module (See related cloneFunctionDecl).
264 ///
265 /// If the target function declaration is not supplied via the NewF parameter
266 /// then it will be looked up via the VMap.
267 ///
268 /// This will delete the body of function 'F' from its original parent module,
269 /// but leave its declaration.
270 void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
271 ValueMaterializer *Materializer = nullptr,
272 Function *NewF = nullptr);
273
274 /// @brief Clone a global variable declaration into a new module.
275 GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
276 ValueToValueMapTy *VMap = nullptr);
277
278 /// @brief Move global variable GV from its parent module to cloned global
279 /// declaration in a different module.
280 ///
281 /// If the target global declaration is not supplied via the NewGV parameter
282 /// then it will be looked up via the VMap.
283 ///
284 /// This will delete the initializer of GV from its original parent module,
285 /// but leave its declaration.
286 void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
287 ValueToValueMapTy &VMap,
288 ValueMaterializer *Materializer = nullptr,
289 GlobalVariable *NewGV = nullptr);
273290
274291 } // End namespace orc.
275292 } // End namespace llvm.
0 add_llvm_library(LLVMOrcJIT
1 CloneSubModule.cpp
21 ExecutionUtils.cpp
32 IndirectionUtils.cpp
43 OrcMCJITReplacement.cpp
+0
-106
lib/ExecutionEngine/Orc/CloneSubModule.cpp less more
None #include "llvm/ExecutionEngine/Orc/CloneSubModule.h"
1 #include "llvm/IR/Function.h"
2 #include "llvm/IR/GlobalVariable.h"
3 #include "llvm/IR/Module.h"
4 #include "llvm/Transforms/Utils/Cloning.h"
5
6 namespace llvm {
7 namespace orc {
8
9 void copyGVInitializer(GlobalVariable &New, const GlobalVariable &Orig,
10 ValueToValueMapTy &VMap) {
11 if (Orig.hasInitializer())
12 New.setInitializer(MapValue(Orig.getInitializer(), VMap));
13 }
14
15 void copyFunctionBody(Function &New, const Function &Orig,
16 ValueToValueMapTy &VMap) {
17 if (!Orig.isDeclaration()) {
18 Function::arg_iterator DestI = New.arg_begin();
19 for (Function::const_arg_iterator J = Orig.arg_begin(); J != Orig.arg_end();
20 ++J) {
21 DestI->setName(J->getName());
22 VMap[J] = DestI++;
23 }
24
25 SmallVector Returns; // Ignore returns cloned.
26 CloneFunctionInto(&New, &Orig, VMap, /*ModuleLevelChanges=*/true, Returns);
27 }
28 }
29
30 void CloneSubModule(llvm::Module &Dst, const Module &Src,
31 HandleGlobalVariableFtor HandleGlobalVariable,
32 HandleFunctionFtor HandleFunction, bool CloneInlineAsm) {
33
34 ValueToValueMapTy VMap;
35
36 if (CloneInlineAsm)
37 Dst.appendModuleInlineAsm(Src.getModuleInlineAsm());
38
39 // Copy global variables (but not initializers, yet).
40 for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end();
41 I != E; ++I) {
42 GlobalVariable *GV = new GlobalVariable(
43 Dst, I->getType()->getElementType(), I->isConstant(), I->getLinkage(),
44 (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr,
45 I->getThreadLocalMode(), I->getType()->getAddressSpace());
46 GV->copyAttributesFrom(I);
47 VMap[I] = GV;
48 }
49
50 // Loop over the functions in the module, making external functions as before
51 for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) {
52 Function *NF =
53 Function::Create(cast(I->getType()->getElementType()),
54 I->getLinkage(), I->getName(), &Dst);
55 NF->copyAttributesFrom(I);
56 VMap[I] = NF;
57 }
58
59 // Loop over the aliases in the module
60 for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end();
61 I != E; ++I) {
62 auto *PTy = cast(I->getType());
63 auto *GA = GlobalAlias::create(PTy, I->getLinkage(), I->getName(), &Dst);
64 GA->copyAttributesFrom(I);
65 VMap[I] = GA;
66 }
67
68 // Now that all of the things that global variable initializer can refer to
69 // have been created, loop through and copy the global variable referrers
70 // over... We also set the attributes on the global now.
71 for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end();
72 I != E; ++I) {
73 GlobalVariable &GV = *cast(VMap[I]);
74 HandleGlobalVariable(GV, *I, VMap);
75 }
76
77 // Similarly, copy over function bodies now...
78 //
79 for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) {
80 Function &F = *cast(VMap[I]);
81 HandleFunction(F, *I, VMap);
82 }
83
84 // And aliases
85 for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end();
86 I != E; ++I) {
87 GlobalAlias *GA = cast(VMap[I]);
88 if (const Constant *C = I->getAliasee())
89 GA->setAliasee(MapValue(C, VMap));
90 }
91
92 // And named metadata....
93 for (Module::const_named_metadata_iterator I = Src.named_metadata_begin(),
94 E = Src.named_metadata_end();
95 I != E; ++I) {
96 const NamedMDNode &NMD = *I;
97 NamedMDNode *NewNMD = Dst.getOrInsertNamedMetadata(NMD.getName());
98 for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
99 NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap));
100 }
101
102 }
103
104 } // End namespace orc.
105 } // End namespace llvm.
88
99 #include "llvm/ADT/STLExtras.h"
1010 #include "llvm/ADT/Triple.h"
11 #include "llvm/ExecutionEngine/Orc/CloneSubModule.h"
1211 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
1312 #include "llvm/IR/CallSite.h"
1413 #include "llvm/IR/IRBuilder.h"
14 #include "llvm/Transforms/Utils/Cloning.h"
1515 #include
1616 #include
1717
3131 const Twine &Name, Constant *Initializer) {
3232 if (!Initializer)
3333 Initializer = Constant::getNullValue(&PT);
34 return new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
35 Initializer, Name, nullptr,
36 GlobalValue::NotThreadLocal, 0, true);
34 auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
35 Initializer, Name, nullptr,
36 GlobalValue::NotThreadLocal, 0, true);
37 IP->setVisibility(GlobalValue::HiddenVisibility);
38 return IP;
3739 }
3840
3941 void makeStub(Function &F, GlobalVariable &ImplPointer) {
4951 CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
5052 Call->setTailCall();
5153 Call->setAttributes(F.getAttributes());
52 Builder.CreateRet(Call);
54 if (F.getReturnType()->isVoidTy())
55 Builder.CreateRetVoid();
56 else
57 Builder.CreateRet(Call);
5358 }
5459
5560 // Utility class for renaming global values and functions during partitioning.
8388 DenseMap Names;
8489 };
8590
86 void partition(Module &M, const ModulePartitionMap &PMap) {
91 static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
92 if (V.hasLocalLinkage()) {
93 if (R.needsRenaming(V))
94 V.setName(R.getRename(V));
95 V.setLinkage(GlobalValue::ExternalLinkage);
96 V.setVisibility(GlobalValue::HiddenVisibility);
97 }
98 V.setUnnamedAddr(false);
99 assert(!R.needsRenaming(V) && "Invalid global name.");
100 }
87101
102 void makeAllSymbolsExternallyAccessible(Module &M) {
88103 GlobalRenamer Renamer;
89104
90 for (auto &KVPair : PMap) {
105 for (auto &F : M)
106 raiseVisibilityOnValue(F, Renamer);
91107
92 auto ExtractGlobalVars =
93 [&](GlobalVariable &New, const GlobalVariable &Orig,
94 ValueToValueMapTy &VMap) {
95 if (KVPair.second.count(&Orig)) {
96 copyGVInitializer(New, Orig, VMap);
97 }
98 if (New.hasLocalLinkage()) {
99 if (Renamer.needsRenaming(New))
100 New.setName(Renamer.getRename(Orig));
101 New.setLinkage(GlobalValue::ExternalLinkage);
102 New.setVisibility(GlobalValue::HiddenVisibility);
103 }
104 assert(!Renamer.needsRenaming(New) && "Invalid global name.");
105 };
106
107 auto ExtractFunctions =
108 [&](Function &New, const Function &Orig, ValueToValueMapTy &VMap) {
109 if (KVPair.second.count(&Orig))
110 copyFunctionBody(New, Orig, VMap);
111 if (New.hasLocalLinkage()) {
112 if (Renamer.needsRenaming(New))
113 New.setName(Renamer.getRename(Orig));
114 New.setLinkage(GlobalValue::ExternalLinkage);
115 New.setVisibility(GlobalValue::HiddenVisibility);
116 }
117 assert(!Renamer.needsRenaming(New) && "Invalid function name.");
118 };
119
120 CloneSubModule(*KVPair.first, M, ExtractGlobalVars, ExtractFunctions,
121 false);
122 }
108 for (auto &GV : M.globals())
109 raiseVisibilityOnValue(GV, Renamer);
123110 }
124111
125 FullyPartitionedModule fullyPartition(Module &M) {
126 FullyPartitionedModule MP;
112 Function* cloneFunctionDecl(Module &Dst, const Function &F,
113 ValueToValueMapTy *VMap) {
114 assert(F.getParent() != &Dst && "Can't copy decl over existing function.");
115 Function *NewF =
116 Function::Create(cast(F.getType()->getElementType()),
117 F.getLinkage(), F.getName(), &Dst);
118 NewF->copyAttributesFrom(&F);
127119
128 ModulePartitionMap PMap;
129
130 for (auto &F : M) {
131
132 if (F.isDeclaration())
133 continue;
134
135 std::string NewModuleName = (M.getName() + "." + F.getName()).str();
136 MP.Functions.push_back(
137 llvm::make_unique(NewModuleName, M.getContext()));
138 MP.Functions.back()->setDataLayout(M.getDataLayout());
139 PMap[MP.Functions.back().get()].insert(&F);
120 if (VMap) {
121 (*VMap)[&F] = NewF;
122 auto NewArgI = NewF->arg_begin();
123 for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
124 ++ArgI, ++NewArgI)
125 (*VMap)[ArgI] = NewArgI;
140126 }
141127
142 MP.GlobalVars =
143 llvm::make_unique((M.getName() + ".globals_and_stubs").str(),
144 M.getContext());
145 MP.GlobalVars->setDataLayout(M.getDataLayout());
128 return NewF;
129 }
146130
147 MP.Commons =
148 llvm::make_unique((M.getName() + ".commons").str(), M.getContext());
149 MP.Commons->setDataLayout(M.getDataLayout());
131 void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
132 ValueMaterializer *Materializer,
133 Function *NewF) {
134 assert(!OrigF.isDeclaration() && "Nothing to move");
135 if (!NewF)
136 NewF = cast(VMap[&OrigF]);
137 else
138 assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
139 assert(NewF && "Function mapping missing from VMap.");
140 assert(NewF->getParent() != OrigF.getParent() &&
141 "moveFunctionBody should only be used to move bodies between "
142 "modules.");
150143
151 // Make sure there's at least an empty set for the stubs map or we'll fail
152 // to clone anything for it (including the decls).
153 PMap[MP.GlobalVars.get()] = ModulePartitionMap::mapped_type();
154 for (auto &GV : M.globals())
155 if (GV.getLinkage() == GlobalValue::CommonLinkage)
156 PMap[MP.Commons.get()].insert(&GV);
157 else
158 PMap[MP.GlobalVars.get()].insert(&GV);
144 SmallVector Returns; // Ignore returns cloned.
145 CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
146 "", nullptr, nullptr, Materializer);
147 OrigF.deleteBody();
148 }
159149
160 partition(M, PMap);
150 GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
151 ValueToValueMapTy *VMap) {
152 assert(GV.getParent() != &Dst && "Can't copy decl over existing global var.");
153 GlobalVariable *NewGV = new GlobalVariable(
154 Dst, GV.getType()->getElementType(), GV.isConstant(),
155 GV.getLinkage(), nullptr, GV.getName(), nullptr,
156 GV.getThreadLocalMode(), GV.getType()->getAddressSpace());
157 NewGV->copyAttributesFrom(&GV);
158 if (VMap)
159 (*VMap)[&GV] = NewGV;
160 return NewGV;
161 }
161162
162 return MP;
163 void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
164 ValueToValueMapTy &VMap,
165 ValueMaterializer *Materializer,
166 GlobalVariable *NewGV) {
167 assert(OrigGV.hasInitializer() && "Nothing to move");
168 if (!NewGV)
169 NewGV = cast(VMap[&OrigGV]);
170 else
171 assert(VMap[&OrigGV] == NewGV &&
172 "Incorrect global variable mapping in VMap.");
173 assert(NewGV->getParent() != OrigGV.getParent() &&
174 "moveGlobalVariable should only be used to move initializers between "
175 "modules");
176
177 NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
178 nullptr, Materializer));
163179 }
164180
165181 } // End namespace orc.
0 ; RUN: lli -jit-kind=orc-lazy -orc-lazy-debug=funcs-to-stdout %s | FileCheck %s
11 ;
22 ; CHECK: Hello
3 ; CHECK: [ {{.*}}main$orc_body ]
3 ; CHECK: [ {{.*}}main ]
44 ; CHECK: Goodbye
55
66 %class.Foo = type { i8 }
2020 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
2121 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
2222 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
23 #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
2423 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
2524 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
2625 #include "llvm/IR/LLVMContext.h"
3635 typedef std::function(std::unique_ptr)>
3736 TransformFtor;
3837 typedef orc::IRTransformLayer IRDumpLayerT;
39 typedef orc::LazyEmittingLayer LazyEmitLayerT;
40 typedef orc::CompileOnDemandLayer
41 CompileCallbackMgr> CODLayerT;
38 typedef orc::CompileOnDemandLayer CompileCallbackMgr> CODLayerT;
4239 typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
4340
4441 typedef std::function<
5653 ObjectLayer(),
5754 CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
5855 IRDumpLayer(CompileLayer, createDebugDumper()),
59 LazyEmitLayer(IRDumpLayer),
6056 CCMgr(BuildCallbackMgr(IRDumpLayer, CCMgrMemMgr, Context)),
61 CODLayer(LazyEmitLayer, *CCMgr),
57 CODLayer(IRDumpLayer, *CCMgr),
6258 CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
6359
6460 ~OrcLazyJIT() {
153149 ObjLayerT ObjectLayer;
154150 CompileLayerT CompileLayer;
155151 IRDumpLayerT IRDumpLayer;
156 LazyEmitLayerT LazyEmitLayer;
157152 std::unique_ptr CCMgr;
158153 CODLayerT CODLayer;
159154