1ff0cc061SDimitry Andric //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
2ff0cc061SDimitry Andric //
3ff0cc061SDimitry Andric //                     The LLVM Compiler Infrastructure
4ff0cc061SDimitry Andric //
5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source
6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details.
7ff0cc061SDimitry Andric //
8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
9ff0cc061SDimitry Andric 
10db17bf38SDimitry Andric #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
11ff0cc061SDimitry Andric #include "llvm/ADT/STLExtras.h"
12ff0cc061SDimitry Andric #include "llvm/ADT/Triple.h"
133ca95b02SDimitry Andric #include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
14ff0cc061SDimitry Andric #include "llvm/IR/CallSite.h"
15ff0cc061SDimitry Andric #include "llvm/IR/IRBuilder.h"
164ba319b5SDimitry Andric #include "llvm/Support/Format.h"
17ff0cc061SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
18ff0cc061SDimitry Andric #include <sstream>
19ff0cc061SDimitry Andric 
204ba319b5SDimitry Andric using namespace llvm;
214ba319b5SDimitry Andric using namespace llvm::orc;
224ba319b5SDimitry Andric 
234ba319b5SDimitry Andric namespace {
244ba319b5SDimitry Andric 
254ba319b5SDimitry Andric class CompileCallbackMaterializationUnit : public orc::MaterializationUnit {
264ba319b5SDimitry Andric public:
274ba319b5SDimitry Andric   using CompileFunction = JITCompileCallbackManager::CompileFunction;
284ba319b5SDimitry Andric 
CompileCallbackMaterializationUnit(SymbolStringPtr Name,CompileFunction Compile,VModuleKey K)294ba319b5SDimitry Andric   CompileCallbackMaterializationUnit(SymbolStringPtr Name,
30*b5893f02SDimitry Andric                                      CompileFunction Compile, VModuleKey K)
31*b5893f02SDimitry Andric       : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}}),
32*b5893f02SDimitry Andric                             std::move(K)),
334ba319b5SDimitry Andric         Name(std::move(Name)), Compile(std::move(Compile)) {}
344ba319b5SDimitry Andric 
getName() const35*b5893f02SDimitry Andric   StringRef getName() const override { return "<Compile Callbacks>"; }
36*b5893f02SDimitry Andric 
374ba319b5SDimitry Andric private:
materialize(MaterializationResponsibility R)38*b5893f02SDimitry Andric   void materialize(MaterializationResponsibility R) override {
394ba319b5SDimitry Andric     SymbolMap Result;
404ba319b5SDimitry Andric     Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported);
414ba319b5SDimitry Andric     R.resolve(Result);
42*b5893f02SDimitry Andric     R.emit();
434ba319b5SDimitry Andric   }
444ba319b5SDimitry Andric 
discard(const JITDylib & JD,const SymbolStringPtr & Name)45*b5893f02SDimitry Andric   void discard(const JITDylib &JD, const SymbolStringPtr &Name) override {
464ba319b5SDimitry Andric     llvm_unreachable("Discard should never occur on a LMU?");
474ba319b5SDimitry Andric   }
484ba319b5SDimitry Andric 
494ba319b5SDimitry Andric   SymbolStringPtr Name;
504ba319b5SDimitry Andric   CompileFunction Compile;
514ba319b5SDimitry Andric };
524ba319b5SDimitry Andric 
534ba319b5SDimitry Andric } // namespace
544ba319b5SDimitry Andric 
55ff0cc061SDimitry Andric namespace llvm {
56ff0cc061SDimitry Andric namespace orc {
57ff0cc061SDimitry Andric 
anchor()587d523365SDimitry Andric void IndirectStubsManager::anchor() {}
anchor()59*b5893f02SDimitry Andric void TrampolinePool::anchor() {}
607d523365SDimitry Andric 
614ba319b5SDimitry Andric Expected<JITTargetAddress>
getCompileCallback(CompileFunction Compile)624ba319b5SDimitry Andric JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) {
63*b5893f02SDimitry Andric   if (auto TrampolineAddr = TP->getTrampoline()) {
64*b5893f02SDimitry Andric     auto CallbackName =
65*b5893f02SDimitry Andric         ES.intern(std::string("cc") + std::to_string(++NextCallbackId));
664ba319b5SDimitry Andric 
674ba319b5SDimitry Andric     std::lock_guard<std::mutex> Lock(CCMgrMutex);
684ba319b5SDimitry Andric     AddrToSymbol[*TrampolineAddr] = CallbackName;
69*b5893f02SDimitry Andric     cantFail(CallbacksJD.define(
704ba319b5SDimitry Andric         llvm::make_unique<CompileCallbackMaterializationUnit>(
71*b5893f02SDimitry Andric             std::move(CallbackName), std::move(Compile),
72*b5893f02SDimitry Andric             ES.allocateVModule())));
734ba319b5SDimitry Andric     return *TrampolineAddr;
744ba319b5SDimitry Andric   } else
754ba319b5SDimitry Andric     return TrampolineAddr.takeError();
764ba319b5SDimitry Andric }
774ba319b5SDimitry Andric 
executeCompileCallback(JITTargetAddress TrampolineAddr)784ba319b5SDimitry Andric JITTargetAddress JITCompileCallbackManager::executeCompileCallback(
794ba319b5SDimitry Andric     JITTargetAddress TrampolineAddr) {
804ba319b5SDimitry Andric   SymbolStringPtr Name;
814ba319b5SDimitry Andric 
824ba319b5SDimitry Andric   {
834ba319b5SDimitry Andric     std::unique_lock<std::mutex> Lock(CCMgrMutex);
844ba319b5SDimitry Andric     auto I = AddrToSymbol.find(TrampolineAddr);
854ba319b5SDimitry Andric 
864ba319b5SDimitry Andric     // If this address is not associated with a compile callback then report an
874ba319b5SDimitry Andric     // error to the execution session and return ErrorHandlerAddress to the
884ba319b5SDimitry Andric     // callee.
894ba319b5SDimitry Andric     if (I == AddrToSymbol.end()) {
904ba319b5SDimitry Andric       Lock.unlock();
914ba319b5SDimitry Andric       std::string ErrMsg;
924ba319b5SDimitry Andric       {
934ba319b5SDimitry Andric         raw_string_ostream ErrMsgStream(ErrMsg);
944ba319b5SDimitry Andric         ErrMsgStream << "No compile callback for trampoline at "
95*b5893f02SDimitry Andric                      << format("0x%016" PRIx64, TrampolineAddr);
964ba319b5SDimitry Andric       }
974ba319b5SDimitry Andric       ES.reportError(
984ba319b5SDimitry Andric           make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode()));
994ba319b5SDimitry Andric       return ErrorHandlerAddress;
1004ba319b5SDimitry Andric     } else
1014ba319b5SDimitry Andric       Name = I->second;
1024ba319b5SDimitry Andric   }
1034ba319b5SDimitry Andric 
104*b5893f02SDimitry Andric   if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name))
1054ba319b5SDimitry Andric     return Sym->getAddress();
1064ba319b5SDimitry Andric   else {
107*b5893f02SDimitry Andric     llvm::dbgs() << "Didn't find callback.\n";
1084ba319b5SDimitry Andric     // If anything goes wrong materializing Sym then report it to the session
1094ba319b5SDimitry Andric     // and return the ErrorHandlerAddress;
1104ba319b5SDimitry Andric     ES.reportError(Sym.takeError());
1114ba319b5SDimitry Andric     return ErrorHandlerAddress;
1124ba319b5SDimitry Andric   }
1134ba319b5SDimitry Andric }
1144ba319b5SDimitry Andric 
115*b5893f02SDimitry Andric Expected<std::unique_ptr<JITCompileCallbackManager>>
createLocalCompileCallbackManager(const Triple & T,ExecutionSession & ES,JITTargetAddress ErrorHandlerAddress)1164ba319b5SDimitry Andric createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES,
117d88c1a5aSDimitry Andric                                   JITTargetAddress ErrorHandlerAddress) {
1183ca95b02SDimitry Andric   switch (T.getArch()) {
119*b5893f02SDimitry Andric   default:
120*b5893f02SDimitry Andric     return make_error<StringError>(
121*b5893f02SDimitry Andric         std::string("No callback manager available for ") + T.str(),
122*b5893f02SDimitry Andric         inconvertibleErrorCode());
1232cab237bSDimitry Andric   case Triple::aarch64: {
1242cab237bSDimitry Andric     typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT;
125*b5893f02SDimitry Andric     return CCMgrT::Create(ES, ErrorHandlerAddress);
1262cab237bSDimitry Andric     }
1272cab237bSDimitry Andric 
1283ca95b02SDimitry Andric     case Triple::x86: {
1293ca95b02SDimitry Andric       typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT;
130*b5893f02SDimitry Andric       return CCMgrT::Create(ES, ErrorHandlerAddress);
131*b5893f02SDimitry Andric     }
132*b5893f02SDimitry Andric 
133*b5893f02SDimitry Andric     case Triple::mips: {
134*b5893f02SDimitry Andric       typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Be> CCMgrT;
135*b5893f02SDimitry Andric       return CCMgrT::Create(ES, ErrorHandlerAddress);
136*b5893f02SDimitry Andric     }
137*b5893f02SDimitry Andric     case Triple::mipsel: {
138*b5893f02SDimitry Andric       typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Le> CCMgrT;
139*b5893f02SDimitry Andric       return CCMgrT::Create(ES, ErrorHandlerAddress);
140*b5893f02SDimitry Andric     }
141*b5893f02SDimitry Andric 
142*b5893f02SDimitry Andric     case Triple::mips64:
143*b5893f02SDimitry Andric     case Triple::mips64el: {
144*b5893f02SDimitry Andric       typedef orc::LocalJITCompileCallbackManager<orc::OrcMips64> CCMgrT;
145*b5893f02SDimitry Andric       return CCMgrT::Create(ES, ErrorHandlerAddress);
1463ca95b02SDimitry Andric     }
1473ca95b02SDimitry Andric 
1483ca95b02SDimitry Andric     case Triple::x86_64: {
1493ca95b02SDimitry Andric       if ( T.getOS() == Triple::OSType::Win32 ) {
1503ca95b02SDimitry Andric         typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT;
151*b5893f02SDimitry Andric         return CCMgrT::Create(ES, ErrorHandlerAddress);
1523ca95b02SDimitry Andric       } else {
1533ca95b02SDimitry Andric         typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT;
154*b5893f02SDimitry Andric         return CCMgrT::Create(ES, ErrorHandlerAddress);
1553ca95b02SDimitry Andric       }
1563ca95b02SDimitry Andric     }
1572cab237bSDimitry Andric 
1583ca95b02SDimitry Andric   }
1593ca95b02SDimitry Andric }
1603ca95b02SDimitry Andric 
1613ca95b02SDimitry Andric std::function<std::unique_ptr<IndirectStubsManager>()>
createLocalIndirectStubsManagerBuilder(const Triple & T)1623ca95b02SDimitry Andric createLocalIndirectStubsManagerBuilder(const Triple &T) {
1633ca95b02SDimitry Andric   switch (T.getArch()) {
1644ba319b5SDimitry Andric     default:
1654ba319b5SDimitry Andric       return [](){
1664ba319b5SDimitry Andric         return llvm::make_unique<
1674ba319b5SDimitry Andric                        orc::LocalIndirectStubsManager<orc::OrcGenericABI>>();
1684ba319b5SDimitry Andric       };
1693ca95b02SDimitry Andric 
1702cab237bSDimitry Andric     case Triple::aarch64:
1712cab237bSDimitry Andric       return [](){
1722cab237bSDimitry Andric         return llvm::make_unique<
1732cab237bSDimitry Andric                        orc::LocalIndirectStubsManager<orc::OrcAArch64>>();
1742cab237bSDimitry Andric       };
1752cab237bSDimitry Andric 
1763ca95b02SDimitry Andric     case Triple::x86:
1773ca95b02SDimitry Andric       return [](){
1783ca95b02SDimitry Andric         return llvm::make_unique<
1793ca95b02SDimitry Andric                        orc::LocalIndirectStubsManager<orc::OrcI386>>();
1803ca95b02SDimitry Andric       };
1813ca95b02SDimitry Andric 
182*b5893f02SDimitry Andric     case Triple::mips:
183*b5893f02SDimitry Andric       return [](){
184*b5893f02SDimitry Andric           return llvm::make_unique<
185*b5893f02SDimitry Andric                       orc::LocalIndirectStubsManager<orc::OrcMips32Be>>();
186*b5893f02SDimitry Andric       };
187*b5893f02SDimitry Andric 
188*b5893f02SDimitry Andric     case Triple::mipsel:
189*b5893f02SDimitry Andric       return [](){
190*b5893f02SDimitry Andric           return llvm::make_unique<
191*b5893f02SDimitry Andric                       orc::LocalIndirectStubsManager<orc::OrcMips32Le>>();
192*b5893f02SDimitry Andric       };
193*b5893f02SDimitry Andric 
194*b5893f02SDimitry Andric     case Triple::mips64:
195*b5893f02SDimitry Andric     case Triple::mips64el:
196*b5893f02SDimitry Andric       return [](){
197*b5893f02SDimitry Andric           return llvm::make_unique<
198*b5893f02SDimitry Andric                       orc::LocalIndirectStubsManager<orc::OrcMips64>>();
199*b5893f02SDimitry Andric       };
200*b5893f02SDimitry Andric 
2013ca95b02SDimitry Andric     case Triple::x86_64:
2023ca95b02SDimitry Andric       if (T.getOS() == Triple::OSType::Win32) {
2033ca95b02SDimitry Andric         return [](){
2043ca95b02SDimitry Andric           return llvm::make_unique<
2053ca95b02SDimitry Andric                      orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>();
2063ca95b02SDimitry Andric         };
2073ca95b02SDimitry Andric       } else {
2083ca95b02SDimitry Andric         return [](){
2093ca95b02SDimitry Andric           return llvm::make_unique<
2103ca95b02SDimitry Andric                      orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>();
2113ca95b02SDimitry Andric         };
2123ca95b02SDimitry Andric       }
2132cab237bSDimitry Andric 
2143ca95b02SDimitry Andric   }
2153ca95b02SDimitry Andric }
2163ca95b02SDimitry Andric 
createIRTypedAddress(FunctionType & FT,JITTargetAddress Addr)217d88c1a5aSDimitry Andric Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) {
218ff0cc061SDimitry Andric   Constant *AddrIntVal =
219ff0cc061SDimitry Andric     ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr);
220ff0cc061SDimitry Andric   Constant *AddrPtrVal =
221ff0cc061SDimitry Andric     ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal,
222ff0cc061SDimitry Andric                           PointerType::get(&FT, 0));
223ff0cc061SDimitry Andric   return AddrPtrVal;
224ff0cc061SDimitry Andric }
225ff0cc061SDimitry Andric 
createImplPointer(PointerType & PT,Module & M,const Twine & Name,Constant * Initializer)226ff0cc061SDimitry Andric GlobalVariable* createImplPointer(PointerType &PT, Module &M,
227ff0cc061SDimitry Andric                                   const Twine &Name, Constant *Initializer) {
228ff0cc061SDimitry Andric   auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage,
229ff0cc061SDimitry Andric                                Initializer, Name, nullptr,
230ff0cc061SDimitry Andric                                GlobalValue::NotThreadLocal, 0, true);
231ff0cc061SDimitry Andric   IP->setVisibility(GlobalValue::HiddenVisibility);
232ff0cc061SDimitry Andric   return IP;
233ff0cc061SDimitry Andric }
234ff0cc061SDimitry Andric 
makeStub(Function & F,Value & ImplPointer)2357d523365SDimitry Andric void makeStub(Function &F, Value &ImplPointer) {
236ff0cc061SDimitry Andric   assert(F.isDeclaration() && "Can't turn a definition into a stub.");
237ff0cc061SDimitry Andric   assert(F.getParent() && "Function isn't in a module.");
238ff0cc061SDimitry Andric   Module &M = *F.getParent();
239ff0cc061SDimitry Andric   BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
240ff0cc061SDimitry Andric   IRBuilder<> Builder(EntryBlock);
241ff0cc061SDimitry Andric   LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
242ff0cc061SDimitry Andric   std::vector<Value*> CallArgs;
243ff0cc061SDimitry Andric   for (auto &A : F.args())
244ff0cc061SDimitry Andric     CallArgs.push_back(&A);
245ff0cc061SDimitry Andric   CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
246ff0cc061SDimitry Andric   Call->setTailCall();
247ff0cc061SDimitry Andric   Call->setAttributes(F.getAttributes());
248ff0cc061SDimitry Andric   if (F.getReturnType()->isVoidTy())
249ff0cc061SDimitry Andric     Builder.CreateRetVoid();
250ff0cc061SDimitry Andric   else
251ff0cc061SDimitry Andric     Builder.CreateRet(Call);
252ff0cc061SDimitry Andric }
253ff0cc061SDimitry Andric 
operator ()(Module & M)254*b5893f02SDimitry Andric std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) {
255*b5893f02SDimitry Andric   std::vector<GlobalValue *> PromotedGlobals;
256ff0cc061SDimitry Andric 
257*b5893f02SDimitry Andric   for (auto &GV : M.global_values()) {
258*b5893f02SDimitry Andric     bool Promoted = true;
259*b5893f02SDimitry Andric 
260*b5893f02SDimitry Andric     // Rename if necessary.
261*b5893f02SDimitry Andric     if (!GV.hasName())
262*b5893f02SDimitry Andric       GV.setName("__orc_anon." + Twine(NextId++));
263*b5893f02SDimitry Andric     else if (GV.getName().startswith("\01L"))
264*b5893f02SDimitry Andric       GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++));
265*b5893f02SDimitry Andric     else if (GV.hasLocalLinkage())
266*b5893f02SDimitry Andric       GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++));
267*b5893f02SDimitry Andric     else
268*b5893f02SDimitry Andric       Promoted = false;
269*b5893f02SDimitry Andric 
270*b5893f02SDimitry Andric     if (GV.hasLocalLinkage()) {
271*b5893f02SDimitry Andric       GV.setLinkage(GlobalValue::ExternalLinkage);
272*b5893f02SDimitry Andric       GV.setVisibility(GlobalValue::HiddenVisibility);
273*b5893f02SDimitry Andric       Promoted = true;
274*b5893f02SDimitry Andric     }
275*b5893f02SDimitry Andric     GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
276*b5893f02SDimitry Andric 
277*b5893f02SDimitry Andric     if (Promoted)
278*b5893f02SDimitry Andric       PromotedGlobals.push_back(&GV);
279ff0cc061SDimitry Andric   }
280ff0cc061SDimitry Andric 
281*b5893f02SDimitry Andric   return PromotedGlobals;
282ff0cc061SDimitry Andric }
283ff0cc061SDimitry Andric 
cloneFunctionDecl(Module & Dst,const Function & F,ValueToValueMapTy * VMap)284ff0cc061SDimitry Andric Function* cloneFunctionDecl(Module &Dst, const Function &F,
285ff0cc061SDimitry Andric                             ValueToValueMapTy *VMap) {
286ff0cc061SDimitry Andric   Function *NewF =
2873ca95b02SDimitry Andric     Function::Create(cast<FunctionType>(F.getValueType()),
288ff0cc061SDimitry Andric                      F.getLinkage(), F.getName(), &Dst);
289ff0cc061SDimitry Andric   NewF->copyAttributesFrom(&F);
290ff0cc061SDimitry Andric 
291ff0cc061SDimitry Andric   if (VMap) {
292ff0cc061SDimitry Andric     (*VMap)[&F] = NewF;
293ff0cc061SDimitry Andric     auto NewArgI = NewF->arg_begin();
294ff0cc061SDimitry Andric     for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE;
295ff0cc061SDimitry Andric          ++ArgI, ++NewArgI)
2967d523365SDimitry Andric       (*VMap)[&*ArgI] = &*NewArgI;
297ff0cc061SDimitry Andric   }
298ff0cc061SDimitry Andric 
299ff0cc061SDimitry Andric   return NewF;
300ff0cc061SDimitry Andric }
301ff0cc061SDimitry Andric 
moveFunctionBody(Function & OrigF,ValueToValueMapTy & VMap,ValueMaterializer * Materializer,Function * NewF)302ff0cc061SDimitry Andric void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap,
303ff0cc061SDimitry Andric                       ValueMaterializer *Materializer,
304ff0cc061SDimitry Andric                       Function *NewF) {
305ff0cc061SDimitry Andric   assert(!OrigF.isDeclaration() && "Nothing to move");
306ff0cc061SDimitry Andric   if (!NewF)
307ff0cc061SDimitry Andric     NewF = cast<Function>(VMap[&OrigF]);
308ff0cc061SDimitry Andric   else
309ff0cc061SDimitry Andric     assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap.");
310ff0cc061SDimitry Andric   assert(NewF && "Function mapping missing from VMap.");
311ff0cc061SDimitry Andric   assert(NewF->getParent() != OrigF.getParent() &&
312ff0cc061SDimitry Andric          "moveFunctionBody should only be used to move bodies between "
313ff0cc061SDimitry Andric          "modules.");
314ff0cc061SDimitry Andric 
315ff0cc061SDimitry Andric   SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned.
316ff0cc061SDimitry Andric   CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns,
317ff0cc061SDimitry Andric                     "", nullptr, nullptr, Materializer);
318ff0cc061SDimitry Andric   OrigF.deleteBody();
319ff0cc061SDimitry Andric }
320ff0cc061SDimitry Andric 
cloneGlobalVariableDecl(Module & Dst,const GlobalVariable & GV,ValueToValueMapTy * VMap)321ff0cc061SDimitry Andric GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV,
322ff0cc061SDimitry Andric                                         ValueToValueMapTy *VMap) {
323ff0cc061SDimitry Andric   GlobalVariable *NewGV = new GlobalVariable(
3243ca95b02SDimitry Andric       Dst, GV.getValueType(), GV.isConstant(),
325ff0cc061SDimitry Andric       GV.getLinkage(), nullptr, GV.getName(), nullptr,
326ff0cc061SDimitry Andric       GV.getThreadLocalMode(), GV.getType()->getAddressSpace());
327ff0cc061SDimitry Andric   NewGV->copyAttributesFrom(&GV);
328ff0cc061SDimitry Andric   if (VMap)
329ff0cc061SDimitry Andric     (*VMap)[&GV] = NewGV;
330ff0cc061SDimitry Andric   return NewGV;
331ff0cc061SDimitry Andric }
332ff0cc061SDimitry Andric 
moveGlobalVariableInitializer(GlobalVariable & OrigGV,ValueToValueMapTy & VMap,ValueMaterializer * Materializer,GlobalVariable * NewGV)333ff0cc061SDimitry Andric void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
334ff0cc061SDimitry Andric                                    ValueToValueMapTy &VMap,
335ff0cc061SDimitry Andric                                    ValueMaterializer *Materializer,
336ff0cc061SDimitry Andric                                    GlobalVariable *NewGV) {
337ff0cc061SDimitry Andric   assert(OrigGV.hasInitializer() && "Nothing to move");
338ff0cc061SDimitry Andric   if (!NewGV)
339ff0cc061SDimitry Andric     NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
340ff0cc061SDimitry Andric   else
341ff0cc061SDimitry Andric     assert(VMap[&OrigGV] == NewGV &&
342ff0cc061SDimitry Andric            "Incorrect global variable mapping in VMap.");
343ff0cc061SDimitry Andric   assert(NewGV->getParent() != OrigGV.getParent() &&
3444ba319b5SDimitry Andric          "moveGlobalVariableInitializer should only be used to move "
3454ba319b5SDimitry Andric          "initializers between modules");
346ff0cc061SDimitry Andric 
347ff0cc061SDimitry Andric   NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
348ff0cc061SDimitry Andric                                  nullptr, Materializer));
349ff0cc061SDimitry Andric }
350ff0cc061SDimitry Andric 
cloneGlobalAliasDecl(Module & Dst,const GlobalAlias & OrigA,ValueToValueMapTy & VMap)3517d523365SDimitry Andric GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA,
3527d523365SDimitry Andric                                   ValueToValueMapTy &VMap) {
3537d523365SDimitry Andric   assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?");
3547d523365SDimitry Andric   auto *NewA = GlobalAlias::create(OrigA.getValueType(),
3557d523365SDimitry Andric                                    OrigA.getType()->getPointerAddressSpace(),
3567d523365SDimitry Andric                                    OrigA.getLinkage(), OrigA.getName(), &Dst);
3577d523365SDimitry Andric   NewA->copyAttributesFrom(&OrigA);
3587d523365SDimitry Andric   VMap[&OrigA] = NewA;
3597d523365SDimitry Andric   return NewA;
3607d523365SDimitry Andric }
3617d523365SDimitry Andric 
cloneModuleFlagsMetadata(Module & Dst,const Module & Src,ValueToValueMapTy & VMap)362d88c1a5aSDimitry Andric void cloneModuleFlagsMetadata(Module &Dst, const Module &Src,
363d88c1a5aSDimitry Andric                               ValueToValueMapTy &VMap) {
364d88c1a5aSDimitry Andric   auto *MFs = Src.getModuleFlagsMetadata();
365d88c1a5aSDimitry Andric   if (!MFs)
366d88c1a5aSDimitry Andric     return;
367d88c1a5aSDimitry Andric   for (auto *MF : MFs->operands())
368d88c1a5aSDimitry Andric     Dst.addModuleFlag(MapMetadata(MF, VMap));
369d88c1a5aSDimitry Andric }
370d88c1a5aSDimitry Andric 
371ff0cc061SDimitry Andric } // End namespace orc.
372ff0cc061SDimitry Andric } // End namespace llvm.
373