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, Triple TargetTriple,
28  unsigned PageSize, std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr)
30 
31  OwnedMemMgr = std::move(MemMgr);
32  if (!OwnedMemMgr)
33  OwnedMemMgr = std::make_unique<jitlink::InProcessMemoryManager>();
34 
35  this->TargetTriple = std::move(TargetTriple);
36  this->PageSize = PageSize;
37  this->MemMgr = OwnedMemMgr.get();
38  this->MemAccess = this;
39  this->JDI = {ExecutorAddress::fromPtr(jitDispatchViaWrapperFunctionManager),
41  if (this->TargetTriple.isOSBinFormatMachO())
42  GlobalManglingPrefix = '_';
43 }
44 
47  std::shared_ptr<SymbolStringPool> SSP,
48  std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr) {
49 
50  if (!SSP)
51  SSP = std::make_shared<SymbolStringPool>();
52 
54  if (!PageSize)
55  return PageSize.takeError();
56 
58 
59  return std::make_unique<SelfExecutorProcessControl>(
61 }
62 
64 SelfExecutorProcessControl::loadDylib(const char *DylibPath) {
65  std::string ErrMsg;
66  auto Dylib = std::make_unique<sys::DynamicLibrary>(
67  sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg));
68  if (!Dylib->isValid())
69  return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
70  DynamicLibraries.push_back(std::move(Dylib));
71  return pointerToJITTargetAddress(DynamicLibraries.back().get());
72 }
73 
76  std::vector<tpctypes::LookupResult> R;
77 
78  for (auto &Elem : Request) {
79  auto *Dylib = jitTargetAddressToPointer<sys::DynamicLibrary *>(Elem.Handle);
80  assert(llvm::any_of(DynamicLibraries,
81  [=](const std::unique_ptr<sys::DynamicLibrary> &DL) {
82  return DL.get() == Dylib;
83  }) &&
84  "Invalid handle");
85 
86  R.push_back(std::vector<JITTargetAddress>());
87  for (auto &KV : Elem.Symbols) {
88  auto &Sym = KV.first;
89  std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
90  (*Sym).size() - !!GlobalManglingPrefix);
91  void *Addr = Dylib->getAddressOfSymbol(Tmp.c_str());
92  if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol) {
93  // FIXME: Collect all failing symbols before erroring out.
94  SymbolNameVector MissingSymbols;
95  MissingSymbols.push_back(Sym);
96  return make_error<SymbolsNotFound>(std::move(MissingSymbols));
97  }
98  R.back().push_back(pointerToJITTargetAddress(Addr));
99  }
100  }
101 
102  return R;
103 }
104 
108  using MainTy = int (*)(int, char *[]);
109  return orc::runAsMain(jitTargetAddressToFunction<MainTy>(MainFnAddr), Args);
110 }
111 
113  SendResultFunction SendResult, JITTargetAddress WrapperFnAddr,
114  ArrayRef<char> ArgBuffer) {
115  using WrapperFnTy =
116  shared::detail::CWrapperFunctionResult (*)(const char *Data, size_t Size);
117  auto *WrapperFn = jitTargetAddressToFunction<WrapperFnTy>(WrapperFnAddr);
118  SendResult(WrapperFn(ArgBuffer.data(), ArgBuffer.size()));
119 }
120 
122 
123 void SelfExecutorProcessControl::writeUInt8sAsync(
124  ArrayRef<tpctypes::UInt8Write> Ws, WriteResultFn OnWriteComplete) {
125  for (auto &W : Ws)
126  *jitTargetAddressToPointer<uint8_t *>(W.Address) = W.Value;
127  OnWriteComplete(Error::success());
128 }
129 
130 void SelfExecutorProcessControl::writeUInt16sAsync(
131  ArrayRef<tpctypes::UInt16Write> Ws, WriteResultFn OnWriteComplete) {
132  for (auto &W : Ws)
133  *jitTargetAddressToPointer<uint16_t *>(W.Address) = W.Value;
134  OnWriteComplete(Error::success());
135 }
136 
137 void SelfExecutorProcessControl::writeUInt32sAsync(
138  ArrayRef<tpctypes::UInt32Write> Ws, WriteResultFn OnWriteComplete) {
139  for (auto &W : Ws)
140  *jitTargetAddressToPointer<uint32_t *>(W.Address) = W.Value;
141  OnWriteComplete(Error::success());
142 }
143 
144 void SelfExecutorProcessControl::writeUInt64sAsync(
145  ArrayRef<tpctypes::UInt64Write> Ws, WriteResultFn OnWriteComplete) {
146  for (auto &W : Ws)
147  *jitTargetAddressToPointer<uint64_t *>(W.Address) = W.Value;
148  OnWriteComplete(Error::success());
149 }
150 
151 void SelfExecutorProcessControl::writeBuffersAsync(
152  ArrayRef<tpctypes::BufferWrite> Ws, WriteResultFn OnWriteComplete) {
153  for (auto &W : Ws)
154  memcpy(jitTargetAddressToPointer<char *>(W.Address), W.Buffer.data(),
155  W.Buffer.size());
156  OnWriteComplete(Error::success());
157 }
158 
159 shared::detail::CWrapperFunctionResult
160 SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
161  void *Ctx, const void *FnTag, const char *Data, size_t Size) {
162 
163  LLVM_DEBUG({
164  dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
165  << " byte payload.\n";
166  });
167 
168  std::promise<shared::WrapperFunctionResult> ResultP;
169  auto ResultF = ResultP.get_future();
170  static_cast<SelfExecutorProcessControl *>(Ctx)
173  [ResultP = std::move(ResultP)](
174  shared::WrapperFunctionResult Result) mutable {
175  ResultP.set_value(std::move(Result));
176  },
177  pointerToJITTargetAddress(FnTag), {Data, Size});
178 
179  return ResultF.get().release();
180 }
181 
182 } // end namespace orc
183 } // end namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorProcessControl::MemMgr
jitlink::JITLinkMemoryManager * MemMgr
Definition: ExecutorProcessControl.h:277
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::unique_function
unique_function is a type-erasing functor similar to std::function.
Definition: FunctionExtras.h:55
llvm::orc::ExecutorProcessControl::MemoryAccess::~MemoryAccess
virtual ~MemoryAccess()
Definition: ExecutorProcessControl.cpp:22
Host.h
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:194
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::orc::ExecutorProcessControl::TargetTriple
Triple TargetTriple
Definition: ExecutorProcessControl.h:273
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:121
llvm::orc::ExecutorProcessControl::getExecutionSession
ExecutionSession & getExecutionSession()
Return the ExecutionSession associated with this instance.
Definition: ExecutorProcessControl.h:129
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:271
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::ArrayRef::data
const T * data() const
Definition: ArrayRef.h:162
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::orc::SelfExecutorProcessControl::runAsMain
Expected< int32_t > runAsMain(JITTargetAddress MainFnAddr, ArrayRef< std::string > Args) override
Run function with a main-like signature.
Definition: ExecutorProcessControl.cpp:106
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::orc::shared::detail::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:37
llvm::Triple::isOSBinFormatMachO
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:645
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
FormatVariadic.h
llvm::orc::ExecutorProcessControl::MemAccess
MemoryAccess * MemAccess
Definition: ExecutorProcessControl.h:276
llvm::orc::ExecutorProcessControl::JDI
JITDispatchInfo JDI
Definition: ExecutorProcessControl.h:275
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:64
uint64_t
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.
llvm::orc::SelfExecutorProcessControl::Create
static Expected< std::unique_ptr< SelfExecutorProcessControl > > Create(std::shared_ptr< SymbolStringPool > SSP=nullptr, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr=nullptr)
Create a SelfExecutorProcessControl with the given symbol string pool and memory manager.
Definition: ExecutorProcessControl.cpp:46
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:1605
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::ExecutorAddress::fromPtr
static ExecutorAddress fromPtr(T *Value)
Create an ExecutorAddress from the given pointer.
Definition: ExecutorAddress.h:44
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:1554
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::orc::SelfExecutorProcessControl::lookupSymbols
Expected< std::vector< tpctypes::LookupResult > > lookupSymbols(ArrayRef< LookupRequest > Request) override
Search for symbols in the target process.
Definition: ExecutorProcessControl.cpp:75
llvm::pointerToJITTargetAddress
JITTargetAddress pointerToJITTargetAddress(T *Ptr)
Convert a pointer to a JITTargetAddress.
Definition: JITSymbol.h:69
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
llvm::sys::getProcessTriple
std::string getProcessTriple()
getProcessTriple() - Return an appropriate target triple for generating code to be loaded into the cu...
Definition: Host.cpp:1748
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
Core.h
llvm::orc::ExecutorProcessControl::~ExecutorProcessControl
virtual ~ExecutorProcessControl()
Definition: ExecutorProcessControl.cpp:24
llvm::orc::ExecutorProcessControl::PageSize
unsigned PageSize
Definition: ExecutorProcessControl.h:274
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::orc::ExecutionSession::runJITDispatchHandler
void runJITDispatchHandler(ExecutorProcessControl::SendResultFunction SendResult, JITTargetAddress HandlerFnTagAddr, ArrayRef< char > ArgBuffer)
Run a registered jit-side wrapper function.
Definition: Core.cpp:2088
ExecutorProcessControl.h
TargetExecutionUtils.h
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:108
llvm::orc::SelfExecutorProcessControl::callWrapperAsync
void callWrapperAsync(SendResultFunction OnComplete, JITTargetAddress WrapperFnAddr, ArrayRef< char > ArgBuffer) override
Run a wrapper function in the executor.
Definition: ExecutorProcessControl.cpp:112
llvm::orc::SelfExecutorProcessControl::SelfExecutorProcessControl
SelfExecutorProcessControl(std::shared_ptr< SymbolStringPool > SSP, Triple TargetTriple, unsigned PageSize, std::unique_ptr< jitlink::JITLinkMemoryManager > MemMgr)
Definition: ExecutorProcessControl.cpp:26