1*0b57cec5SDimitry Andric //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h" 10*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 11*0b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 12*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/OrcABISupport.h" 13*0b57cec5SDimitry Andric #include "llvm/IR/CallSite.h" 14*0b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h" 15*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 16*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 17*0b57cec5SDimitry Andric #include <sstream> 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric using namespace llvm; 20*0b57cec5SDimitry Andric using namespace llvm::orc; 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric namespace { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric class CompileCallbackMaterializationUnit : public orc::MaterializationUnit { 25*0b57cec5SDimitry Andric public: 26*0b57cec5SDimitry Andric using CompileFunction = JITCompileCallbackManager::CompileFunction; 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric CompileCallbackMaterializationUnit(SymbolStringPtr Name, 29*0b57cec5SDimitry Andric CompileFunction Compile, VModuleKey K) 30*0b57cec5SDimitry Andric : MaterializationUnit(SymbolFlagsMap({{Name, JITSymbolFlags::Exported}}), 31*0b57cec5SDimitry Andric std::move(K)), 32*0b57cec5SDimitry Andric Name(std::move(Name)), Compile(std::move(Compile)) {} 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric StringRef getName() const override { return "<Compile Callbacks>"; } 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric private: 37*0b57cec5SDimitry Andric void materialize(MaterializationResponsibility R) override { 38*0b57cec5SDimitry Andric SymbolMap Result; 39*0b57cec5SDimitry Andric Result[Name] = JITEvaluatedSymbol(Compile(), JITSymbolFlags::Exported); 40*0b57cec5SDimitry Andric R.notifyResolved(Result); 41*0b57cec5SDimitry Andric R.notifyEmitted(); 42*0b57cec5SDimitry Andric } 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric void discard(const JITDylib &JD, const SymbolStringPtr &Name) override { 45*0b57cec5SDimitry Andric llvm_unreachable("Discard should never occur on a LMU?"); 46*0b57cec5SDimitry Andric } 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric SymbolStringPtr Name; 49*0b57cec5SDimitry Andric CompileFunction Compile; 50*0b57cec5SDimitry Andric }; 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric } // namespace 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric namespace llvm { 55*0b57cec5SDimitry Andric namespace orc { 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric void IndirectStubsManager::anchor() {} 58*0b57cec5SDimitry Andric void TrampolinePool::anchor() {} 59*0b57cec5SDimitry Andric 60*0b57cec5SDimitry Andric Expected<JITTargetAddress> 61*0b57cec5SDimitry Andric JITCompileCallbackManager::getCompileCallback(CompileFunction Compile) { 62*0b57cec5SDimitry Andric if (auto TrampolineAddr = TP->getTrampoline()) { 63*0b57cec5SDimitry Andric auto CallbackName = 64*0b57cec5SDimitry Andric ES.intern(std::string("cc") + std::to_string(++NextCallbackId)); 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric std::lock_guard<std::mutex> Lock(CCMgrMutex); 67*0b57cec5SDimitry Andric AddrToSymbol[*TrampolineAddr] = CallbackName; 68*0b57cec5SDimitry Andric cantFail(CallbacksJD.define( 69*0b57cec5SDimitry Andric llvm::make_unique<CompileCallbackMaterializationUnit>( 70*0b57cec5SDimitry Andric std::move(CallbackName), std::move(Compile), 71*0b57cec5SDimitry Andric ES.allocateVModule()))); 72*0b57cec5SDimitry Andric return *TrampolineAddr; 73*0b57cec5SDimitry Andric } else 74*0b57cec5SDimitry Andric return TrampolineAddr.takeError(); 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric JITTargetAddress JITCompileCallbackManager::executeCompileCallback( 78*0b57cec5SDimitry Andric JITTargetAddress TrampolineAddr) { 79*0b57cec5SDimitry Andric SymbolStringPtr Name; 80*0b57cec5SDimitry Andric 81*0b57cec5SDimitry Andric { 82*0b57cec5SDimitry Andric std::unique_lock<std::mutex> Lock(CCMgrMutex); 83*0b57cec5SDimitry Andric auto I = AddrToSymbol.find(TrampolineAddr); 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric // If this address is not associated with a compile callback then report an 86*0b57cec5SDimitry Andric // error to the execution session and return ErrorHandlerAddress to the 87*0b57cec5SDimitry Andric // callee. 88*0b57cec5SDimitry Andric if (I == AddrToSymbol.end()) { 89*0b57cec5SDimitry Andric Lock.unlock(); 90*0b57cec5SDimitry Andric std::string ErrMsg; 91*0b57cec5SDimitry Andric { 92*0b57cec5SDimitry Andric raw_string_ostream ErrMsgStream(ErrMsg); 93*0b57cec5SDimitry Andric ErrMsgStream << "No compile callback for trampoline at " 94*0b57cec5SDimitry Andric << format("0x%016" PRIx64, TrampolineAddr); 95*0b57cec5SDimitry Andric } 96*0b57cec5SDimitry Andric ES.reportError( 97*0b57cec5SDimitry Andric make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode())); 98*0b57cec5SDimitry Andric return ErrorHandlerAddress; 99*0b57cec5SDimitry Andric } else 100*0b57cec5SDimitry Andric Name = I->second; 101*0b57cec5SDimitry Andric } 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric if (auto Sym = ES.lookup(JITDylibSearchList({{&CallbacksJD, true}}), Name)) 104*0b57cec5SDimitry Andric return Sym->getAddress(); 105*0b57cec5SDimitry Andric else { 106*0b57cec5SDimitry Andric llvm::dbgs() << "Didn't find callback.\n"; 107*0b57cec5SDimitry Andric // If anything goes wrong materializing Sym then report it to the session 108*0b57cec5SDimitry Andric // and return the ErrorHandlerAddress; 109*0b57cec5SDimitry Andric ES.reportError(Sym.takeError()); 110*0b57cec5SDimitry Andric return ErrorHandlerAddress; 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric Expected<std::unique_ptr<JITCompileCallbackManager>> 115*0b57cec5SDimitry Andric createLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, 116*0b57cec5SDimitry Andric JITTargetAddress ErrorHandlerAddress) { 117*0b57cec5SDimitry Andric switch (T.getArch()) { 118*0b57cec5SDimitry Andric default: 119*0b57cec5SDimitry Andric return make_error<StringError>( 120*0b57cec5SDimitry Andric std::string("No callback manager available for ") + T.str(), 121*0b57cec5SDimitry Andric inconvertibleErrorCode()); 122*0b57cec5SDimitry Andric case Triple::aarch64: { 123*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcAArch64> CCMgrT; 124*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric case Triple::x86: { 128*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcI386> CCMgrT; 129*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric case Triple::mips: { 133*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Be> CCMgrT; 134*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 135*0b57cec5SDimitry Andric } 136*0b57cec5SDimitry Andric case Triple::mipsel: { 137*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcMips32Le> CCMgrT; 138*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric case Triple::mips64: 142*0b57cec5SDimitry Andric case Triple::mips64el: { 143*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcMips64> CCMgrT; 144*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 145*0b57cec5SDimitry Andric } 146*0b57cec5SDimitry Andric 147*0b57cec5SDimitry Andric case Triple::x86_64: { 148*0b57cec5SDimitry Andric if ( T.getOS() == Triple::OSType::Win32 ) { 149*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_Win32> CCMgrT; 150*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 151*0b57cec5SDimitry Andric } else { 152*0b57cec5SDimitry Andric typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64_SysV> CCMgrT; 153*0b57cec5SDimitry Andric return CCMgrT::Create(ES, ErrorHandlerAddress); 154*0b57cec5SDimitry Andric } 155*0b57cec5SDimitry Andric } 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric } 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric std::function<std::unique_ptr<IndirectStubsManager>()> 161*0b57cec5SDimitry Andric createLocalIndirectStubsManagerBuilder(const Triple &T) { 162*0b57cec5SDimitry Andric switch (T.getArch()) { 163*0b57cec5SDimitry Andric default: 164*0b57cec5SDimitry Andric return [](){ 165*0b57cec5SDimitry Andric return llvm::make_unique< 166*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcGenericABI>>(); 167*0b57cec5SDimitry Andric }; 168*0b57cec5SDimitry Andric 169*0b57cec5SDimitry Andric case Triple::aarch64: 170*0b57cec5SDimitry Andric return [](){ 171*0b57cec5SDimitry Andric return llvm::make_unique< 172*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcAArch64>>(); 173*0b57cec5SDimitry Andric }; 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric case Triple::x86: 176*0b57cec5SDimitry Andric return [](){ 177*0b57cec5SDimitry Andric return llvm::make_unique< 178*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcI386>>(); 179*0b57cec5SDimitry Andric }; 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric case Triple::mips: 182*0b57cec5SDimitry Andric return [](){ 183*0b57cec5SDimitry Andric return llvm::make_unique< 184*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcMips32Be>>(); 185*0b57cec5SDimitry Andric }; 186*0b57cec5SDimitry Andric 187*0b57cec5SDimitry Andric case Triple::mipsel: 188*0b57cec5SDimitry Andric return [](){ 189*0b57cec5SDimitry Andric return llvm::make_unique< 190*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcMips32Le>>(); 191*0b57cec5SDimitry Andric }; 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric case Triple::mips64: 194*0b57cec5SDimitry Andric case Triple::mips64el: 195*0b57cec5SDimitry Andric return [](){ 196*0b57cec5SDimitry Andric return llvm::make_unique< 197*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcMips64>>(); 198*0b57cec5SDimitry Andric }; 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric case Triple::x86_64: 201*0b57cec5SDimitry Andric if (T.getOS() == Triple::OSType::Win32) { 202*0b57cec5SDimitry Andric return [](){ 203*0b57cec5SDimitry Andric return llvm::make_unique< 204*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcX86_64_Win32>>(); 205*0b57cec5SDimitry Andric }; 206*0b57cec5SDimitry Andric } else { 207*0b57cec5SDimitry Andric return [](){ 208*0b57cec5SDimitry Andric return llvm::make_unique< 209*0b57cec5SDimitry Andric orc::LocalIndirectStubsManager<orc::OrcX86_64_SysV>>(); 210*0b57cec5SDimitry Andric }; 211*0b57cec5SDimitry Andric } 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric } 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 216*0b57cec5SDimitry Andric Constant* createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr) { 217*0b57cec5SDimitry Andric Constant *AddrIntVal = 218*0b57cec5SDimitry Andric ConstantInt::get(Type::getInt64Ty(FT.getContext()), Addr); 219*0b57cec5SDimitry Andric Constant *AddrPtrVal = 220*0b57cec5SDimitry Andric ConstantExpr::getCast(Instruction::IntToPtr, AddrIntVal, 221*0b57cec5SDimitry Andric PointerType::get(&FT, 0)); 222*0b57cec5SDimitry Andric return AddrPtrVal; 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric GlobalVariable* createImplPointer(PointerType &PT, Module &M, 226*0b57cec5SDimitry Andric const Twine &Name, Constant *Initializer) { 227*0b57cec5SDimitry Andric auto IP = new GlobalVariable(M, &PT, false, GlobalValue::ExternalLinkage, 228*0b57cec5SDimitry Andric Initializer, Name, nullptr, 229*0b57cec5SDimitry Andric GlobalValue::NotThreadLocal, 0, true); 230*0b57cec5SDimitry Andric IP->setVisibility(GlobalValue::HiddenVisibility); 231*0b57cec5SDimitry Andric return IP; 232*0b57cec5SDimitry Andric } 233*0b57cec5SDimitry Andric 234*0b57cec5SDimitry Andric void makeStub(Function &F, Value &ImplPointer) { 235*0b57cec5SDimitry Andric assert(F.isDeclaration() && "Can't turn a definition into a stub."); 236*0b57cec5SDimitry Andric assert(F.getParent() && "Function isn't in a module."); 237*0b57cec5SDimitry Andric Module &M = *F.getParent(); 238*0b57cec5SDimitry Andric BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F); 239*0b57cec5SDimitry Andric IRBuilder<> Builder(EntryBlock); 240*0b57cec5SDimitry Andric LoadInst *ImplAddr = Builder.CreateLoad(F.getType(), &ImplPointer); 241*0b57cec5SDimitry Andric std::vector<Value*> CallArgs; 242*0b57cec5SDimitry Andric for (auto &A : F.args()) 243*0b57cec5SDimitry Andric CallArgs.push_back(&A); 244*0b57cec5SDimitry Andric CallInst *Call = Builder.CreateCall(F.getFunctionType(), ImplAddr, CallArgs); 245*0b57cec5SDimitry Andric Call->setTailCall(); 246*0b57cec5SDimitry Andric Call->setAttributes(F.getAttributes()); 247*0b57cec5SDimitry Andric if (F.getReturnType()->isVoidTy()) 248*0b57cec5SDimitry Andric Builder.CreateRetVoid(); 249*0b57cec5SDimitry Andric else 250*0b57cec5SDimitry Andric Builder.CreateRet(Call); 251*0b57cec5SDimitry Andric } 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric std::vector<GlobalValue *> SymbolLinkagePromoter::operator()(Module &M) { 254*0b57cec5SDimitry Andric std::vector<GlobalValue *> PromotedGlobals; 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andric for (auto &GV : M.global_values()) { 257*0b57cec5SDimitry Andric bool Promoted = true; 258*0b57cec5SDimitry Andric 259*0b57cec5SDimitry Andric // Rename if necessary. 260*0b57cec5SDimitry Andric if (!GV.hasName()) 261*0b57cec5SDimitry Andric GV.setName("__orc_anon." + Twine(NextId++)); 262*0b57cec5SDimitry Andric else if (GV.getName().startswith("\01L")) 263*0b57cec5SDimitry Andric GV.setName("__" + GV.getName().substr(1) + "." + Twine(NextId++)); 264*0b57cec5SDimitry Andric else if (GV.hasLocalLinkage()) 265*0b57cec5SDimitry Andric GV.setName("__orc_lcl." + GV.getName() + "." + Twine(NextId++)); 266*0b57cec5SDimitry Andric else 267*0b57cec5SDimitry Andric Promoted = false; 268*0b57cec5SDimitry Andric 269*0b57cec5SDimitry Andric if (GV.hasLocalLinkage()) { 270*0b57cec5SDimitry Andric GV.setLinkage(GlobalValue::ExternalLinkage); 271*0b57cec5SDimitry Andric GV.setVisibility(GlobalValue::HiddenVisibility); 272*0b57cec5SDimitry Andric Promoted = true; 273*0b57cec5SDimitry Andric } 274*0b57cec5SDimitry Andric GV.setUnnamedAddr(GlobalValue::UnnamedAddr::None); 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric if (Promoted) 277*0b57cec5SDimitry Andric PromotedGlobals.push_back(&GV); 278*0b57cec5SDimitry Andric } 279*0b57cec5SDimitry Andric 280*0b57cec5SDimitry Andric return PromotedGlobals; 281*0b57cec5SDimitry Andric } 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric Function* cloneFunctionDecl(Module &Dst, const Function &F, 284*0b57cec5SDimitry Andric ValueToValueMapTy *VMap) { 285*0b57cec5SDimitry Andric Function *NewF = 286*0b57cec5SDimitry Andric Function::Create(cast<FunctionType>(F.getValueType()), 287*0b57cec5SDimitry Andric F.getLinkage(), F.getName(), &Dst); 288*0b57cec5SDimitry Andric NewF->copyAttributesFrom(&F); 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric if (VMap) { 291*0b57cec5SDimitry Andric (*VMap)[&F] = NewF; 292*0b57cec5SDimitry Andric auto NewArgI = NewF->arg_begin(); 293*0b57cec5SDimitry Andric for (auto ArgI = F.arg_begin(), ArgE = F.arg_end(); ArgI != ArgE; 294*0b57cec5SDimitry Andric ++ArgI, ++NewArgI) 295*0b57cec5SDimitry Andric (*VMap)[&*ArgI] = &*NewArgI; 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric return NewF; 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric void moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, 302*0b57cec5SDimitry Andric ValueMaterializer *Materializer, 303*0b57cec5SDimitry Andric Function *NewF) { 304*0b57cec5SDimitry Andric assert(!OrigF.isDeclaration() && "Nothing to move"); 305*0b57cec5SDimitry Andric if (!NewF) 306*0b57cec5SDimitry Andric NewF = cast<Function>(VMap[&OrigF]); 307*0b57cec5SDimitry Andric else 308*0b57cec5SDimitry Andric assert(VMap[&OrigF] == NewF && "Incorrect function mapping in VMap."); 309*0b57cec5SDimitry Andric assert(NewF && "Function mapping missing from VMap."); 310*0b57cec5SDimitry Andric assert(NewF->getParent() != OrigF.getParent() && 311*0b57cec5SDimitry Andric "moveFunctionBody should only be used to move bodies between " 312*0b57cec5SDimitry Andric "modules."); 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. 315*0b57cec5SDimitry Andric CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns, 316*0b57cec5SDimitry Andric "", nullptr, nullptr, Materializer); 317*0b57cec5SDimitry Andric OrigF.deleteBody(); 318*0b57cec5SDimitry Andric } 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andric GlobalVariable* cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, 321*0b57cec5SDimitry Andric ValueToValueMapTy *VMap) { 322*0b57cec5SDimitry Andric GlobalVariable *NewGV = new GlobalVariable( 323*0b57cec5SDimitry Andric Dst, GV.getValueType(), GV.isConstant(), 324*0b57cec5SDimitry Andric GV.getLinkage(), nullptr, GV.getName(), nullptr, 325*0b57cec5SDimitry Andric GV.getThreadLocalMode(), GV.getType()->getAddressSpace()); 326*0b57cec5SDimitry Andric NewGV->copyAttributesFrom(&GV); 327*0b57cec5SDimitry Andric if (VMap) 328*0b57cec5SDimitry Andric (*VMap)[&GV] = NewGV; 329*0b57cec5SDimitry Andric return NewGV; 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric void moveGlobalVariableInitializer(GlobalVariable &OrigGV, 333*0b57cec5SDimitry Andric ValueToValueMapTy &VMap, 334*0b57cec5SDimitry Andric ValueMaterializer *Materializer, 335*0b57cec5SDimitry Andric GlobalVariable *NewGV) { 336*0b57cec5SDimitry Andric assert(OrigGV.hasInitializer() && "Nothing to move"); 337*0b57cec5SDimitry Andric if (!NewGV) 338*0b57cec5SDimitry Andric NewGV = cast<GlobalVariable>(VMap[&OrigGV]); 339*0b57cec5SDimitry Andric else 340*0b57cec5SDimitry Andric assert(VMap[&OrigGV] == NewGV && 341*0b57cec5SDimitry Andric "Incorrect global variable mapping in VMap."); 342*0b57cec5SDimitry Andric assert(NewGV->getParent() != OrigGV.getParent() && 343*0b57cec5SDimitry Andric "moveGlobalVariableInitializer should only be used to move " 344*0b57cec5SDimitry Andric "initializers between modules"); 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None, 347*0b57cec5SDimitry Andric nullptr, Materializer)); 348*0b57cec5SDimitry Andric } 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric GlobalAlias* cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, 351*0b57cec5SDimitry Andric ValueToValueMapTy &VMap) { 352*0b57cec5SDimitry Andric assert(OrigA.getAliasee() && "Original alias doesn't have an aliasee?"); 353*0b57cec5SDimitry Andric auto *NewA = GlobalAlias::create(OrigA.getValueType(), 354*0b57cec5SDimitry Andric OrigA.getType()->getPointerAddressSpace(), 355*0b57cec5SDimitry Andric OrigA.getLinkage(), OrigA.getName(), &Dst); 356*0b57cec5SDimitry Andric NewA->copyAttributesFrom(&OrigA); 357*0b57cec5SDimitry Andric VMap[&OrigA] = NewA; 358*0b57cec5SDimitry Andric return NewA; 359*0b57cec5SDimitry Andric } 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric void cloneModuleFlagsMetadata(Module &Dst, const Module &Src, 362*0b57cec5SDimitry Andric ValueToValueMapTy &VMap) { 363*0b57cec5SDimitry Andric auto *MFs = Src.getModuleFlagsMetadata(); 364*0b57cec5SDimitry Andric if (!MFs) 365*0b57cec5SDimitry Andric return; 366*0b57cec5SDimitry Andric for (auto *MF : MFs->operands()) 367*0b57cec5SDimitry Andric Dst.addModuleFlag(MapMetadata(MF, VMap)); 368*0b57cec5SDimitry Andric } 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric } // End namespace orc. 371*0b57cec5SDimitry Andric } // End namespace llvm. 372