blob: 2003f8e43b88ea297240cba6b4260b7018ee5824 [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"
Andrew Scull0372a572018-11-16 15:47:06 +000019#include "llvm/ADT/Optional.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010020#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/ExecutionEngine/JITSymbol.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010024#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
25#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010026#include "llvm/ExecutionEngine/Orc/Layer.h"
Andrew Scull0372a572018-11-16 15:47:06 +000027#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010028#include "llvm/ExecutionEngine/Orc/Legacy.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010029#include "llvm/ExecutionEngine/Orc/OrcError.h"
30#include "llvm/ExecutionEngine/RuntimeDyld.h"
31#include "llvm/IR/Attributes.h"
32#include "llvm/IR/Constant.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DataLayout.h"
35#include "llvm/IR/Function.h"
36#include "llvm/IR/GlobalAlias.h"
37#include "llvm/IR/GlobalValue.h"
38#include "llvm/IR/GlobalVariable.h"
39#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Mangler.h"
41#include "llvm/IR/Module.h"
42#include "llvm/IR/Type.h"
43#include "llvm/Support/Casting.h"
44#include "llvm/Support/raw_ostream.h"
45#include "llvm/Transforms/Utils/ValueMapper.h"
46#include <algorithm>
47#include <cassert>
48#include <functional>
49#include <iterator>
50#include <list>
51#include <memory>
52#include <set>
53#include <string>
54#include <utility>
55#include <vector>
56
57namespace llvm {
58
59class Value;
60
61namespace orc {
62
Andrew Scullcdfcccc2018-10-05 20:58:37 +010063class ExtractingIRMaterializationUnit;
64
65class CompileOnDemandLayer2 : public IRLayer {
Andrew Scull0372a572018-11-16 15:47:06 +000066 friend class PartitioningIRMaterializationUnit;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010067
68public:
69 /// Builder for IndirectStubsManagers.
70 using IndirectStubsManagerBuilder =
71 std::function<std::unique_ptr<IndirectStubsManager>()>;
72
Andrew Scull0372a572018-11-16 15:47:06 +000073 using GlobalValueSet = std::set<const GlobalValue *>;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074
Andrew Scull0372a572018-11-16 15:47:06 +000075 /// Partitioning function.
76 using PartitionFunction =
77 std::function<Optional<GlobalValueSet>(GlobalValueSet Requested)>;
78
79 /// Off-the-shelf partitioning which compiles all requested symbols (usually
80 /// a single function at a time).
81 static Optional<GlobalValueSet> compileRequested(GlobalValueSet Requested);
82
83 /// Off-the-shelf partitioning which compiles whole modules whenever any
84 /// symbol in them is requested.
85 static Optional<GlobalValueSet> compileWholeModule(GlobalValueSet Requested);
86
87 /// Construct a CompileOnDemandLayer2.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010088 CompileOnDemandLayer2(ExecutionSession &ES, IRLayer &BaseLayer,
Andrew Scull0372a572018-11-16 15:47:06 +000089 LazyCallThroughManager &LCTMgr,
90 IndirectStubsManagerBuilder BuildIndirectStubsManager);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010091
Andrew Scull0372a572018-11-16 15:47:06 +000092 /// Sets the partition function.
93 void setPartitionFunction(PartitionFunction Partition);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010094
Andrew Scull0372a572018-11-16 15:47:06 +000095 /// Emits the given module. This should not be called by clients: it will be
96 /// called by the JIT when a definition added via the add method is requested.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010097 void emit(MaterializationResponsibility R, VModuleKey K,
Andrew Scull0372a572018-11-16 15:47:06 +000098 ThreadSafeModule TSM) override;
Andrew Scullcdfcccc2018-10-05 20:58:37 +010099
100private:
Andrew Scull0372a572018-11-16 15:47:06 +0000101 struct PerDylibResources {
102 public:
103 PerDylibResources(JITDylib &ImplD,
104 std::unique_ptr<IndirectStubsManager> ISMgr)
105 : ImplD(ImplD), ISMgr(std::move(ISMgr)) {}
106 JITDylib &getImplDylib() { return ImplD; }
107 IndirectStubsManager &getISManager() { return *ISMgr; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100108
Andrew Scull0372a572018-11-16 15:47:06 +0000109 private:
110 JITDylib &ImplD;
111 std::unique_ptr<IndirectStubsManager> ISMgr;
112 };
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100113
Andrew Scull0372a572018-11-16 15:47:06 +0000114 using PerDylibResourcesMap = std::map<const JITDylib *, PerDylibResources>;
115
116 PerDylibResources &getPerDylibResources(JITDylib &TargetD);
117
118 void cleanUpModule(Module &M);
119
120 void expandPartition(GlobalValueSet &Partition);
121
122 void emitPartition(MaterializationResponsibility R, ThreadSafeModule TSM,
123 IRMaterializationUnit::SymbolNameToDefinitionMap Defs);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100124
125 mutable std::mutex CODLayerMutex;
126
127 IRLayer &BaseLayer;
Andrew Scull0372a572018-11-16 15:47:06 +0000128 LazyCallThroughManager &LCTMgr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100129 IndirectStubsManagerBuilder BuildIndirectStubsManager;
Andrew Scull0372a572018-11-16 15:47:06 +0000130 PerDylibResourcesMap DylibResources;
131 PartitionFunction Partition = compileRequested;
132 SymbolLinkagePromoter PromoteSymbols;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100133};
134
135/// Compile-on-demand layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100136///
137/// When a module is added to this layer a stub is created for each of its
138/// function definitions. The stubs and other global values are immediately
139/// added to the layer below. When a stub is called it triggers the extraction
140/// of the function body from the original module. The extracted body is then
141/// compiled and executed.
142template <typename BaseLayerT,
143 typename CompileCallbackMgrT = JITCompileCallbackManager,
144 typename IndirectStubsMgrT = IndirectStubsManager>
145class CompileOnDemandLayer {
146private:
147 template <typename MaterializerFtor>
148 class LambdaMaterializer final : public ValueMaterializer {
149 public:
150 LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {}
151
152 Value *materialize(Value *V) final { return M(V); }
153
154 private:
155 MaterializerFtor M;
156 };
157
158 template <typename MaterializerFtor>
159 LambdaMaterializer<MaterializerFtor>
160 createLambdaMaterializer(MaterializerFtor M) {
161 return LambdaMaterializer<MaterializerFtor>(std::move(M));
162 }
163
164 // Provide type-erasure for the Modules and MemoryManagers.
165 template <typename ResourceT>
166 class ResourceOwner {
167 public:
168 ResourceOwner() = default;
169 ResourceOwner(const ResourceOwner &) = delete;
170 ResourceOwner &operator=(const ResourceOwner &) = delete;
171 virtual ~ResourceOwner() = default;
172
173 virtual ResourceT& getResource() const = 0;
174 };
175
176 template <typename ResourceT, typename ResourcePtrT>
177 class ResourceOwnerImpl : public ResourceOwner<ResourceT> {
178 public:
179 ResourceOwnerImpl(ResourcePtrT ResourcePtr)
180 : ResourcePtr(std::move(ResourcePtr)) {}
181
182 ResourceT& getResource() const override { return *ResourcePtr; }
183
184 private:
185 ResourcePtrT ResourcePtr;
186 };
187
188 template <typename ResourceT, typename ResourcePtrT>
189 std::unique_ptr<ResourceOwner<ResourceT>>
190 wrapOwnership(ResourcePtrT ResourcePtr) {
191 using RO = ResourceOwnerImpl<ResourceT, ResourcePtrT>;
192 return llvm::make_unique<RO>(std::move(ResourcePtr));
193 }
194
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100195 struct LogicalDylib {
196 struct SourceModuleEntry {
197 std::unique_ptr<Module> SourceMod;
198 std::set<Function*> StubsToClone;
199 };
200
201 using SourceModulesList = std::vector<SourceModuleEntry>;
202 using SourceModuleHandle = typename SourceModulesList::size_type;
203
204 LogicalDylib() = default;
205
206 LogicalDylib(VModuleKey K, std::shared_ptr<SymbolResolver> BackingResolver,
207 std::unique_ptr<IndirectStubsMgrT> StubsMgr)
208 : K(std::move(K)), BackingResolver(std::move(BackingResolver)),
209 StubsMgr(std::move(StubsMgr)) {}
210
211 SourceModuleHandle addSourceModule(std::unique_ptr<Module> M) {
212 SourceModuleHandle H = SourceModules.size();
213 SourceModules.push_back(SourceModuleEntry());
214 SourceModules.back().SourceMod = std::move(M);
215 return H;
216 }
217
218 Module& getSourceModule(SourceModuleHandle H) {
219 return *SourceModules[H].SourceMod;
220 }
221
222 std::set<Function*>& getStubsToClone(SourceModuleHandle H) {
223 return SourceModules[H].StubsToClone;
224 }
225
226 JITSymbol findSymbol(BaseLayerT &BaseLayer, const std::string &Name,
227 bool ExportedSymbolsOnly) {
228 if (auto Sym = StubsMgr->findStub(Name, ExportedSymbolsOnly))
229 return Sym;
230 for (auto BLK : BaseLayerVModuleKeys)
231 if (auto Sym = BaseLayer.findSymbolIn(BLK, Name, ExportedSymbolsOnly))
232 return Sym;
233 else if (auto Err = Sym.takeError())
234 return std::move(Err);
235 return nullptr;
236 }
237
238 Error removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
239 for (auto &BLK : BaseLayerVModuleKeys)
240 if (auto Err = BaseLayer.removeModule(BLK))
241 return Err;
242 return Error::success();
243 }
244
245 VModuleKey K;
246 std::shared_ptr<SymbolResolver> BackingResolver;
247 std::unique_ptr<IndirectStubsMgrT> StubsMgr;
Andrew Scull0372a572018-11-16 15:47:06 +0000248 SymbolLinkagePromoter PromoteSymbols;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100249 SourceModulesList SourceModules;
250 std::vector<VModuleKey> BaseLayerVModuleKeys;
251 };
252
253public:
254
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100255 /// Module partitioning functor.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100256 using PartitioningFtor = std::function<std::set<Function*>(Function&)>;
257
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100258 /// Builder for IndirectStubsManagers.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100259 using IndirectStubsManagerBuilderT =
260 std::function<std::unique_ptr<IndirectStubsMgrT>()>;
261
262 using SymbolResolverGetter =
263 std::function<std::shared_ptr<SymbolResolver>(VModuleKey K)>;
264
265 using SymbolResolverSetter =
266 std::function<void(VModuleKey K, std::shared_ptr<SymbolResolver> R)>;
267
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100268 /// Construct a compile-on-demand layer instance.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100269 CompileOnDemandLayer(ExecutionSession &ES, BaseLayerT &BaseLayer,
270 SymbolResolverGetter GetSymbolResolver,
271 SymbolResolverSetter SetSymbolResolver,
272 PartitioningFtor Partition,
273 CompileCallbackMgrT &CallbackMgr,
274 IndirectStubsManagerBuilderT CreateIndirectStubsManager,
275 bool CloneStubsIntoPartitions = true)
276 : ES(ES), BaseLayer(BaseLayer),
277 GetSymbolResolver(std::move(GetSymbolResolver)),
278 SetSymbolResolver(std::move(SetSymbolResolver)),
279 Partition(std::move(Partition)), CompileCallbackMgr(CallbackMgr),
280 CreateIndirectStubsManager(std::move(CreateIndirectStubsManager)),
281 CloneStubsIntoPartitions(CloneStubsIntoPartitions) {}
282
283 ~CompileOnDemandLayer() {
284 // FIXME: Report error on log.
285 while (!LogicalDylibs.empty())
286 consumeError(removeModule(LogicalDylibs.begin()->first));
287 }
288
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100289 /// Add a module to the compile-on-demand layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100290 Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
291
292 assert(!LogicalDylibs.count(K) && "VModuleKey K already in use");
293 auto I = LogicalDylibs.insert(
294 LogicalDylibs.end(),
295 std::make_pair(K, LogicalDylib(K, GetSymbolResolver(K),
296 CreateIndirectStubsManager())));
297
298 return addLogicalModule(I->second, std::move(M));
299 }
300
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100301 /// Add extra modules to an existing logical module.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100302 Error addExtraModule(VModuleKey K, std::unique_ptr<Module> M) {
303 return addLogicalModule(LogicalDylibs[K], std::move(M));
304 }
305
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100306 /// Remove the module represented by the given key.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100307 ///
308 /// This will remove all modules in the layers below that were derived from
309 /// the module represented by K.
310 Error removeModule(VModuleKey K) {
311 auto I = LogicalDylibs.find(K);
312 assert(I != LogicalDylibs.end() && "VModuleKey K not valid here");
313 auto Err = I->second.removeModulesFromBaseLayer(BaseLayer);
314 LogicalDylibs.erase(I);
315 return Err;
316 }
317
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100318 /// Search for the given named symbol.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100319 /// @param Name The name of the symbol to search for.
320 /// @param ExportedSymbolsOnly If true, search only for exported symbols.
321 /// @return A handle for the given named symbol, if it exists.
322 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
323 for (auto &KV : LogicalDylibs) {
324 if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
325 return Sym;
326 if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
327 return Sym;
328 else if (auto Err = Sym.takeError())
329 return std::move(Err);
330 }
331 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
332 }
333
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100334 /// Get the address of a symbol provided by this layer, or some layer
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100335 /// below this one.
336 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
337 bool ExportedSymbolsOnly) {
338 assert(LogicalDylibs.count(K) && "VModuleKey K is not valid here");
339 return LogicalDylibs[K].findSymbol(BaseLayer, Name, ExportedSymbolsOnly);
340 }
341
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100342 /// Update the stub for the given function to point at FnBodyAddr.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100343 /// This can be used to support re-optimization.
344 /// @return true if the function exists and the stub is updated, false
345 /// otherwise.
346 //
347 // FIXME: We should track and free associated resources (unused compile
348 // callbacks, uncompiled IR, and no-longer-needed/reachable function
349 // implementations).
350 Error updatePointer(std::string FuncName, JITTargetAddress FnBodyAddr) {
351 //Find out which logical dylib contains our symbol
352 auto LDI = LogicalDylibs.begin();
353 for (auto LDE = LogicalDylibs.end(); LDI != LDE; ++LDI) {
354 if (auto LMResources =
355 LDI->getLogicalModuleResourcesForSymbol(FuncName, false)) {
356 Module &SrcM = LMResources->SourceModule->getResource();
357 std::string CalledFnName = mangle(FuncName, SrcM.getDataLayout());
358 if (auto Err = LMResources->StubsMgr->updatePointer(CalledFnName,
359 FnBodyAddr))
360 return Err;
361 return Error::success();
362 }
363 }
364 return make_error<JITSymbolNotFound>(FuncName);
365 }
366
367private:
368 Error addLogicalModule(LogicalDylib &LD, std::unique_ptr<Module> SrcMPtr) {
369
Andrew Scull0372a572018-11-16 15:47:06 +0000370 // Rename anonymous globals and promote linkage to ensure that everything
371 // will resolve properly after we partition SrcM.
372 LD.PromoteSymbols(*SrcMPtr);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100373
374 // Create a logical module handle for SrcM within the logical dylib.
375 Module &SrcM = *SrcMPtr;
376 auto LMId = LD.addSourceModule(std::move(SrcMPtr));
377
378 // Create stub functions.
379 const DataLayout &DL = SrcM.getDataLayout();
380 {
381 typename IndirectStubsMgrT::StubInitsMap StubInits;
382 for (auto &F : SrcM) {
383 // Skip declarations.
384 if (F.isDeclaration())
385 continue;
386
387 // Skip weak functions for which we already have definitions.
388 auto MangledName = mangle(F.getName(), DL);
389 if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
390 if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
391 continue;
392 else if (auto Err = Sym.takeError())
393 return std::move(Err);
394 }
395
396 // Record all functions defined by this module.
397 if (CloneStubsIntoPartitions)
398 LD.getStubsToClone(LMId).insert(&F);
399
400 // Create a callback, associate it with the stub for the function,
401 // and set the compile action to compile the partition containing the
402 // function.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100403 auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
404 if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
405 return *FnImplAddrOrErr;
406 else {
407 // FIXME: Report error, return to 'abort' or something similar.
408 consumeError(FnImplAddrOrErr.takeError());
409 return 0;
410 }
411 };
412 if (auto CCAddr =
413 CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100414 StubInits[MangledName] =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100415 std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
416 else
417 return CCAddr.takeError();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100418 }
419
420 if (auto Err = LD.StubsMgr->createStubs(StubInits))
421 return Err;
422 }
423
424 // If this module doesn't contain any globals, aliases, or module flags then
425 // we can bail out early and avoid the overhead of creating and managing an
426 // empty globals module.
427 if (SrcM.global_empty() && SrcM.alias_empty() &&
428 !SrcM.getModuleFlagsMetadata())
429 return Error::success();
430
431 // Create the GlobalValues module.
432 auto GVsM = llvm::make_unique<Module>((SrcM.getName() + ".globals").str(),
433 SrcM.getContext());
434 GVsM->setDataLayout(DL);
435
436 ValueToValueMapTy VMap;
437
438 // Clone global variable decls.
439 for (auto &GV : SrcM.globals())
440 if (!GV.isDeclaration() && !VMap.count(&GV))
441 cloneGlobalVariableDecl(*GVsM, GV, &VMap);
442
443 // And the aliases.
444 for (auto &A : SrcM.aliases())
445 if (!VMap.count(&A))
446 cloneGlobalAliasDecl(*GVsM, A, VMap);
447
448 // Clone the module flags.
449 cloneModuleFlagsMetadata(*GVsM, SrcM, VMap);
450
451 // Now we need to clone the GV and alias initializers.
452
453 // Initializers may refer to functions declared (but not defined) in this
454 // module. Build a materializer to clone decls on demand.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100455 auto Materializer = createLambdaMaterializer(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100456 [&LD, &GVsM](Value *V) -> Value* {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100457 if (auto *F = dyn_cast<Function>(V)) {
458 // Decls in the original module just get cloned.
459 if (F->isDeclaration())
460 return cloneFunctionDecl(*GVsM, *F);
461
462 // Definitions in the original module (which we have emitted stubs
463 // for at this point) get turned into a constant alias to the stub
464 // instead.
465 const DataLayout &DL = GVsM->getDataLayout();
466 std::string FName = mangle(F->getName(), DL);
467 unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(F->getType());
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100468 JITTargetAddress StubAddr =
469 LD.StubsMgr->findStub(FName, false).getAddress();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100470
471 ConstantInt *StubAddrCI =
472 ConstantInt::get(GVsM->getContext(), APInt(PtrBitWidth, StubAddr));
473 Constant *Init = ConstantExpr::getCast(Instruction::IntToPtr,
474 StubAddrCI, F->getType());
475 return GlobalAlias::create(F->getFunctionType(),
476 F->getType()->getAddressSpace(),
477 F->getLinkage(), F->getName(),
478 Init, GVsM.get());
479 }
480 // else....
481 return nullptr;
482 });
483
484 // Clone the global variable initializers.
485 for (auto &GV : SrcM.globals())
486 if (!GV.isDeclaration())
487 moveGlobalVariableInitializer(GV, VMap, &Materializer);
488
489 // Clone the global alias initializers.
490 for (auto &A : SrcM.aliases()) {
491 auto *NewA = cast<GlobalAlias>(VMap[&A]);
492 assert(NewA && "Alias not cloned?");
493 Value *Init = MapValue(A.getAliasee(), VMap, RF_None, nullptr,
494 &Materializer);
495 NewA->setAliasee(cast<Constant>(Init));
496 }
497
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100498 // Build a resolver for the globals module and add it to the base layer.
499 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
500 if (auto Sym = LD.StubsMgr->findStub(Name, false))
501 return Sym;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100502
503 if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
504 return Sym;
505 else if (auto Err = Sym.takeError())
506 return std::move(Err);
507
508 return nullptr;
509 };
510
511 auto GVsResolver = createSymbolResolver(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100512 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
Andrew Scull0372a572018-11-16 15:47:06 +0000513 auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100514
Andrew Scull0372a572018-11-16 15:47:06 +0000515 if (!RS) {
516 logAllUnhandledErrors(
517 RS.takeError(), errs(),
518 "CODLayer/GVsResolver responsibility set lookup failed: ");
519 return SymbolNameSet();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100520 }
521
Andrew Scull0372a572018-11-16 15:47:06 +0000522 if (RS->size() == Symbols.size())
523 return *RS;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100524
525 SymbolNameSet NotFoundViaLegacyLookup;
526 for (auto &S : Symbols)
Andrew Scull0372a572018-11-16 15:47:06 +0000527 if (!RS->count(S))
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100528 NotFoundViaLegacyLookup.insert(S);
Andrew Scull0372a572018-11-16 15:47:06 +0000529 auto RS2 =
530 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100531
Andrew Scull0372a572018-11-16 15:47:06 +0000532 for (auto &S : RS2)
533 (*RS).insert(S);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100534
Andrew Scull0372a572018-11-16 15:47:06 +0000535 return *RS;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100536 },
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100537 [this, &LD,
538 LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Query,
539 SymbolNameSet Symbols) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100540 auto NotFoundViaLegacyLookup =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100541 lookupWithLegacyFn(ES, *Query, Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100542 return LD.BackingResolver->lookup(Query, NotFoundViaLegacyLookup);
543 });
544
545 SetSymbolResolver(LD.K, std::move(GVsResolver));
546
547 if (auto Err = BaseLayer.addModule(LD.K, std::move(GVsM)))
548 return Err;
549
550 LD.BaseLayerVModuleKeys.push_back(LD.K);
551
552 return Error::success();
553 }
554
555 static std::string mangle(StringRef Name, const DataLayout &DL) {
556 std::string MangledName;
557 {
558 raw_string_ostream MangledNameStream(MangledName);
559 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
560 }
561 return MangledName;
562 }
563
564 Expected<JITTargetAddress>
565 extractAndCompile(LogicalDylib &LD,
566 typename LogicalDylib::SourceModuleHandle LMId,
567 Function &F) {
568 Module &SrcM = LD.getSourceModule(LMId);
569
570 // If F is a declaration we must already have compiled it.
571 if (F.isDeclaration())
572 return 0;
573
574 // Grab the name of the function being called here.
575 std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
576
577 JITTargetAddress CalledAddr = 0;
578 auto Part = Partition(F);
579 if (auto PartKeyOrErr = emitPartition(LD, LMId, Part)) {
580 auto &PartKey = *PartKeyOrErr;
581 for (auto *SubF : Part) {
582 std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
583 if (auto FnBodySym = BaseLayer.findSymbolIn(PartKey, FnName, false)) {
584 if (auto FnBodyAddrOrErr = FnBodySym.getAddress()) {
585 JITTargetAddress FnBodyAddr = *FnBodyAddrOrErr;
586
587 // If this is the function we're calling record the address so we can
588 // return it from this function.
589 if (SubF == &F)
590 CalledAddr = FnBodyAddr;
591
592 // Update the function body pointer for the stub.
593 if (auto EC = LD.StubsMgr->updatePointer(FnName, FnBodyAddr))
594 return 0;
595
596 } else
597 return FnBodyAddrOrErr.takeError();
598 } else if (auto Err = FnBodySym.takeError())
599 return std::move(Err);
600 else
601 llvm_unreachable("Function not emitted for partition");
602 }
603
604 LD.BaseLayerVModuleKeys.push_back(PartKey);
605 } else
606 return PartKeyOrErr.takeError();
607
608 return CalledAddr;
609 }
610
611 template <typename PartitionT>
612 Expected<VModuleKey>
613 emitPartition(LogicalDylib &LD,
614 typename LogicalDylib::SourceModuleHandle LMId,
615 const PartitionT &Part) {
616 Module &SrcM = LD.getSourceModule(LMId);
617
618 // Create the module.
619 std::string NewName = SrcM.getName();
620 for (auto *F : Part) {
621 NewName += ".";
622 NewName += F->getName();
623 }
624
625 auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
626 M->setDataLayout(SrcM.getDataLayout());
627 ValueToValueMapTy VMap;
628
629 auto Materializer = createLambdaMaterializer([&LD, &LMId,
630 &M](Value *V) -> Value * {
631 if (auto *GV = dyn_cast<GlobalVariable>(V))
632 return cloneGlobalVariableDecl(*M, *GV);
633
634 if (auto *F = dyn_cast<Function>(V)) {
635 // Check whether we want to clone an available_externally definition.
636 if (!LD.getStubsToClone(LMId).count(F))
637 return cloneFunctionDecl(*M, *F);
638
639 // Ok - we want an inlinable stub. For that to work we need a decl
640 // for the stub pointer.
641 auto *StubPtr = createImplPointer(*F->getType(), *M,
642 F->getName() + "$stub_ptr", nullptr);
643 auto *ClonedF = cloneFunctionDecl(*M, *F);
644 makeStub(*ClonedF, *StubPtr);
645 ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
646 ClonedF->addFnAttr(Attribute::AlwaysInline);
647 return ClonedF;
648 }
649
650 if (auto *A = dyn_cast<GlobalAlias>(V)) {
651 auto *Ty = A->getValueType();
652 if (Ty->isFunctionTy())
653 return Function::Create(cast<FunctionType>(Ty),
654 GlobalValue::ExternalLinkage, A->getName(),
655 M.get());
656
657 return new GlobalVariable(*M, Ty, false, GlobalValue::ExternalLinkage,
658 nullptr, A->getName(), nullptr,
659 GlobalValue::NotThreadLocal,
660 A->getType()->getAddressSpace());
661 }
662
663 return nullptr;
664 });
665
666 // Create decls in the new module.
667 for (auto *F : Part)
668 cloneFunctionDecl(*M, *F, &VMap);
669
670 // Move the function bodies.
671 for (auto *F : Part)
672 moveFunctionBody(*F, VMap, &Materializer);
673
674 auto K = ES.allocateVModule();
675
676 auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
677 return LD.findSymbol(BaseLayer, Name, false);
678 };
679
680 // Create memory manager and symbol resolver.
681 auto Resolver = createSymbolResolver(
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100682 [&LD, LegacyLookup](const SymbolNameSet &Symbols) {
Andrew Scull0372a572018-11-16 15:47:06 +0000683 auto RS = getResponsibilitySetWithLegacyFn(Symbols, LegacyLookup);
684 if (!RS) {
685 logAllUnhandledErrors(
686 RS.takeError(), errs(),
687 "CODLayer/SubResolver responsibility set lookup failed: ");
688 return SymbolNameSet();
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100689 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100690
Andrew Scull0372a572018-11-16 15:47:06 +0000691 if (RS->size() == Symbols.size())
692 return *RS;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100693
694 SymbolNameSet NotFoundViaLegacyLookup;
695 for (auto &S : Symbols)
Andrew Scull0372a572018-11-16 15:47:06 +0000696 if (!RS->count(S))
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100697 NotFoundViaLegacyLookup.insert(S);
698
Andrew Scull0372a572018-11-16 15:47:06 +0000699 auto RS2 =
700 LD.BackingResolver->getResponsibilitySet(NotFoundViaLegacyLookup);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100701
Andrew Scull0372a572018-11-16 15:47:06 +0000702 for (auto &S : RS2)
703 (*RS).insert(S);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100704
Andrew Scull0372a572018-11-16 15:47:06 +0000705 return *RS;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100706 },
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100707 [this, &LD, LegacyLookup](std::shared_ptr<AsynchronousSymbolQuery> Q,
708 SymbolNameSet Symbols) {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100709 auto NotFoundViaLegacyLookup =
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100710 lookupWithLegacyFn(ES, *Q, Symbols, LegacyLookup);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100711 return LD.BackingResolver->lookup(Q,
712 std::move(NotFoundViaLegacyLookup));
713 });
714 SetSymbolResolver(K, std::move(Resolver));
715
716 if (auto Err = BaseLayer.addModule(std::move(K), std::move(M)))
717 return std::move(Err);
718
719 return K;
720 }
721
722 ExecutionSession &ES;
723 BaseLayerT &BaseLayer;
724 SymbolResolverGetter GetSymbolResolver;
725 SymbolResolverSetter SetSymbolResolver;
726 PartitioningFtor Partition;
727 CompileCallbackMgrT &CompileCallbackMgr;
728 IndirectStubsManagerBuilderT CreateIndirectStubsManager;
729
730 std::map<VModuleKey, LogicalDylib> LogicalDylibs;
731 bool CloneStubsIntoPartitions;
732};
733
734} // end namespace orc
735
736} // end namespace llvm
737
738#endif // LLVM_EXECUTIONENGINE_ORC_COMPILEONDEMANDLAYER_H