LLVM  14.0.0git
EPCIndirectionUtils.h
Go to the documentation of this file.
1 //===--- EPCIndirectionUtils.h - EPC based indirection utils ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Indirection utilities (stubs, trampolines, lazy call-throughs) that use the
10 // ExecutorProcessControl API to interact with the executor process.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
15 #define LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
16 
20 
21 #include <mutex>
22 
23 namespace llvm {
24 namespace orc {
25 
26 class ExecutorProcessControl;
27 
28 /// Provides ExecutorProcessControl based indirect stubs, trampoline pool and
29 /// lazy call through manager.
32 
33 public:
34  /// ABI support base class. Used to write resolver, stub, and trampoline
35  /// blocks.
36  class ABISupport {
37  protected:
38  ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize,
39  unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
40  : PointerSize(PointerSize), TrampolineSize(TrampolineSize),
41  StubSize(StubSize),
42  StubToPointerMaxDisplacement(StubToPointerMaxDisplacement),
43  ResolverCodeSize(ResolverCodeSize) {}
44 
45  public:
46  virtual ~ABISupport();
47 
48  unsigned getPointerSize() const { return PointerSize; }
49  unsigned getTrampolineSize() const { return TrampolineSize; }
50  unsigned getStubSize() const { return StubSize; }
52  return StubToPointerMaxDisplacement;
53  }
54  unsigned getResolverCodeSize() const { return ResolverCodeSize; }
55 
56  virtual void writeResolverCode(char *ResolverWorkingMem,
57  JITTargetAddress ResolverTargetAddr,
58  JITTargetAddress ReentryFnAddr,
59  JITTargetAddress ReentryCtxAddr) const = 0;
60 
61  virtual void writeTrampolines(char *TrampolineBlockWorkingMem,
62  JITTargetAddress TrampolineBlockTragetAddr,
63  JITTargetAddress ResolverAddr,
64  unsigned NumTrampolines) const = 0;
65 
66  virtual void
67  writeIndirectStubsBlock(char *StubsBlockWorkingMem,
68  JITTargetAddress StubsBlockTargetAddress,
69  JITTargetAddress PointersBlockTargetAddress,
70  unsigned NumStubs) const = 0;
71 
72  private:
73  unsigned PointerSize = 0;
74  unsigned TrampolineSize = 0;
75  unsigned StubSize = 0;
76  unsigned StubToPointerMaxDisplacement = 0;
77  unsigned ResolverCodeSize = 0;
78  };
79 
80  /// Create using the given ABI class.
81  template <typename ORCABI>
82  static std::unique_ptr<EPCIndirectionUtils>
84 
85  /// Create based on the ExecutorProcessControl triple.
88 
89  /// Return a reference to the ExecutorProcessControl object.
91 
92  /// Return a reference to the ABISupport object for this instance.
93  ABISupport &getABISupport() const { return *ABI; }
94 
95  /// Release memory for resources held by this instance. This *must* be called
96  /// prior to destruction of the class.
97  Error cleanup();
98 
99  /// Write resolver code to the executor process and return its address.
100  /// This must be called before any call to createTrampolinePool or
101  /// createLazyCallThroughManager.
103  writeResolverBlock(JITTargetAddress ReentryFnAddr,
104  JITTargetAddress ReentryCtxAddr);
105 
106  /// Returns the address of the Resolver block. Returns zero if the
107  /// writeResolverBlock method has not previously been called.
108  JITTargetAddress getResolverBlockAddress() const { return ResolverBlockAddr; }
109 
110  /// Create an IndirectStubsManager for the executor process.
111  std::unique_ptr<IndirectStubsManager> createIndirectStubsManager();
112 
113  /// Create a TrampolinePool for the executor process.
115 
116  /// Create a LazyCallThroughManager.
117  /// This function should only be called once.
120  JITTargetAddress ErrorHandlerAddr);
121 
122  /// Create a LazyCallThroughManager for the executor process.
124  assert(LCTM && "createLazyCallThroughManager must be called first");
125  return *LCTM;
126  }
127 
128 private:
129  using FinalizedAlloc = jitlink::JITLinkMemoryManager::FinalizedAlloc;
130 
131  struct IndirectStubInfo {
132  IndirectStubInfo() = default;
133  IndirectStubInfo(JITTargetAddress StubAddress,
134  JITTargetAddress PointerAddress)
135  : StubAddress(StubAddress), PointerAddress(PointerAddress) {}
136  JITTargetAddress StubAddress = 0;
137  JITTargetAddress PointerAddress = 0;
138  };
139 
140  using IndirectStubInfoVector = std::vector<IndirectStubInfo>;
141 
142  /// Create an EPCIndirectionUtils instance.
143  EPCIndirectionUtils(ExecutorProcessControl &EPC,
144  std::unique_ptr<ABISupport> ABI);
145 
146  Expected<IndirectStubInfoVector> getIndirectStubs(unsigned NumStubs);
147 
148  std::mutex EPCUIMutex;
149  ExecutorProcessControl &EPC;
150  std::unique_ptr<ABISupport> ABI;
151  JITTargetAddress ResolverBlockAddr;
152  FinalizedAlloc ResolverBlock;
153  std::unique_ptr<TrampolinePool> TP;
154  std::unique_ptr<LazyCallThroughManager> LCTM;
155 
156  std::vector<IndirectStubInfo> AvailableIndirectStubs;
157  std::vector<FinalizedAlloc> IndirectStubAllocs;
158 };
159 
160 /// This will call writeResolver on the given EPCIndirectionUtils instance
161 /// to set up re-entry via a function that will directly return the trampoline
162 /// landing address.
163 ///
164 /// The EPCIndirectionUtils' LazyCallThroughManager must have been previously
165 /// created via EPCIndirectionUtils::createLazyCallThroughManager.
166 ///
167 /// The EPCIndirectionUtils' writeResolver method must not have been previously
168 /// called.
169 ///
170 /// This function is experimental and likely subject to revision.
171 Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU);
172 
173 namespace detail {
174 
175 template <typename ORCABI>
177 public:
179  : ABISupport(ORCABI::PointerSize, ORCABI::TrampolineSize,
180  ORCABI::StubSize, ORCABI::StubToPointerMaxDisplacement,
181  ORCABI::ResolverCodeSize) {}
182 
183  void writeResolverCode(char *ResolverWorkingMem,
184  JITTargetAddress ResolverTargetAddr,
185  JITTargetAddress ReentryFnAddr,
186  JITTargetAddress ReentryCtxAddr) const override {
187  ORCABI::writeResolverCode(ResolverWorkingMem, ResolverTargetAddr,
188  ReentryFnAddr, ReentryCtxAddr);
189  }
190 
191  void writeTrampolines(char *TrampolineBlockWorkingMem,
192  JITTargetAddress TrampolineBlockTargetAddr,
193  JITTargetAddress ResolverAddr,
194  unsigned NumTrampolines) const override {
195  ORCABI::writeTrampolines(TrampolineBlockWorkingMem,
196  TrampolineBlockTargetAddr, ResolverAddr,
197  NumTrampolines);
198  }
199 
200  void writeIndirectStubsBlock(char *StubsBlockWorkingMem,
201  JITTargetAddress StubsBlockTargetAddress,
202  JITTargetAddress PointersBlockTargetAddress,
203  unsigned NumStubs) const override {
204  ORCABI::writeIndirectStubsBlock(StubsBlockWorkingMem,
205  StubsBlockTargetAddress,
206  PointersBlockTargetAddress, NumStubs);
207  }
208 };
209 
210 } // end namespace detail
211 
212 template <typename ORCABI>
213 std::unique_ptr<EPCIndirectionUtils>
215  return std::unique_ptr<EPCIndirectionUtils>(new EPCIndirectionUtils(
216  EPC, std::make_unique<detail::ABISupportImpl<ORCABI>>()));
217 }
218 
219 } // end namespace orc
220 } // end namespace llvm
221 
222 #endif // LLVM_EXECUTIONENGINE_ORC_EPCINDIRECTIONUTILS_H
llvm::orc::EPCIndirectionUtils::cleanup
Error cleanup()
Release memory for resources held by this instance.
Definition: EPCIndirectionUtils.cpp:272
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::orc::EPCIndirectionUtils::ABISupport::ABISupport
ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize, unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
Definition: EPCIndirectionUtils.h:38
llvm::orc::EPCIndirectionUtils::createIndirectStubsManager
std::unique_ptr< IndirectStubsManager > createIndirectStubsManager()
Create an IndirectStubsManager for the executor process.
Definition: EPCIndirectionUtils.cpp:317
llvm::orc::setUpInProcessLCTMReentryViaEPCIU
Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU)
This will call writeResolver on the given EPCIndirectionUtils instance to set up re-entry via a funct...
Definition: EPCIndirectionUtils.cpp:417
LazyReexports.h
llvm::orc::LazyCallThroughManager
Manages a set of 'lazy call-through' trampolines.
Definition: LazyReexports.h:38
llvm::orc::ExecutorProcessControl
ExecutorProcessControl supports interaction with a JIT target process.
Definition: ExecutorProcessControl.h:38
llvm::orc::EPCIndirectionUtils::getLazyCallThroughManager
LazyCallThroughManager & getLazyCallThroughManager()
Create a LazyCallThroughManager for the executor process.
Definition: EPCIndirectionUtils.h:123
llvm::orc::EPCIndirectionUtilsAccess
Definition: EPCIndirectionUtils.cpp:22
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::EPCIndirectionUtils::getExecutorProcessControl
ExecutorProcessControl & getExecutorProcessControl() const
Return a reference to the ExecutorProcessControl object.
Definition: EPCIndirectionUtils.h:90
llvm::orc::EPCIndirectionUtils::ABISupport::~ABISupport
virtual ~ABISupport()
Definition: EPCIndirectionUtils.cpp:237
llvm::orc::detail::ABISupportImpl::writeIndirectStubsBlock
void writeIndirectStubsBlock(char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress, JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) const override
Definition: EPCIndirectionUtils.h:200
llvm::orc::EPCIndirectionUtils::ABISupport::getResolverCodeSize
unsigned getResolverCodeSize() const
Definition: EPCIndirectionUtils.h:54
llvm::orc::TrampolinePool
Base class for pools of compiler re-entry trampolines.
Definition: IndirectionUtils.h:63
llvm::orc::EPCIndirectionUtils::ABISupport::writeTrampolines
virtual void writeTrampolines(char *TrampolineBlockWorkingMem, JITTargetAddress TrampolineBlockTragetAddr, JITTargetAddress ResolverAddr, unsigned NumTrampolines) const =0
llvm::orc::detail::ABISupportImpl::ABISupportImpl
ABISupportImpl()
Definition: EPCIndirectionUtils.h:178
uint64_t
llvm::orc::detail::ABISupportImpl
Definition: EPCIndirectionUtils.h:176
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::orc::EPCIndirectionUtils::getTrampolinePool
TrampolinePool & getTrampolinePool()
Create a TrampolinePool for the executor process.
Definition: EPCIndirectionUtils.cpp:321
llvm::orc::EPCIndirectionUtils::getABISupport
ABISupport & getABISupport() const
Return a reference to the ABISupport object for this instance.
Definition: EPCIndirectionUtils.h:93
llvm::orc::EPCIndirectionUtils::ABISupport::writeIndirectStubsBlock
virtual void writeIndirectStubsBlock(char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress, JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) const =0
llvm::orc::detail::ABISupportImpl::writeResolverCode
void writeResolverCode(char *ResolverWorkingMem, JITTargetAddress ResolverTargetAddr, JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr) const override
Definition: EPCIndirectionUtils.h:183
llvm::orc::EPCIndirectionUtils::writeResolverBlock
Expected< JITTargetAddress > writeResolverBlock(JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr)
Write resolver code to the executor process and return its address.
Definition: EPCIndirectionUtils.cpp:289
JITLinkMemoryManager.h
llvm::orc::EPCIndirectionUtils::getResolverBlockAddress
JITTargetAddress getResolverBlockAddress() const
Returns the address of the Resolver block.
Definition: EPCIndirectionUtils.h:108
llvm::orc::EPCIndirectionUtils::ABISupport::getTrampolineSize
unsigned getTrampolineSize() const
Definition: EPCIndirectionUtils.h:49
llvm::orc::EPCIndirectionUtils::CreateWithABI
static std::unique_ptr< EPCIndirectionUtils > CreateWithABI(ExecutorProcessControl &EPC)
Create using the given ABI class.
Definition: EPCIndirectionUtils.h:214
llvm::orc::EPCIndirectionUtils::Create
static Expected< std::unique_ptr< EPCIndirectionUtils > > Create(ExecutorProcessControl &EPC)
Create based on the ExecutorProcessControl triple.
Definition: EPCIndirectionUtils.cpp:240
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1359
llvm::JITTargetAddress
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42
llvm::orc::EPCIndirectionUtils::createLazyCallThroughManager
LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LazyCallThroughManager.
Definition: EPCIndirectionUtils.cpp:327
llvm::orc::EPCIndirectionUtils::ABISupport::getStubToPointerMaxDisplacement
unsigned getStubToPointerMaxDisplacement() const
Definition: EPCIndirectionUtils.h:51
llvm::orc::EPCIndirectionUtils::ABISupport::writeResolverCode
virtual void writeResolverCode(char *ResolverWorkingMem, JITTargetAddress ResolverTargetAddr, JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr) const =0
llvm::orc::EPCIndirectionUtils
Provides ExecutorProcessControl based indirect stubs, trampoline pool and lazy call through manager.
Definition: EPCIndirectionUtils.h:30
IndirectionUtils.h
llvm::orc::detail::ABISupportImpl::writeTrampolines
void writeTrampolines(char *TrampolineBlockWorkingMem, JITTargetAddress TrampolineBlockTargetAddr, JITTargetAddress ResolverAddr, unsigned NumTrampolines) const override
Definition: EPCIndirectionUtils.h:191
llvm::orc::EPCIndirectionUtils::ABISupport::getPointerSize
unsigned getPointerSize() const
Definition: EPCIndirectionUtils.h:48
llvm::orc::EPCIndirectionUtils::ABISupport::getStubSize
unsigned getStubSize() const
Definition: EPCIndirectionUtils.h:50
llvm::orc::EPCIndirectionUtils::ABISupport
ABI support base class.
Definition: EPCIndirectionUtils.h:36