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