+ TargetAddress extractAndCompile(CODLogicalDylib &LD,
+ LogicalModuleHandle LMH,
+ Function &F) {
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+ Module &SrcM = *LMResources.SourceModule;
+
+ // If F is a declaration we must already have compiled it.
+ if (F.isDeclaration())
+ return 0;
+
+ // Grab the name of the function being called here.
+ std::string CalledFnName = mangle(F.getName(), SrcM.getDataLayout());
+
+ auto Part = Partition(F);
+ auto PartH = emitPartition(LD, LMH, Part);
+
+ TargetAddress CalledAddr = 0;
+ for (auto *SubF : Part) {
+ std::string FnName = mangle(SubF->getName(), SrcM.getDataLayout());
+ auto FnBodySym = BaseLayer.findSymbolIn(PartH, FnName, false);
+ assert(FnBodySym && "Couldn't find function body.");
+
+ TargetAddress FnBodyAddr = FnBodySym.getAddress();
+
+ // If this is the function we're calling record the address so we can
+ // return it from this function.
+ if (SubF == &F)
+ CalledAddr = FnBodyAddr;
+
+ // Update the function body pointer for the stub.
+ if (auto EC = LMResources.StubsMgr->updatePointer(FnName, FnBodyAddr))
+ return 0;
+ }
+
+ return CalledAddr;
+ }
+
+ template <typename PartitionT>
+ BaseLayerModuleSetHandleT emitPartition(CODLogicalDylib &LD,
+ LogicalModuleHandle LMH,
+ const PartitionT &Part) {
+ auto &LMResources = LD.getLogicalModuleResources(LMH);
+ Module &SrcM = *LMResources.SourceModule;
+
+ // Create the module.
+ std::string NewName = SrcM.getName();
+ for (auto *F : Part) {
+ NewName += ".";
+ NewName += F->getName();
+ }
+
+ auto M = llvm::make_unique<Module>(NewName, SrcM.getContext());
+ M->setDataLayout(SrcM.getDataLayout());
+ ValueToValueMapTy VMap;
+
+ auto Materializer = createLambdaMaterializer(
+ [this, &LMResources, &M, &VMap](Value *V) -> Value* {
+ if (auto *GV = dyn_cast<GlobalVariable>(V)) {
+ return cloneGlobalVariableDecl(*M, *GV);
+ } else if (auto *F = dyn_cast<Function>(V)) {
+ // Check whether we want to clone an available_externally definition.
+ if (LMResources.StubsToClone.count(F)) {
+ // Ok - we want an inlinable stub. For that to work we need a decl
+ // for the stub pointer.
+ auto *StubPtr = createImplPointer(*F->getType(), *M,
+ F->getName() + "$stub_ptr",
+ nullptr);
+ auto *ClonedF = cloneFunctionDecl(*M, *F);
+ makeStub(*ClonedF, *StubPtr);
+ ClonedF->setLinkage(GlobalValue::AvailableExternallyLinkage);
+ ClonedF->addFnAttr(Attribute::AlwaysInline);
+ return ClonedF;
+ }
+
+ return cloneFunctionDecl(*M, *F);
+ } else if (auto *A = dyn_cast<GlobalAlias>(V)) {
+ auto *PTy = cast<PointerType>(A->getType());
+ if (PTy->getElementType()->isFunctionTy())
+ return Function::Create(cast<FunctionType>(PTy->getElementType()),
+ GlobalValue::ExternalLinkage,
+ A->getName(), M.get());
+ // else
+ return new GlobalVariable(*M, PTy->getElementType(), false,
+ GlobalValue::ExternalLinkage,
+ nullptr, A->getName(), nullptr,
+ GlobalValue::NotThreadLocal,
+ PTy->getAddressSpace());
+ }
+ // Else.
+ return nullptr;
+ });
+
+ // Create decls in the new module.
+ for (auto *F : Part)
+ cloneFunctionDecl(*M, *F, &VMap);
+
+ // Move the function bodies.
+ for (auto *F : Part)
+ moveFunctionBody(*F, VMap, &Materializer);
+
+ // Create memory manager and symbol resolver.
+ auto MemMgr = llvm::make_unique<SectionMemoryManager>();
+ auto Resolver = createLambdaResolver(
+ [this, &LD, LMH](const std::string &Name) {
+ if (auto Symbol = LD.findSymbolInternally(LMH, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return LD.getDylibResources().ExternalSymbolResolver(Name);
+ },
+ [this, &LD, LMH](const std::string &Name) {
+ if (auto Symbol = LD.findSymbolInternally(LMH, Name))
+ return RuntimeDyld::SymbolInfo(Symbol.getAddress(),
+ Symbol.getFlags());
+ return RuntimeDyld::SymbolInfo(nullptr);
+ });
+ std::vector<std::unique_ptr<Module>> PartMSet;
+ PartMSet.push_back(std::move(M));
+ return BaseLayer.addModuleSet(std::move(PartMSet), std::move(MemMgr),
+ std::move(Resolver));
+ }
+