blob: 8bd21a0e3dd6786cb3e87992d9e6aa5dc97b1752 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- CompileOnDemandLayer.h - Compile each function on demand -*- 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// JIT layer for breaking up modules and inserting callbacks to allow
11// individual functions to be compiled on demand.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
16#define LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H
17
18#include "llvm/ADT/APInt.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/ExecutionEngine/JITSymbol.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010023#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
24#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010025#include "llvm/ExecutionEngine/Orc/Layer.h"
26#include "llvm/ExecutionEngine/Orc/Legacy.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010027#include "llvm/ExecutionEngine/Orc/OrcError.h"
28#include "llvm/ExecutionEngine/RuntimeDyld.h"
29#include "llvm/IR/Attributes.h"
30#include "llvm/IR/Constant.h"
31#include "llvm/IR/Constants.h"
32#include "llvm/IR/DataLayout.h"
33#include "llvm/IR/Function.h"
34#include "llvm/IR/GlobalAlias.h"
35#include "llvm/IR/GlobalValue.h"
36#include "llvm/IR/GlobalVariable.h"
37#include "llvm/IR/Instruction.h"
38#include "llvm/IR/Mangler.h"
39#include "llvm/IR/Module.h"
40#include "llvm/IR/Type.h"
41#include "llvm/Support/Casting.h"
42#include "llvm/Support/raw_ostream.h"
43#include "llvm/Transforms/Utils/ValueMapper.h"
44#include <algorithm>
45#include <cassert>
46#include <functional>
47#include <iterator>
48#include <list>
49#include <memory>
50#include <set>
51#include <string>
52#include <utility>
53#include <vector>
54
55namespace llvm {
56
57class Value;
58
59namespace orc {
60
Andrew Scullcdfcccc2018-10-05 20:58:37 +010061class ExtractingIRMaterializationUnit;
62
63class CompileOnDemandLayer2 : public IRLayer {
64 friend class ExtractingIRMaterializationUnit;
65
66public:
67 /// Builder for IndirectStubsManagers.
68 using IndirectStubsManagerBuilder =
69 std::function<std::unique_ptr<IndirectStubsManager>()>;
70
71 using GetAvailableContextFunction = std::function<LLVMContext &()>;
72
73 CompileOnDemandLayer2(ExecutionSession &ES, IRLayer &BaseLayer,
74 JITCompileCallbackManager &CCMgr,
75 IndirectStubsManagerBuilder BuildIndirectStubsManager,
76 GetAvailableContextFunction GetAvailableContext);
77
78 Error add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) override;
79
80 void emit(MaterializationResponsibility R, VModuleKey K,
81 std::unique_ptr<Module> M) override;
82
83private:
84 using StubManagersMap =
85 std::map<const VSO *, std::unique_ptr<IndirectStubsManager>>;
86
87 IndirectStubsManager &getStubsManager(const VSO &V);
88
89 void emitExtractedFunctionsModule(MaterializationResponsibility R,
90 std::unique_ptr<Module> M);
91
92 mutable std::mutex CODLayerMutex;
93
94 IRLayer &BaseLayer;
95 JITCompileCallbackManager &CCMgr;
96 IndirectStubsManagerBuilder BuildIndirectStubsManager;
97 StubManagersMap StubsMgrs;
98 GetAvailableContextFunction GetAvailableContext;
99};
100
101/// Compile-on-demand layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100102///
103/// When a module is added to this layer a stub is created for each of its
104/// function definitions. The stubs and other global values are immediately
105/// added to the layer below. When a stub is called it triggers the extraction
106/// of the function body from the original module. The extracted body is then
107/// compiled and executed.
108template <typename BaseLayerT,
109 typename CompileCallbackMgrT = JITCompileCallbackManager,
110 typename IndirectStubsMgrT = IndirectStubsManager>
111class CompileOnDemandLayer {
112private:
113 template <typename MaterializerFtor>
114 class LambdaMaterializer final : public ValueMaterializer {
115 public:
116 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
117
118 Value *materialize(Value *V) final { return M(V); }
119
120 private:
121 MaterializerFtor M;
122 };
123
124 template <typename MaterializerFtor>
125 LambdaMaterializer<MaterializerFtor>
126 createLambdaMaterializer(MaterializerFtor M) {
127 return LambdaMaterializer<MaterializerFtor>(std::move(M));
128 }
129
130 // Provide type-erasure for the Modules and MemoryManagers.
131 template <typename ResourceT>
132 class ResourceOwner {
133 public:
134 ResourceOwner() = default;
135 ResourceOwner(const ResourceOwner &) = delete;
136 ResourceOwner &operator=(const ResourceOwner &) = delete;
137 virtual ~ResourceOwner() = default;
138
139 virtual ResourceT& getResource() const = 0;
140 };
141
142 template <typename ResourceT, typename ResourcePtrT>
143 class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
144 public:
145 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
146 : ResourcePtr(std::move(ResourcePtr)) {}
147
148 ResourceT& getResource() const override { return *ResourcePtr; }
149
150 private:
151 ResourcePtrT ResourcePtr;
152 };
153
154 template <typename ResourceT, typename ResourcePtrT>
155 std::unique_ptr<ResourceOwner<ResourceT>>
156 wrapOwnership(ResourcePtrT ResourcePtr) {
157 using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
158 return llvm::make_unique<RO>(std::move(ResourcePtr));
159 }
160
161 class StaticGlobalRenamer {
162 public:
163 StaticGlobalRenamer() = default;
164 StaticGlobalRenamer(StaticGlobalRenamer &&) = default;
165 StaticGlobalRenamer &operator=(StaticGlobalRenamer &&) = default;
166
167 void rename(Module &M) {
168 for (auto &F : M)
169 if (F.hasLocalLinkage())
170 F.setName("$static." + Twine(NextId++));
171 for (auto &G : M.globals())
172 if (G.hasLocalLinkage())
173 G.setName("$static." + Twine(NextId++));
174 }
175
176 private:
177 unsigned NextId = 0;
178 };
179
180 struct LogicalDylib {
181 struct SourceModuleEntry {
182 std::unique_ptr<Module> SourceMod;
183 std::set<Function*> StubsToClone;
184 };
185
186 using SourceModulesList = std::vector<SourceModuleEntry>;
187 using SourceModuleHandle = typename SourceModulesList::size_type;
188
189 LogicalDylib() = default;
190
191 LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
192 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
193 : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
194 StubsMgr(std::move(StubsMgr)) {}
195
196 SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
197 SourceModuleHandle H = SourceModules.size();
198 SourceModules.push_back(SourceModuleEntry());
199 SourceModules.back().SourceMod = std::move(M);
200 return H;
201 }
202
203 Module& getSourceModule(SourceModuleHandle H) {
204 return *SourceModules[H].SourceMod;
205 }
206
207 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
208 return SourceModules[H].StubsToClone;
209 }
210
211 JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
212 bool ExportedSymbolsOnly) {
213 if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
214 return Sym;
215 for (auto BLK : BaseLayerVModuleKeys)
216 if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
217 return Sym;
218 else if (auto Err = Sym.takeError())
219 return std::move(Err);
220 return nullptr;
221 }
222
223 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
224 for (auto &BLK : BaseLayerVModuleKeys)
225 if (auto Err = BaseLayer.removeModule(BLK))
226 return Err;
227 return Error::success();
228 }
229
230 VModuleKey K;
231 std::shared_ptr<SymbolResolver> BackingResolver;
232 std::unique_ptr<IndirectStubsMgrT> StubsMgr;
233 StaticGlobalRenamer StaticRenamer;
234 SourceModulesList SourceModules;
235 std::vector<VModuleKey> BaseLayerVModuleKeys;
236 };
237
238public:
239
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100240 /// Module partitioning functor.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100241 using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
242
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100243 /// Builder for IndirectStubsManagers.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100244 using IndirectStubsManagerBuilderT =
245 std::function<std::unique_ptr<IndirectStubsMgrT>()>;
246
247 using SymbolResolverGetter =
248 std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
249
250 using SymbolResolverSetter =
251 std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
252
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100253 /// Construct a compile-on-demand layer instance.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100254 CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
255 SymbolResolverGetter GetSymbolResolver,
256 SymbolResolverSetter SetSymbolResolver,
257 PartitioningFtor Partition,
258 CompileCallbackMgrT &CallbackMgr,
259 IndirectStubsManagerBuilderT CreateIndirectStubsManager,
260 bool CloneStubsIntoPartitions = true)
261 : ES(ES), BaseLayer(BaseLayer),
262 GetSymbolResolver(std::move(GetSymbolResolver)),
263 SetSymbolResolver(std::move(SetSymbolResolver)),
264 Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
265 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
266 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
267
268 ~CompileOnDemandLayer() {
269 // FIXME: Report error on log.
270 while (!LogicalDylibs.empty())
271 consumeError(removeModule(LogicalDylibs.begin()->first));
272 }
273
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100274 /// Add a module to the compile-on-demand layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100275 Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
276
277 assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
278 auto I = LogicalDylibs.insert(
279 LogicalDylibs.end(),
280 std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
281 CreateIndirectStubsManager())));
282
283 return addLogicalModule(I->second, std::move(M));
284 }
285
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100286 /// Add extra modules to an existing logical module.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100287 Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
288 return addLogicalModule(LogicalDylibs[K], std::move(M));
289 }
290
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100291 /// Remove the module represented by the given key.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100292 ///
293 /// This will remove all modules in the layers below that were derived from
294 /// the module represented by K.
295 Error removeModule(VModuleKey K) {
296 auto I = LogicalDylibs.find(K);
297 assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
298 auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
299 LogicalDylibs.erase(I);
300 return Err;
301 }
302
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100303 /// Search for the given named symbol.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100304 /// @param Name The name of the symbol to search for.
305 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
306 /// @return A handle for the given named symbol, if it exists.
307 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
308 for (auto &KV : LogicalDylibs) {
309 if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
310 return Sym;
311 if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
312 return Sym;
313 else if (auto Err = Sym.takeError())
314 return std::move(Err);
315 }
316 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
317 }
318
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100319 /// Get the address of a symbol provided by this layer, or some layer
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100320 /// below this one.
321 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
322 bool ExportedSymbolsOnly) {
323 assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
324 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
325 }
326
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100327 /// Update the stub for the given function to point at FnBodyAddr.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100328 /// This can be used to support re-optimization.
329 /// @return true if the function exists and the stub is updated, false
330 /// otherwise.
331 //
332 // FIXME: We should track and free associated resources (unused compile
333 // callbacks, uncompiled IR, and no-longer-needed/reachable function
334 // implementations).
335 Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
336 //Find out which logical dylib contains our symbol
337 auto LDI = LogicalDylibs.begin();
338 for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
339 if (auto LMResources =
340 LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
341 Module &SrcM = LMResources->SourceModule->getResource();
342 std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
343 if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
344 FnBodyAddr))
345 return Err;
346 return Error::success();
347 }
348 }
349 return make_error<JITSymbolNotFound>(FuncName);
350 }
351
352private:
353 Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
354
355 // Rename all static functions / globals to $static.X :
356 // This will unique the names across all modules in the logical dylib,
357 // simplifying symbol lookup.
358 LD.StaticRenamer.rename(*SrcMPtr);
359
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100360 // Bump the linkage and rename any anonymous/private members in SrcM to
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100361 // ensure that everything will resolve properly after we partition SrcM.
362 makeAllSymbolsExternallyAccessible(*SrcMPtr);
363
364 // Create a logical module handle for SrcM within the logical dylib.
365 Module &SrcM = *SrcMPtr;
366 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
367
368 // Create stub functions.
369 const DataLayout &DL = SrcM.getDataLayout();
370 {
371 typename IndirectStubsMgrT::StubInitsMap StubInits;
372 for (auto &F : SrcM) {
373 // Skip declarations.
374 if (F.isDeclaration())
375 continue;
376
377 // Skip weak functions for which we already have definitions.
378 auto MangledName = mangle(F.getName(), DL);
379 if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
380 if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
381 continue;
382 else if (auto Err = Sym.takeError())
383 return std::move(Err);
384 }
385
386 // Record all functions defined by this module.
387 if (CloneStubsIntoPartitions)
388 LD.getStubsToClone(LMId).insert(&F);
389
390 // Create a callback, associate it with the stub for the function,
391 // and set the compile action to compile the partition containing the
392 // function.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100393 auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
394 if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
395 return *FnImplAddrOrErr;
396 else {
397 // FIXME: Report error, return to 'abort' or something similar.
398 consumeError(FnImplAddrOrErr.takeError());
399 return 0;
400 }
401 };
402 if (auto CCAddr =
403 CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100404 StubInits[MangledName] =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100405 std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
406 else
407 return CCAddr.takeError();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100408 }
409
410 if (auto Err = LD.StubsMgr->createStubs(StubInits))
411 return Err;
412 }
413
414 // If this module doesn't contain any globals, aliases, or module flags then
415 // we can bail out early and avoid the overhead of creating and managing an
416 // empty globals module.
417 if (SrcM.global_empty() && SrcM.alias_empty() &&
418 !SrcM.getModuleFlagsMetadata())
419 return Error::success();
420
421 // Create the GlobalValues module.
422 auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
423 SrcM.getContext());
424 GVsM->setDataLayout(DL);
425
426 ValueToValueMapTy VMap;
427
428 // Clone global variable decls.
429 for (auto &GV : SrcM.globals())
430 if (!GV.isDeclaration() && !VMap.count(&GV))
431 cloneGlobalVariableDecl(*GVsM, GV, &VMap);
432
433 // And the aliases.
434 for (auto &A : SrcM.aliases())
435 if (!VMap.count(&A))
436 cloneGlobalAliasDecl(*GVsM, A, VMap);
437
438 // Clone the module flags.
439 cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
440
441 // Now we need to clone the GV and alias initializers.
442
443 // Initializers may refer to functions declared (but not defined) in this
444 // module. Build a materializer to clone decls on demand.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100445 auto Materializer = createLambdaMaterializer(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100446 [&LD, &GVsM](Value *V) -> Value* {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100447 if (auto *F = dyn_cast<Function>(V)) {
448 // Decls in the original module just get cloned.
449 if (F->isDeclaration())
450 return cloneFunctionDecl(*GVsM, *F);
451
452 // Definitions in the original module (which we have emitted stubs
453 // for at this point) get turned into a constant alias to the stub
454 // instead.
455 const DataLayout &DL = GVsM->getDataLayout();
456 std::string FName = mangle(F->getName(), DL);
457 unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100458 JITTargetAddress StubAddr =
459 LD.StubsMgr->findStub(FName, false).getAddress();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100460
461 ConstantInt *StubAddrCI =
462 ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
463 Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
464 StubAddrCI, F->getType());
465 return GlobalAlias::create(F->getFunctionType(),
466 F->getType()->getAddressSpace(),
467 F->getLinkage(), F->getName(),
468 Init, GVsM.get());
469 }
470 // else....
471 return nullptr;
472 });
473
474 // Clone the global variable initializers.
475 for (auto &GV : SrcM.globals())
476 if (!GV.isDeclaration())
477 moveGlobalVariableInitializer(GV, VMap, &Materializer);
478
479 // Clone the global alias initializers.
480 for (auto &A : SrcM.aliases()) {
481 auto *NewA = cast<GlobalAlias>(VMap[&A]);
482 assert(NewA && "Alias not cloned?");
483 Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
484 &Materializer);
485 NewA->setAliasee(cast<Constant>(Init));
486 }
487
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100488 // Build a resolver for the globals module and add it to the base layer.
489 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
490 if (auto Sym = LD.StubsMgr->findStub(Name, false))
491 return Sym;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100492
493 if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
494 return Sym;
495 else if (auto Err = Sym.takeError())
496 return std::move(Err);
497
498 return nullptr;
499 };
500
501 auto GVsResolver = createSymbolResolver(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100502 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
503 auto SymbolFlags = lookupFlagsWithLegacyFn(Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100504
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100505 if (!SymbolFlags) {
506 logAllUnhandledErrors(SymbolFlags.takeError(), errs(),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100507 "CODLayer/GVsResolver flags lookup failed: ");
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100508 return SymbolFlagsMap();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100509 }
510
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100511 if (SymbolFlags->size() == Symbols.size())
512 return *SymbolFlags;
513
514 SymbolNameSet NotFoundViaLegacyLookup;
515 for (auto &S : Symbols)
516 if (!SymbolFlags->count(S))
517 NotFoundViaLegacyLookup.insert(S);
518 auto SymbolFlags2 =
519 LD.BackingResolver->lookupFlags(NotFoundViaLegacyLookup);
520
521 for (auto &KV : SymbolFlags2)
522 (*SymbolFlags)[KV.first] = std::move(KV.second);
523
524 return *SymbolFlags;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100525 },
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100526 [this, &LD,
527 LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
528 SymbolNameSet Symbols) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100529 auto NotFoundViaLegacyLookup =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100530 lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100531 return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
532 });
533
534 SetSymbolResolver(LD.K, std::move(GVsResolver));
535
536 if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
537 return Err;
538
539 LD.BaseLayerVModuleKeys.push_back(LD.K);
540
541 return Error::success();
542 }
543
544 static std::string mangle(StringRef Name, const DataLayout &DL) {
545 std::string MangledName;
546 {
547 raw_string_ostream MangledNameStream(MangledName);
548 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
549 }
550 return MangledName;
551 }
552
553 Expected<JITTargetAddress>
554 extractAndCompile(LogicalDylib &LD,
555 typename LogicalDylib::SourceModuleHandle LMId,
556 Function &F) {
557 Module &SrcM = LD.getSourceModule(LMId);
558
559 // If F is a declaration we must already have compiled it.
560 if (F.isDeclaration())
561 return 0;
562
563 // Grab the name of the function being called here.
564 std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
565
566 JITTargetAddress CalledAddr = 0;
567 auto Part = Partition(F);
568 if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
569 auto &PartKey = *PartKeyOrErr;
570 for (auto *SubF : Part) {
571 std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
572 if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
573 if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
574 JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
575
576 // If this is the function we're calling record the address so we can
577 // return it from this function.
578 if (SubF == &F)
579 CalledAddr = FnBodyAddr;
580
581 // Update the function body pointer for the stub.
582 if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
583 return 0;
584
585 } else
586 return FnBodyAddrOrErr.takeError();
587 } else if (auto Err = FnBodySym.takeError())
588 return std::move(Err);
589 else
590 llvm_unreachable("Function not emitted for partition");
591 }
592
593 LD.BaseLayerVModuleKeys.push_back(PartKey);
594 } else
595 return PartKeyOrErr.takeError();
596
597 return CalledAddr;
598 }
599
600 template <typename PartitionT>
601 Expected<VModuleKey>
602 emitPartition(LogicalDylib &LD,
603 typename LogicalDylib::SourceModuleHandle LMId,
604 const PartitionT &Part) {
605 Module &SrcM = LD.getSourceModule(LMId);
606
607 // Create the module.
608 std::string NewName = SrcM.getName();
609 for (auto *F : Part) {
610 NewName += ".";
611 NewName += F->getName();
612 }
613
614 auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
615 M->setDataLayout(SrcM.getDataLayout());
616 ValueToValueMapTy VMap;
617
618 auto Materializer = createLambdaMaterializer([&LD, &LMId,
619 &M](Value *V) -> Value * {
620 if (auto *GV = dyn_cast<GlobalVariable>(V))
621 return cloneGlobalVariableDecl(*M, *GV);
622
623 if (auto *F = dyn_cast<Function>(V)) {
624 // Check whether we want to clone an available_externally definition.
625 if (!LD.getStubsToClone(LMId).count(F))
626 return cloneFunctionDecl(*M, *F);
627
628 // Ok - we want an inlinable stub. For that to work we need a decl
629 // for the stub pointer.
630 auto *StubPtr = createImplPointer(*F->getType(), *M,
631 F->getName() + "$stub_ptr", nullptr);
632 auto *ClonedF = cloneFunctionDecl(*M, *F);
633 makeStub(*ClonedF, *StubPtr);
634 ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
635 ClonedF->addFnAttr(Attribute::AlwaysInline);
636 return ClonedF;
637 }
638
639 if (auto *A = dyn_cast<GlobalAlias>(V)) {
640 auto *Ty = A->getValueType();
641 if (Ty->isFunctionTy())
642 return Function::Create(cast<FunctionType>(Ty),
643 GlobalValue::ExternalLinkage, A->getName(),
644 M.get());
645
646 return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
647 nullptr, A->getName(), nullptr,
648 GlobalValue::NotThreadLocal,
649 A->getType()->getAddressSpace());
650 }
651
652 return nullptr;
653 });
654
655 // Create decls in the new module.
656 for (auto *F : Part)
657 cloneFunctionDecl(*M, *F, &VMap);
658
659 // Move the function bodies.
660 for (auto *F : Part)
661 moveFunctionBody(*F, VMap, &Materializer);
662
663 auto K = ES.allocateVModule();
664
665 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
666 return LD.findSymbol(BaseLayer, Name, false);
667 };
668
669 // Create memory manager and symbol resolver.
670 auto Resolver = createSymbolResolver(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100671 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
672 auto SymbolFlags = lookupFlagsWithLegacyFn(Symbols, LegacyLookup);
673 if (!SymbolFlags) {
674 logAllUnhandledErrors(SymbolFlags.takeError(), errs(),
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100675 "CODLayer/SubResolver flags lookup failed: ");
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100676 return SymbolFlagsMap();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100677 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100678
679 if (SymbolFlags->size() == Symbols.size())
680 return *SymbolFlags;
681
682 SymbolNameSet NotFoundViaLegacyLookup;
683 for (auto &S : Symbols)
684 if (!SymbolFlags->count(S))
685 NotFoundViaLegacyLookup.insert(S);
686
687 auto SymbolFlags2 =
688 LD.BackingResolver->lookupFlags(NotFoundViaLegacyLookup);
689
690 for (auto &KV : SymbolFlags2)
691 (*SymbolFlags)[KV.first] = std::move(KV.second);
692
693 return *SymbolFlags;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100694 },
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100695 [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
696 SymbolNameSet Symbols) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100697 auto NotFoundViaLegacyLookup =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100698 lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100699 return LD.BackingResolver->lookup(Q,
700 std::move(NotFoundViaLegacyLookup));
701 });
702 SetSymbolResolver(K, std::move(Resolver));
703
704 if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
705 return std::move(Err);
706
707 return K;
708 }
709
710 ExecutionSession &ES;
711 BaseLayerT &BaseLayer;
712 SymbolResolverGetter GetSymbolResolver;
713 SymbolResolverSetter SetSymbolResolver;
714 PartitioningFtor Partition;
715 CompileCallbackMgrT &CompileCallbackMgr;
716 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
717
718 std::map<VModuleKey, LogicalDylib> LogicalDylibs;
719 bool CloneStubsIntoPartitions;
720};
721
722} // end namespace orc
723
724} // end namespace llvm
725
726#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H