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