LLVM  14.0.0git
ExecutorProcessControl.cpp
Go to the documentation of this file.
1 //===---- ExecutorProcessControl.cpp -- Executor process control APIs -----===//
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 
10 
14 #include "llvm/Support/Host.h"
15 #include "llvm/Support/Process.h"
16 
17 #define DEBUG_TYPE "orc"
18 
19 namespace llvm {
20 namespace orc {
21 
23 
25 
27  std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
28  Triple TargetTriple, unsigned PageSize,
29  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)
31 
32  OwnedMemMgr = std::move(MemMgr);
33  if (!OwnedMemMgr)
34  OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>(
36 
37  this->TargetTriple = std::move(TargetTriple);
38  this->PageSize = PageSize;
39  this->MemMgr = OwnedMemMgr.get();
40  this->MemAccess = this;
41  this->JDI = {ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager),
42  ExecutorAddr::fromPtr(this)};
43  if (this->TargetTriple.isOSBinFormatMachO())
44  GlobalManglingPrefix = '_';
45 }
46 
49  std::shared_ptr<SymbolStringPool> SSP,
50  std::unique_ptr<TaskDispatcher> D,
51  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
52 
53  if (!SSP)
54  SSP = std::make_shared<SymbolStringPool>();
55 
56  if (!D) {
57 #if LLVM_ENABLE_THREADS
58  D = std::make_unique<DynamicThreadPoolTaskDispatcher>();
59 #else
60  D = std::make_unique<InPlaceTaskDispatcher>();
61 #endif
62  }
63 
65  if (!PageSize)
66  return PageSize.takeError();
67 
69 
70  return std::make_unique<SelfExecutorProcessControl>(
72  std::move(MemMgr));
73 }
74 
76 SelfExecutorProcessControl::loadDylib(const char *DylibPath) {
77  std::string ErrMsg;
78  auto Dylib = std::make_unique<sys::DynamicLibrary>(
79  sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg));
80  if (!Dylib->isValid())
81  return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
82  DynamicLibraries.push_back(std::move(Dylib));
83  return pointerToJITTargetAddress(DynamicLibraries.back().get());
84 }
85 
88  std::vector<tpctypes::LookupResult> R;
89 
90  for (auto &Elem : Request) {
91  auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
92  assert(llvm::any_of(DynamicLibraries,
93  [=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
94  return DL.get() == Dylib;
95  }) &&
96  "Invalid handle");
97 
98  R.push_back(std::vector<JITTargetAddress>());
99  for (auto &KV : Elem.Symbols) {
100  auto &Sym = KV.first;
101  std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
102  (*Sym).size() - !!GlobalManglingPrefix);
103  void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
104  if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
105  // FIXME: Collect all failing symbols before erroring out.
106  SymbolNameVector MissingSymbols;
107  MissingSymbols.push_back(Sym);
108  return make_error<SymbolsNotFound>(SSP, std::move(MissingSymbols));
109  }
110  R.back().push_back(pointerToJITTargetAddress(Addr));
111  }
112  }
113 
114  return R;
115 }
116 
120  using MainTy = int (*)(int, char *[]);
121  return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);
122 }
123 
125  IncomingWFRHandler SendResult,
126  ArrayRef<char> ArgBuffer) {
127  using WrapperFnTy =
128  shared::CWrapperFunctionResult (*)(const char *Data, size_t Size);
129  auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();
130  SendResult(WrapperFn(ArgBuffer.data(), ArgBuffer.size()));
131 }
132 
134  D->shutdown();
135  return Error::success();
136 }
137 
138 void SelfExecutorProcessControl::writeUInt8sAsync(
139  ArrayRef<tpctypes::UInt8Write> Ws, WriteResultFn OnWriteComplete) {
140  for (auto &W : Ws)
141  *W.Addr.toPtr<uint8_t *>() = W.Value;
142  OnWriteComplete(Error::success());
143 }
144 
145 void SelfExecutorProcessControl::writeUInt16sAsync(
146  ArrayRef<tpctypes::UInt16Write> Ws, WriteResultFn OnWriteComplete) {
147  for (auto &W : Ws)
148  *W.Addr.toPtr<uint16_t *>() = W.Value;
149  OnWriteComplete(Error::success());
150 }
151 
152 void SelfExecutorProcessControl::writeUInt32sAsync(
153  ArrayRef<tpctypes::UInt32Write> Ws, WriteResultFn OnWriteComplete) {
154  for (auto &W : Ws)
155  *W.Addr.toPtr<uint32_t *>() = W.Value;
156  OnWriteComplete(Error::success());
157 }
158 
159 void SelfExecutorProcessControl::writeUInt64sAsync(
160  ArrayRef<tpctypes::UInt64Write> Ws, WriteResultFn OnWriteComplete) {
161  for (auto &W : Ws)
162  *W.Addr.toPtr<uint64_t *>() = W.Value;
163  OnWriteComplete(Error::success());
164 }
165 
166 void SelfExecutorProcessControl::writeBuffersAsync(
167  ArrayRef<tpctypes::BufferWrite> Ws, WriteResultFn OnWriteComplete) {
168  for (auto &W : Ws)
169  memcpy(W.Addr.toPtr<char *>(), W.Buffer.data(), W.Buffer.size());
170  OnWriteComplete(Error::success());
171 }
172 
173 shared::CWrapperFunctionResult
174 SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
175  void *Ctx, const void *FnTag, const char *Data, size_t Size) {
176 
177  LLVM_DEBUG({
178  dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
179  << " byte payload.\n";
180  });
181 
182  std::promise<shared::WrapperFunctionResult> ResultP;
183  auto ResultF = ResultP.get_future();
184  static_cast<SelfExecutorProcessControl *>(Ctx)
187  [ResultP = std::move(ResultP)](
188  shared::WrapperFunctionResult Result) mutable {
189  ResultP.set_value(std::move(Result));
190  },
191  pointerToJITTargetAddress(FnTag), {Data, Size});
192 
193  return ResultF.get().release();
194 }
195 
196 } // end namespace orc
197 } // end namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:37
llvm::orc::ExecutorProcessControl::MemMgr
jitlink::JITLinkMemoryManager * MemMgr
Definition: ExecutorProcessControl.h:365
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::orc::shared::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:33
llvm::orc::ExecutorProcessControl::MemoryAccess::~MemoryAccess
virtual ~MemoryAccess()
Definition: ExecutorProcessControl.cpp:22
Host.h
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:208
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::orc::ExecutorProcessControl::TargetTriple
Triple TargetTriple
Definition: ExecutorProcessControl.h:361
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
llvm::orc::SelfExecutorProcessControl::disconnect
Error disconnect() override
Disconnect from the target process.
Definition: ExecutorProcessControl.cpp:133
llvm::orc::ExecutorProcessControl::getExecutionSession
ExecutionSession & getExecutionSession()
Return the ExecutionSession associated with this instance.
Definition: ExecutorProcessControl.h:187
llvm::orc::ExecutorProcessControl
ExecutorProcessControl supports interaction with a JIT target process.
Definition: ExecutorProcessControl.h:38
llvm::orc::ExecutorProcessControl::SSP
std::shared_ptr< SymbolStringPool > SSP
Definition: ExecutorProcessControl.h:358
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::orc::ExecutionSession::runJITDispatchHandler
void runJITDispatchHandler(SendResultFunction SendResult, JITTargetAddress HandlerFnTagAddr, ArrayRef< char > ArgBuffer)
Run a registered jit-side wrapper function.
Definition: Core.cpp:2091
llvm::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:160
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Process.h
llvm::sys::DynamicLibrary::getPermanentLibrary
static DynamicLibrary getPermanentLibrary(const char *filename, std::string *errMsg=nullptr)
This function permanently loads the dynamic library at the given path.
Definition: DynamicLibrary.cpp:146
int
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
Definition: README.txt:536
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::Triple::isOSBinFormatMachO
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:648
llvm::orc::runAsMain
int runAsMain(int(*Main)(int, char *[]), ArrayRef< std::string > Args, Optional< StringRef > ProgramName=None)
Run a main function, returning the result.
Definition: TargetExecutionUtils.cpp:16
llvm::orc::ExecutorAddr::fromPtr
static ExecutorAddr fromPtr(T *Value)
Create an ExecutorAddr from the given pointer.
Definition: ExecutorAddress.h:46
FormatVariadic.h
llvm::orc::ExecutorProcessControl::MemAccess
MemoryAccess * MemAccess
Definition: ExecutorProcessControl.h:364
llvm::orc::ExecutorProcessControl::JDI
JITDispatchInfo JDI
Definition: ExecutorProcessControl.h:363
llvm::orc::ExecutorProcessControl::IncomingWFRHandler
A handler or incoming WrapperFunctionResults – either return values from callWrapper* calls,...
Definition: ExecutorProcessControl.h:48
llvm::orc::SelfExecutorProcessControl::loadDylib
Expected< tpctypes::DylibHandle > loadDylib(const char *DylibPath) override
Load the dynamic library at the given path and return a handle to it.
Definition: ExecutorProcessControl.cpp:76
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::sys::Process::getPageSize
static Expected< unsigned > getPageSize()
Get the process's page size.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1639
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::orc::SelfExecutorProcessControl::callWrapperAsync
void callWrapperAsync(ExecutorAddr WrapperFnAddr, IncomingWFRHandler OnComplete, ArrayRef< char > ArgBuffer) override
Run a wrapper function in the executor.
Definition: ExecutorProcessControl.cpp:124
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1588
uint32_t
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::orc::SelfExecutorProcessControl::SelfExecutorProcessControl
SelfExecutorProcessControl(std::shared_ptr< SymbolStringPool > SSP, std::unique_ptr< TaskDispatcher > D, Triple TargetTriple, unsigned PageSize, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr)
Definition: ExecutorProcessControl.cpp:26
llvm::orc::SelfExecutorProcessControl::lookupSymbols
Expected< std::vector< tpctypes::LookupResult > > lookupSymbols(ArrayRef< LookupRequest > Request) override
Search for symbols in the target process.
Definition: ExecutorProcessControl.cpp:87
llvm::pointerToJITTargetAddress
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Definition: JITSymbol.h:69
llvm::orc::SelfExecutorProcessControl::Create
static Expected< std::unique_ptr< SelfExecutorProcessControl > > Create(std::shared_ptr< SymbolStringPool > SSP=nullptr, std::unique_ptr< TaskDispatcher > D=nullptr, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr=nullptr)
Create a SelfExecutorProcessControl with the given symbol string pool and memory manager.
Definition: ExecutorProcessControl.cpp:48
std
Definition: BitVector.h:838
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
uint16_t
llvm::sys::getProcessTriple
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:1758
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutorProcessControl::D
std::unique_ptr< TaskDispatcher > D
Definition: ExecutorProcessControl.h:359
Core.h
llvm::orc::ExecutorProcessControl::~ExecutorProcessControl
virtual ~ExecutorProcessControl()
Definition: ExecutorProcessControl.cpp:24
llvm::orc::ExecutorProcessControl::PageSize
unsigned PageSize
Definition: ExecutorProcessControl.h:362
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
ExecutorProcessControl.h
llvm::orc::ExecutorAddr::toPtr
T toPtr() const
Cast this ExecutorAddr to a pointer of the given type.
Definition: ExecutorAddress.h:53
TargetExecutionUtils.h
llvm::sys::Process::getPageSizeEstimate
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
Definition: Process.h:62
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::orc::SymbolLookupFlags::RequiredSymbol
@ RequiredSymbol
llvm::orc::SymbolNameVector
std::vector< SymbolStringPtr > SymbolNameVector
A vector of symbol names.
Definition: Core.h:109
llvm::orc::SelfExecutorProcessControl::runAsMain
Expected< int32_t > runAsMain(ExecutorAddr MainFnAddr, ArrayRef< std::string > Args) override
Run function with a main-like signature.
Definition: ExecutorProcessControl.cpp:118