LLVM 17.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
23namespace llvm {
24namespace orc {
25
26class ExecutorProcessControl;
27
28/// Provides ExecutorProcessControl based indirect stubs, trampoline pool and
29/// lazy call through manager.
32
33public:
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.
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
128private:
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 = 0;
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.
171Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU);
172
173namespace detail {
174
175template <typename ORCABI>
177public:
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
212template <typename ORCABI>
213std::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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Tagged union holding either a T or a Error.
Definition: Error.h:470
virtual void writeResolverCode(char *ResolverWorkingMem, JITTargetAddress ResolverTargetAddr, JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr) const =0
ABISupport(unsigned PointerSize, unsigned TrampolineSize, unsigned StubSize, unsigned StubToPointerMaxDisplacement, unsigned ResolverCodeSize)
virtual void writeTrampolines(char *TrampolineBlockWorkingMem, JITTargetAddress TrampolineBlockTragetAddr, JITTargetAddress ResolverAddr, unsigned NumTrampolines) const =0
virtual void writeIndirectStubsBlock(char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress, JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) const =0
Provides ExecutorProcessControl based indirect stubs, trampoline pool and lazy call through manager.
std::unique_ptr< IndirectStubsManager > createIndirectStubsManager()
Create an IndirectStubsManager for the executor process.
LazyCallThroughManager & getLazyCallThroughManager()
Create a LazyCallThroughManager for the executor process.
static std::unique_ptr< EPCIndirectionUtils > CreateWithABI(ExecutorProcessControl &EPC)
Create using the given ABI class.
ExecutorProcessControl & getExecutorProcessControl() const
Return a reference to the ExecutorProcessControl object.
LazyCallThroughManager & createLazyCallThroughManager(ExecutionSession &ES, JITTargetAddress ErrorHandlerAddr)
Create a LazyCallThroughManager.
Error cleanup()
Release memory for resources held by this instance.
Expected< JITTargetAddress > writeResolverBlock(JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr)
Write resolver code to the executor process and return its address.
TrampolinePool & getTrampolinePool()
Create a TrampolinePool for the executor process.
static Expected< std::unique_ptr< EPCIndirectionUtils > > Create(ExecutorProcessControl &EPC)
Create based on the ExecutorProcessControl triple.
ABISupport & getABISupport() const
Return a reference to the ABISupport object for this instance.
JITTargetAddress getResolverBlockAddress() const
Returns the address of the Resolver block.
An ExecutionSession represents a running JIT program.
Definition: Core.h:1373
ExecutorProcessControl supports interaction with a JIT target process.
Manages a set of 'lazy call-through' trampolines.
Definition: LazyReexports.h:38
Base class for pools of compiler re-entry trampolines.
void writeIndirectStubsBlock(char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress, JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) const override
void writeResolverCode(char *ResolverWorkingMem, JITTargetAddress ResolverTargetAddr, JITTargetAddress ReentryFnAddr, JITTargetAddress ReentryCtxAddr) const override
void writeTrampolines(char *TrampolineBlockWorkingMem, JITTargetAddress TrampolineBlockTargetAddr, JITTargetAddress ResolverAddr, unsigned NumTrampolines) const override
Error setUpInProcessLCTMReentryViaEPCIU(EPCIndirectionUtils &EPCIU)
This will call writeResolver on the given EPCIndirectionUtils instance to set up re-entry via a funct...
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
uint64_t JITTargetAddress
Represents an address in the target process's address space.
Definition: JITSymbol.h:42