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 // 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.
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.
140  static WrapperFunctionResult createOutOfBandError(const char *Msg) {
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, typename T>
360 class ResultSerializer<SPSRetTagT, Expected<T>> {
361 public:
363  return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
365  }
366 };
367 
368 template <typename SPSRetTagT, typename RetT> class ResultDeserializer {
369 public:
370  static RetT makeValue() { return RetT(); }
371  static void makeSafe(RetT &Result) {}
372 
373  static Error deserialize(RetT &Result, const char *ArgData, size_t ArgSize) {
374  SPSInputBuffer IB(ArgData, ArgSize);
375  if (!SPSArgList<SPSRetTagT>::deserialize(IB, Result))
376  return make_error<StringError>(
377  "Error deserializing return value from blob in call",
379  return Error::success();
380  }
381 };
382 
383 template <> class ResultDeserializer<SPSError, Error> {
384 public:
385  static Error makeValue() { return Error::success(); }
386  static void makeSafe(Error &Err) { cantFail(std::move(Err)); }
387 
388  static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize) {
389  SPSInputBuffer IB(ArgData, ArgSize);
391  if (!SPSArgList<SPSError>::deserialize(IB, BSE))
392  return make_error<StringError>(
393  "Error deserializing return value from blob in call",
395  Err = fromSPSSerializable(std::move(BSE));
396  return Error::success();
397  }
398 };
399 
400 template <typename SPSTagT, typename T>
402 public:
403  static Expected<T> makeValue() { return T(); }
404  static void makeSafe(Expected<T> &E) { cantFail(E.takeError()); }
405 
406  static Error deserialize(Expected<T> &E, const char *ArgData,
407  size_t ArgSize) {
408  SPSInputBuffer IB(ArgData, ArgSize);
411  return make_error<StringError>(
412  "Error deserializing return value from blob in call",
415  return Error::success();
416  }
417 };
418 
419 template <typename SPSRetTagT, typename RetT> class AsyncCallResultHelper {
420  // Did you forget to use Error / Expected in your handler?
421 };
422 
423 } // end namespace detail
424 
425 template <typename SPSSignature> class WrapperFunction;
426 
427 template <typename SPSRetTagT, typename... SPSTagTs>
428 class WrapperFunction<SPSRetTagT(SPSTagTs...)> {
429 private:
430  template <typename RetT>
432 
433 public:
434  /// Call a wrapper function. Caller should be callable as
435  /// WrapperFunctionResult Fn(const char *ArgData, size_t ArgSize);
436  template <typename CallerFn, typename RetT, typename... ArgTs>
437  static Error call(const CallerFn &Caller, RetT &Result,
438  const ArgTs &...Args) {
439 
440  // RetT might be an Error or Expected value. Set the checked flag now:
441  // we don't want the user to have to check the unused result if this
442  // operation fails.
444 
445  auto ArgBuffer =
447  Args...);
448  if (const char *ErrMsg = ArgBuffer.getOutOfBandError())
449  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
450 
451  WrapperFunctionResult ResultBuffer =
452  Caller(ArgBuffer.data(), ArgBuffer.size());
453  if (auto ErrMsg = ResultBuffer.getOutOfBandError())
454  return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
455 
457  Result, ResultBuffer.data(), ResultBuffer.size());
458  }
459 
460  /// Call an async wrapper function.
461  /// Caller should be callable as
462  /// void Fn(unique_function<void(WrapperFunctionResult)> SendResult,
463  /// WrapperFunctionResult ArgBuffer);
464  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
465  typename... ArgTs>
466  static void callAsync(AsyncCallerFn &&Caller,
467  SendDeserializedResultFn &&SendDeserializedResult,
468  const ArgTs &...Args) {
469  using RetT = typename std::tuple_element<
471  std::remove_reference_t<SendDeserializedResultFn>,
472  ResultSerializer, SPSRetTagT>::ArgTuple>::type;
473 
474  auto ArgBuffer =
476  Args...);
477  if (auto *ErrMsg = ArgBuffer.getOutOfBandError()) {
478  SendDeserializedResult(
479  make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
481  return;
482  }
483 
484  auto SendSerializedResult = [SDR = std::move(SendDeserializedResult)](
485  WrapperFunctionResult R) mutable {
488 
489  if (auto *ErrMsg = R.getOutOfBandError()) {
490  SDR(make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
491  std::move(RetVal));
492  return;
493  }
494 
495  SPSInputBuffer IB(R.data(), R.size());
497  RetVal, R.data(), R.size()))
498  SDR(std::move(Err), std::move(RetVal));
499 
500  SDR(Error::success(), std::move(RetVal));
501  };
502 
503  Caller(std::move(SendSerializedResult), ArgBuffer.data(), ArgBuffer.size());
504  }
505 
506  /// Handle a call to a wrapper function.
507  template <typename HandlerT>
508  static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize,
509  HandlerT &&Handler) {
510  using WFHH =
512  ResultSerializer, SPSTagTs...>;
513  return WFHH::apply(std::forward<HandlerT>(Handler), ArgData, ArgSize);
514  }
515 
516  /// Handle a call to an async wrapper function.
517  template <typename HandlerT, typename SendResultT>
518  static void handleAsync(const char *ArgData, size_t ArgSize,
519  HandlerT &&Handler, SendResultT &&SendResult) {
521  std::remove_reference_t<HandlerT>, ResultSerializer, SPSTagTs...>;
522  WFAHH::applyAsync(std::forward<HandlerT>(Handler),
523  std::forward<SendResultT>(SendResult), ArgData, ArgSize);
524  }
525 
526 private:
527  template <typename T> static const T &makeSerializable(const T &Value) {
528  return Value;
529  }
530 
531  static detail::SPSSerializableError makeSerializable(Error Err) {
533  }
534 
535  template <typename T>
536  static detail::SPSSerializableExpected<T> makeSerializable(Expected<T> E) {
538  }
539 };
540 
541 template <typename... SPSTagTs>
542 class WrapperFunction<void(SPSTagTs...)>
543  : private WrapperFunction<SPSEmpty(SPSTagTs...)> {
544 
545 public:
546  template <typename CallerFn, typename... ArgTs>
547  static Error call(const CallerFn &Caller, const ArgTs &...Args) {
548  SPSEmpty BE;
549  return WrapperFunction<SPSEmpty(SPSTagTs...)>::call(Caller, BE, Args...);
550  }
551 
552  template <typename AsyncCallerFn, typename SendDeserializedResultFn,
553  typename... ArgTs>
554  static void callAsync(AsyncCallerFn &&Caller,
555  SendDeserializedResultFn &&SendDeserializedResult,
556  const ArgTs &...Args) {
557  WrapperFunction<SPSEmpty(SPSTagTs...)>::callAsync(
558  std::forward<AsyncCallerFn>(Caller),
559  [SDR = std::move(SendDeserializedResult)](Error SerializeErr,
560  SPSEmpty E) mutable {
561  SDR(std::move(SerializeErr));
562  },
563  Args...);
564  }
565 
566  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handle;
567  using WrapperFunction<SPSEmpty(SPSTagTs...)>::handleAsync;
568 };
569 
570 /// A function object that takes an ExecutorAddr as its first argument,
571 /// casts that address to a ClassT*, then calls the given method on that
572 /// pointer passing in the remaining function arguments. This utility
573 /// removes some of the boilerplate from writing wrappers for method calls.
574 ///
575 /// @code{.cpp}
576 /// class MyClass {
577 /// public:
578 /// void myMethod(uint32_t, bool) { ... }
579 /// };
580 ///
581 /// // SPS Method signature -- note MyClass object address as first argument.
582 /// using SPSMyMethodWrapperSignature =
583 /// SPSTuple<SPSExecutorAddr, uint32_t, bool>;
584 ///
585 /// WrapperFunctionResult
586 /// myMethodCallWrapper(const char *ArgData, size_t ArgSize) {
587 /// return WrapperFunction<SPSMyMethodWrapperSignature>::handle(
588 /// ArgData, ArgSize, makeMethodWrapperHandler(&MyClass::myMethod));
589 /// }
590 /// @endcode
591 ///
592 template <typename RetT, typename ClassT, typename... ArgTs>
594 public:
595  using MethodT = RetT (ClassT::*)(ArgTs...);
597  RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args) {
598  return (ObjAddr.toPtr<ClassT*>()->*M)(std::forward<ArgTs>(Args)...);
599  }
600 
601 private:
602  MethodT M;
603 };
604 
605 /// Create a MethodWrapperHandler object from the given method pointer.
606 template <typename RetT, typename ClassT, typename... ArgTs>
607 MethodWrapperHandler<RetT, ClassT, ArgTs...>
608 makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
609  return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
610 }
611 
612 } // end namespace shared
613 } // end namespace orc
614 } // end namespace llvm
615 
616 #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
This is an optimization pass for GlobalISel generic memory operations.
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:518
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:386
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:419
llvm::orc::shared::WrapperFunction< void(SPSTagTs...)>::callAsync
static void callAsync(AsyncCallerFn &&Caller, SendDeserializedResultFn &&SendDeserializedResult, const ArgTs &...Args)
Definition: WrapperFunctionUtils.h:554
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:370
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:113
llvm::orc::shared::WrapperFunction
Definition: WrapperFunctionUtils.h:425
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:437
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::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::X86II::OB
@ OB
Definition: X86BaseInfo.h:801
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:213
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::orc::shared::CWrapperFunctionResultDataUnion
Definition: WrapperFunctionUtils.h:27
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:373
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:1318
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::orc::shared::detail::fromSPSSerializable
Error fromSPSSerializable(SPSSerializableError BSE)
Definition: SimplePackedSerialization.h:533
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeValue
static Expected< T > makeValue()
Definition: WrapperFunctionUtils.h:403
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:511
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:596
llvm::orc::shared::SPSEmpty
Definition: SimplePackedSerialization.h:177
llvm::orc::shared::WrapperFunctionResult::operator=
WrapperFunctionResult & operator=(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:63
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:466
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::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:368
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:547
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:498
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:595
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:277
SimplePackedSerialization.h
llvm::orc::shared::detail::WrapperFunctionHandlerCaller
Definition: WrapperFunctionUtils.h:182
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: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:385
llvm::orc::shared::detail::ResultDeserializer::makeSafe
static void makeSafe(RetT &Result)
Definition: WrapperFunctionUtils.h:371
llvm::orc::shared::detail::ResultDeserializer< SPSExpected< SPSTagT >, Expected< T > >::makeSafe
static void makeSafe(Expected< T > &E)
Definition: WrapperFunctionUtils.h:404
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::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:362
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:508
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:406
llvm::orc::shared::CWrapperFunctionResult::Data
CWrapperFunctionResultDataUnion Data
Definition: WrapperFunctionUtils.h:34
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:597
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::shared::detail::toSPSSerializable
SPSSerializableError toSPSSerializable(Error Err)
Definition: SimplePackedSerialization.h:527
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::orc::shared::detail::SPSSerializableExpected
Helper type for serializing Expected<T>s.
Definition: SimplePackedSerialization.h:521
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:140
llvm::orc::shared::detail::WrapperFunctionAsyncHandlerHelper
Definition: WrapperFunctionUtils.h:266
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:608
llvm::orc::shared::WrapperFunctionResult::release
CWrapperFunctionResult release()
Release ownership of the contained CWrapperFunctionResult.
Definition: WrapperFunctionUtils.h:79
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:388
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:389
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: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:593
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1191
llvm::orc::shared::WrapperFunctionResult::WrapperFunctionResult
WrapperFunctionResult(WrapperFunctionResult &&Other)
Definition: WrapperFunctionUtils.h:58