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