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