LLVM 24.0.0git
Proxy.h
Go to the documentation of this file.
1//===------- Proxy.h - Runtime-agnostic executor call APIs ------*- 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// Runtime-agnostic interfaces for invoking executor-side operations. These
10// abstract over how a call reaches the executor, so clients can be written
11// once and used whether the operation is provided by a full ORC runtime or by
12// LLVM's own ORC-runtime-lite. Concrete implementations live in subdirectories
13// (e.g. RTBridge/SPS).
14//
15// This header provides only the core Proxy machinery. Named proxies for
16// specific operation families live in sibling headers (e.g. CallProxies.h,
17// MemoryAccessProxies.h).
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
22#define LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
23
27#include "llvm/Support/Error.h"
29
30#include <future>
31#include <type_traits>
32
33namespace llvm::orc::rt {
34
35class ProxyBase {
36public:
37 ProxyBase() = default;
38 ProxyBase(ExecutorAddr CalleeAddr) : CalleeAddr(CalleeAddr) {}
39
40 /// Returns the address of the callee in the executor.
41 const ExecutorAddr &calleeAddr() const { return CalleeAddr; }
42
43 /// Evaluates to true if the callee is non-null.
44 explicit operator bool() const { return !!CalleeAddr; }
45
46private:
47 ExecutorAddr CalleeAddr;
48};
49
50template <typename FnT> class Proxy;
51
52namespace detail {
53
54/// Maps a proxy's callee return type to the type delivered to the client, so a
55/// dispatch failure can always be reported alongside the result:
56///
57/// void -> Error
58/// Error -> Error
59/// T -> Expected<T>
60/// Expected<T> -> Expected<T>
61template <typename T> struct ProxyErrorRet {
63};
64template <> struct ProxyErrorRet<void> {
65 using type = Error;
66};
67template <> struct ProxyErrorRet<Error> {
68 using type = Error;
69};
70template <typename T> struct ProxyErrorRet<Expected<T>> {
72};
73
74/// Maps a proxy's client-facing return type to the std::promise value type used
75/// by the blocking call operator (working around MSVC's std::promise).
76template <typename T> struct ProxyRetPromise;
77template <> struct ProxyRetPromise<Error> {
78 using type = std::promise<MSVCPError>;
79};
80template <typename T> struct ProxyRetPromise<Expected<T>> {
81 using type = std::promise<MSVCPExpected<T>>;
82};
83
84} // namespace detail
85
86/// Runtime-agnostic interface for invoking an executor-side operation with the
87/// signature RetT(ArgTs...).
88///
89/// Two call operators are provided: an asynchronous form that delivers the
90/// result to an OnComplete continuation, and a synchronous form that blocks
91/// until the result is available.
92///
93/// A Proxy abstracts over how the operation is dispatched to the executor. Its
94/// dispatch function is supplied by a spec (e.g. rt::sps::ProxySpec).
95template <typename RetT, typename... ArgTs>
96class Proxy<RetT(ArgTs...)> : public ProxyBase {
97public:
98 using FnType = RetT(ArgTs...);
99
100 /// The result type produced by the executor-side function itself.
101 using CalleeRetT = RetT;
102
103 /// The result type delivered to the client: Error when the callee returns
104 /// void or Error, otherwise Expected<T> (with Expected<T> callees flattened
105 /// rather than nested), so that dispatch failures can be reported alongside
106 /// the result.
108
109 using DispatchFn = void (*)(unique_function<void(ErrorRetT)> OnComplete,
110 ExecutionSession &ES, ExecutorAddr Callee,
111 const ArgTs &...Args);
112
113 Proxy() = default;
114 Proxy(DispatchFn Dispatch, ExecutorAddr CalleeAddr)
115 : ProxyBase(CalleeAddr), Dispatch(Dispatch) {}
116
118 StringRef Name, SymbolLookupFlags LF) {
119 auto &ES = JD.getExecutionSession();
120 if (auto CalleeSyms = ES.lookup(makeJITDylibSearchOrder(&JD),
121 SymbolLookupSet{ES.intern(Name), LF})) {
122 if (!CalleeSyms->empty())
123 return Proxy(Dispatch, CalleeSyms->begin()->second.getAddress());
125 return Proxy();
126 } else
127 return CalleeSyms.takeError();
128 }
129
131 StringRef Name, SymbolLookupFlags LF) {
132 return Create(Dispatch, ES.getBootstrapJITDylib(), Name, LF);
133 }
134
135 /// Asynchronously invoke the operation with the given Args, delivering its
136 /// result (or an error) to OnComplete.
137 void operator()(unique_function<void(ErrorRetT)> OnComplete,
138 ExecutionSession &ES, const ArgTs &...Args) const {
139 assert(Dispatch && "Proxy's Dispatch member is not set");
140 Dispatch(std::move(OnComplete), ES, calleeAddr(), Args...);
141 }
142
143 /// Invoke the operation with the given Args, blocking until its result (or an
144 /// error) is available.
145 ErrorRetT operator()(ExecutionSession &ES, const ArgTs &...Args) const {
147 auto F = P.get_future();
148 this->operator()(
149 [P = std::move(P)](ErrorRetT R) mutable { P.set_value(std::move(R)); },
150 ES, Args...);
151 return F.get();
152 }
153
154private:
155 DispatchFn Dispatch = nullptr;
156};
157
164
165template <typename FnT>
168 StringRef Name,
170 return {P, Dispatch, Name, LookupFlags};
171}
172
173template <typename ProxySpecT, typename FnT>
174ProxyInit<FnT>
177 return {P, ProxySpecT::dispatch, ProxySpecT::Name, LookupFlags};
178}
179
180template <typename ProxySpecT, typename FnT>
181ProxyInit<FnT>
184 return {P, ProxySpecT::dispatch, Name, LookupFlags};
185}
186
187/// buildProxies base case.
188inline Error buildProxies(JITDylib &JD) { return Error::success(); }
189
190/// buildProxies: Given an ExecutionSession, use BootstrapJITDylib.
191template <typename... FnTs>
195
196/// Build a sequence of proxies from their respective specs.
197template <typename FnT, typename... FnTs>
199 if (auto POrErr =
201 *PI.P = std::move(*POrErr);
202 else
203 return POrErr.takeError();
204 return buildProxies(JD, PIs...);
205}
206
207} // namespace llvm::orc::rt
208
209#endif // LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
#define F(x, y, z)
Definition MD5.cpp:54
#define T
#define P(N)
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
An ExecutionSession represents a running JIT program.
Definition Core.h:1111
JITDylib & getBootstrapJITDylib()
Returns a reference to the bootstrap JITDylib.
Definition Core.h:1177
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition Core.h:675
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition Core.h:694
A set of symbols to look up, each associated with a SymbolLookupFlags value.
ProxyBase(ExecutorAddr CalleeAddr)
Definition Proxy.h:38
const ExecutorAddr & calleeAddr() const
Returns the address of the callee in the executor.
Definition Proxy.h:41
static Expected< Proxy > Create(DispatchFn Dispatch, ExecutionSession &ES, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:130
void(*)(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, ExecutorAddr Callee, const ArgTs &...Args) DispatchFn
Definition Proxy.h:109
Proxy(DispatchFn Dispatch, ExecutorAddr CalleeAddr)
Definition Proxy.h:114
ErrorRetT operator()(ExecutionSession &ES, const ArgTs &...Args) const
Invoke the operation with the given Args, blocking until its result (or an error) is available.
Definition Proxy.h:145
static Expected< Proxy > Create(DispatchFn Dispatch, JITDylib &JD, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:117
typename detail::ProxyErrorRet< RetT >::type ErrorRetT
The result type delivered to the client: Error when the callee returns void or Error,...
Definition Proxy.h:107
void operator()(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, const ArgTs &...Args) const
Asynchronously invoke the operation with the given Args, delivering its result (or an error) to OnCom...
Definition Proxy.h:137
RetT CalleeRetT
The result type produced by the executor-side function itself.
Definition Proxy.h:101
unique_function is a type-erasing functor similar to std::function.
ProxyInit< FnT > proxyInit(Proxy< FnT > *P, typename Proxy< FnT >::DispatchFn Dispatch, StringRef Name, SymbolLookupFlags LookupFlags=SymbolLookupFlags::RequiredSymbol)
Definition Proxy.h:167
Error buildProxies(JITDylib &JD)
buildProxies base case.
Definition Proxy.h:188
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition Core.h:153
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
Proxy< FnT > * P
Definition Proxy.h:159
SymbolLookupFlags LookupFlags
Definition Proxy.h:162
Proxy< FnT >::DispatchFn Dispatch
Definition Proxy.h:160
Maps a proxy's callee return type to the type delivered to the client, so a dispatch failure can alwa...
Definition Proxy.h:61
std::promise< MSVCPError > type
Definition Proxy.h:78
std::promise< MSVCPExpected< T > > type
Definition Proxy.h:81
Maps a proxy's client-facing return type to the std::promise value type used by the blocking call ope...
Definition Proxy.h:76