153ccf888SLang Hames //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===// 253ccf888SLang Hames // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 653ccf888SLang Hames // 753ccf888SLang Hames //===----------------------------------------------------------------------===// 853ccf888SLang Hames 96bda14b3SChandler Carruth #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" 100a446fd5SBenjamin Kramer #include "llvm/ADT/STLExtras.h" 1193de2a12SLang Hames #include "llvm/ADT/Triple.h" 12105518feSLang Hames #include "llvm/ExecutionEngine/Orc/OrcABISupport.h" 1393de2a12SLang Hames #include "llvm/IR/IRBuilder.h" 14bd0cb787SLang Hames #include "llvm/Support/Format.h" 15cd68eba3SLang Hames #include "llvm/Transforms/Utils/Cloning.h" 16c6de458fSLang Hames #include <sstream> 1793de2a12SLang Hames 18bd0cb787SLang Hames using namespace llvm; 19bd0cb787SLang Hames using namespace llvm::orc; 20bd0cb787SLang Hames 21bd0cb787SLang Hames namespace { 22bd0cb787SLang Hames 23bd0cb787SLang Hames class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { 24bd0cb787SLang Hames public: 25bd0cb787SLang Hames using CompileFunction = JITCompileCallbackManager::CompileFunction; 26bd0cb787SLang Hames 27bd0cb787SLang Hames CompileCallbackMaterializationUnit(SymbolStringPtr Name, 280aec49c8SLang Hames CompileFunction Compile) 298b94274fSLang Hames : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}}), 300aec49c8SLang Hames nullptr), 31bd0cb787SLang Hames Name(std::move(Name)), Compile(std::move(Compile)) {} 32bd0cb787SLang Hames 3346f40a71SLang Hames StringRef getName() const override { return "<Compile Callbacks>"; } 3446f40a71SLang Hames 35bd0cb787SLang Hames private: 367dcd0042SLang Hames void materialize(std::unique_ptr<MaterializationResponsibility> R) override { 37bd0cb787SLang Hames SymbolMap Result; 38bd0cb787SLang Hames Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); 39e00585c7SLang Hames // No dependencies, so these calls cannot fail. 407dcd0042SLang Hames cantFail(R->notifyResolved(Result)); 417dcd0042SLang Hames cantFail(R->notifyEmitted()); 42bd0cb787SLang Hames } 43bd0cb787SLang Hames 44cb5702c3SLang Hames void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { 45bd0cb787SLang Hames llvm_unreachable("Discard should never occur on a LMU?"); 46bd0cb787SLang Hames } 47bd0cb787SLang Hames 48bd0cb787SLang Hames SymbolStringPtr Name; 49bd0cb787SLang Hames CompileFunction Compile; 50bd0cb787SLang Hames }; 51bd0cb787SLang Hames 52bd0cb787SLang Hames } // namespace 53bd0cb787SLang Hames 5493de2a12SLang Hames namespace llvm { 55e738061cSLang Hames namespace orc { 5693de2a12SLang Hames 570d944e00SLang Hames TrampolinePool::~TrampolinePool() {} 58ea39de81SLang Hames void IndirectStubsManager::anchor() {} 5998c2ac13SLang Hames 60bd0cb787SLang Hames Expected<JITTargetAddress> 61bd0cb787SLang Hames JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) { 6250b33441SLang Hames if (auto TrampolineAddr = TP->getTrampoline()) { 6371d781c4SLang Hames auto CallbackName = 6471d781c4SLang Hames ES.intern(std::string("cc") + std::to_string(++NextCallbackId)); 65bd0cb787SLang Hames 66bd0cb787SLang Hames std::lock_guard<std::mutex> Lock(CCMgrMutex); 67bd0cb787SLang Hames AddrToSymbol[*TrampolineAddr] = CallbackName; 680aec49c8SLang Hames cantFail( 690aec49c8SLang Hames CallbacksJD.define(std::make_unique<CompileCallbackMaterializationUnit>( 700aec49c8SLang Hames std::move(CallbackName), std::move(Compile)))); 71bd0cb787SLang Hames return *TrampolineAddr; 72bd0cb787SLang Hames } else 73bd0cb787SLang Hames return TrampolineAddr.takeError(); 74bd0cb787SLang Hames } 75bd0cb787SLang Hames 76bd0cb787SLang Hames JITTargetAddress JITCompileCallbackManager::executeCompileCallback( 77bd0cb787SLang Hames JITTargetAddress TrampolineAddr) { 78bd0cb787SLang Hames SymbolStringPtr Name; 79bd0cb787SLang Hames 80bd0cb787SLang Hames { 81bd0cb787SLang Hames std::unique_lock<std::mutex> Lock(CCMgrMutex); 82bd0cb787SLang Hames auto I = AddrToSymbol.find(TrampolineAddr); 83bd0cb787SLang Hames 84bd0cb787SLang Hames // If this address is not associated with a compile callback then report an 85bd0cb787SLang Hames // error to the execution session and return ErrorHandlerAddress to the 86bd0cb787SLang Hames // callee. 87bd0cb787SLang Hames if (I == AddrToSymbol.end()) { 88bd0cb787SLang Hames Lock.unlock(); 89bd0cb787SLang Hames std::string ErrMsg; 90bd0cb787SLang Hames { 91bd0cb787SLang Hames raw_string_ostream ErrMsgStream(ErrMsg); 92bd0cb787SLang Hames ErrMsgStream << "No compile callback for trampoline at " 9391449355SLang Hames << format("0x%016" PRIx64, TrampolineAddr); 94bd0cb787SLang Hames } 95bd0cb787SLang Hames ES.reportError( 96bd0cb787SLang Hames make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode())); 97bd0cb787SLang Hames return ErrorHandlerAddress; 98bd0cb787SLang Hames } else 99bd0cb787SLang Hames Name = I->second; 100bd0cb787SLang Hames } 101bd0cb787SLang Hames 102674df13bSLang Hames if (auto Sym = 103674df13bSLang Hames ES.lookup(makeJITDylibSearchOrder( 104674df13bSLang Hames &CallbacksJD, JITDylibLookupFlags::MatchAllSymbols), 105674df13bSLang Hames Name)) 106bd0cb787SLang Hames return Sym->getAddress(); 107bd0cb787SLang Hames else { 1087899ccbcSLang Hames llvm::dbgs() << "Didn't find callback.\n"; 109bd0cb787SLang Hames // If anything goes wrong materializing Sym then report it to the session 110bd0cb787SLang Hames // and return the ErrorHandlerAddress; 111bd0cb787SLang Hames ES.reportError(Sym.takeError()); 112bd0cb787SLang Hames return ErrorHandlerAddress; 113bd0cb787SLang Hames } 114bd0cb787SLang Hames } 115bd0cb787SLang Hames 11650b33441SLang Hames Expected<std::unique_ptr<JITCompileCallbackManager>> 117bd0cb787SLang Hames createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, 118ad4a911fSLang Hames JITTargetAddress ErrorHandlerAddress) { 119105518feSLang Hames switch (T.getArch()) { 12050b33441SLang Hames default: 12150b33441SLang Hames return make_error<StringError>( 12250b33441SLang Hames std::string("No callback manager available for ") + T.str(), 12350b33441SLang Hames inconvertibleErrorCode()); 124f1c28929STim Northover case Triple::aarch64: 125f1c28929STim Northover case Triple::aarch64_32: { 126359983bdSLang Hames typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT; 12750b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 128359983bdSLang Hames } 129359983bdSLang Hames 130105518feSLang Hames case Triple::x86: { 131105518feSLang Hames typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT; 13250b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 133105518feSLang Hames } 134105518feSLang Hames 1355abf4bb5SPetar Jovanovic case Triple::mips: { 1365abf4bb5SPetar Jovanovic typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Be> CCMgrT; 13750b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 1385abf4bb5SPetar Jovanovic } 1395abf4bb5SPetar Jovanovic case Triple::mipsel: { 1405abf4bb5SPetar Jovanovic typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Le> CCMgrT; 14150b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 1425abf4bb5SPetar Jovanovic } 1435abf4bb5SPetar Jovanovic 1445abf4bb5SPetar Jovanovic case Triple::mips64: 1455abf4bb5SPetar Jovanovic case Triple::mips64el: { 1465abf4bb5SPetar Jovanovic typedef orc::LocalJITCompileCallbackManager<orc::OrcMips64> CCMgrT; 14750b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 1485abf4bb5SPetar Jovanovic } 1495abf4bb5SPetar Jovanovic 150105518feSLang Hames case Triple::x86_64: { 151105518feSLang Hames if (T.getOS() == Triple::OSType::Win32) { 152105518feSLang Hames typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT; 15350b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 154105518feSLang Hames } else { 155105518feSLang Hames typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT; 15650b33441SLang Hames return CCMgrT::Create(ES, ErrorHandlerAddress); 157105518feSLang Hames } 158105518feSLang Hames } 159359983bdSLang Hames 160105518feSLang Hames } 161105518feSLang Hames } 162105518feSLang Hames 163105518feSLang Hames std::function<std::unique_ptr<IndirectStubsManager>()> 164c321e534SBenjamin Kramer createLocalIndirectStubsManagerBuilder(const Triple &T) { 165105518feSLang Hames switch (T.getArch()) { 166a95b0df5SLang Hames default: 167a95b0df5SLang Hames return [](){ 1680eaee545SJonas Devlieghere return std::make_unique< 169a95b0df5SLang Hames orc::LocalIndirectStubsManager<orc::OrcGenericABI>>(); 170a95b0df5SLang Hames }; 171105518feSLang Hames 172359983bdSLang Hames case Triple::aarch64: 173f1c28929STim Northover case Triple::aarch64_32: 174359983bdSLang Hames return [](){ 1750eaee545SJonas Devlieghere return std::make_unique< 176359983bdSLang Hames orc::LocalIndirectStubsManager<orc::OrcAArch64>>(); 177359983bdSLang Hames }; 178359983bdSLang Hames 179105518feSLang Hames case Triple::x86: 180105518feSLang Hames return [](){ 1810eaee545SJonas Devlieghere return std::make_unique< 182105518feSLang Hames orc::LocalIndirectStubsManager<orc::OrcI386>>(); 183105518feSLang Hames }; 184105518feSLang Hames 1855abf4bb5SPetar Jovanovic case Triple::mips: 1865abf4bb5SPetar Jovanovic return [](){ 1870eaee545SJonas Devlieghere return std::make_unique< 1885abf4bb5SPetar Jovanovic orc::LocalIndirectStubsManager<orc::OrcMips32Be>>(); 1895abf4bb5SPetar Jovanovic }; 1905abf4bb5SPetar Jovanovic 1915abf4bb5SPetar Jovanovic case Triple::mipsel: 1925abf4bb5SPetar Jovanovic return [](){ 1930eaee545SJonas Devlieghere return std::make_unique< 1945abf4bb5SPetar Jovanovic orc::LocalIndirectStubsManager<orc::OrcMips32Le>>(); 1955abf4bb5SPetar Jovanovic }; 1965abf4bb5SPetar Jovanovic 1975abf4bb5SPetar Jovanovic case Triple::mips64: 1985abf4bb5SPetar Jovanovic case Triple::mips64el: 1995abf4bb5SPetar Jovanovic return [](){ 2000eaee545SJonas Devlieghere return std::make_unique< 2015abf4bb5SPetar Jovanovic orc::LocalIndirectStubsManager<orc::OrcMips64>>(); 2025abf4bb5SPetar Jovanovic }; 2035abf4bb5SPetar Jovanovic 204105518feSLang Hames case Triple::x86_64: 205105518feSLang Hames if (T.getOS() == Triple::OSType::Win32) { 206105518feSLang Hames return [](){ 2070eaee545SJonas Devlieghere return std::make_unique< 208105518feSLang Hames orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>(); 209105518feSLang Hames }; 210105518feSLang Hames } else { 211105518feSLang Hames return [](){ 2120eaee545SJonas Devlieghere return std::make_unique< 213105518feSLang Hames orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>(); 214105518feSLang Hames }; 215105518feSLang Hames } 216359983bdSLang Hames 217105518feSLang Hames } 218105518feSLang Hames } 219105518feSLang Hames 220ad4a911fSLang Hames Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) { 221eb9bdb5dSLang Hames Constant *AddrIntVal = 222eb9bdb5dSLang Hames ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr); 223eb9bdb5dSLang Hames Constant *AddrPtrVal = 224eb9bdb5dSLang Hames ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal, 225eb9bdb5dSLang Hames PointerType::get(&FT, 0)); 226eb9bdb5dSLang Hames return AddrPtrVal; 227eb9bdb5dSLang Hames } 228eb9bdb5dSLang Hames 229eb9bdb5dSLang Hames GlobalVariable* createImplPointer(PointerType &PT, Module &M, 230eb9bdb5dSLang Hames const Twine &Name, Constant *Initializer) { 231cd68eba3SLang Hames auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage, 2322754714fSLang Hames Initializer, Name, nullptr, 23393de2a12SLang Hames GlobalValue::NotThreadLocal, 0, true); 234cd68eba3SLang Hames IP->setVisibility(GlobalValue::HiddenVisibility); 235cd68eba3SLang Hames return IP; 2362754714fSLang Hames } 23793de2a12SLang Hames 23898c2ac13SLang Hames void makeStub(Function &F, Value &ImplPointer) { 2392754714fSLang Hames assert(F.isDeclaration() && "Can't turn a definition into a stub."); 2402754714fSLang Hames assert(F.getParent() && "Function isn't in a module."); 2412754714fSLang Hames Module &M = *F.getParent(); 2422754714fSLang Hames BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F); 24393de2a12SLang Hames IRBuilder<> Builder(EntryBlock); 24414359ef1SJames Y Knight LoadInst *ImplAddr = Builder.CreateLoad(F.getType(), &ImplPointer); 24593de2a12SLang Hames std::vector<Value*> CallArgs; 2462754714fSLang Hames for (auto &A : F.args()) 2472754714fSLang Hames CallArgs.push_back(&A); 24814359ef1SJames Y Knight CallInst *Call = Builder.CreateCall(F.getFunctionType(), ImplAddr, CallArgs); 24993de2a12SLang Hames Call->setTailCall(); 250dc4260dbSLang Hames Call->setAttributes(F.getAttributes()); 251cd68eba3SLang Hames if (F.getReturnType()->isVoidTy()) 252cd68eba3SLang Hames Builder.CreateRetVoid(); 253cd68eba3SLang Hames else 25493de2a12SLang Hames Builder.CreateRet(Call); 25593de2a12SLang Hames } 25693de2a12SLang Hames 257bf6603e9SLang Hames std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) { 258bf6603e9SLang Hames std::vector<GlobalValue *> PromotedGlobals; 259bf6603e9SLang Hames 260c5192f75SLang Hames for (auto &GV : M.global_values()) { 261bf6603e9SLang Hames bool Promoted = true; 262c6de458fSLang Hames 263c5192f75SLang Hames // Rename if necessary. 264c5192f75SLang Hames if (!GV.hasName()) 265c5192f75SLang Hames GV.setName("__orc_anon." + Twine(NextId++)); 266c5192f75SLang Hames else if (GV.getName().startswith("\01L")) 267c5192f75SLang Hames GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++)); 268c5192f75SLang Hames else if (GV.hasLocalLinkage()) 269c5192f75SLang Hames GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++)); 270bf6603e9SLang Hames else 271bf6603e9SLang Hames Promoted = false; 272c5192f75SLang Hames 273c5192f75SLang Hames if (GV.hasLocalLinkage()) { 274c5192f75SLang Hames GV.setLinkage(GlobalValue::ExternalLinkage); 275c5192f75SLang Hames GV.setVisibility(GlobalValue::HiddenVisibility); 276bf6603e9SLang Hames Promoted = true; 277c6de458fSLang Hames } 278c5192f75SLang Hames GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None); 279bf6603e9SLang Hames 280bf6603e9SLang Hames if (Promoted) 281bf6603e9SLang Hames PromotedGlobals.push_back(&GV); 282c6de458fSLang Hames } 283bf6603e9SLang Hames 284bf6603e9SLang Hames return PromotedGlobals; 285cd68eba3SLang Hames } 286cd68eba3SLang Hames 287cd68eba3SLang Hames Function* cloneFunctionDecl(Module &Dst, const Function &F, 288cd68eba3SLang Hames ValueToValueMapTy *VMap) { 289cd68eba3SLang Hames Function *NewF = 2905f6eaac6SManuel Jacob Function::Create(cast<FunctionType>(F.getValueType()), 291cd68eba3SLang Hames F.getLinkage(), F.getName(), &Dst); 292cd68eba3SLang Hames NewF->copyAttributesFrom(&F); 293cd68eba3SLang Hames 294cd68eba3SLang Hames if (VMap) { 295cd68eba3SLang Hames (*VMap)[&F] = NewF; 296cd68eba3SLang Hames auto NewArgI = NewF->arg_begin(); 297cd68eba3SLang Hames for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE; 298cd68eba3SLang Hames ++ArgI, ++NewArgI) 2991275bffaSDuncan P. N. Exon Smith (*VMap)[&*ArgI] = &*NewArgI; 300cd68eba3SLang Hames } 301cd68eba3SLang Hames 302cd68eba3SLang Hames return NewF; 303cd68eba3SLang Hames } 304cd68eba3SLang Hames 305cd68eba3SLang Hames void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, 306cd68eba3SLang Hames ValueMaterializer *Materializer, 307cd68eba3SLang Hames Function *NewF) { 308cd68eba3SLang Hames assert(!OrigF.isDeclaration() && "Nothing to move"); 309cd68eba3SLang Hames if (!NewF) 310cd68eba3SLang Hames NewF = cast<Function>(VMap[&OrigF]); 3112754714fSLang Hames else 312cd68eba3SLang Hames assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap."); 313cd68eba3SLang Hames assert(NewF && "Function mapping missing from VMap."); 314cd68eba3SLang Hames assert(NewF->getParent() != OrigF.getParent() && 315cd68eba3SLang Hames "moveFunctionBody should only be used to move bodies between " 316cd68eba3SLang Hames "modules."); 3172754714fSLang Hames 318cd68eba3SLang Hames SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. 319*22a52dfdSDuncan P. N. Exon Smith CloneFunctionInto(NewF, &OrigF, VMap, 320*22a52dfdSDuncan P. N. Exon Smith CloneFunctionChangeType::DifferentModule, Returns, "", 321*22a52dfdSDuncan P. N. Exon Smith nullptr, nullptr, Materializer); 322cd68eba3SLang Hames OrigF.deleteBody(); 323cd68eba3SLang Hames } 3242754714fSLang Hames 325cd68eba3SLang Hames GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, 326cd68eba3SLang Hames ValueToValueMapTy *VMap) { 327cd68eba3SLang Hames GlobalVariable *NewGV = new GlobalVariable( 3285f6eaac6SManuel Jacob Dst, GV.getValueType(), GV.isConstant(), 329cd68eba3SLang Hames GV.getLinkage(), nullptr, GV.getName(), nullptr, 330cd68eba3SLang Hames GV.getThreadLocalMode(), GV.getType()->getAddressSpace()); 331cd68eba3SLang Hames NewGV->copyAttributesFrom(&GV); 332cd68eba3SLang Hames if (VMap) 333cd68eba3SLang Hames (*VMap)[&GV] = NewGV; 334cd68eba3SLang Hames return NewGV; 335cd68eba3SLang Hames } 336cd68eba3SLang Hames 337cd68eba3SLang Hames void moveGlobalVariableInitializer(GlobalVariable &OrigGV, 338cd68eba3SLang Hames ValueToValueMapTy &VMap, 339cd68eba3SLang Hames ValueMaterializer *Materializer, 340cd68eba3SLang Hames GlobalVariable *NewGV) { 341cd68eba3SLang Hames assert(OrigGV.hasInitializer() && "Nothing to move"); 342cd68eba3SLang Hames if (!NewGV) 343cd68eba3SLang Hames NewGV = cast<GlobalVariable>(VMap[&OrigGV]); 344cd68eba3SLang Hames else 345cd68eba3SLang Hames assert(VMap[&OrigGV] == NewGV && 346cd68eba3SLang Hames "Incorrect global variable mapping in VMap."); 347cd68eba3SLang Hames assert(NewGV->getParent() != OrigGV.getParent() && 348d3b69c6bSStefan Granitz "moveGlobalVariableInitializer should only be used to move " 349d3b69c6bSStefan Granitz "initializers between modules"); 350cd68eba3SLang Hames 351cd68eba3SLang Hames NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None, 352cd68eba3SLang Hames nullptr, Materializer)); 35393de2a12SLang Hames } 35493de2a12SLang Hames 35598c2ac13SLang Hames GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, 35698c2ac13SLang Hames ValueToValueMapTy &VMap) { 35744780acdSLang Hames assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?"); 35844780acdSLang Hames auto *NewA = GlobalAlias::create(OrigA.getValueType(), 35944780acdSLang Hames OrigA.getType()->getPointerAddressSpace(), 36044780acdSLang Hames OrigA.getLinkage(), OrigA.getName(), &Dst); 36144780acdSLang Hames NewA->copyAttributesFrom(&OrigA); 36244780acdSLang Hames VMap[&OrigA] = NewA; 36344780acdSLang Hames return NewA; 36444780acdSLang Hames } 36544780acdSLang Hames 36638c7927bSLang Hames void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, 36738c7927bSLang Hames ValueToValueMapTy &VMap) { 36838c7927bSLang Hames auto *MFs = Src.getModuleFlagsMetadata(); 36938c7927bSLang Hames if (!MFs) 37038c7927bSLang Hames return; 37138c7927bSLang Hames for (auto *MF : MFs->operands()) 37238c7927bSLang Hames Dst.addModuleFlag(MapMetadata(MF, VMap)); 37338c7927bSLang Hames } 37438c7927bSLang Hames 375e738061cSLang Hames } // End namespace orc. 376e738061cSLang Hames } // End namespace llvm. 377