LLVM  14.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 namespace detail {
27 
28 // DO NOT USE DIRECTLY.
29 // Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
31  char *ValuePtr;
32  char Value[sizeof(ValuePtr)];
33 };
34 
35 // DO NOT USE DIRECTLY.
36 // Must be kept in-sync with compiler-rt/lib/orc/c-api.h.
37 typedef struct {
39  size_t Size;
41 
42 } // end namespace detail
43 
44 /// C++ wrapper function result: Same as CWrapperFunctionResult but
45 /// auto-releases memory.
47 public:
48  /// Create a default WrapperFunctionResult.
49  WrapperFunctionResult() { init(R); }
50 
51  /// Create a WrapperFunctionResult by taking ownership of a
52  /// detail::CWrapperFunctionResult.
53  ///
54  /// Warning: This should only be used by clients writing wrapper-function
55  /// caller utilities (like TargetProcessControl).
57  // Reset R.
58  init(R);
59  }
60 
63 
65  init(R);
66  std::swap(R, Other.R);
67  }
68 
71  std::swap(R, Tmp.R);
72  return *this;
73  }
74 
76  if ((R.Size > sizeof(R.Data.Value)) ||
77  (R.Size == 0 && R.Data.ValuePtr != nullptr))
78  free(R.Data.ValuePtr);
79  }
80 
81  /// Release ownership of the contained detail::CWrapperFunctionResult.
82  /// Warning: Do not use -- this method will be removed in the future. It only
83  /// exists to temporarily support some code that will eventually be moved to
84  /// the ORC runtime.
87  init(Tmp);
88  std::swap(R, Tmp);
89  return Tmp;
90  }
91 
92  /// Get a pointer to the data contained in this instance.
93  char *data() {
94  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
95  "Cannot get data for out-of-band error value");
96  return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
97  }
98 
99  /// Get a const pointer to the data contained in this instance.
100  const char *data() const {
101  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
102  "Cannot get data for out-of-band error value");
103  return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
104  }
105 
106  /// Returns the size of the data contained in this instance.
107  size_t size() const {
108  assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
109  "Cannot get data for out-of-band error value");
110  return R.Size;
111  }
112 
113  /// Returns true if this value is equivalent to a default-constructed
114  /// WrapperFunctionResult.
115  bool empty() const { return R.Size == 0 && R.Data.ValuePtr == nullptr; }
116 
117  /// Create a WrapperFunctionResult with the given size and return a pointer
118  /// to the underlying memory.
120  // Reset.
122  WFR.R.Size = Size;
123  if (WFR.R.Size > sizeof(WFR.R.Data.Value))
124  WFR.R.Data.ValuePtr = (char *)malloc(WFR.R.Size);
125  return WFR;
126  }
127 
128  /// Copy from the given char range.
129  static WrapperFunctionResult copyFrom(const char *Source, size_t Size) {
130  auto WFR = allocate(Size);
131  memcpy(WFR.data(), Source, Size);
132  return WFR;
133  }
134 
135  /// Copy from the given null-terminated string (includes the null-terminator).
136  static WrapperFunctionResult copyFrom(const char *Source) {
137  return copyFrom(Source, strlen(Source) + 1);
138  }
139 
140  /// Copy from the given std::string (includes the null terminator).
141  static WrapperFunctionResult copyFrom(const std::string &Source) {
142  return copyFrom(Source.c_str());
143  }
144 
145  /// Create an out-of-band error by copying the given string.
146  static WrapperFunctionResult createOutOfBandError(const char *Msg) {
147  // Reset.
149  char *Tmp = (char *)malloc(strlen(Msg) + 1);
150  strcpy(Tmp, Msg);
151  WFR.R.Data.ValuePtr = Tmp;
152  return WFR;
153  }
154 
155  /// Create an out-of-band error by copying the given string.
156  static WrapperFunctionResult createOutOfBandError(const std::string &Msg) {
157  return createOutOfBandError(Msg.c_str());
158  }
159 
160  /// If this value is an out-of-band error then this returns the error message,
161  /// otherwise returns nullptr.
162  const char *getOutOfBandError() const {
163  return R.Size == 0 ? R.Data.ValuePtr : nullptr;
164  }
165 
166 private:
167  static void init(detail::CWrapperFunctionResult &R) {
168  R.Data.ValuePtr = nullptr;
169  R.Size = 0;
170  }
171 
172  detail::CWrapperFunctionResult R;
173 };
174 
175 namespace detail {
176 
177 template <typename SPSArgListT, typename... ArgTs>
178 WrapperFunctionResult
181  SPSOutputBuffer OB(Result.data(), Result.size());
182  if (!SPSArgListT::serialize(OB, Args...))
184  "Error serializing arguments to blob in call");
185  return Result;
186 }
187 
188 template <typename RetT> class WrapperFunctionHandlerCaller {
189 public:
190  template <typename HandlerT, typename ArgTupleT, std::size_t... I>
191  static decltype(auto) call(HandlerT &&H, ArgTupleT &Args,
192  std::index_sequence<I...>) {
193  return std::forward<HandlerT>(H)(std::get<I>(Args)...);
194  }
195 };
196 
197 template <> class WrapperFunctionHandlerCaller<void> {
198 public:
199  template <typename HandlerT, typename ArgTupleT, std::size_t... I>
200  static SPSEmpty call(HandlerT &&H, ArgTupleT &Args,
201  std::index_sequence<I...>) {
202  std::forward<HandlerT>(H)(std::get<I>(Args)...);
203  return SPSEmpty();
204  }
205 };
206 
207 template <typename WrapperFunctionImplT,
208  template <typename> class ResultSerializer, typename... SPSTagTs>
211  decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
212  ResultSerializer, SPSTagTs...> {};
213 
214 template <typename RetT, typename... ArgTs,
215  template <typename> class ResultSerializer, typename... SPSTagTs>
217  SPSTagTs...> {
218 public:
219  using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
220  using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
221 
222  template <typename HandlerT>
223  static WrapperFunctionResult apply(HandlerT &&H, const char *ArgData,
224  size_t ArgSize) {
225  ArgTuple Args;
226  if (!deserialize(ArgData, ArgSize, Args, ArgIndices{}))
228  "Could not deserialize arguments for wrapper function call");
229 
230  auto HandlerResult = WrapperFunctionHandlerCaller<RetT>::call(
231  std::forward<HandlerT>(H), Args, ArgIndices{});
232 
233  return ResultSerializer<decltype(HandlerResult)>::serialize(
234  std::move(HandlerResult));
235  }
236 
237 private:
238  template <std::size_t... I>
239  static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
240  std::index_sequence<I...>) {
241  SPSInputBuffer IB(ArgData, ArgSize);
242  return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
243  }
244 };
245 
246 // Map function pointers to function types.
247 template <typename RetT, typename... ArgTs,
248  template <typename> class ResultSerializer, typename... SPSTagTs>
250  SPSTagTs...>
251  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
252  SPSTagTs...> {};
253 
254 // Map non-const member function types to function types.
255 template <typename ClassT, typename RetT, typename... ArgTs,
256  template <typename> class ResultSerializer, typename... SPSTagTs>
257 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...), ResultSerializer,
258  SPSTagTs...>
259  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
260  SPSTagTs...> {};
261 
262 // Map const member function types to function types.
263 template <typename ClassT, typename RetT, typename... ArgTs,
264  template <typename> class ResultSerializer, typename... SPSTagTs>
265 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
266  ResultSerializer, SPSTagTs...>
267  : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
268  SPSTagTs...> {};
269 
270 template <typename WrapperFunctionImplT,
271  template <typename> class ResultSerializer, typename... SPSTagTs>
274  decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
275  ResultSerializer, SPSTagTs...> {};
276 
277 template <typename RetT, typename SendResultT, typename... ArgTs,
278  template <typename> class ResultSerializer, typename... SPSTagTs>
279 class WrapperFunctionAsyncHandlerHelper<RetT(SendResultT, ArgTs...),
280  ResultSerializer, SPSTagTs...> {
281 public:
282  using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
283  using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
284 
285  template <typename HandlerT, typename SendWrapperFunctionResultT>
286  static void applyAsync(HandlerT &&H,
287  SendWrapperFunctionResultT &&SendWrapperFunctionResult,
288  const char *ArgData, size_t ArgSize) {
289  ArgTuple Args;
290  if (!deserialize(ArgData, ArgSize, Args, ArgIndices{})) {
291  SendWrapperFunctionResult(WrapperFunctionResult::createOutOfBandError(
292  "Could not deserialize arguments for wrapper function call"));
293  return;
294  }
295 
296  auto SendResult =
297  [SendWFR = std::move(SendWrapperFunctionResult)](auto Result) mutable {
298  using ResultT = decltype(Result);
300  };
301 
302  callAsync(std::forward<HandlerT>(H), std::move(SendResult), std::move(Args),
303  ArgIndices{});
304  }
305 
306 private:
307  template <std::size_t... I>
308  static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
309  std::index_sequence<I...>) {
310  SPSInputBuffer IB(ArgData, ArgSize);
311  return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
312  }
313 
314  template <typename HandlerT, typename SerializeAndSendResultT,
315  typename ArgTupleT, std::size_t... I>
316  static void callAsync(HandlerT &&H,
317  SerializeAndSendResultT &&SerializeAndSendResult,
318  ArgTupleT Args, std::index_sequence<I...>) {
319  (void)Args; // Silence a buggy GCC warning.
320  return std::forward<HandlerT>(H)(std::move(SerializeAndSendResult),
321  std::move(std::get<I>(Args))...);
322  }
323 };
324 
325 // Map function pointers to function types.
326 template <typename RetT, typename... ArgTs,
327  template <typename> class ResultSerializer, typename... SPSTagTs>
329  SPSTagTs...>
330  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
331  SPSTagTs...> {};
332 
333 // Map non-const member function types to function types.
334 template <typename ClassT, typename RetT, typename... ArgTs,
335  template <typename> class ResultSerializer, typename... SPSTagTs>
336 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...),
337  ResultSerializer, SPSTagTs...>
338  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
339  SPSTagTs...> {};
340 
341 // Map const member function types to function types.
342 template <typename ClassT, typename RetT, typename... ArgTs,
343  template <typename> class ResultSerializer, typename... SPSTagTs>
344 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
345  ResultSerializer, SPSTagTs...>
346  : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
347  SPSTagTs...> {};
348 
349 template <typename SPSRetTagT, typename RetT> class ResultSerializer {
350 public:
351  static WrapperFunctionResult serialize(RetT Result) {
352  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
353  Result);
354  }
355 };
356 
357 template <typename SPSRetTagT> class ResultSerializer<SPSRetTagT, Error> {
358 public:
360  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
362  }
363 };
364 
365 template <typename SPSRetTagT, typename T>
366 class ResultSerializer<SPSRetTagT, Expected<T>> {
367 public:
369  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
371  }
372 };
373 
374 template <typename SPSRetTagT, typename RetT> class ResultDeserializer {
375 public:
376  static RetT makeValue() { return RetT(); }
377  static void makeSafe(RetT &Result) {}
378 
379  static Error deserialize(RetT &Result, const char *ArgData, size_t ArgSize) {
380  SPSInputBuffer IB(ArgData, ArgSize);
381  if (!SPSArgList<SPSRetTagT>::deserialize(IB, Result))
382  return make_error<StringError>(
383  "Error deserializing return value from blob in call",
385  return Error::success();
386  }
387 };
388 
389 template <> class ResultDeserializer<SPSError, Error> {
390 public:
391  static Error makeValue() { return Error::success(); }
392  static void makeSafe(Error &Err) { cantFail(std::move(Err)); }
393 
394  static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize) {
395  SPSInputBuffer IB(ArgData, ArgSize);
397  if (!SPSArgList<SPSError>::deserialize(IB, BSE))
398  return make_error<StringError>(
399  "Error deserializing return value from blob in call",
401  Err = fromSPSSerializable(std::move(BSE));
402  return Error::success();
403  }
404 };
405 
406 template <typename SPSTagT, typename T>
408 public:
409  static Expected<T> makeValue() { return T(); }
410  static void makeSafe(Expected<T> &E) { cantFail(E.takeError()); }
411 
412  static Error deserialize(Expected<T> &E, const char *ArgData,
413  size_t ArgSize) {
414  SPSInputBuffer IB(ArgData, ArgSize);
417  return make_error<StringError>(
418  "Error deserializing return value from blob in call",
421  return Error::success();
422  }
423 };
424 
425 template <typename SPSRetTagT, typename RetT> class AsyncCallResultHelper {
426  // Did you forget to use Error / Expected in your handler?
427 };
428 
429 } // end namespace detail
430 
431 template <typename SPSSignature> class WrapperFunction;
432 
433 template <typename SPSRetTagT, typename... SPSTagTs>
434 class WrapperFunction<SPSRetTagT(SPSTagTs...)> {
435 private:
436  template <typename RetT>
438 
439 public:
440  /// Call a wrapper function. Caller should be callable as
441  /// WrapperFunctionResult Fn(const char *ArgData, size_t ArgSize);
442  template <typename CallerFn, typename RetT, typename... ArgTs>
443  static Error call(const CallerFn &Caller, RetT &Result,
444  const ArgTs &...Args) {
445 
446  // RetT might be an Error or Expected value. Set the checked flag now:
447  // we don't want the user to have to check the unused result if this
448  // operation fails.
450 
451  auto ArgBuffer =
453  Args...);
454  if (const char *ErrMsg = ArgBuffer.getOutOfBandError())
455  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
456 
457  WrapperFunctionResult ResultBuffer =
458  Caller(ArgBuffer.data(), ArgBuffer.size());
459  if (auto ErrMsg = ResultBuffer.getOutOfBandError())
460  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
461 
463  Result, ResultBuffer.data(), ResultBuffer.size());
464  }
465 
466  /// Call an async wrapper function.
467  /// Caller should be callable as
468  /// void Fn(unique_function<void(WrapperFunctionResult)> SendResult,
469  /// WrapperFunctionResult ArgBuffer);
470  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
471  typename... ArgTs>
472  static void callAsync(AsyncCallerFn &&Caller,
473  SendDeserializedResultFn &&SendDeserializedResult,
474  const ArgTs &...Args) {
475  using RetT = typename std::tuple_element<
477  std::remove_reference_t<SendDeserializedResultFn>,
478  ResultSerializer, SPSRetTagT>::ArgTuple>::type;
479 
480  auto ArgBuffer =
482  Args...);
483  if (auto *ErrMsg = ArgBuffer.getOutOfBandError()) {
484  SendDeserializedResult(
485  make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
487  return;
488  }
489 
490  auto SendSerializedResult = [SDR = std::move(SendDeserializedResult)](
491  WrapperFunctionResult R) mutable {
494 
495  if (auto *ErrMsg = R.getOutOfBandError()) {
496  SDR(make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
497  std::move(RetVal));
498  return;
499  }
500 
501  SPSInputBuffer IB(R.data(), R.size());
503  RetVal, R.data(), R.size()))
504  SDR(std::move(Err), std::move(RetVal));
505 
506  SDR(Error::success(), std::move(RetVal));
507  };
508 
509  Caller(std::move(SendSerializedResult), ArgBuffer.data(), ArgBuffer.size());
510  }
511 
512  /// Handle a call to a wrapper function.
513  template <typename HandlerT>
514  static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize,
515  HandlerT &&Handler) {
516  using WFHH =
518  ResultSerializer, SPSTagTs...>;
519  return WFHH::apply(std::forward<HandlerT>(Handler), ArgData, ArgSize);
520  }
521 
522  /// Handle a call to an async wrapper function.
523  template <typename HandlerT, typename SendResultT>
524  static void handleAsync(const char *ArgData, size_t ArgSize,
525  HandlerT &&Handler, SendResultT &&SendResult) {
527  std::remove_reference_t<HandlerT>, ResultSerializer, SPSTagTs...>;
528  WFAHH::applyAsync(std::forward<HandlerT>(Handler),
529  std::forward<SendResultT>(SendResult), ArgData, ArgSize);
530  }
531 
532 private:
533  template <typename T> static const T &makeSerializable(const T &Value) {
534  return Value;
535  }
536 
537  static detail::SPSSerializableError makeSerializable(Error Err) {
539  }
540 
541  template <typename T>
542  static detail::SPSSerializableExpected<T> makeSerializable(Expected<T> E) {
544  }
545 };
546 
547 template <typename... SPSTagTs>
548 class WrapperFunction<void(SPSTagTs...)>
549  : private WrapperFunction<SPSEmpty(SPSTagTs...)> {
550 
551 public:
552  template <typename CallerFn, typename... ArgTs>
553  static Error call(const CallerFn &Caller, const ArgTs &...Args) {
554  SPSEmpty BE;
555  return WrapperFunction<SPSEmpty(SPSTagTs...)>::call(Caller, BE, Args...);
556  }
557 
558  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
559  typename... ArgTs>
560  static void callAsync(AsyncCallerFn &&Caller,
561  SendDeserializedResultFn &&SendDeserializedResult,
562  const ArgTs &...Args) {
563  WrapperFunction<SPSEmpty(SPSTagTs...)>::callAsync(
564  std::forward<AsyncCallerFn>(Caller),
565  [SDR = std::move(SendDeserializedResult)](Error SerializeErr,
566  SPSEmpty E) mutable {
567  SDR(std::move(SerializeErr));
568  },
569  Args...);
570  }
571 
572  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handle;
573  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handleAsync;
574 };
575 
576 /// A function object that takes an ExecutorAddr as its first argument,
577 /// casts that address to a ClassT*, then calls the given method on that
578 /// pointer passing in the remaining function arguments. This utility
579 /// removes some of the boilerplate from writing wrappers for method calls.
580 ///
581 /// @code{.cpp}
582 /// class MyClass {
583 /// public:
584 /// void myMethod(uint32_t, bool) { ... }
585 /// };
586 ///
587 /// // SPS Method signature -- note MyClass object address as first argument.
588 /// using SPSMyMethodWrapperSignature =
589 /// SPSTuple<SPSExecutorAddr, uint32_t, bool>;
590 ///
591 /// WrapperFunctionResult
592 /// myMethodCallWrapper(const char *ArgData, size_t ArgSize) {
593 /// return WrapperFunction<SPSMyMethodWrapperSignature>::handle(
594 /// ArgData, ArgSize, makeMethodWrapperHandler(&MyClass::myMethod));
595 /// }
596 /// @endcode
597 ///
598 template <typename RetT, typename ClassT, typename... ArgTs>
600 public:
601  using MethodT = RetT (ClassT::*)(ArgTs...);
603  RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args) {
604  return (ObjAddr.toPtr<ClassT*>()->*M)(std::forward<ArgTs>(Args)...);
605  }
606 
607 private:
608  MethodT M;
609 };
610 
611 /// Create a MethodWrapperHandler object from the given method pointer.
612 template <typename RetT, typename ClassT, typename... ArgTs>
613 MethodWrapperHandler<RetT, ClassT, ArgTs...>
614 makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
615  return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
616 }
617 
618 } // end namespace shared
619 } // end namespace orc
620 } // end namespace llvm
621 
622 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:37
llvm::orc::shared::WrapperFunctionResult::release
detail::CWrapperFunctionResult release()
Release ownership of the contained detail::CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:85
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
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:524
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:392
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:156
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult()
Create a default WrapperFunctionResult.
Definition: WrapperFunctionUtils.h:49
llvm::orc::shared::detail::AsyncCallResultHelper
Definition: WrapperFunctionUtils.h:425
llvm::orc::shared::WrapperFunction< void(SPSTagTs...)>::callAsync
static void callAsync(AsyncCallerFn &&Caller, SendDeserializedResultFn &&SendDeserializedResult, const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:560
llvm::orc::shared::detail::CWrapperFunctionResultDataUnion
Definition: WrapperFunctionUtils.h:30
llvm::orc::shared::detail::CWrapperFunctionResultDataUnion::ValuePtr
char * ValuePtr
Definition: WrapperFunctionUtils.h:31
llvm::orc::shared::WrapperFunctionResult::~WrapperFunctionResult
~WrapperFunctionResult()
Definition: WrapperFunctionUtils.h:75
llvm::orc::shared::detail::ResultDeserializer::makeValue
static RetT makeValue()
Definition: WrapperFunctionUtils.h:376
llvm::orc::shared::WrapperFunctionResult::operator=
WrapperFunctionResult & operator=(const WrapperFunctionResult &)=delete
llvm::orc::shared::SPSOutputBuffer
Output char buffer with overflow check.
Definition: SimplePackedSerialization.h:53
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:119
llvm::orc::shared::WrapperFunction
Definition: WrapperFunctionUtils.h:431
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
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:443
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:141
llvm::orc::shared::WrapperFunctionResult::empty
bool empty() const
Returns true if this value is equivalent to a default-constructed WrapperFunctionResult.
Definition: WrapperFunctionUtils.h:115
llvm::orc::shared::detail::WrapperFunctionHandlerCaller::call
static decltype(auto) call(HandlerT &&H, ArgTupleT &Args, std::index_sequence< I... >)
Definition: WrapperFunctionUtils.h:191
llvm::orc::shared::detail::WrapperFunctionHandlerCaller< void >::call
static SPSEmpty call(HandlerT &&H, ArgTupleT &Args, std::index_sequence< I... >)
Definition: WrapperFunctionUtils.h:200
llvm::orc::shared::detail::WrapperFunctionHandlerHelper
Definition: WrapperFunctionUtils.h:209
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::orc::shared::SPSInputBuffer
Input char buffer with underflow check.
Definition: SimplePackedSerialization.h:72
llvm::orc::shared::detail::WrapperFunctionHandlerHelper< RetT(ArgTs...), ResultSerializer, SPSTagTs... >::ArgTuple
std::tuple< std::decay_t< ArgTs >... > ArgTuple
Definition: WrapperFunctionUtils.h:219
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
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:379
llvm::orc::shared::detail::ResultSerializer
Definition: WrapperFunctionUtils.h:349
llvm::orc::shared::WrapperFunctionResult::copyFrom
static WrapperFunctionResult copyFrom(const char *Source, size_t Size)
Copy from the given char range.
Definition: WrapperFunctionUtils.h:129
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:136
llvm::cl::apply
void apply(Opt *O, const Mod &M, const Mods &... Ms)
Definition: CommandLine.h:1318
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::orc::shared::detail::fromSPSSerializable
Error fromSPSSerializable(SPSSerializableError BSE)
Definition: SimplePackedSerialization.h:540
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeValue
static Expected< T > makeValue()
Definition: WrapperFunctionUtils.h:409
llvm::orc::shared::detail::CWrapperFunctionResult::Data
CWrapperFunctionResultDataUnion Data
Definition: WrapperFunctionUtils.h:38
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:286
llvm::orc::shared::detail::SPSSerializableError
Helper type for serializing Errors.
Definition: SimplePackedSerialization.h:518
llvm::orc::shared::MethodWrapperHandler::MethodWrapperHandler
MethodWrapperHandler(MethodT M)
Definition: WrapperFunctionUtils.h:602
llvm::orc::shared::detail::CWrapperFunctionResult
Definition: WrapperFunctionUtils.h:37
llvm::orc::shared::SPSEmpty
Definition: SimplePackedSerialization.h:177
llvm::orc::shared::WrapperFunctionResult::operator=
WrapperFunctionResult & operator=(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:69
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:472
llvm::orc::shared::detail::ResultSerializer::serialize
static WrapperFunctionResult serialize(RetT Result)
Definition: WrapperFunctionUtils.h:351
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper< RetT(SendResultT, ArgTs...), ResultSerializer, SPSTagTs... >::ArgTuple
std::tuple< std::decay_t< ArgTs >... > ArgTuple
Definition: WrapperFunctionUtils.h:282
llvm::orc::shared::detail::serializeViaSPSToWrapperFunctionResult
WrapperFunctionResult serializeViaSPSToWrapperFunctionResult(const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:179
llvm::orc::shared::WrapperFunctionResult
C++ wrapper function result: Same as CWrapperFunctionResult but auto-releases memory.
Definition: WrapperFunctionUtils.h:46
llvm::orc::shared::detail::WrapperFunctionHandlerHelper< RetT(ArgTs...), ResultSerializer, SPSTagTs... >::apply
static WrapperFunctionResult apply(HandlerT &&H, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:223
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:359
llvm::orc::shared::detail::ResultDeserializer
Definition: WrapperFunctionUtils.h:374
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:220
llvm::orc::shared::WrapperFunction< void(SPSTagTs...)>::call
static Error call(const CallerFn &Caller, const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:553
llvm::orc::shared::WrapperFunctionResult::data
char * data()
Get a pointer to the data contained in this instance.
Definition: WrapperFunctionUtils.h:93
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:505
I
#define I(x, y, z)
Definition: MD5.cpp:59
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
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::orc::shared::MethodWrapperHandler::MethodT
RetT(ClassT::*)(ArgTs...) MethodT
Definition: WrapperFunctionUtils.h:601
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
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:283
SimplePackedSerialization.h
llvm::orc::shared::detail::WrapperFunctionHandlerCaller
Definition: WrapperFunctionUtils.h:188
llvm::Sched::Source
@ Source
Definition: TargetLowering.h:100
llvm::orc::shared::WrapperFunctionResult::size
size_t size() const
Returns the size of the data contained in this instance.
Definition: WrapperFunctionUtils.h:107
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:162
llvm::orc::shared::WrapperFunctionResult::data
const char * data() const
Get a const pointer to the data contained in this instance.
Definition: WrapperFunctionUtils.h:100
llvm::orc::shared::detail::ResultDeserializer< SPSError, Error >::makeValue
static Error makeValue()
Definition: WrapperFunctionUtils.h:391
llvm::orc::shared::detail::ResultDeserializer::makeSafe
static void makeSafe(RetT &Result)
Definition: WrapperFunctionUtils.h:377
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeSafe
static void makeSafe(Expected< T > &E)
Definition: WrapperFunctionUtils.h:410
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:747
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:796
llvm::orc::shared::detail::ResultSerializer< SPSRetTagT, Expected< T > >::serialize
static WrapperFunctionResult serialize(Expected< T > E)
Definition: WrapperFunctionUtils.h:368
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:514
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:412
std
Definition: BitVector.h:838
H
#define H(x, y, z)
Definition: MD5.cpp:58
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::MethodWrapperHandler::operator()
RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args)
Definition: WrapperFunctionUtils.h:603
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::shared::detail::CWrapperFunctionResultDataUnion::Value
char Value[sizeof(ValuePtr)]
Definition: WrapperFunctionUtils.h:32
llvm::orc::shared::detail::toSPSSerializable
SPSSerializableError toSPSSerializable(Error Err)
Definition: SimplePackedSerialization.h:534
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::orc::shared::detail::SPSSerializableExpected
Helper type for serializing Expected<T>s.
Definition: SimplePackedSerialization.h:528
llvm::MipsISD::SDR
@ SDR
Definition: MipsISelLowering.h:252
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:146
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper
Definition: WrapperFunctionUtils.h:272
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:614
llvm::orc::ExecutorAddr::toPtr
T toPtr() const
Cast this ExecutorAddr to a pointer of the given type.
Definition: ExecutorAddress.h:53
llvm::orc::shared::detail::ResultDeserializer< SPSError, Error >::deserialize
static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize)
Definition: WrapperFunctionUtils.h:394
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
llvm::orc::shared::detail::CWrapperFunctionResult::Size
size_t Size
Definition: WrapperFunctionUtils.h:39
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult(detail::CWrapperFunctionResult R)
Create a WrapperFunctionResult by taking ownership of a detail::CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:56
llvm::orc::shared::SPSArgList
A utility class for serializing to a blob from a variadic list.
Definition: SimplePackedSerialization.h:106
llvm::orc::shared::MethodWrapperHandler
A function object that takes an ExecutorAddr as its first argument, casts that address to a ClassT*,...
Definition: WrapperFunctionUtils.h:599
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1184
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:64