1321369Sdim//===- IndirectionUtils.h - Utilities for adding indirections ---*- C++ -*-===// 2283625Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6283625Sdim// 7283625Sdim//===----------------------------------------------------------------------===// 8283625Sdim// 9283625Sdim// Contains utilities for adding indirections and breaking up modules. 10283625Sdim// 11283625Sdim//===----------------------------------------------------------------------===// 12283625Sdim 13283625Sdim#ifndef LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H 14283625Sdim#define LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H 15283625Sdim 16314564Sdim#include "llvm/ADT/StringMap.h" 17314564Sdim#include "llvm/ADT/StringRef.h" 18314564Sdim#include "llvm/ADT/Twine.h" 19314564Sdim#include "llvm/ExecutionEngine/JITSymbol.h" 20341825Sdim#include "llvm/ExecutionEngine/Orc/Core.h" 21314564Sdim#include "llvm/Support/Error.h" 22314564Sdim#include "llvm/Support/Memory.h" 23309124Sdim#include "llvm/Support/Process.h" 24283625Sdim#include "llvm/Transforms/Utils/ValueMapper.h" 25314564Sdim#include <algorithm> 26314564Sdim#include <cassert> 27314564Sdim#include <cstdint> 28314564Sdim#include <functional> 29314564Sdim#include <map> 30314564Sdim#include <memory> 31314564Sdim#include <system_error> 32314564Sdim#include <utility> 33314564Sdim#include <vector> 34283625Sdim 35283625Sdimnamespace llvm { 36321369Sdim 37321369Sdimclass Constant; 38321369Sdimclass Function; 39321369Sdimclass FunctionType; 40321369Sdimclass GlobalAlias; 41321369Sdimclass GlobalVariable; 42321369Sdimclass Module; 43321369Sdimclass PointerType; 44321369Sdimclass Triple; 45321369Sdimclass Value; 46321369Sdim 47283625Sdimnamespace orc { 48283625Sdim 49344779Sdim/// Base class for pools of compiler re-entry trampolines. 50344779Sdim/// These trampolines are callable addresses that save all register state 51344779Sdim/// before calling a supplied function to return the trampoline landing 52344779Sdim/// address, then restore all state before jumping to that address. They 53344779Sdim/// are used by various ORC APIs to support lazy compilation 54344779Sdimclass TrampolinePool { 55283625Sdimpublic: 56344779Sdim virtual ~TrampolinePool() {} 57283625Sdim 58344779Sdim /// Get an available trampoline address. 59344779Sdim /// Returns an error if no trampoline can be created. 60344779Sdim virtual Expected<JITTargetAddress> getTrampoline() = 0; 61283625Sdim 62344779Sdimprivate: 63344779Sdim virtual void anchor(); 64344779Sdim}; 65283625Sdim 66344779Sdim/// A trampoline pool for trampolines within the current process. 67344779Sdimtemplate <typename ORCABI> class LocalTrampolinePool : public TrampolinePool { 68344779Sdimpublic: 69344779Sdim using GetTrampolineLandingFunction = 70344779Sdim std::function<JITTargetAddress(JITTargetAddress TrampolineAddr)>; 71341825Sdim 72344779Sdim /// Creates a LocalTrampolinePool with the given RunCallback function. 73344779Sdim /// Returns an error if this function is unable to correctly allocate, write 74344779Sdim /// and protect the resolver code block. 75344779Sdim static Expected<std::unique_ptr<LocalTrampolinePool>> 76344779Sdim Create(GetTrampolineLandingFunction GetTrampolineLanding) { 77344779Sdim Error Err = Error::success(); 78283625Sdim 79344779Sdim auto LTP = std::unique_ptr<LocalTrampolinePool>( 80344779Sdim new LocalTrampolinePool(std::move(GetTrampolineLanding), Err)); 81296417Sdim 82344779Sdim if (Err) 83344779Sdim return std::move(Err); 84344779Sdim return std::move(LTP); 85344779Sdim } 86344779Sdim 87360784Sdim /// Get a free trampoline. Returns an error if one can not be provided (e.g. 88344779Sdim /// because the pool is empty and can not be grown). 89344779Sdim Expected<JITTargetAddress> getTrampoline() override { 90344779Sdim std::lock_guard<std::mutex> Lock(LTPMutex); 91344779Sdim if (AvailableTrampolines.empty()) { 92327952Sdim if (auto Err = grow()) 93327952Sdim return std::move(Err); 94344779Sdim } 95344779Sdim assert(!AvailableTrampolines.empty() && "Failed to grow trampoline pool"); 96344779Sdim auto TrampolineAddr = AvailableTrampolines.back(); 97344779Sdim AvailableTrampolines.pop_back(); 98296417Sdim return TrampolineAddr; 99296417Sdim } 100296417Sdim 101344779Sdim /// Returns the given trampoline to the pool for re-use. 102344779Sdim void releaseTrampoline(JITTargetAddress TrampolineAddr) { 103344779Sdim std::lock_guard<std::mutex> Lock(LTPMutex); 104344779Sdim AvailableTrampolines.push_back(TrampolineAddr); 105344779Sdim } 106296417Sdim 107344779Sdimprivate: 108344779Sdim static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) { 109344779Sdim LocalTrampolinePool<ORCABI> *TrampolinePool = 110344779Sdim static_cast<LocalTrampolinePool *>(TrampolinePoolPtr); 111344779Sdim return TrampolinePool->GetTrampolineLanding(static_cast<JITTargetAddress>( 112344779Sdim reinterpret_cast<uintptr_t>(TrampolineId))); 113344779Sdim } 114341825Sdim 115344779Sdim LocalTrampolinePool(GetTrampolineLandingFunction GetTrampolineLanding, 116344779Sdim Error &Err) 117344779Sdim : GetTrampolineLanding(std::move(GetTrampolineLanding)) { 118283625Sdim 119344779Sdim ErrorAsOutParameter _(&Err); 120344779Sdim 121344779Sdim /// Try to set up the resolver block. 122296417Sdim std::error_code EC; 123309124Sdim ResolverBlock = sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( 124344779Sdim ORCABI::ResolverCodeSize, nullptr, 125309124Sdim sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); 126344779Sdim if (EC) { 127344779Sdim Err = errorCodeToError(EC); 128344779Sdim return; 129344779Sdim } 130296417Sdim 131344779Sdim ORCABI::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()), 132344779Sdim &reenter, this); 133296417Sdim 134296417Sdim EC = sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(), 135296417Sdim sys::Memory::MF_READ | 136296417Sdim sys::Memory::MF_EXEC); 137344779Sdim if (EC) { 138344779Sdim Err = errorCodeToError(EC); 139344779Sdim return; 140344779Sdim } 141283625Sdim } 142283625Sdim 143344779Sdim Error grow() { 144296417Sdim assert(this->AvailableTrampolines.empty() && "Growing prematurely?"); 145296417Sdim 146296417Sdim std::error_code EC; 147296417Sdim auto TrampolineBlock = 148309124Sdim sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory( 149353358Sdim sys::Process::getPageSizeEstimate(), nullptr, 150309124Sdim sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC)); 151327952Sdim if (EC) 152327952Sdim return errorCodeToError(EC); 153296417Sdim 154296417Sdim unsigned NumTrampolines = 155353358Sdim (sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) / 156344779Sdim ORCABI::TrampolineSize; 157296417Sdim 158309124Sdim uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base()); 159344779Sdim ORCABI::writeTrampolines(TrampolineMem, ResolverBlock.base(), 160344779Sdim NumTrampolines); 161296417Sdim 162296417Sdim for (unsigned I = 0; I < NumTrampolines; ++I) 163296417Sdim this->AvailableTrampolines.push_back( 164314564Sdim static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>( 165344779Sdim TrampolineMem + (I * ORCABI::TrampolineSize)))); 166296417Sdim 167327952Sdim if (auto EC = sys::Memory::protectMappedMemory( 168327952Sdim TrampolineBlock.getMemoryBlock(), 169327952Sdim sys::Memory::MF_READ | sys::Memory::MF_EXEC)) 170327952Sdim return errorCodeToError(EC); 171296417Sdim 172296417Sdim TrampolineBlocks.push_back(std::move(TrampolineBlock)); 173327952Sdim return Error::success(); 174296417Sdim } 175296417Sdim 176344779Sdim GetTrampolineLandingFunction GetTrampolineLanding; 177344779Sdim 178344779Sdim std::mutex LTPMutex; 179296417Sdim sys::OwningMemoryBlock ResolverBlock; 180296417Sdim std::vector<sys::OwningMemoryBlock> TrampolineBlocks; 181344779Sdim std::vector<JITTargetAddress> AvailableTrampolines; 182296417Sdim}; 183296417Sdim 184344779Sdim/// Target-independent base class for compile callback management. 185344779Sdimclass JITCompileCallbackManager { 186344779Sdimpublic: 187344779Sdim using CompileFunction = std::function<JITTargetAddress()>; 188344779Sdim 189344779Sdim virtual ~JITCompileCallbackManager() = default; 190344779Sdim 191344779Sdim /// Reserve a compile callback. 192344779Sdim Expected<JITTargetAddress> getCompileCallback(CompileFunction Compile); 193344779Sdim 194344779Sdim /// Execute the callback for the given trampoline id. Called by the JIT 195344779Sdim /// to compile functions on demand. 196344779Sdim JITTargetAddress executeCompileCallback(JITTargetAddress TrampolineAddr); 197344779Sdim 198344779Sdimprotected: 199344779Sdim /// Construct a JITCompileCallbackManager. 200344779Sdim JITCompileCallbackManager(std::unique_ptr<TrampolinePool> TP, 201344779Sdim ExecutionSession &ES, 202344779Sdim JITTargetAddress ErrorHandlerAddress) 203344779Sdim : TP(std::move(TP)), ES(ES), 204344779Sdim CallbacksJD(ES.createJITDylib("<Callbacks>")), 205344779Sdim ErrorHandlerAddress(ErrorHandlerAddress) {} 206344779Sdim 207344779Sdim void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) { 208344779Sdim this->TP = std::move(TP); 209344779Sdim } 210344779Sdim 211344779Sdimprivate: 212344779Sdim std::mutex CCMgrMutex; 213344779Sdim std::unique_ptr<TrampolinePool> TP; 214344779Sdim ExecutionSession &ES; 215344779Sdim JITDylib &CallbacksJD; 216344779Sdim JITTargetAddress ErrorHandlerAddress; 217344779Sdim std::map<JITTargetAddress, SymbolStringPtr> AddrToSymbol; 218344779Sdim size_t NextCallbackId = 0; 219344779Sdim}; 220344779Sdim 221344779Sdim/// Manage compile callbacks for in-process JITs. 222344779Sdimtemplate <typename ORCABI> 223344779Sdimclass LocalJITCompileCallbackManager : public JITCompileCallbackManager { 224344779Sdimpublic: 225344779Sdim /// Create a new LocalJITCompileCallbackManager. 226344779Sdim static Expected<std::unique_ptr<LocalJITCompileCallbackManager>> 227344779Sdim Create(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddress) { 228344779Sdim Error Err = Error::success(); 229344779Sdim auto CCMgr = std::unique_ptr<LocalJITCompileCallbackManager>( 230344779Sdim new LocalJITCompileCallbackManager(ES, ErrorHandlerAddress, Err)); 231344779Sdim if (Err) 232344779Sdim return std::move(Err); 233344779Sdim return std::move(CCMgr); 234344779Sdim } 235344779Sdim 236344779Sdimprivate: 237344779Sdim /// Construct a InProcessJITCompileCallbackManager. 238344779Sdim /// @param ErrorHandlerAddress The address of an error handler in the target 239344779Sdim /// process to be used if a compile callback fails. 240344779Sdim LocalJITCompileCallbackManager(ExecutionSession &ES, 241344779Sdim JITTargetAddress ErrorHandlerAddress, 242344779Sdim Error &Err) 243344779Sdim : JITCompileCallbackManager(nullptr, ES, ErrorHandlerAddress) { 244344779Sdim ErrorAsOutParameter _(&Err); 245344779Sdim auto TP = LocalTrampolinePool<ORCABI>::Create( 246344779Sdim [this](JITTargetAddress TrampolineAddr) { 247344779Sdim return executeCompileCallback(TrampolineAddr); 248344779Sdim }); 249344779Sdim 250344779Sdim if (!TP) { 251344779Sdim Err = TP.takeError(); 252344779Sdim return; 253344779Sdim } 254344779Sdim 255344779Sdim setTrampolinePool(std::move(*TP)); 256344779Sdim } 257344779Sdim}; 258344779Sdim 259341825Sdim/// Base class for managing collections of named indirect stubs. 260296417Sdimclass IndirectStubsManager { 261296417Sdimpublic: 262341825Sdim /// Map type for initializing the manager. See init. 263321369Sdim using StubInitsMap = StringMap<std::pair<JITTargetAddress, JITSymbolFlags>>; 264296417Sdim 265314564Sdim virtual ~IndirectStubsManager() = default; 266296417Sdim 267341825Sdim /// Create a single stub with the given name, target address and flags. 268314564Sdim virtual Error createStub(StringRef StubName, JITTargetAddress StubAddr, 269309124Sdim JITSymbolFlags StubFlags) = 0; 270296417Sdim 271341825Sdim /// Create StubInits.size() stubs with the given names, target 272296417Sdim /// addresses, and flags. 273309124Sdim virtual Error createStubs(const StubInitsMap &StubInits) = 0; 274296417Sdim 275341825Sdim /// Find the stub with the given name. If ExportedStubsOnly is true, 276296417Sdim /// this will only return a result if the stub's flags indicate that it 277296417Sdim /// is exported. 278341825Sdim virtual JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) = 0; 279296417Sdim 280341825Sdim /// Find the implementation-pointer for the stub. 281341825Sdim virtual JITEvaluatedSymbol findPointer(StringRef Name) = 0; 282296417Sdim 283341825Sdim /// Change the value of the implementation pointer for the stub. 284314564Sdim virtual Error updatePointer(StringRef Name, JITTargetAddress NewAddr) = 0; 285309124Sdim 286283625Sdimprivate: 287296417Sdim virtual void anchor(); 288296417Sdim}; 289283625Sdim 290341825Sdim/// IndirectStubsManager implementation for the host architecture, e.g. 291296417Sdim/// OrcX86_64. (See OrcArchitectureSupport.h). 292296417Sdimtemplate <typename TargetT> 293296417Sdimclass LocalIndirectStubsManager : public IndirectStubsManager { 294296417Sdimpublic: 295314564Sdim Error createStub(StringRef StubName, JITTargetAddress StubAddr, 296309124Sdim JITSymbolFlags StubFlags) override { 297344779Sdim std::lock_guard<std::mutex> Lock(StubsMutex); 298309124Sdim if (auto Err = reserveStubs(1)) 299309124Sdim return Err; 300296417Sdim 301296417Sdim createStubInternal(StubName, StubAddr, StubFlags); 302296417Sdim 303309124Sdim return Error::success(); 304283625Sdim } 305283625Sdim 306309124Sdim Error createStubs(const StubInitsMap &StubInits) override { 307344779Sdim std::lock_guard<std::mutex> Lock(StubsMutex); 308309124Sdim if (auto Err = reserveStubs(StubInits.size())) 309309124Sdim return Err; 310296417Sdim 311296417Sdim for (auto &Entry : StubInits) 312296417Sdim createStubInternal(Entry.first(), Entry.second.first, 313296417Sdim Entry.second.second); 314296417Sdim 315309124Sdim return Error::success(); 316283625Sdim } 317283625Sdim 318341825Sdim JITEvaluatedSymbol findStub(StringRef Name, bool ExportedStubsOnly) override { 319344779Sdim std::lock_guard<std::mutex> Lock(StubsMutex); 320296417Sdim auto I = StubIndexes.find(Name); 321296417Sdim if (I == StubIndexes.end()) 322296417Sdim return nullptr; 323296417Sdim auto Key = I->second.first; 324296417Sdim void *StubAddr = IndirectStubsInfos[Key.first].getStub(Key.second); 325296417Sdim assert(StubAddr && "Missing stub address"); 326296417Sdim auto StubTargetAddr = 327314564Sdim static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(StubAddr)); 328341825Sdim auto StubSymbol = JITEvaluatedSymbol(StubTargetAddr, I->second.second); 329314564Sdim if (ExportedStubsOnly && !StubSymbol.getFlags().isExported()) 330296417Sdim return nullptr; 331296417Sdim return StubSymbol; 332283625Sdim } 333283625Sdim 334341825Sdim JITEvaluatedSymbol findPointer(StringRef Name) override { 335344779Sdim std::lock_guard<std::mutex> Lock(StubsMutex); 336296417Sdim auto I = StubIndexes.find(Name); 337296417Sdim if (I == StubIndexes.end()) 338296417Sdim return nullptr; 339296417Sdim auto Key = I->second.first; 340296417Sdim void *PtrAddr = IndirectStubsInfos[Key.first].getPtr(Key.second); 341296417Sdim assert(PtrAddr && "Missing pointer address"); 342296417Sdim auto PtrTargetAddr = 343314564Sdim static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(PtrAddr)); 344341825Sdim return JITEvaluatedSymbol(PtrTargetAddr, I->second.second); 345283625Sdim } 346283625Sdim 347314564Sdim Error updatePointer(StringRef Name, JITTargetAddress NewAddr) override { 348344779Sdim using AtomicIntPtr = std::atomic<uintptr_t>; 349344779Sdim 350344779Sdim std::lock_guard<std::mutex> Lock(StubsMutex); 351296417Sdim auto I = StubIndexes.find(Name); 352296417Sdim assert(I != StubIndexes.end() && "No stub pointer for symbol"); 353296417Sdim auto Key = I->second.first; 354344779Sdim AtomicIntPtr *AtomicStubPtr = reinterpret_cast<AtomicIntPtr *>( 355344779Sdim IndirectStubsInfos[Key.first].getPtr(Key.second)); 356344779Sdim *AtomicStubPtr = static_cast<uintptr_t>(NewAddr); 357309124Sdim return Error::success(); 358296417Sdim } 359296417Sdim 360296417Sdimprivate: 361309124Sdim Error reserveStubs(unsigned NumStubs) { 362296417Sdim if (NumStubs <= FreeStubs.size()) 363309124Sdim return Error::success(); 364296417Sdim 365296417Sdim unsigned NewStubsRequired = NumStubs - FreeStubs.size(); 366296417Sdim unsigned NewBlockId = IndirectStubsInfos.size(); 367296417Sdim typename TargetT::IndirectStubsInfo ISI; 368309124Sdim if (auto Err = 369309124Sdim TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired, nullptr)) 370309124Sdim return Err; 371296417Sdim for (unsigned I = 0; I < ISI.getNumStubs(); ++I) 372296417Sdim FreeStubs.push_back(std::make_pair(NewBlockId, I)); 373296417Sdim IndirectStubsInfos.push_back(std::move(ISI)); 374309124Sdim return Error::success(); 375296417Sdim } 376296417Sdim 377314564Sdim void createStubInternal(StringRef StubName, JITTargetAddress InitAddr, 378296417Sdim JITSymbolFlags StubFlags) { 379296417Sdim auto Key = FreeStubs.back(); 380296417Sdim FreeStubs.pop_back(); 381296417Sdim *IndirectStubsInfos[Key.first].getPtr(Key.second) = 382309124Sdim reinterpret_cast<void *>(static_cast<uintptr_t>(InitAddr)); 383296417Sdim StubIndexes[StubName] = std::make_pair(Key, StubFlags); 384296417Sdim } 385296417Sdim 386344779Sdim std::mutex StubsMutex; 387296417Sdim std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos; 388321369Sdim using StubKey = std::pair<uint16_t, uint16_t>; 389296417Sdim std::vector<StubKey> FreeStubs; 390296417Sdim StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes; 391283625Sdim}; 392283625Sdim 393341825Sdim/// Create a local compile callback manager. 394309124Sdim/// 395309124Sdim/// The given target triple will determine the ABI, and the given 396309124Sdim/// ErrorHandlerAddress will be used by the resulting compile callback 397309124Sdim/// manager if a compile callback fails. 398344779SdimExpected<std::unique_ptr<JITCompileCallbackManager>> 399341825SdimcreateLocalCompileCallbackManager(const Triple &T, ExecutionSession &ES, 400314564Sdim JITTargetAddress ErrorHandlerAddress); 401309124Sdim 402341825Sdim/// Create a local indriect stubs manager builder. 403309124Sdim/// 404309124Sdim/// The given target triple will determine the ABI. 405309124Sdimstd::function<std::unique_ptr<IndirectStubsManager>()> 406309124SdimcreateLocalIndirectStubsManagerBuilder(const Triple &T); 407309124Sdim 408341825Sdim/// Build a function pointer of FunctionType with the given constant 409283625Sdim/// address. 410283625Sdim/// 411283625Sdim/// Usage example: Turn a trampoline address into a function pointer constant 412283625Sdim/// for use in a stub. 413314564SdimConstant *createIRTypedAddress(FunctionType &FT, JITTargetAddress Addr); 414283625Sdim 415341825Sdim/// Create a function pointer with the given type, name, and initializer 416283625Sdim/// in the given Module. 417309124SdimGlobalVariable *createImplPointer(PointerType &PT, Module &M, const Twine &Name, 418309124Sdim Constant *Initializer); 419283625Sdim 420341825Sdim/// Turn a function declaration into a stub function that makes an 421283625Sdim/// indirect call using the given function pointer. 422296417Sdimvoid makeStub(Function &F, Value &ImplPointer); 423283625Sdim 424344779Sdim/// Promotes private symbols to global hidden, and renames to prevent clashes 425344779Sdim/// with other promoted symbols. The same SymbolPromoter instance should be 426344779Sdim/// used for all symbols to be added to a single JITDylib. 427344779Sdimclass SymbolLinkagePromoter { 428344779Sdimpublic: 429344779Sdim /// Promote symbols in the given module. Returns the set of global values 430344779Sdim /// that have been renamed/promoted. 431344779Sdim std::vector<GlobalValue *> operator()(Module &M); 432283625Sdim 433344779Sdimprivate: 434344779Sdim unsigned NextId = 0; 435344779Sdim}; 436344779Sdim 437341825Sdim/// Clone a function declaration into a new module. 438283625Sdim/// 439283625Sdim/// This function can be used as the first step towards creating a callback 440283625Sdim/// stub (see makeStub), or moving a function body (see moveFunctionBody). 441283625Sdim/// 442283625Sdim/// If the VMap argument is non-null, a mapping will be added between F and 443283625Sdim/// the new declaration, and between each of F's arguments and the new 444283625Sdim/// declaration's arguments. This map can then be passed in to moveFunction to 445283625Sdim/// move the function body if required. Note: When moving functions between 446283625Sdim/// modules with these utilities, all decls should be cloned (and added to a 447283625Sdim/// single VMap) before any bodies are moved. This will ensure that references 448283625Sdim/// between functions all refer to the versions in the new module. 449309124SdimFunction *cloneFunctionDecl(Module &Dst, const Function &F, 450283625Sdim ValueToValueMapTy *VMap = nullptr); 451283625Sdim 452341825Sdim/// Move the body of function 'F' to a cloned function declaration in a 453283625Sdim/// different module (See related cloneFunctionDecl). 454283625Sdim/// 455283625Sdim/// If the target function declaration is not supplied via the NewF parameter 456283625Sdim/// then it will be looked up via the VMap. 457283625Sdim/// 458283625Sdim/// This will delete the body of function 'F' from its original parent module, 459283625Sdim/// but leave its declaration. 460283625Sdimvoid moveFunctionBody(Function &OrigF, ValueToValueMapTy &VMap, 461283625Sdim ValueMaterializer *Materializer = nullptr, 462283625Sdim Function *NewF = nullptr); 463283625Sdim 464341825Sdim/// Clone a global variable declaration into a new module. 465309124SdimGlobalVariable *cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, 466283625Sdim ValueToValueMapTy *VMap = nullptr); 467283625Sdim 468341825Sdim/// Move global variable GV from its parent module to cloned global 469283625Sdim/// declaration in a different module. 470283625Sdim/// 471283625Sdim/// If the target global declaration is not supplied via the NewGV parameter 472283625Sdim/// then it will be looked up via the VMap. 473283625Sdim/// 474283625Sdim/// This will delete the initializer of GV from its original parent module, 475283625Sdim/// but leave its declaration. 476283625Sdimvoid moveGlobalVariableInitializer(GlobalVariable &OrigGV, 477283625Sdim ValueToValueMapTy &VMap, 478283625Sdim ValueMaterializer *Materializer = nullptr, 479283625Sdim GlobalVariable *NewGV = nullptr); 480283625Sdim 481341825Sdim/// Clone a global alias declaration into a new module. 482309124SdimGlobalAlias *cloneGlobalAliasDecl(Module &Dst, const GlobalAlias &OrigA, 483296417Sdim ValueToValueMapTy &VMap); 484296417Sdim 485341825Sdim/// Clone module flags metadata into the destination module. 486314564Sdimvoid cloneModuleFlagsMetadata(Module &Dst, const Module &Src, 487314564Sdim ValueToValueMapTy &VMap); 488283625Sdim 489314564Sdim} // end namespace orc 490321369Sdim 491314564Sdim} // end namespace llvm 492314564Sdim 493283625Sdim#endif // LLVM_EXECUTIONENGINE_ORC_INDIRECTIONUTILS_H 494