void IRCompileLayer::emit(MaterializationResponsibility R, VModuleKey K, ThreadSafeModule TSM) { assert(TSM.getModule() && "Module must not be null"); if (auto Obj = Compile(*TSM.getModule())) { { std::lock_guard<std::mutex> Lock(IRLayerMutex); if (NotifyCompiled) NotifyCompiled(K, std::move(TSM)); else TSM = ThreadSafeModule(); } BaseLayer.emit(std::move(R), std::move(K), std::move(*Obj)); } else { R.failMaterialization(); getExecutionSession().reportError(Obj.takeError()); } }
ThreadSafeModule cloneToNewContext(ThreadSafeModule &TSM, GVPredicate ShouldCloneDef, GVModifier UpdateClonedDefSource) { assert(TSM && "Can not clone null module"); if (!ShouldCloneDef) ShouldCloneDef = [](const GlobalValue &) { return true; }; auto Lock = TSM.getContextLock(); SmallVector<char, 1> ClonedModuleBuffer; { std::set<GlobalValue *> ClonedDefsInSrc; ValueToValueMapTy VMap; auto Tmp = CloneModule(*TSM.getModule(), VMap, [&](const GlobalValue *GV) { if (ShouldCloneDef(*GV)) { ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV)); return true; } return false; }); if (UpdateClonedDefSource) for (auto *GV : ClonedDefsInSrc) UpdateClonedDefSource(*GV); BitcodeWriter BCWriter(ClonedModuleBuffer); BCWriter.writeModule(*Tmp); BCWriter.writeSymtab(); BCWriter.writeStrtab(); } MemoryBufferRef ClonedModuleBufferRef( StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()), "cloned module buffer"); ThreadSafeContext NewTSCtx(llvm::make_unique<LLVMContext>()); auto ClonedModule = cantFail(parseBitcodeFile(ClonedModuleBufferRef, *NewTSCtx.getContext())); ClonedModule->setModuleIdentifier(TSM.getModule()->getName()); return ThreadSafeModule(std::move(ClonedModule), std::move(NewTSCtx)); }