LLVM  15.0.0git
WrapperFunctionUtils.h
Go to the documentation of this file.
1 //===- WrapperFunctionUtils.h - Utilities for wrapper functions -*- 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 // A buffer for serialized results.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
14 #define LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
15 
18 #include "llvm/Support/Error.h"
19 
20 #include <type_traits>
21 
22 namespace llvm {
23 namespace orc {
24 namespace shared {
25 
26 // Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
28  char *ValuePtr;
29  char Value[sizeof(ValuePtr)];
30 };
31 
32 // Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
33 typedef struct {
35  size_t Size;
37 
38 /// C++ wrapper function result: Same as CWrapperFunctionResult but
39 /// auto-releases memory.
41 public:
42  /// Create a default WrapperFunctionResult.
43  WrapperFunctionResult() { init(R); }
44 
45  /// Create a WrapperFunctionResult by taking ownership of a
46  /// CWrapperFunctionResult.
47  ///
48  /// Warning: This should only be used by clients writing wrapper-function
49  /// caller utilities (like TargetProcessControl).
51  // Reset R.
52  init(R);
53  }
54 
57 
59  init(R);
60  std::swap(R, Other.R);
61  }
62 
65  std::swap(R, Tmp.R);
66  return *this;
67  }
68 
70  if ((R.Size > sizeof(R.Data.Value)) ||
71  (R.Size == 0 && R.Data.ValuePtr != nullptr))
72  free(R.Data.ValuePtr);
73  }
74 
75  /// Release ownership of the contained CWrapperFunctionResult.
76  /// Warning: Do not use -- this method will be removed in the future. It only
77  /// exists to temporarily support some code that will eventually be moved to
78  /// the ORC runtime.
81  init(Tmp);
82  std::swap(R, Tmp);
83  return Tmp;
84  }
85 
86  /// Get a pointer to the data contained in this instance.
87  char *data() {
88  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
89  "Cannot get data for out-of-band error value");
90  return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
91  }
92 
93  /// Get a const pointer to the data contained in this instance.
94  const char *data() const {
95  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
96  "Cannot get data for out-of-band error value");
97  return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
98  }
99 
100  /// Returns the size of the data contained in this instance.
101  size_t size() const {
102  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
103  "Cannot get data for out-of-band error value");
104  return R.Size;
105  }
106 
107  /// Returns true if this value is equivalent to a default-constructed
108  /// WrapperFunctionResult.
109  bool empty() const { return R.Size == 0 && R.Data.ValuePtr == nullptr; }
110 
111  /// Create a WrapperFunctionResult with the given size and return a pointer
112  /// to the underlying memory.
113  static WrapperFunctionResult allocate(size_t Size) {
114  // Reset.
116  WFR.R.Size = Size;
117  if (WFR.R.Size > sizeof(WFR.R.Data.Value))
118  WFR.R.Data.ValuePtr = (char *)malloc(WFR.R.Size);
119  return WFR;
120  }
121 
122  /// Copy from the given char range.
123  static WrapperFunctionResult copyFrom(const char *Source, size_t Size) {
124  auto WFR = allocate(Size);
125  memcpy(WFR.data(), Source, Size);
126  return WFR;
127  }
128 
129  /// Copy from the given null-terminated string (includes the null-terminator).
130  static WrapperFunctionResult copyFrom(const char *Source) {
131  return copyFrom(Source, strlen(Source) + 1);
132  }
133 
134  /// Copy from the given std::string (includes the null terminator).
135  static WrapperFunctionResult copyFrom(const std::string &Source) {
136  return copyFrom(Source.c_str());
137  }
138 
139  /// Create an out-of-band error by copying the given string.
141  // Reset.
143  char *Tmp = (char *)malloc(strlen(Msg) + 1);
144  strcpy(Tmp, Msg);
145  WFR.R.Data.ValuePtr = Tmp;
146  return WFR;
147  }
148 
149  /// Create an out-of-band error by copying the given string.
150  static WrapperFunctionResult createOutOfBandError(const std::string &Msg) {
151  return createOutOfBandError(Msg.c_str());
152  }
153 
154  /// If this value is an out-of-band error then this returns the error message,
155  /// otherwise returns nullptr.
156  const char *getOutOfBandError() const {
157  return R.Size == 0 ? R.Data.ValuePtr : nullptr;
158  }
159 
160 private:
161  static void init(CWrapperFunctionResult &R) {
162  R.Data.ValuePtr = nullptr;
163  R.Size = 0;
164  }
165 
166  CWrapperFunctionResult R;
167 };
168 
169 namespace detail {
170 
171 template <typename SPSArgListT, typename... ArgTs>
172 WrapperFunctionResult
175  SPSOutputBuffer OB(Result.data(), Result.size());
176  if (!SPSArgListT::serialize(OB, Args...))
178  "Error serializing arguments to blob in call");
179  return Result;
180 }
181 
182 template <typename RetT> class WrapperFunctionHandlerCaller {
183 public:
184  template <typename HandlerT, typename ArgTupleT, std::size_t... I>
185  static decltype(auto) call(HandlerT &&H, ArgTupleT &Args,
186  std::index_sequence<I...>) {
187  return std::forward<HandlerT>(H)(std::get<I>(Args)...);
188  }
189 };
190 
191 template <> class WrapperFunctionHandlerCaller<void> {
192 public:
193  template <typename HandlerT, typename ArgTupleT, std::size_t... I>
194  static SPSEmpty call(HandlerT &&H, ArgTupleT &Args,
195  std::index_sequence<I...>) {
196  std::forward<HandlerT>(H)(std::get<I>(Args)...);
197  return SPSEmpty();
198  }
199 };
200 
201 template <typename WrapperFunctionImplT,
202  template <typename> class ResultSerializer, typename... SPSTagTs>
205  decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
206  ResultSerializer, SPSTagTs...> {};
207 
208 template <typename RetT, typename... ArgTs,
209  template <typename> class ResultSerializer, typename... SPSTagTs>
211  SPSTagTs...> {
212 public:
213  using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
214  using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
215 
216  template <typename HandlerT>
217  static WrapperFunctionResult apply(HandlerT &&H, const char *ArgData,
218  size_t ArgSize) {
219  ArgTuple Args;
220  if (!deserialize(ArgData, ArgSize, Args, ArgIndices{}))
222  "Could not deserialize arguments for wrapper function call");
223 
224  auto HandlerResult = WrapperFunctionHandlerCaller<RetT>::call(
225  std::forward<HandlerT>(H), Args, ArgIndices{});
226 
227  return ResultSerializer<decltype(HandlerResult)>::serialize(
228  std::move(HandlerResult));
229  }
230 
231 private:
232  template <std::size_t... I>
233  static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
234  std::index_sequence<I...>) {
235  SPSInputBuffer IB(ArgData, ArgSize);
236  return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
237  }
238 };
239 
240 // Map function pointers to function types.
241 template <typename RetT, typename... ArgTs,
242  template <typename> class ResultSerializer, typename... SPSTagTs>
244  SPSTagTs...>
245  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
246  SPSTagTs...> {};
247 
248 // Map non-const member function types to function types.
249 template <typename ClassT, typename RetT, typename... ArgTs,
250  template <typename> class ResultSerializer, typename... SPSTagTs>
251 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...), ResultSerializer,
252  SPSTagTs...>
253  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
254  SPSTagTs...> {};
255 
256 // Map const member function types to function types.
257 template <typename ClassT, typename RetT, typename... ArgTs,
258  template <typename> class ResultSerializer, typename... SPSTagTs>
259 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
260  ResultSerializer, SPSTagTs...>
261  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
262  SPSTagTs...> {};
263 
264 template <typename WrapperFunctionImplT,
265  template <typename> class ResultSerializer, typename... SPSTagTs>
268  decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
269  ResultSerializer, SPSTagTs...> {};
270 
271 template <typename RetT, typename SendResultT, typename... ArgTs,
272  template <typename> class ResultSerializer, typename... SPSTagTs>
273 class WrapperFunctionAsyncHandlerHelper<RetT(SendResultT, ArgTs...),
274  ResultSerializer, SPSTagTs...> {
275 public:
276  using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
277  using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
278 
279  template <typename HandlerT, typename SendWrapperFunctionResultT>
280  static void applyAsync(HandlerT &&H,
281  SendWrapperFunctionResultT &&SendWrapperFunctionResult,
282  const char *ArgData, size_t ArgSize) {
283  ArgTuple Args;
284  if (!deserialize(ArgData, ArgSize, Args, ArgIndices{})) {
285  SendWrapperFunctionResult(WrapperFunctionResult::createOutOfBandError(
286  "Could not deserialize arguments for wrapper function call"));
287  return;
288  }
289 
290  auto SendResult =
291  [SendWFR = std::move(SendWrapperFunctionResult)](auto Result) mutable {
292  using ResultT = decltype(Result);
294  };
295 
296  callAsync(std::forward<HandlerT>(H), std::move(SendResult), std::move(Args),
297  ArgIndices{});
298  }
299 
300 private:
301  template <std::size_t... I>
302  static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
303  std::index_sequence<I...>) {
304  SPSInputBuffer IB(ArgData, ArgSize);
305  return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
306  }
307 
308  template <typename HandlerT, typename SerializeAndSendResultT,
309  typename ArgTupleT, std::size_t... I>
310  static void callAsync(HandlerT &&H,
311  SerializeAndSendResultT &&SerializeAndSendResult,
312  ArgTupleT Args, std::index_sequence<I...>) {
313  (void)Args; // Silence a buggy GCC warning.
314  return std::forward<HandlerT>(H)(std::move(SerializeAndSendResult),
315  std::move(std::get<I>(Args))...);
316  }
317 };
318 
319 // Map function pointers to function types.
320 template <typename RetT, typename... ArgTs,
321  template <typename> class ResultSerializer, typename... SPSTagTs>
323  SPSTagTs...>
324  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
325  SPSTagTs...> {};
326 
327 // Map non-const member function types to function types.
328 template <typename ClassT, typename RetT, typename... ArgTs,
329  template <typename> class ResultSerializer, typename... SPSTagTs>
330 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...),
331  ResultSerializer, SPSTagTs...>
332  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
333  SPSTagTs...> {};
334 
335 // Map const member function types to function types.
336 template <typename ClassT, typename RetT, typename... ArgTs,
337  template <typename> class ResultSerializer, typename... SPSTagTs>
338 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
339  ResultSerializer, SPSTagTs...>
340  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
341  SPSTagTs...> {};
342 
343 template <typename SPSRetTagT, typename RetT> class ResultSerializer {
344 public:
345  static WrapperFunctionResult serialize(RetT Result) {
346  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
347  Result);
348  }
349 };
350 
351 template <typename SPSRetTagT> class ResultSerializer<SPSRetTagT, Error> {
352 public:
354  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
356  }
357 };
358 
359 template <typename SPSRetTagT>
360 class ResultSerializer<SPSRetTagT, ErrorSuccess> {
361 public:
363  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
365  }
366 };
367 
368 template <typename SPSRetTagT, typename T>
369 class ResultSerializer<SPSRetTagT, Expected<T>> {
370 public:
372  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
374  }
375 };
376 
377 template <typename SPSRetTagT, typename RetT> class ResultDeserializer {
378 public:
379  static RetT makeValue() { return RetT(); }
380  static void makeSafe(RetT &Result) {}
381 
382  static Error deserialize(RetT &Result, const char *ArgData, size_t ArgSize) {
383  SPSInputBuffer IB(ArgData, ArgSize);
384  if (!SPSArgList<SPSRetTagT>::deserialize(IB, Result))
385  return make_error<StringError>(
386  "Error deserializing return value from blob in call",
388  return Error::success();
389  }
390 };
391 
392 template <> class ResultDeserializer<SPSError, Error> {
393 public:
394  static Error makeValue() { return Error::success(); }
395  static void makeSafe(Error &Err) { cantFail(std::move(Err)); }
396 
397  static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize) {
398  SPSInputBuffer IB(ArgData, ArgSize);
400  if (!SPSArgList<SPSError>::deserialize(IB, BSE))
401  return make_error<StringError>(
402  "Error deserializing return value from blob in call",
404  Err = fromSPSSerializable(std::move(BSE));
405  return Error::success();
406  }
407 };
408 
409 template <typename SPSTagT, typename T>
411 public:
412  static Expected<T> makeValue() { return T(); }
413  static void makeSafe(Expected<T> &E) { cantFail(E.takeError()); }
414 
415  static Error deserialize(Expected<T> &E, const char *ArgData,
416  size_t ArgSize) {
417  SPSInputBuffer IB(ArgData, ArgSize);
420  return make_error<StringError>(
421  "Error deserializing return value from blob in call",
424  return Error::success();
425  }
426 };
427 
428 template <typename SPSRetTagT, typename RetT> class AsyncCallResultHelper {
429  // Did you forget to use Error / Expected in your handler?
430 };
431 
432 } // end namespace detail
433 
434 template <typename SPSSignature> class WrapperFunction;
435 
436 template <typename SPSRetTagT, typename... SPSTagTs>
437 class WrapperFunction<SPSRetTagT(SPSTagTs...)> {
438 private:
439  template <typename RetT>
441 
442 public:
443  /// Call a wrapper function. Caller should be callable as
444  /// WrapperFunctionResult Fn(const char *ArgData, size_t ArgSize);
445  template <typename CallerFn, typename RetT, typename... ArgTs>
446  static Error call(const CallerFn &Caller, RetT &Result,
447  const ArgTs &...Args) {
448 
449  // RetT might be an Error or Expected value. Set the checked flag now:
450  // we don't want the user to have to check the unused result if this
451  // operation fails.
453 
454  auto ArgBuffer =
456  Args...);
457  if (const char *ErrMsg = ArgBuffer.getOutOfBandError())
458  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
459 
460  WrapperFunctionResult ResultBuffer =
461  Caller(ArgBuffer.data(), ArgBuffer.size());
462  if (auto ErrMsg = ResultBuffer.getOutOfBandError())
463  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
464 
466  Result, ResultBuffer.data(), ResultBuffer.size());
467  }
468 
469  /// Call an async wrapper function.
470  /// Caller should be callable as
471  /// void Fn(unique_function<void(WrapperFunctionResult)> SendResult,
472  /// WrapperFunctionResult ArgBuffer);
473  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
474  typename... ArgTs>
475  static void callAsync(AsyncCallerFn &&Caller,
476  SendDeserializedResultFn &&SendDeserializedResult,
477  const ArgTs &...Args) {
478  using RetT = typename std::tuple_element<
480  std::remove_reference_t<SendDeserializedResultFn>,
481  ResultSerializer, SPSRetTagT>::ArgTuple>::type;
482 
483  auto ArgBuffer =
485  Args...);
486  if (auto *ErrMsg = ArgBuffer.getOutOfBandError()) {
487  SendDeserializedResult(
488  make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
490  return;
491  }
492 
493  auto SendSerializedResult = [SDR = std::move(SendDeserializedResult)](
494  WrapperFunctionResult R) mutable {
497 
498  if (auto *ErrMsg = R.getOutOfBandError()) {
499  SDR(make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
500  std::move(RetVal));
501  return;
502  }
503 
504  SPSInputBuffer IB(R.data(), R.size());
506  RetVal, R.data(), R.size()))
507  SDR(std::move(Err), std::move(RetVal));
508 
509  SDR(Error::success(), std::move(RetVal));
510  };
511 
512  Caller(std::move(SendSerializedResult), ArgBuffer.data(), ArgBuffer.size());
513  }
514 
515  /// Handle a call to a wrapper function.
516  template <typename HandlerT>
517  static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize,
518  HandlerT &&Handler) {
519  using WFHH =
521  ResultSerializer, SPSTagTs...>;
522  return WFHH::apply(std::forward<HandlerT>(Handler), ArgData, ArgSize);
523  }
524 
525  /// Handle a call to an async wrapper function.
526  template <typename HandlerT, typename SendResultT>
527  static void handleAsync(const char *ArgData, size_t ArgSize,
528  HandlerT &&Handler, SendResultT &&SendResult) {
530  std::remove_reference_t<HandlerT>, ResultSerializer, SPSTagTs...>;
531  WFAHH::applyAsync(std::forward<HandlerT>(Handler),
532  std::forward<SendResultT>(SendResult), ArgData, ArgSize);
533  }
534 
535 private:
536  template <typename T> static const T &makeSerializable(const T &Value) {
537  return Value;
538  }
539 
540  static detail::SPSSerializableError makeSerializable(Error Err) {
542  }
543 
544  template <typename T>
545  static detail::SPSSerializableExpected<T> makeSerializable(Expected<T> E) {
547  }
548 };
549 
550 template <typename... SPSTagTs>
551 class WrapperFunction<void(SPSTagTs...)>
552  : private WrapperFunction<SPSEmpty(SPSTagTs...)> {
553 
554 public:
555  template <typename CallerFn, typename... ArgTs>
556  static Error call(const CallerFn &Caller, const ArgTs &...Args) {
557  SPSEmpty BE;
558  return WrapperFunction<SPSEmpty(SPSTagTs...)>::call(Caller, BE, Args...);
559  }
560 
561  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
562  typename... ArgTs>
563  static void callAsync(AsyncCallerFn &&Caller,
564  SendDeserializedResultFn &&SendDeserializedResult,
565  const ArgTs &...Args) {
566  WrapperFunction<SPSEmpty(SPSTagTs...)>::callAsync(
567  std::forward<AsyncCallerFn>(Caller),
568  [SDR = std::move(SendDeserializedResult)](Error SerializeErr,
569  SPSEmpty E) mutable {
570  SDR(std::move(SerializeErr));
571  },
572  Args...);
573  }
574 
575  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handle;
576  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handleAsync;
577 };
578 
579 /// A function object that takes an ExecutorAddr as its first argument,
580 /// casts that address to a ClassT*, then calls the given method on that
581 /// pointer passing in the remaining function arguments. This utility
582 /// removes some of the boilerplate from writing wrappers for method calls.
583 ///
584 /// @code{.cpp}
585 /// class MyClass {
586 /// public:
587 /// void myMethod(uint32_t, bool) { ... }
588 /// };
589 ///
590 /// // SPS Method signature -- note MyClass object address as first argument.
591 /// using SPSMyMethodWrapperSignature =
592 /// SPSTuple<SPSExecutorAddr, uint32_t, bool>;
593 ///
594 /// WrapperFunctionResult
595 /// myMethodCallWrapper(const char *ArgData, size_t ArgSize) {
596 /// return WrapperFunction<SPSMyMethodWrapperSignature>::handle(
597 /// ArgData, ArgSize, makeMethodWrapperHandler(&MyClass::myMethod));
598 /// }
599 /// @endcode
600 ///
601 template <typename RetT, typename ClassT, typename... ArgTs>
603 public:
604  using MethodT = RetT (ClassT::*)(ArgTs...);
606  RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args) {
607  return (ObjAddr.toPtr<ClassT*>()->*M)(std::forward<ArgTs>(Args)...);
608  }
609 
610 private:
611  MethodT M;
612 };
613 
614 /// Create a MethodWrapperHandler object from the given method pointer.
615 template <typename RetT, typename ClassT, typename... ArgTs>
616 MethodWrapperHandler<RetT, ClassT, ArgTs...>
617 makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
618  return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
619 }
620 
621 /// Represents a serialized wrapper function call.
622 /// Serializing calls themselves allows us to batch them: We can make one
623 /// "run-wrapper-functions" utility and send it a list of calls to run.
624 ///
625 /// The motivating use-case for this API is JITLink allocation actions, where
626 /// we want to run multiple functions to finalize linked memory without having
627 /// to make separate IPC calls for each one.
629 public:
631 
632  /// Create a WrapperFunctionCall using the given SPS serializer to serialize
633  /// the arguments.
634  template <typename SPSSerializer, typename... ArgTs>
636  const ArgTs &...Args) {
637  ArgDataBufferType ArgData;
638  ArgData.resize(SPSSerializer::size(Args...));
639  SPSOutputBuffer OB(&ArgData[0], ArgData.size());
640  if (SPSSerializer::serialize(OB, Args...))
641  return WrapperFunctionCall(FnAddr, std::move(ArgData));
642  return make_error<StringError>("Cannot serialize arguments for "
643  "AllocActionCall",
645  }
646 
647  WrapperFunctionCall() = default;
648 
649  /// Create a WrapperFunctionCall from a target function and arg buffer.
651  : FnAddr(FnAddr), ArgData(std::move(ArgData)) {}
652 
653  /// Returns the address to be called.
654  const ExecutorAddr &getCallee() const { return FnAddr; }
655 
656  /// Returns the argument data.
657  const ArgDataBufferType &getArgData() const { return ArgData; }
658 
659  /// WrapperFunctionCalls convert to true if the callee is non-null.
660  explicit operator bool() const { return !!FnAddr; }
661 
662  /// Run call returning raw WrapperFunctionResult.
664  using FnTy =
665  shared::CWrapperFunctionResult(const char *ArgData, size_t ArgSize);
667  FnAddr.toPtr<FnTy *>()(ArgData.data(), ArgData.size()));
668  }
669 
670  /// Run call and deserialize result using SPS.
671  template <typename SPSRetT, typename RetT>
672  std::enable_if_t<!std::is_same<SPSRetT, void>::value, Error>
673  runWithSPSRet(RetT &RetVal) const {
674  auto WFR = run();
675  if (const char *ErrMsg = WFR.getOutOfBandError())
676  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
677  shared::SPSInputBuffer IB(WFR.data(), WFR.size());
679  return make_error<StringError>("Could not deserialize result from "
680  "serialized wrapper function call",
682  return Error::success();
683  }
684 
685  /// Overload for SPS functions returning void.
686  template <typename SPSRetT>
687  std::enable_if_t<std::is_same<SPSRetT, void>::value, Error>
688  runWithSPSRet() const {
690  return runWithSPSRet<shared::SPSEmpty>(E);
691  }
692 
693  /// Run call and deserialize an SPSError result. SPSError returns and
694  /// deserialization failures are merged into the returned error.
697  if (auto Err = runWithSPSRet<SPSError>(RetErr))
698  return Err;
699  return detail::fromSPSSerializable(std::move(RetErr));
700  }
701 
702 private:
703  orc::ExecutorAddr FnAddr;
704  ArgDataBufferType ArgData;
705 };
706 
708 
709 template <>
711 public:
712  static size_t size(const WrapperFunctionCall &WFC) {
714  WFC.getArgData());
715  }
716 
717  static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionCall &WFC) {
718  return SPSWrapperFunctionCall::AsArgList::serialize(OB, WFC.getCallee(),
719  WFC.getArgData());
720  }
721 
723  ExecutorAddr FnAddr;
725  if (!SPSWrapperFunctionCall::AsArgList::deserialize(IB, FnAddr, ArgData))
726  return false;
727  WFC = WrapperFunctionCall(FnAddr, std::move(ArgData));
728  return true;
729  }
730 };
731 
732 } // end namespace shared
733 } // end namespace orc
734 } // end namespace llvm
735 
736 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:30
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:801
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::orc::shared::WrapperFunction< SPSRetTagT(SPSTagTs...)>::handleAsync
static void handleAsync(const char *ArgData, size_t ArgSize, HandlerT &&Handler, SendResultT &&SendResult)
Handle a call to an async wrapper function.
Definition: WrapperFunctionUtils.h:527
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::orc::shared::detail::ResultDeserializer< SPSError, Error >::makeSafe
static void makeSafe(Error &Err)
Definition: WrapperFunctionUtils.h:395
llvm::orc::shared::WrapperFunctionResult::createOutOfBandError
static WrapperFunctionResult createOutOfBandError(const std::string &Msg)
Create an out-of-band error by copying the given string.
Definition: WrapperFunctionUtils.h:150
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult()
Create a default WrapperFunctionResult.
Definition: WrapperFunctionUtils.h:43
llvm::orc::shared::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:33
llvm::orc::shared::detail::AsyncCallResultHelper
Definition: WrapperFunctionUtils.h:428
llvm::orc::shared::WrapperFunction< void(SPSTagTs...)>::callAsync
static void callAsync(AsyncCallerFn &&Caller, SendDeserializedResultFn &&SendDeserializedResult, const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:563
llvm::orc::shared::SPSSerializationTraits
Specialize to describe how to serialize/deserialize to/from the given concrete type.
Definition: SimplePackedSerialization.h:104
llvm::orc::shared::detail::ResultSerializer< SPSRetTagT, ErrorSuccess >::serialize
static WrapperFunctionResult serialize(ErrorSuccess Err)
Definition: WrapperFunctionUtils.h:362
llvm::orc::shared::WrapperFunctionCall::run
shared::WrapperFunctionResult run() const
Run call returning raw WrapperFunctionResult.
Definition: WrapperFunctionUtils.h:663
llvm::orc::shared::WrapperFunctionResult::~WrapperFunctionResult
~WrapperFunctionResult()
Definition: WrapperFunctionUtils.h:69
llvm::orc::shared::CWrapperFunctionResultDataUnion::ValuePtr
char * ValuePtr
Definition: WrapperFunctionUtils.h:28
llvm::orc::shared::detail::ResultDeserializer::makeValue
static RetT makeValue()
Definition: WrapperFunctionUtils.h:379
llvm::orc::shared::WrapperFunctionResult::operator=
WrapperFunctionResult & operator=(const WrapperFunctionResult &)=delete
llvm::SmallVector< char, 24 >
llvm::orc::shared::SPSOutputBuffer
Output char buffer with overflow check.
Definition: SimplePackedSerialization.h:54
llvm::orc::shared::WrapperFunctionResult::allocate
static WrapperFunctionResult allocate(size_t Size)
Create a WrapperFunctionResult with the given size and return a pointer to the underlying memory.
Definition: WrapperFunctionUtils.h:113
llvm::orc::shared::WrapperFunction
Definition: WrapperFunctionUtils.h:434
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::orc::shared::WrapperFunction< SPSRetTagT(SPSTagTs...)>::call
static Error call(const CallerFn &Caller, RetT &Result, const ArgTs &...Args)
Call a wrapper function.
Definition: WrapperFunctionUtils.h:446
Error.h
llvm::orc::shared::WrapperFunctionResult::copyFrom
static WrapperFunctionResult copyFrom(const std::string &Source)
Copy from the given std::string (includes the null terminator).
Definition: WrapperFunctionUtils.h:135
llvm::orc::shared::WrapperFunctionResult::empty
bool empty() const
Returns true if this value is equivalent to a default-constructed WrapperFunctionResult.
Definition: WrapperFunctionUtils.h:109
llvm::orc::shared::detail::WrapperFunctionHandlerCaller::call
static decltype(auto) call(HandlerT &&H, ArgTupleT &Args, std::index_sequence< I... >)
Definition: WrapperFunctionUtils.h:185
llvm::orc::shared::WrapperFunctionCall::Create
static Expected< WrapperFunctionCall > Create(ExecutorAddr FnAddr, const ArgTs &...Args)
Create a WrapperFunctionCall using the given SPS serializer to serialize the arguments.
Definition: WrapperFunctionUtils.h:635
llvm::orc::shared::WrapperFunctionCall::runWithSPSRet
std::enable_if_t<!std::is_same< SPSRetT, void >::value, Error > runWithSPSRet(RetT &RetVal) const
Run call and deserialize result using SPS.
Definition: WrapperFunctionUtils.h:673
llvm::orc::ExecutorAddr::toPtr
std::enable_if_t< std::is_pointer< T >::value, T > toPtr() const
Cast this ExecutorAddr to a pointer of the given type.
Definition: ExecutorAddress.h:47
llvm::orc::shared::detail::WrapperFunctionHandlerCaller< void >::call
static SPSEmpty call(HandlerT &&H, ArgTupleT &Args, std::index_sequence< I... >)
Definition: WrapperFunctionUtils.h:194
llvm::orc::shared::detail::WrapperFunctionHandlerHelper
Definition: WrapperFunctionUtils.h:203
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::orc::shared::SPSInputBuffer
Input char buffer with underflow check.
Definition: SimplePackedSerialization.h:73
llvm::orc::shared::detail::WrapperFunctionHandlerHelper< RetT(ArgTs...), ResultSerializer, SPSTagTs... >::ArgTuple
std::tuple< std::decay_t< ArgTs >... > ArgTuple
Definition: WrapperFunctionUtils.h:213
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::orc::shared::CWrapperFunctionResultDataUnion
Definition: WrapperFunctionUtils.h:27
llvm::orc::shared::SPSTuple
SPS tag type for tuples.
Definition: SimplePackedSerialization.h:194
handle
then ret i32 result Tail recursion elimination should handle
Definition: README.txt:355
llvm::orc::shared::detail::ResultDeserializer::deserialize
static Error deserialize(RetT &Result, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:382
llvm::orc::shared::detail::ResultSerializer
Definition: WrapperFunctionUtils.h:343
llvm::orc::shared::WrapperFunctionResult::copyFrom
static WrapperFunctionResult copyFrom(const char *Source, size_t Size)
Copy from the given char range.
Definition: WrapperFunctionUtils.h:123
llvm::orc::shared::WrapperFunctionResult::copyFrom
static WrapperFunctionResult copyFrom(const char *Source)
Copy from the given null-terminated string (includes the null-terminator).
Definition: WrapperFunctionUtils.h:130
llvm::cl::apply
void apply(Opt *O, const Mod &M, const Mods &... Ms)
Definition: CommandLine.h:1280
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::orc::shared::WrapperFunctionCall::getArgData
const ArgDataBufferType & getArgData() const
Returns the argument data.
Definition: WrapperFunctionUtils.h:657
llvm::orc::shared::detail::fromSPSSerializable
Error fromSPSSerializable(SPSSerializableError BSE)
Definition: SimplePackedSerialization.h:578
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeValue
static Expected< T > makeValue()
Definition: WrapperFunctionUtils.h:412
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper< RetT(SendResultT, ArgTs...), ResultSerializer, SPSTagTs... >::applyAsync
static void applyAsync(HandlerT &&H, SendWrapperFunctionResultT &&SendWrapperFunctionResult, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:280
llvm::orc::shared::detail::SPSSerializableError
Helper type for serializing Errors.
Definition: SimplePackedSerialization.h:556
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult(CWrapperFunctionResult R)
Create a WrapperFunctionResult by taking ownership of a CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:50
llvm::orc::shared::CWrapperFunctionResult::Size
size_t Size
Definition: WrapperFunctionUtils.h:35
llvm::orc::shared::MethodWrapperHandler::MethodWrapperHandler
MethodWrapperHandler(MethodT M)
Definition: WrapperFunctionUtils.h:605
llvm::orc::shared::SPSEmpty
Definition: SimplePackedSerialization.h:188
llvm::orc::shared::WrapperFunctionCall::getCallee
const ExecutorAddr & getCallee() const
Returns the address to be called.
Definition: WrapperFunctionUtils.h:654
llvm::orc::shared::WrapperFunctionResult::operator=
WrapperFunctionResult & operator=(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:63
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition: SmallVector.h:619
llvm::orc::shared::WrapperFunction< SPSRetTagT(SPSTagTs...)>::callAsync
static void callAsync(AsyncCallerFn &&Caller, SendDeserializedResultFn &&SendDeserializedResult, const ArgTs &...Args)
Call an async wrapper function.
Definition: WrapperFunctionUtils.h:475
llvm::orc::shared::detail::ResultSerializer::serialize
static WrapperFunctionResult serialize(RetT Result)
Definition: WrapperFunctionUtils.h:345
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper< RetT(SendResultT, ArgTs...), ResultSerializer, SPSTagTs... >::ArgTuple
std::tuple< std::decay_t< ArgTs >... > ArgTuple
Definition: WrapperFunctionUtils.h:276
llvm::orc::shared::WrapperFunctionCall::runWithSPSRetErrorMerged
Error runWithSPSRetErrorMerged() const
Run call and deserialize an SPSError result.
Definition: WrapperFunctionUtils.h:695
llvm::orc::shared::SPSSerializationTraits< SPSWrapperFunctionCall, WrapperFunctionCall >::size
static size_t size(const WrapperFunctionCall &WFC)
Definition: WrapperFunctionUtils.h:712
llvm::orc::shared::detail::serializeViaSPSToWrapperFunctionResult
WrapperFunctionResult serializeViaSPSToWrapperFunctionResult(const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:173
llvm::orc::shared::WrapperFunctionResult
C++ wrapper function result: Same as CWrapperFunctionResult but auto-releases memory.
Definition: WrapperFunctionUtils.h:40
llvm::orc::shared::detail::WrapperFunctionHandlerHelper< RetT(ArgTs...), ResultSerializer, SPSTagTs... >::apply
static WrapperFunctionResult apply(HandlerT &&H, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:217
type
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference and DH registers in an instruction requiring REX prefix divb and mulb both produce results in AH If isel emits a CopyFromReg which gets turned into a movb and that can be allocated a r8b r15b To get around isel emits a CopyFromReg from AX and then right shift it down by and truncate it It s not pretty but it works We need some register allocation magic to make the hack go which would often require a callee saved register Callees usually need to keep this value live for most of their body so it doesn t add a significant burden on them We currently implement this in however this is suboptimal because it means that it would be quite awkward to implement the optimization for callers A better implementation would be to relax the LLVM IR rules for sret arguments to allow a function with an sret argument to have a non void return type
Definition: README-X86-64.txt:70
llvm::orc::shared::detail::ResultSerializer< SPSRetTagT, Error >::serialize
static WrapperFunctionResult serialize(Error Err)
Definition: WrapperFunctionUtils.h:353
llvm::orc::shared::detail::ResultDeserializer
Definition: WrapperFunctionUtils.h:377
llvm::orc::shared::WrapperFunctionCall::WrapperFunctionCall
WrapperFunctionCall(ExecutorAddr FnAddr, ArgDataBufferType ArgData)
Create a WrapperFunctionCall from a target function and arg buffer.
Definition: WrapperFunctionUtils.h:650
const
aarch64 promote const
Definition: AArch64PromoteConstant.cpp:232
llvm::orc::shared::detail::WrapperFunctionHandlerHelper< RetT(ArgTs...), ResultSerializer, SPSTagTs... >::ArgIndices
std::make_index_sequence< std::tuple_size< ArgTuple >::value > ArgIndices
Definition: WrapperFunctionUtils.h:214
llvm::orc::shared::WrapperFunction< void(SPSTagTs...)>::call
static Error call(const CallerFn &Caller, const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:556
llvm::orc::shared::WrapperFunctionResult::data
char * data()
Get a pointer to the data contained in this instance.
Definition: WrapperFunctionUtils.h:87
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::orc::shared::SPSExpected
SPS tag type for expecteds, which are either a T or a string representing an error.
Definition: SimplePackedSerialization.h:543
llvm::ErrorSuccess
Subclass of Error for the sole purpose of identifying the success path in the type system.
Definition: Error.h:327
I
#define I(x, y, z)
Definition: MD5.cpp:58
call
S is passed via registers r2 But gcc stores them to the and then reload them to and r3 before issuing the call(r0 contains the address of the format string)
Definition: README.txt:190
size
i< reg-> size
Definition: README.txt:166
llvm::orc::shared::WrapperFunctionCall
Represents a serialized wrapper function call.
Definition: WrapperFunctionUtils.h:628
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:1663
llvm::orc::shared::MethodWrapperHandler::MethodT
RetT(ClassT::*)(ArgTs...) MethodT
Definition: WrapperFunctionUtils.h:604
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:853
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::shared::detail::WrapperFunctionAsyncHandlerHelper< RetT(SendResultT, ArgTs...), ResultSerializer, SPSTagTs... >::ArgIndices
std::make_index_sequence< std::tuple_size< ArgTuple >::value > ArgIndices
Definition: WrapperFunctionUtils.h:277
SimplePackedSerialization.h
llvm::orc::shared::SPSSerializationTraits< SPSWrapperFunctionCall, WrapperFunctionCall >::serialize
static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionCall &WFC)
Definition: WrapperFunctionUtils.h:717
llvm::orc::shared::detail::WrapperFunctionHandlerCaller
Definition: WrapperFunctionUtils.h:182
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:99
llvm::orc::shared::WrapperFunctionResult::size
size_t size() const
Returns the size of the data contained in this instance.
Definition: WrapperFunctionUtils.h:101
llvm::orc::shared::WrapperFunctionResult::getOutOfBandError
const char * getOutOfBandError() const
If this value is an out-of-band error then this returns the error message, otherwise returns nullptr.
Definition: WrapperFunctionUtils.h:156
llvm::orc::shared::WrapperFunctionResult::data
const char * data() const
Get a const pointer to the data contained in this instance.
Definition: WrapperFunctionUtils.h:94
llvm::orc::shared::detail::ResultDeserializer< SPSError, Error >::makeValue
static Error makeValue()
Definition: WrapperFunctionUtils.h:394
llvm::orc::shared::detail::ResultDeserializer::makeSafe
static void makeSafe(RetT &Result)
Definition: WrapperFunctionUtils.h:380
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeSafe
static void makeSafe(Expected< T > &E)
Definition: WrapperFunctionUtils.h:413
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:745
llvm::orc::shared::CWrapperFunctionResultDataUnion::Value
char Value[sizeof(ValuePtr)]
Definition: WrapperFunctionUtils.h:29
llvm::orc::shared::detail::ResultSerializer< SPSRetTagT, Expected< T > >::serialize
static WrapperFunctionResult serialize(Expected< T > E)
Definition: WrapperFunctionUtils.h:371
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::orc::shared::WrapperFunction< SPSRetTagT(SPSTagTs...)>::handle
static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize, HandlerT &&Handler)
Handle a call to a wrapper function.
Definition: WrapperFunctionUtils.h:517
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::deserialize
static Error deserialize(Expected< T > &E, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:415
llvm::orc::shared::CWrapperFunctionResult::Data
CWrapperFunctionResultDataUnion Data
Definition: WrapperFunctionUtils.h:34
std
Definition: BitVector.h:851
H
#define H(x, y, z)
Definition: MD5.cpp:57
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
ExecutorAddress.h
llvm::orc::shared::WrapperFunctionCall::WrapperFunctionCall
WrapperFunctionCall()=default
llvm::orc::shared::SPSSerializationTraits< SPSWrapperFunctionCall, WrapperFunctionCall >::deserialize
static bool deserialize(SPSInputBuffer &IB, WrapperFunctionCall &WFC)
Definition: WrapperFunctionUtils.h:722
llvm::orc::shared::MethodWrapperHandler::operator()
RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args)
Definition: WrapperFunctionUtils.h:606
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::orc::shared::detail::toSPSSerializable
SPSSerializableError toSPSSerializable(Error Err)
Definition: SimplePackedSerialization.h:572
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::orc::shared::detail::SPSSerializableExpected
Helper type for serializing Expected<T>s.
Definition: SimplePackedSerialization.h:566
llvm::MipsISD::SDR
@ SDR
Definition: MipsISelLowering.h:255
llvm::orc::shared::WrapperFunctionResult::createOutOfBandError
static WrapperFunctionResult createOutOfBandError(const char *Msg)
Create an out-of-band error by copying the given string.
Definition: WrapperFunctionUtils.h:140
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper
Definition: WrapperFunctionUtils.h:266
llvm::orc::shared::WrapperFunctionCall::ArgDataBufferType
SmallVector< char, 24 > ArgDataBufferType
Definition: WrapperFunctionUtils.h:630
llvm::orc::shared::makeMethodWrapperHandler
MethodWrapperHandler< RetT, ClassT, ArgTs... > makeMethodWrapperHandler(RetT(ClassT::*Method)(ArgTs...))
Create a MethodWrapperHandler object from the given method pointer.
Definition: WrapperFunctionUtils.h:617
llvm::orc::shared::WrapperFunctionResult::release
CWrapperFunctionResult release()
Release ownership of the contained CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:79
llvm::orc::shared::detail::ResultDeserializer< SPSError, Error >::deserialize
static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:397
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::orc::shared::WrapperFunctionCall::runWithSPSRet
std::enable_if_t< std::is_same< SPSRetT, void >::value, Error > runWithSPSRet() const
Overload for SPS functions returning void.
Definition: WrapperFunctionUtils.h:688
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::orc::shared::SPSArgList
A utility class for serializing to a blob from a variadic list.
Definition: SimplePackedSerialization.h:107
llvm::orc::shared::MethodWrapperHandler
A function object that takes an ExecutorAddr as its first argument, casts that address to a ClassT*,...
Definition: WrapperFunctionUtils.h:602
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1225
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:58