LLVM  17.0.0git
SimplePackedSerialization.h
Go to the documentation of this file.
1 //===---- SimplePackedSerialization.h - simple serialization ----*- 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 // The behavior of the utilities in this header must be synchronized with the
10 // behavior of the utilities in
11 // compiler-rt/lib/orc/simple_packed_serialization.h.
12 //
13 // The Simple Packed Serialization (SPS) utilities are used to generate
14 // argument and return buffers for wrapper functions using the following
15 // serialization scheme:
16 //
17 // Primitives (signed types should be two's complement):
18 // bool, char, int8_t, uint8_t -- 8-bit (0=false, 1=true)
19 // int16_t, uint16_t -- 16-bit little endian
20 // int32_t, uint32_t -- 32-bit little endian
21 // int64_t, int64_t -- 64-bit little endian
22 //
23 // Sequence<T>:
24 // Serialized as the sequence length (as a uint64_t) followed by the
25 // serialization of each of the elements without padding.
26 //
27 // Tuple<T1, ..., TN>:
28 // Serialized as each of the element types from T1 to TN without padding.
29 //
30 //===----------------------------------------------------------------------===//
31 
32 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
33 #define LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
34 
35 #include "llvm/ADT/STLExtras.h"
36 #include "llvm/ADT/SmallVector.h"
37 #include "llvm/ADT/StringMap.h"
38 #include "llvm/ADT/StringRef.h"
39 #include "llvm/Support/Error.h"
41 
42 #include <limits>
43 #include <optional>
44 #include <string>
45 #include <tuple>
46 #include <type_traits>
47 #include <utility>
48 #include <vector>
49 
50 namespace llvm {
51 namespace orc {
52 namespace shared {
53 
54 /// Output char buffer with overflow check.
56 public:
57  SPSOutputBuffer(char *Buffer, size_t Remaining)
58  : Buffer(Buffer), Remaining(Remaining) {}
59  bool write(const char *Data, size_t Size) {
60  assert(Data && "Data must not be null");
61  if (Size > Remaining)
62  return false;
63  memcpy(Buffer, Data, Size);
64  Buffer += Size;
65  Remaining -= Size;
66  return true;
67  }
68 
69 private:
70  char *Buffer = nullptr;
71  size_t Remaining = 0;
72 };
73 
74 /// Input char buffer with underflow check.
76 public:
77  SPSInputBuffer() = default;
78  SPSInputBuffer(const char *Buffer, size_t Remaining)
79  : Buffer(Buffer), Remaining(Remaining) {}
80  bool read(char *Data, size_t Size) {
81  if (Size > Remaining)
82  return false;
83  memcpy(Data, Buffer, Size);
84  Buffer += Size;
85  Remaining -= Size;
86  return true;
87  }
88 
89  const char *data() const { return Buffer; }
90  bool skip(size_t Size) {
91  if (Size > Remaining)
92  return false;
93  Buffer += Size;
94  Remaining -= Size;
95  return true;
96  }
97 
98 private:
99  const char *Buffer = nullptr;
100  size_t Remaining = 0;
101 };
102 
103 /// Specialize to describe how to serialize/deserialize to/from the given
104 /// concrete type.
105 template <typename SPSTagT, typename ConcreteT, typename _ = void>
107 
108 /// A utility class for serializing to a blob from a variadic list.
109 template <typename... ArgTs> class SPSArgList;
110 
111 // Empty list specialization for SPSArgList.
112 template <> class SPSArgList<> {
113 public:
114  static size_t size() { return 0; }
115 
116  static bool serialize(SPSOutputBuffer &OB) { return true; }
117  static bool deserialize(SPSInputBuffer &IB) { return true; }
118 
119  static bool serializeToSmallVector(SmallVectorImpl<char> &V) { return true; }
120 
122  return true;
123  }
124 };
125 
126 // Non-empty list specialization for SPSArgList.
127 template <typename SPSTagT, typename... SPSTagTs>
128 class SPSArgList<SPSTagT, SPSTagTs...> {
129 public:
130  // FIXME: This typedef is here to enable SPS arg serialization from
131  // JITLink. It can be removed once JITLink can access SPS directly.
133 
134  template <typename ArgT, typename... ArgTs>
135  static size_t size(const ArgT &Arg, const ArgTs &...Args) {
138  }
139 
140  template <typename ArgT, typename... ArgTs>
141  static bool serialize(SPSOutputBuffer &OB, const ArgT &Arg,
142  const ArgTs &...Args) {
145  }
146 
147  template <typename ArgT, typename... ArgTs>
148  static bool deserialize(SPSInputBuffer &IB, ArgT &Arg, ArgTs &...Args) {
151  }
152 };
153 
154 /// SPS serialization for integral types, bool, and char.
155 template <typename SPSTagT>
157  SPSTagT, SPSTagT,
158  std::enable_if_t<std::is_same<SPSTagT, bool>::value ||
159  std::is_same<SPSTagT, char>::value ||
160  std::is_same<SPSTagT, int8_t>::value ||
161  std::is_same<SPSTagT, int16_t>::value ||
162  std::is_same<SPSTagT, int32_t>::value ||
163  std::is_same<SPSTagT, int64_t>::value ||
164  std::is_same<SPSTagT, uint8_t>::value ||
165  std::is_same<SPSTagT, uint16_t>::value ||
166  std::is_same<SPSTagT, uint32_t>::value ||
167  std::is_same<SPSTagT, uint64_t>::value>> {
168 public:
169  static size_t size(const SPSTagT &Value) { return sizeof(SPSTagT); }
170 
171  static bool serialize(SPSOutputBuffer &OB, const SPSTagT &Value) {
172  SPSTagT Tmp = Value;
174  sys::swapByteOrder(Tmp);
175  return OB.write(reinterpret_cast<const char *>(&Tmp), sizeof(Tmp));
176  }
177 
178  static bool deserialize(SPSInputBuffer &IB, SPSTagT &Value) {
179  SPSTagT Tmp;
180  if (!IB.read(reinterpret_cast<char *>(&Tmp), sizeof(Tmp)))
181  return false;
183  sys::swapByteOrder(Tmp);
184  Value = Tmp;
185  return true;
186  }
187 };
188 
189 // Any empty placeholder suitable as a substitute for void when deserializing
190 class SPSEmpty {};
191 
192 /// SPS tag type for tuples.
193 ///
194 /// A blob tuple should be serialized by serializing each of the elements in
195 /// sequence.
196 template <typename... SPSTagTs> class SPSTuple {
197 public:
198  /// Convenience typedef of the corresponding arg list.
199  typedef SPSArgList<SPSTagTs...> AsArgList;
200 };
201 
202 /// SPS tag type for optionals.
203 ///
204 /// SPSOptionals should be serialized as a bool with true indicating that an
205 /// SPSTagT value is present, and false indicating that there is no value.
206 /// If the boolean is true then the serialized SPSTagT will follow immediately
207 /// after it.
208 template <typename SPSTagT> class SPSOptional {};
209 
210 /// SPS tag type for sequences.
211 ///
212 /// SPSSequences should be serialized as a uint64_t sequence length,
213 /// followed by the serialization of each of the elements.
214 template <typename SPSElementTagT> class SPSSequence;
215 
216 /// SPS tag type for strings, which are equivalent to sequences of chars.
218 
219 /// SPS tag type for maps.
220 ///
221 /// SPS maps are just sequences of (Key, Value) tuples.
222 template <typename SPSTagT1, typename SPSTagT2>
224 
225 /// Serialization for SPSEmpty type.
227 public:
228  static size_t size(const SPSEmpty &EP) { return 0; }
229  static bool serialize(SPSOutputBuffer &OB, const SPSEmpty &BE) {
230  return true;
231  }
232  static bool deserialize(SPSInputBuffer &IB, SPSEmpty &BE) { return true; }
233 };
234 
235 /// Specialize this to implement 'trivial' sequence serialization for
236 /// a concrete sequence type.
237 ///
238 /// Trivial sequence serialization uses the sequence's 'size' member to get the
239 /// length of the sequence, and uses a range-based for loop to iterate over the
240 /// elements.
241 ///
242 /// Specializing this template class means that you do not need to provide a
243 /// specialization of SPSSerializationTraits for your type.
244 template <typename SPSElementTagT, typename ConcreteSequenceT>
246 public:
247  static constexpr bool available = false;
248 };
249 
250 /// Specialize this to implement 'trivial' sequence deserialization for
251 /// a concrete sequence type.
252 ///
253 /// Trivial deserialization calls a static 'reserve(SequenceT&)' method on your
254 /// specialization (you must implement this) to reserve space, and then calls
255 /// a static 'append(SequenceT&, ElementT&) method to append each of the
256 /// deserialized elements.
257 ///
258 /// Specializing this template class means that you do not need to provide a
259 /// specialization of SPSSerializationTraits for your type.
260 template <typename SPSElementTagT, typename ConcreteSequenceT>
262 public:
263  static constexpr bool available = false;
264 };
265 
266 /// Trivial std::string -> SPSSequence<char> serialization.
267 template <> class TrivialSPSSequenceSerialization<char, std::string> {
268 public:
269  static constexpr bool available = true;
270 };
271 
272 /// Trivial SPSSequence<char> -> std::string deserialization.
273 template <> class TrivialSPSSequenceDeserialization<char, std::string> {
274 public:
275  static constexpr bool available = true;
276 
277  using element_type = char;
278 
279  static void reserve(std::string &S, uint64_t Size) { S.reserve(Size); }
280  static bool append(std::string &S, char C) {
281  S.push_back(C);
282  return true;
283  }
284 };
285 
286 /// Trivial std::vector<T> -> SPSSequence<SPSElementTagT> serialization.
287 template <typename SPSElementTagT, typename T>
288 class TrivialSPSSequenceSerialization<SPSElementTagT, std::vector<T>> {
289 public:
290  static constexpr bool available = true;
291 };
292 
293 /// Trivial SPSSequence<SPSElementTagT> -> std::vector<T> deserialization.
294 template <typename SPSElementTagT, typename T>
295 class TrivialSPSSequenceDeserialization<SPSElementTagT, std::vector<T>> {
296 public:
297  static constexpr bool available = true;
298 
299  using element_type = typename std::vector<T>::value_type;
300 
301  static void reserve(std::vector<T> &V, uint64_t Size) { V.reserve(Size); }
302  static bool append(std::vector<T> &V, T E) {
303  V.push_back(std::move(E));
304  return true;
305  }
306 };
307 
308 /// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
309 template <typename SPSElementTagT, typename T>
311 public:
312  static constexpr bool available = true;
313 };
314 
315 /// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
316 template <typename SPSElementTagT, typename T>
318 public:
319  static constexpr bool available = true;
320 
322 
323  static void reserve(SmallVectorImpl<T> &V, uint64_t Size) { V.reserve(Size); }
324  static bool append(SmallVectorImpl<T> &V, T E) {
325  V.push_back(std::move(E));
326  return true;
327  }
328 };
329 
330 /// Trivial SmallVectorImpl<T> -> SPSSequence<char> serialization.
331 template <typename SPSElementTagT, typename T, unsigned N>
333  : public TrivialSPSSequenceSerialization<SPSElementTagT,
334  SmallVectorImpl<T>> {};
335 
336 /// Trivial SPSSequence<SPSElementTagT> -> SmallVectorImpl<T> deserialization.
337 template <typename SPSElementTagT, typename T, unsigned N>
339  : public TrivialSPSSequenceDeserialization<SPSElementTagT,
340  SmallVectorImpl<T>> {};
341 
342 /// Trivial ArrayRef<T> -> SPSSequence<SPSElementTagT> serialization.
343 template <typename SPSElementTagT, typename T>
344 class TrivialSPSSequenceSerialization<SPSElementTagT, ArrayRef<T>> {
345 public:
346  static constexpr bool available = true;
347 };
348 
349 /// Specialized SPSSequence<char> -> ArrayRef<char> serialization.
350 ///
351 /// On deserialize, points directly into the input buffer.
352 template <> class SPSSerializationTraits<SPSSequence<char>, ArrayRef<char>> {
353 public:
354  static size_t size(const ArrayRef<char> &A) {
355  return SPSArgList<uint64_t>::size(static_cast<uint64_t>(A.size())) +
356  A.size();
357  }
358 
359  static bool serialize(SPSOutputBuffer &OB, const ArrayRef<char> &A) {
360  if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(A.size())))
361  return false;
362  if (A.empty()) // Empty ArrayRef may have null data, so bail out early.
363  return true;
364  return OB.write(A.data(), A.size());
365  }
366 
368  uint64_t Size;
370  return false;
372  return false;
373  A = {Size ? IB.data() : nullptr, static_cast<size_t>(Size)};
374  return IB.skip(Size);
375  }
376 };
377 
378 /// 'Trivial' sequence serialization: Sequence is serialized as a uint64_t size
379 /// followed by a for-earch loop over the elements of the sequence to serialize
380 /// each of them.
381 template <typename SPSElementTagT, typename SequenceT>
382 class SPSSerializationTraits<SPSSequence<SPSElementTagT>, SequenceT,
383  std::enable_if_t<TrivialSPSSequenceSerialization<
384  SPSElementTagT, SequenceT>::available>> {
385 public:
386  static size_t size(const SequenceT &S) {
387  size_t Size = SPSArgList<uint64_t>::size(static_cast<uint64_t>(S.size()));
388  for (const auto &E : S)
390  return Size;
391  }
392 
393  static bool serialize(SPSOutputBuffer &OB, const SequenceT &S) {
394  if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(S.size())))
395  return false;
396  for (const auto &E : S)
398  return false;
399  return true;
400  }
401 
402  static bool deserialize(SPSInputBuffer &IB, SequenceT &S) {
404  uint64_t Size;
406  return false;
407  TBSD::reserve(S, Size);
408  for (size_t I = 0; I != Size; ++I) {
409  typename TBSD::element_type E;
411  return false;
412  if (!TBSD::append(S, std::move(E)))
413  return false;
414  }
415  return true;
416  }
417 };
418 
419 /// SPSTuple serialization for std::tuple.
420 template <typename... SPSTagTs, typename... Ts>
421 class SPSSerializationTraits<SPSTuple<SPSTagTs...>, std::tuple<Ts...>> {
422 private:
423  using TupleArgList = typename SPSTuple<SPSTagTs...>::AsArgList;
424  using ArgIndices = std::make_index_sequence<sizeof...(Ts)>;
425 
426  template <std::size_t... I>
427  static size_t size(const std::tuple<Ts...> &T, std::index_sequence<I...>) {
428  return TupleArgList::size(std::get<I>(T)...);
429  }
430 
431  template <std::size_t... I>
432  static bool serialize(SPSOutputBuffer &OB, const std::tuple<Ts...> &T,
433  std::index_sequence<I...>) {
434  return TupleArgList::serialize(OB, std::get<I>(T)...);
435  }
436 
437  template <std::size_t... I>
438  static bool deserialize(SPSInputBuffer &IB, std::tuple<Ts...> &T,
439  std::index_sequence<I...>) {
440  return TupleArgList::deserialize(IB, std::get<I>(T)...);
441  }
442 
443 public:
444  static size_t size(const std::tuple<Ts...> &T) {
445  return size(T, ArgIndices{});
446  }
447 
448  static bool serialize(SPSOutputBuffer &OB, const std::tuple<Ts...> &T) {
449  return serialize(OB, T, ArgIndices{});
450  }
451 
452  static bool deserialize(SPSInputBuffer &IB, std::tuple<Ts...> &T) {
453  return deserialize(IB, T, ArgIndices{});
454  }
455 };
456 
457 /// SPSTuple serialization for std::pair.
458 template <typename SPSTagT1, typename SPSTagT2, typename T1, typename T2>
459 class SPSSerializationTraits<SPSTuple<SPSTagT1, SPSTagT2>, std::pair<T1, T2>> {
460 public:
461  static size_t size(const std::pair<T1, T2> &P) {
462  return SPSArgList<SPSTagT1>::size(P.first) +
464  }
465 
466  static bool serialize(SPSOutputBuffer &OB, const std::pair<T1, T2> &P) {
467  return SPSArgList<SPSTagT1>::serialize(OB, P.first) &&
469  }
470 
471  static bool deserialize(SPSInputBuffer &IB, std::pair<T1, T2> &P) {
472  return SPSArgList<SPSTagT1>::deserialize(IB, P.first) &&
474  }
475 };
476 
477 /// SPSOptional serialization for std::optional.
478 template <typename SPSTagT, typename T>
479 class SPSSerializationTraits<SPSOptional<SPSTagT>, std::optional<T>> {
480 public:
481  static size_t size(const std::optional<T> &Value) {
482  size_t Size = SPSArgList<bool>::size(!!Value);
483  if (Value)
485  return Size;
486  }
487 
488  static bool serialize(SPSOutputBuffer &OB, const std::optional<T> &Value) {
490  return false;
491  if (Value)
493  return true;
494  }
495 
496  static bool deserialize(SPSInputBuffer &IB, std::optional<T> &Value) {
497  bool HasValue;
499  return false;
500  if (HasValue) {
501  Value = T();
503  } else
504  Value = std::optional<T>();
505  return true;
506  }
507 };
508 
509 /// Serialization for StringRefs.
510 ///
511 /// Serialization is as for regular strings. Deserialization points directly
512 /// into the blob.
514 public:
515  static size_t size(const StringRef &S) {
516  return SPSArgList<uint64_t>::size(static_cast<uint64_t>(S.size())) +
517  S.size();
518  }
519 
521  if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(S.size())))
522  return false;
523  if (S.empty()) // Empty StringRef may have null data, so bail out early.
524  return true;
525  return OB.write(S.data(), S.size());
526  }
527 
529  const char *Data = nullptr;
530  uint64_t Size;
532  return false;
533  Data = IB.data();
534  if (!IB.skip(Size))
535  return false;
536  S = StringRef(Size ? Data : nullptr, Size);
537  return true;
538  }
539 };
540 
541 /// Serialization for StringMap<ValueT>s.
542 template <typename SPSValueT, typename ValueT>
544  StringMap<ValueT>> {
545 public:
546  static size_t size(const StringMap<ValueT> &M) {
547  size_t Sz = SPSArgList<uint64_t>::size(static_cast<uint64_t>(M.size()));
548  for (auto &E : M)
549  Sz += SPSArgList<SPSString, SPSValueT>::size(E.first(), E.second);
550  return Sz;
551  }
552 
553  static bool serialize(SPSOutputBuffer &OB, const StringMap<ValueT> &M) {
554  if (!SPSArgList<uint64_t>::serialize(OB, static_cast<uint64_t>(M.size())))
555  return false;
556 
557  for (auto &E : M)
558  if (!SPSArgList<SPSString, SPSValueT>::serialize(OB, E.first(), E.second))
559  return false;
560 
561  return true;
562  }
563 
565  uint64_t Size;
566  assert(M.empty() && "M already contains elements");
567 
569  return false;
570 
571  while (Size--) {
572  StringRef S;
573  ValueT V;
575  return false;
576  if (!M.insert(std::make_pair(S, V)).second)
577  return false;
578  }
579 
580  return true;
581  }
582 };
583 
584 /// SPS tag type for errors.
585 class SPSError;
586 
587 /// SPS tag type for expecteds, which are either a T or a string representing
588 /// an error.
589 template <typename SPSTagT> class SPSExpected;
590 
591 namespace detail {
592 
593 /// Helper type for serializing Errors.
594 ///
595 /// llvm::Errors are move-only, and not inspectable except by consuming them.
596 /// This makes them unsuitable for direct serialization via
597 /// SPSSerializationTraits, which needs to inspect values twice (once to
598 /// determine the amount of space to reserve, and then again to serialize).
599 ///
600 /// The SPSSerializableError type is a helper that can be
601 /// constructed from an llvm::Error, but inspected more than once.
603  bool HasError = false;
604  std::string ErrMsg;
605 };
606 
607 /// Helper type for serializing Expected<T>s.
608 ///
609 /// See SPSSerializableError for more details.
610 ///
611 // FIXME: Use std::variant for storage once we have c++17.
612 template <typename T> struct SPSSerializableExpected {
613  bool HasValue = false;
614  T Value{};
615  std::string ErrMsg;
616 };
617 
619  if (Err)
620  return {true, toString(std::move(Err))};
621  return {false, {}};
622 }
623 
625  if (BSE.HasError)
626  return make_error<StringError>(BSE.ErrMsg, inconvertibleErrorCode());
627  return Error::success();
628 }
629 
630 template <typename T>
632  if (E)
633  return {true, std::move(*E), {}};
634  else
635  return {false, T(), toString(E.takeError())};
636 }
637 
638 template <typename T>
640  if (BSE.HasValue)
641  return std::move(BSE.Value);
642  else
643  return make_error<StringError>(BSE.ErrMsg, inconvertibleErrorCode());
644 }
645 
646 } // end namespace detail
647 
648 /// Serialize to a SPSError from a detail::SPSSerializableError.
649 template <>
650 class SPSSerializationTraits<SPSError, detail::SPSSerializableError> {
651 public:
652  static size_t size(const detail::SPSSerializableError &BSE) {
653  size_t Size = SPSArgList<bool>::size(BSE.HasError);
654  if (BSE.HasError)
655  Size += SPSArgList<SPSString>::size(BSE.ErrMsg);
656  return Size;
657  }
658 
660  const detail::SPSSerializableError &BSE) {
662  return false;
663  if (BSE.HasError)
665  return false;
666  return true;
667  }
668 
672  return false;
673 
674  if (!BSE.HasError)
675  return true;
676 
678  }
679 };
680 
681 /// Serialize to a SPSExpected<SPSTagT> from a
682 /// detail::SPSSerializableExpected<T>.
683 template <typename SPSTagT, typename T>
685  detail::SPSSerializableExpected<T>> {
686 public:
687  static size_t size(const detail::SPSSerializableExpected<T> &BSE) {
688  size_t Size = SPSArgList<bool>::size(BSE.HasValue);
689  if (BSE.HasValue)
690  Size += SPSArgList<SPSTagT>::size(BSE.Value);
691  else
692  Size += SPSArgList<SPSString>::size(BSE.ErrMsg);
693  return Size;
694  }
695 
699  return false;
700 
701  if (BSE.HasValue)
703 
705  }
706 
710  return false;
711 
712  if (BSE.HasValue)
714 
716  }
717 };
718 
719 /// Serialize to a SPSExpected<SPSTagT> from a detail::SPSSerializableError.
720 template <typename SPSTagT>
722  detail::SPSSerializableError> {
723 public:
724  static size_t size(const detail::SPSSerializableError &BSE) {
725  assert(BSE.HasError && "Cannot serialize expected from a success value");
726  return SPSArgList<bool>::size(false) +
728  }
729 
731  const detail::SPSSerializableError &BSE) {
732  assert(BSE.HasError && "Cannot serialize expected from a success value");
733  if (!SPSArgList<bool>::serialize(OB, false))
734  return false;
736  }
737 };
738 
739 /// Serialize to a SPSExpected<SPSTagT> from a T.
740 template <typename SPSTagT, typename T>
742 public:
743  static size_t size(const T &Value) {
745  }
746 
747  static bool serialize(SPSOutputBuffer &OB, const T &Value) {
748  if (!SPSArgList<bool>::serialize(OB, true))
749  return false;
751  }
752 };
753 
754 } // end namespace shared
755 } // end namespace orc
756 } // end namespace llvm
757 
758 #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_SIMPLEPACKEDSERIALIZATION_H
llvm::X86II::OB
@ OB
Definition: X86BaseInfo.h:806
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, detail::SPSSerializableExpected< T > >::serialize
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableExpected< T > &BSE)
Definition: SimplePackedSerialization.h:696
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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::sys::IsBigEndianHost
constexpr bool IsBigEndianHost
Definition: SwapByteOrder.h:64
llvm::orc::shared::SPSSequence
SPS tag type for sequences.
Definition: SimplePackedSerialization.h:214
llvm::sys::swapByteOrder
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:112
llvm::orc::shared::TrivialSPSSequenceSerialization
Specialize this to implement 'trivial' sequence serialization for a concrete sequence type.
Definition: SimplePackedSerialization.h:245
llvm::orc::shared::SPSSerializationTraits
Specialize to describe how to serialize/deserialize to/from the given concrete type.
Definition: SimplePackedSerialization.h:106
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, std::vector< T > >::reserve
static void reserve(std::vector< T > &V, uint64_t Size)
Definition: SimplePackedSerialization.h:301
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::orc::shared::SPSOutputBuffer
Output char buffer with overflow check.
Definition: SimplePackedSerialization.h:55
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSTuple< SPSString, SPSValueT > >, StringMap< ValueT > >::deserialize
static bool deserialize(SPSInputBuffer &IB, StringMap< ValueT > &M)
Definition: SimplePackedSerialization.h:564
Error.h
SwapByteOrder.h
llvm::orc::shared::SPSArgList<>::serialize
static bool serialize(SPSOutputBuffer &OB)
Definition: SimplePackedSerialization.h:116
llvm::orc::shared::SPSSerializationTraits< SPSOptional< SPSTagT >, std::optional< T > >::deserialize
static bool deserialize(SPSInputBuffer &IB, std::optional< T > &Value)
Definition: SimplePackedSerialization.h:496
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagTs... >, std::tuple< Ts... > >::size
static size_t size(const std::tuple< Ts... > &T)
Definition: SimplePackedSerialization.h:444
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagT1, SPSTagT2 >, std::pair< T1, T2 > >::serialize
static bool serialize(SPSOutputBuffer &OB, const std::pair< T1, T2 > &P)
Definition: SimplePackedSerialization.h:466
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::orc::shared::SPSSerializationTraits< SPSSequence< char >, ArrayRef< char > >::serialize
static bool serialize(SPSOutputBuffer &OB, const ArrayRef< char > &A)
Definition: SimplePackedSerialization.h:359
llvm::orc::shared::SPSInputBuffer
Input char buffer with underflow check.
Definition: SimplePackedSerialization.h:75
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSElementTagT >, SequenceT, std::enable_if_t< TrivialSPSSequenceSerialization< SPSElementTagT, SequenceT >::available > >::size
static size_t size(const SequenceT &S)
Definition: SimplePackedSerialization.h:386
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
STLExtras.h
llvm::orc::shared::SPSSerializationTraits< SPSSequence< char >, ArrayRef< char > >::deserialize
static bool deserialize(SPSInputBuffer &IB, ArrayRef< char > &A)
Definition: SimplePackedSerialization.h:367
llvm::orc::shared::SPSTuple
SPS tag type for tuples.
Definition: SimplePackedSerialization.h:196
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSTuple< SPSString, SPSValueT > >, StringMap< ValueT > >::size
static size_t size(const StringMap< ValueT > &M)
Definition: SimplePackedSerialization.h:546
llvm::orc::shared::SPSSerializationTraits< SPSOptional< SPSTagT >, std::optional< T > >::serialize
static bool serialize(SPSOutputBuffer &OB, const std::optional< T > &Value)
Definition: SimplePackedSerialization.h:488
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:187
llvm::orc::shared::SPSInputBuffer::SPSInputBuffer
SPSInputBuffer()=default
llvm::orc::shared::SPSArgList< SPSTagT, SPSTagTs... >::size
static size_t size(const ArgT &Arg, const ArgTs &...Args)
Definition: SimplePackedSerialization.h:135
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, std::vector< T > >::element_type
typename std::vector< T >::value_type element_type
Definition: SimplePackedSerialization.h:299
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagT1, SPSTagT2 >, std::pair< T1, T2 > >::deserialize
static bool deserialize(SPSInputBuffer &IB, std::pair< T1, T2 > &P)
Definition: SimplePackedSerialization.h:471
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::orc::shared::detail::fromSPSSerializable
Error fromSPSSerializable(SPSSerializableError BSE)
Definition: SimplePackedSerialization.h:624
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::orc::shared::detail::SPSSerializableError
Helper type for serializing Errors.
Definition: SimplePackedSerialization.h:602
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::deserialize
static bool deserialize(SPSInputBuffer &IB, SPSTagT &Value)
Definition: SimplePackedSerialization.h:178
llvm::orc::shared::SPSOutputBuffer::write
bool write(const char *Data, size_t Size)
Definition: SimplePackedSerialization.h:59
llvm::orc::shared::SPSEmpty
Definition: SimplePackedSerialization.h:190
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, detail::SPSSerializableError >::size
static size_t size(const detail::SPSSerializableError &BSE)
Definition: SimplePackedSerialization.h:724
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, SmallVectorImpl< T > >::append
static bool append(SmallVectorImpl< T > &V, T E)
Definition: SimplePackedSerialization.h:324
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, SmallVectorImpl< T > >::reserve
static void reserve(SmallVectorImpl< T > &V, uint64_t Size)
Definition: SimplePackedSerialization.h:323
llvm::orc::shared::SPSOptional
SPS tag type for optionals.
Definition: SimplePackedSerialization.h:208
llvm::orc::shared::SPSSerializationTraits< SPSSequence< char >, ArrayRef< char > >::size
static size_t size(const ArrayRef< char > &A)
Definition: SimplePackedSerialization.h:354
llvm::orc::shared::SPSSerializationTraits< SPSString, StringRef >::size
static size_t size(const StringRef &S)
Definition: SimplePackedSerialization.h:515
llvm::orc::shared::SPSInputBuffer::read
bool read(char *Data, size_t Size)
Definition: SimplePackedSerialization.h:80
llvm::orc::shared::TrivialSPSSequenceDeserialization< char, std::string >::append
static bool append(std::string &S, char C)
Definition: SimplePackedSerialization.h:280
llvm::orc::shared::SPSOutputBuffer::SPSOutputBuffer
SPSOutputBuffer(char *Buffer, size_t Remaining)
Definition: SimplePackedSerialization.h:57
llvm::orc::shared::SPSSerializationTraits< SPSError, detail::SPSSerializableError >::size
static size_t size(const detail::SPSSerializableError &BSE)
Definition: SimplePackedSerialization.h:652
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::size
static size_t size(const SPSTagT &Value)
Definition: SimplePackedSerialization.h:169
llvm::orc::shared::SPSArgList<>::deserialize
static bool deserialize(SPSInputBuffer &IB)
Definition: SimplePackedSerialization.h:117
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:110
llvm::orc::shared::SPSArgList< SPSTagT, SPSTagTs... >::deserialize
static bool deserialize(SPSInputBuffer &IB, ArgT &Arg, ArgTs &...Args)
Definition: SimplePackedSerialization.h:148
llvm::orc::shared::TrivialSPSSequenceDeserialization::available
static constexpr bool available
Definition: SimplePackedSerialization.h:263
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, T >::serialize
static bool serialize(SPSOutputBuffer &OB, const T &Value)
Definition: SimplePackedSerialization.h:747
llvm::orc::shared::SPSSerializationTraits< SPSString, StringRef >::serialize
static bool serialize(SPSOutputBuffer &OB, StringRef S)
Definition: SimplePackedSerialization.h:520
llvm::orc::shared::TrivialSPSSequenceSerialization::available
static constexpr bool available
Definition: SimplePackedSerialization.h:247
llvm::orc::shared::SPSSerializationTraits< SPSOptional< SPSTagT >, std::optional< T > >::size
static size_t size(const std::optional< T > &Value)
Definition: SimplePackedSerialization.h:481
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, T >::size
static size_t size(const T &Value)
Definition: SimplePackedSerialization.h:743
uint64_t
llvm::orc::shared::SPSSerializationTraits< SPSTagT, SPSTagT, std::enable_if_t< std::is_same< SPSTagT, bool >::value||std::is_same< SPSTagT, char >::value||std::is_same< SPSTagT, int8_t >::value||std::is_same< SPSTagT, int16_t >::value||std::is_same< SPSTagT, int32_t >::value||std::is_same< SPSTagT, int64_t >::value||std::is_same< SPSTagT, uint8_t >::value||std::is_same< SPSTagT, uint16_t >::value||std::is_same< SPSTagT, uint32_t >::value||std::is_same< SPSTagT, uint64_t >::value > >::serialize
static bool serialize(SPSOutputBuffer &OB, const SPSTagT &Value)
Definition: SimplePackedSerialization.h:171
llvm::orc::shared::SPSSerializationTraits< SPSEmpty, SPSEmpty >::deserialize
static bool deserialize(SPSInputBuffer &IB, SPSEmpty &BE)
Definition: SimplePackedSerialization.h:232
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:589
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, detail::SPSSerializableError >::serialize
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableError &BSE)
Definition: SimplePackedSerialization.h:730
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::AArch64PACKey::IB
@ IB
Definition: AArch64BaseInfo.h:826
llvm::orc::shared::detail::SPSSerializableError::HasError
bool HasError
Definition: SimplePackedSerialization.h:603
llvm::orc::shared::SPSInputBuffer::data
const char * data() const
Definition: SimplePackedSerialization.h:89
llvm::orc::shared::TrivialSPSSequenceDeserialization< char, std::string >::element_type
char element_type
Definition: SimplePackedSerialization.h:277
size
i< reg-> size
Definition: README.txt:166
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSElementTagT >, SequenceT, std::enable_if_t< TrivialSPSSequenceSerialization< SPSElementTagT, SequenceT >::available > >::serialize
static bool serialize(SPSOutputBuffer &OB, const SequenceT &S)
Definition: SimplePackedSerialization.h:393
llvm::orc::shared::SPSArgList<>::deserializeFromSmallVector
static bool deserializeFromSmallVector(const SmallVectorImpl< char > &V)
Definition: SimplePackedSerialization.h:121
llvm::orc::shared::SPSSerializationTraits< SPSError, detail::SPSSerializableError >::deserialize
static bool deserialize(SPSInputBuffer &IB, detail::SPSSerializableError &BSE)
Definition: SimplePackedSerialization.h:669
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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::SPSSerializableExpected::ErrMsg
std::string ErrMsg
Definition: SimplePackedSerialization.h:615
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, SmallVectorImpl< T > >::element_type
typename SmallVectorImpl< T >::value_type element_type
Definition: SimplePackedSerialization.h:321
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1716
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, detail::SPSSerializableExpected< T > >::deserialize
static bool deserialize(SPSInputBuffer &IB, detail::SPSSerializableExpected< T > &BSE)
Definition: SimplePackedSerialization.h:707
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:33
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::orc::shared::SPSArgList< SPSTagT, SPSTagTs... >::serialize
static bool serialize(SPSOutputBuffer &OB, const ArgT &Arg, const ArgTs &...Args)
Definition: SimplePackedSerialization.h:141
ValueT
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::orc::shared::SPSTuple::AsArgList
SPSArgList< SPSTagTs... > AsArgList
Convenience typedef of the corresponding arg list.
Definition: SimplePackedSerialization.h:199
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSTuple< SPSString, SPSValueT > >, StringMap< ValueT > >::serialize
static bool serialize(SPSOutputBuffer &OB, const StringMap< ValueT > &M)
Definition: SimplePackedSerialization.h:553
std
Definition: BitVector.h:851
llvm::orc::shared::TrivialSPSSequenceDeserialization< SPSElementTagT, std::vector< T > >::append
static bool append(std::vector< T > &V, T E)
Definition: SimplePackedSerialization.h:302
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:79
llvm::orc::shared::SPSInputBuffer::SPSInputBuffer
SPSInputBuffer(const char *Buffer, size_t Remaining)
Definition: SimplePackedSerialization.h:78
llvm::orc::shared::detail::SPSSerializableError::ErrMsg
std::string ErrMsg
Definition: SimplePackedSerialization.h:604
llvm::orc::shared::SPSSerializationTraits< SPSString, StringRef >::deserialize
static bool deserialize(SPSInputBuffer &IB, StringRef &S)
Definition: SimplePackedSerialization.h:528
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition: DWARFUnitIndex.h:67
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
llvm::orc::shared::TrivialSPSSequenceDeserialization
Specialize this to implement 'trivial' sequence deserialization for a concrete sequence type.
Definition: SimplePackedSerialization.h:261
llvm::orc::shared::detail::toSPSSerializable
SPSSerializableError toSPSSerializable(Error Err)
Definition: SimplePackedSerialization.h:618
llvm::orc::shared::SPSSerializationTraits< SPSError, detail::SPSSerializableError >::serialize
static bool serialize(SPSOutputBuffer &OB, const detail::SPSSerializableError &BSE)
Definition: SimplePackedSerialization.h:659
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::orc::shared::SPSArgList<>::serializeToSmallVector
static bool serializeToSmallVector(SmallVectorImpl< char > &V)
Definition: SimplePackedSerialization.h:119
llvm::orc::shared::detail::SPSSerializableExpected::HasValue
bool HasValue
Definition: SimplePackedSerialization.h:613
llvm::orc::shared::detail::SPSSerializableExpected
Helper type for serializing Expected<T>s.
Definition: SimplePackedSerialization.h:612
llvm::HasValue
detail::ValueMatchesPoly< M > HasValue(M Matcher)
Definition: Error.h:221
llvm::orc::shared::SPSSerializationTraits< SPSSequence< SPSElementTagT >, SequenceT, std::enable_if_t< TrivialSPSSequenceSerialization< SPSElementTagT, SequenceT >::available > >::deserialize
static bool deserialize(SPSInputBuffer &IB, SequenceT &S)
Definition: SimplePackedSerialization.h:402
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagTs... >, std::tuple< Ts... > >::deserialize
static bool deserialize(SPSInputBuffer &IB, std::tuple< Ts... > &T)
Definition: SimplePackedSerialization.h:452
llvm::orc::shared::SPSSerializationTraits< SPSExpected< SPSTagT >, detail::SPSSerializableExpected< T > >::size
static size_t size(const detail::SPSSerializableExpected< T > &BSE)
Definition: SimplePackedSerialization.h:687
SmallVector.h
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagT1, SPSTagT2 >, std::pair< T1, T2 > >::size
static size_t size(const std::pair< T1, T2 > &P)
Definition: SimplePackedSerialization.h:461
N
#define N
llvm::orc::shared::detail::SPSSerializableExpected::Value
T Value
Definition: SimplePackedSerialization.h:614
llvm::orc::shared::TrivialSPSSequenceDeserialization< char, std::string >::reserve
static void reserve(std::string &S, uint64_t Size)
Definition: SimplePackedSerialization.h:279
llvm::SmallVectorImpl< char >
llvm::orc::shared::SPSArgList<>::size
static size_t size()
Definition: SimplePackedSerialization.h:114
StringMap.h
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::orc::shared::SPSInputBuffer::skip
bool skip(size_t Size)
Definition: SimplePackedSerialization.h:90
llvm::orc::shared::SPSSerializationTraits< SPSTuple< SPSTagTs... >, std::tuple< Ts... > >::serialize
static bool serialize(SPSOutputBuffer &OB, const std::tuple< Ts... > &T)
Definition: SimplePackedSerialization.h:448
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:667
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:109
SpecialSubKind::string
@ string
llvm::orc::shared::SPSSerializationTraits< SPSEmpty, SPSEmpty >::size
static size_t size(const SPSEmpty &EP)
Definition: SimplePackedSerialization.h:228
llvm::orc::shared::SPSSerializationTraits< SPSEmpty, SPSEmpty >::serialize
static bool serialize(SPSOutputBuffer &OB, const SPSEmpty &BE)
Definition: SimplePackedSerialization.h:229