LLVM  10.0.0svn
LegalizerInfo.h
Go to the documentation of this file.
1 //===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- 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 /// Interface for Targets to specify which operations they can successfully
10 /// select and how the others should be expanded most efficiently.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16 
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/None.h"
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SmallVector.h"
27 #include <cassert>
28 #include <cstdint>
29 #include <tuple>
30 #include <unordered_map>
31 #include <utility>
32 
33 namespace llvm {
34 
35 extern cl::opt<bool> DisableGISelLegalityCheck;
36 
37 class MachineInstr;
38 class MachineIRBuilder;
39 class MachineRegisterInfo;
40 class MCInstrInfo;
41 class GISelChangeObserver;
42 
43 namespace LegalizeActions {
44 enum LegalizeAction : std::uint8_t {
45  /// The operation is expected to be selectable directly by the target, and
46  /// no transformation is necessary.
48 
49  /// The operation should be synthesized from multiple instructions acting on
50  /// a narrower scalar base-type. For example a 64-bit add might be
51  /// implemented in terms of 32-bit add-with-carry.
53 
54  /// The operation should be implemented in terms of a wider scalar
55  /// base-type. For example a <2 x s8> add could be implemented as a <2
56  /// x s32> add (ignoring the high bits).
58 
59  /// The (vector) operation should be implemented by splitting it into
60  /// sub-vectors where the operation is legal. For example a <8 x s64> add
61  /// might be implemented as 4 separate <2 x s64> adds.
63 
64  /// The (vector) operation should be implemented by widening the input
65  /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
66  /// rarely legal, but you might perform an <8 x i8> and then only look at
67  /// the first two results.
69 
70  /// The operation itself must be expressed in terms of simpler actions on
71  /// this target. E.g. a SREM replaced by an SDIV and subtraction.
73 
74  /// The operation should be implemented as a call to some kind of runtime
75  /// support library. For example this usually happens on machines that don't
76  /// support floating-point operations natively.
78 
79  /// The target wants to do something special with this combination of
80  /// operand and type. A callback will be issued when it is needed.
82 
83  /// This operation is completely unsupported on the target. A programming
84  /// error has occurred.
86 
87  /// Sentinel value for when no action was found in the specified table.
89 
90  /// Fall back onto the old rules.
91  /// TODO: Remove this once we've migrated
93 };
94 } // end namespace LegalizeActions
96 
98 
99 /// Legalization is decided based on an instruction's opcode, which type slot
100 /// we're considering, and what the existing type is. These aspects are gathered
101 /// together for convenience in the InstrAspect class.
102 struct InstrAspect {
103  unsigned Opcode;
104  unsigned Idx = 0;
106 
107  InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
108  InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
109  : Opcode(Opcode), Idx(Idx), Type(Type) {}
110 
111  bool operator==(const InstrAspect &RHS) const {
112  return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
113  }
114 };
115 
116 /// The LegalityQuery object bundles together all the information that's needed
117 /// to decide whether a given operation is legal or not.
118 /// For efficiency, it doesn't make a copy of Types so care must be taken not
119 /// to free it before using the query.
121  unsigned Opcode;
123 
124  struct MemDesc {
125  uint64_t SizeInBits;
126  uint64_t AlignInBits;
128  };
129 
130  /// Operations which require memory can use this to place requirements on the
131  /// memory type for each MMO.
133 
134  constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types,
135  const ArrayRef<MemDesc> MMODescrs)
136  : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
137  constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types)
138  : LegalityQuery(Opcode, Types, {}) {}
139 
140  raw_ostream &print(raw_ostream &OS) const;
141 };
142 
143 /// The result of a query. It either indicates a final answer of Legal or
144 /// Unsupported or describes an action that must be taken to make an operation
145 /// more legal.
147  /// The action to take or the final answer.
149  /// If describing an action, the type index to change. Otherwise zero.
150  unsigned TypeIdx;
151  /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
153 
154  LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
155  const LLT &NewType)
156  : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
157 
158  bool operator==(const LegalizeActionStep &RHS) const {
159  return std::tie(Action, TypeIdx, NewType) ==
160  std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
161  }
162 };
163 
164 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
165 using LegalizeMutation =
166  std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
167 
172  uint64_t MemSize;
173  uint64_t Align;
174 
175  bool operator==(const TypePairAndMemDesc &Other) const {
176  return Type0 == Other.Type0 && Type1 == Other.Type1 &&
177  Align == Other.Align &&
178  MemSize == Other.MemSize;
179  }
180 
181  /// \returns true if this memory access is legal with for the acecss described
182  /// by \p Other (The alignment is sufficient for the size and result type).
183  bool isCompatible(const TypePairAndMemDesc &Other) const {
184  return Type0 == Other.Type0 && Type1 == Other.Type1 &&
185  Align >= Other.Align &&
186  MemSize == Other.MemSize;
187  }
188 };
189 
190 /// True iff P0 and P1 are true.
191 template<typename Predicate>
193  return [=](const LegalityQuery &Query) {
194  return P0(Query) && P1(Query);
195  };
196 }
197 /// True iff all given predicates are true.
198 template<typename Predicate, typename... Args>
200  return all(all(P0, P1), args...);
201 }
202 /// True iff the given type index is the specified types.
203 LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
204 /// True iff the given type index is one of the specified types.
205 LegalityPredicate typeInSet(unsigned TypeIdx,
206  std::initializer_list<LLT> TypesInit);
207 /// True iff the given types for the given pair of type indexes is one of the
208 /// specified type pairs.
210 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
211  std::initializer_list<std::pair<LLT, LLT>> TypesInit);
212 /// True iff the given types for the given pair of type indexes is one of the
213 /// specified type pairs.
215  unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
216  std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
217 /// True iff the specified type index is a scalar.
218 LegalityPredicate isScalar(unsigned TypeIdx);
219 /// True iff the specified type index is a vector.
220 LegalityPredicate isVector(unsigned TypeIdx);
221 /// True iff the specified type index is a pointer (with any address space).
222 LegalityPredicate isPointer(unsigned TypeIdx);
223 /// True iff the specified type index is a pointer with the specified address
224 /// space.
225 LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
226 
227 /// True iff the specified type index is a scalar that's narrower than the given
228 /// size.
229 LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
230 
231 /// True iff the specified type index is a scalar that's wider than the given
232 /// size.
233 LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
234 
235 /// True iff the specified type index is a scalar or vector with an element type
236 /// that's narrower than the given size.
237 LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
238 
239 /// True iff the specified type index is a scalar or a vector with an element
240 /// type that's wider than the given size.
241 LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
242 
243 /// True iff the specified type index is a scalar whose size is not a power of
244 /// 2.
245 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
246 
247 /// True iff the specified type index is a scalar or vector whose element size
248 /// is not a power of 2.
249 LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
250 
251 /// True iff the specified type indices are both the same bit size.
252 LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
253 /// True iff the specified MMO index has a size that is not a power of 2
255 /// True iff the specified type index is a vector whose element count is not a
256 /// power of 2.
257 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
258 /// True iff the specified MMO index has at an atomic ordering of at Ordering or
259 /// stronger.
261  AtomicOrdering Ordering);
262 } // end namespace LegalityPredicates
263 
264 namespace LegalizeMutations {
265 /// Select this specific type for the given type index.
266 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
267 
268 /// Keep the same type as the given type index.
269 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
270 
271 /// Keep the same scalar or element type as the given type index.
272 LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
273 
274 /// Keep the same scalar or element type as the given type.
275 LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
276 
277 /// Widen the scalar type or vector element type for the given type index to the
278 /// next power of 2.
279 LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
280 
281 /// Add more elements to the type for the given type index to the next power of
282 /// 2.
283 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
284 /// Break up the vector type for the given type index into the element type.
285 LegalizeMutation scalarize(unsigned TypeIdx);
286 } // end namespace LegalizeMutations
287 
288 /// A single rule in a legalizer info ruleset.
289 /// The specified action is chosen when the predicate is true. Where appropriate
290 /// for the action (e.g. for WidenScalar) the new type is selected using the
291 /// given mutator.
294  LegalizeAction Action;
296 
297 public:
299  LegalizeMutation Mutation = nullptr)
300  : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
301 
302  /// Test whether the LegalityQuery matches.
303  bool match(const LegalityQuery &Query) const {
304  return Predicate(Query);
305  }
306 
307  LegalizeAction getAction() const { return Action; }
308 
309  /// Determine the change to make.
310  std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
311  if (Mutation)
312  return Mutation(Query);
313  return std::make_pair(0, LLT{});
314  }
315 };
316 
318  /// When non-zero, the opcode we are an alias of
319  unsigned AliasOf;
320  /// If true, there is another opcode that aliases this one
321  bool IsAliasedByAnother;
323 
324 #ifndef NDEBUG
325  /// If bit I is set, this rule set contains a rule that may handle (predicate
326  /// or perform an action upon (or both)) the type index I. The uncertainty
327  /// comes from free-form rules executing user-provided lambda functions. We
328  /// conservatively assume such rules do the right thing and cover all type
329  /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
330  /// to be to distinguish such cases from the cases where all type indices are
331  /// individually handled.
336 #endif
337 
338  unsigned typeIdx(unsigned TypeIdx) {
339  assert(TypeIdx <=
340  (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
341  "Type Index is out of bounds");
342 #ifndef NDEBUG
343  TypeIdxsCovered.set(TypeIdx);
344 #endif
345  return TypeIdx;
346  }
347 
348  unsigned immIdx(unsigned ImmIdx) {
350  MCOI::OPERAND_FIRST_GENERIC_IMM) &&
351  "Imm Index is out of bounds");
352 #ifndef NDEBUG
353  ImmIdxsCovered.set(ImmIdx);
354 #endif
355  return ImmIdx;
356  }
357 
358  void markAllIdxsAsCovered() {
359 #ifndef NDEBUG
360  TypeIdxsCovered.set();
361  ImmIdxsCovered.set();
362 #endif
363  }
364 
365  void add(const LegalizeRule &Rule) {
366  assert(AliasOf == 0 &&
367  "RuleSet is aliased, change the representative opcode instead");
368  Rules.push_back(Rule);
369  }
370 
371  static bool always(const LegalityQuery &) { return true; }
372 
373  /// Use the given action when the predicate is true.
374  /// Action should not be an action that requires mutation.
375  LegalizeRuleSet &actionIf(LegalizeAction Action,
377  add({Predicate, Action});
378  return *this;
379  }
380  /// Use the given action when the predicate is true.
381  /// Action should be an action that requires mutation.
382  LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
384  add({Predicate, Action, Mutation});
385  return *this;
386  }
387  /// Use the given action when type index 0 is any type in the given list.
388  /// Action should not be an action that requires mutation.
389  LegalizeRuleSet &actionFor(LegalizeAction Action,
390  std::initializer_list<LLT> Types) {
391  using namespace LegalityPredicates;
392  return actionIf(Action, typeInSet(typeIdx(0), Types));
393  }
394  /// Use the given action when type index 0 is any type in the given list.
395  /// Action should be an action that requires mutation.
396  LegalizeRuleSet &actionFor(LegalizeAction Action,
397  std::initializer_list<LLT> Types,
398  LegalizeMutation Mutation) {
399  using namespace LegalityPredicates;
400  return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
401  }
402  /// Use the given action when type indexes 0 and 1 is any type pair in the
403  /// given list.
404  /// Action should not be an action that requires mutation.
405  LegalizeRuleSet &actionFor(LegalizeAction Action,
406  std::initializer_list<std::pair<LLT, LLT>> Types) {
407  using namespace LegalityPredicates;
408  return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
409  }
410  /// Use the given action when type indexes 0 and 1 is any type pair in the
411  /// given list.
412  /// Action should be an action that requires mutation.
413  LegalizeRuleSet &actionFor(LegalizeAction Action,
414  std::initializer_list<std::pair<LLT, LLT>> Types,
415  LegalizeMutation Mutation) {
416  using namespace LegalityPredicates;
417  return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
418  Mutation);
419  }
420  /// Use the given action when type index 0 is any type in the given list and
421  /// imm index 0 is anything. Action should not be an action that requires
422  /// mutation.
423  LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
424  std::initializer_list<LLT> Types) {
425  using namespace LegalityPredicates;
426  immIdx(0); // Inform verifier imm idx 0 is handled.
427  return actionIf(Action, typeInSet(typeIdx(0), Types));
428  }
429  /// Use the given action when type indexes 0 and 1 are both in the given list.
430  /// That is, the type pair is in the cartesian product of the list.
431  /// Action should not be an action that requires mutation.
432  LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
433  std::initializer_list<LLT> Types) {
434  using namespace LegalityPredicates;
435  return actionIf(Action, all(typeInSet(typeIdx(0), Types),
436  typeInSet(typeIdx(1), Types)));
437  }
438  /// Use the given action when type indexes 0 and 1 are both in their
439  /// respective lists.
440  /// That is, the type pair is in the cartesian product of the lists
441  /// Action should not be an action that requires mutation.
443  actionForCartesianProduct(LegalizeAction Action,
444  std::initializer_list<LLT> Types0,
445  std::initializer_list<LLT> Types1) {
446  using namespace LegalityPredicates;
447  return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
448  typeInSet(typeIdx(1), Types1)));
449  }
450  /// Use the given action when type indexes 0, 1, and 2 are all in their
451  /// respective lists.
452  /// That is, the type triple is in the cartesian product of the lists
453  /// Action should not be an action that requires mutation.
454  LegalizeRuleSet &actionForCartesianProduct(
455  LegalizeAction Action, std::initializer_list<LLT> Types0,
456  std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
457  using namespace LegalityPredicates;
458  return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
459  all(typeInSet(typeIdx(1), Types1),
460  typeInSet(typeIdx(2), Types2))));
461  }
462 
463 public:
464  LegalizeRuleSet() : AliasOf(0), IsAliasedByAnother(false), Rules() {}
465 
466  bool isAliasedByAnother() { return IsAliasedByAnother; }
467  void setIsAliasedByAnother() { IsAliasedByAnother = true; }
468  void aliasTo(unsigned Opcode) {
469  assert((AliasOf == 0 || AliasOf == Opcode) &&
470  "Opcode is already aliased to another opcode");
471  assert(Rules.empty() && "Aliasing will discard rules");
472  AliasOf = Opcode;
473  }
474  unsigned getAlias() const { return AliasOf; }
475 
476  /// The instruction is legal if predicate is true.
478  // We have no choice but conservatively assume that the free-form
479  // user-provided Predicate properly handles all type indices:
480  markAllIdxsAsCovered();
481  return actionIf(LegalizeAction::Legal, Predicate);
482  }
483  /// The instruction is legal when type index 0 is any type in the given list.
484  LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
485  return actionFor(LegalizeAction::Legal, Types);
486  }
487  /// The instruction is legal when type indexes 0 and 1 is any type pair in the
488  /// given list.
489  LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
490  return actionFor(LegalizeAction::Legal, Types);
491  }
492  /// The instruction is legal when type index 0 is any type in the given list
493  /// and imm index 0 is anything.
494  LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
495  markAllIdxsAsCovered();
496  return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
497  }
498  /// The instruction is legal when type indexes 0 and 1 along with the memory
499  /// size and minimum alignment is any type and size tuple in the given list.
501  std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
502  TypesAndMemDesc) {
503  return actionIf(LegalizeAction::Legal,
505  typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
506  }
507  /// The instruction is legal when type indexes 0 and 1 are both in the given
508  /// list. That is, the type pair is in the cartesian product of the list.
509  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
510  return actionForCartesianProduct(LegalizeAction::Legal, Types);
511  }
512  /// The instruction is legal when type indexes 0 and 1 are both their
513  /// respective lists.
514  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
515  std::initializer_list<LLT> Types1) {
516  return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
517  }
518  /// The instruction is legal when type indexes 0, 1, and 2 are both their
519  /// respective lists.
520  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
521  std::initializer_list<LLT> Types1,
522  std::initializer_list<LLT> Types2) {
523  return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
524  Types2);
525  }
526 
528  using namespace LegalizeMutations;
529  markAllIdxsAsCovered();
530  return actionIf(LegalizeAction::Legal, always);
531  }
532 
533  /// The instruction is lowered.
535  using namespace LegalizeMutations;
536  // We have no choice but conservatively assume that predicate-less lowering
537  // properly handles all type indices by design:
538  markAllIdxsAsCovered();
539  return actionIf(LegalizeAction::Lower, always);
540  }
541  /// The instruction is lowered if predicate is true. Keep type index 0 as the
542  /// same type.
544  using namespace LegalizeMutations;
545  // We have no choice but conservatively assume that lowering with a
546  // free-form user provided Predicate properly handles all type indices:
547  markAllIdxsAsCovered();
548  return actionIf(LegalizeAction::Lower, Predicate);
549  }
550  /// The instruction is lowered if predicate is true.
552  LegalizeMutation Mutation) {
553  // We have no choice but conservatively assume that lowering with a
554  // free-form user provided Predicate properly handles all type indices:
555  markAllIdxsAsCovered();
556  return actionIf(LegalizeAction::Lower, Predicate, Mutation);
557  }
558  /// The instruction is lowered when type index 0 is any type in the given
559  /// list. Keep type index 0 as the same type.
560  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
561  return actionFor(LegalizeAction::Lower, Types,
563  }
564  /// The instruction is lowered when type index 0 is any type in the given
565  /// list.
566  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
567  LegalizeMutation Mutation) {
568  return actionFor(LegalizeAction::Lower, Types, Mutation);
569  }
570  /// The instruction is lowered when type indexes 0 and 1 is any type pair in
571  /// the given list. Keep type index 0 as the same type.
572  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
573  return actionFor(LegalizeAction::Lower, Types,
575  }
576  /// The instruction is lowered when type indexes 0 and 1 is any type pair in
577  /// the given list.
578  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
579  LegalizeMutation Mutation) {
580  return actionFor(LegalizeAction::Lower, Types, Mutation);
581  }
582  /// The instruction is lowered when type indexes 0 and 1 are both in their
583  /// respective lists.
584  LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
585  std::initializer_list<LLT> Types1) {
586  using namespace LegalityPredicates;
587  return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
588  }
589  /// The instruction is lowered when when type indexes 0, 1, and 2 are all in
590  /// their respective lists.
591  LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
592  std::initializer_list<LLT> Types1,
593  std::initializer_list<LLT> Types2) {
594  using namespace LegalityPredicates;
595  return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
596  Types2);
597  }
598 
599  /// Like legalIf, but for the Libcall action.
601  // We have no choice but conservatively assume that a libcall with a
602  // free-form user provided Predicate properly handles all type indices:
603  markAllIdxsAsCovered();
604  return actionIf(LegalizeAction::Libcall, Predicate);
605  }
606  LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
607  return actionFor(LegalizeAction::Libcall, Types);
608  }
610  libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
611  return actionFor(LegalizeAction::Libcall, Types);
612  }
614  libcallForCartesianProduct(std::initializer_list<LLT> Types) {
615  return actionForCartesianProduct(LegalizeAction::Libcall, Types);
616  }
618  libcallForCartesianProduct(std::initializer_list<LLT> Types0,
619  std::initializer_list<LLT> Types1) {
620  return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
621  }
622 
623  /// Widen the scalar to the one selected by the mutation if the predicate is
624  /// true.
626  LegalizeMutation Mutation) {
627  // We have no choice but conservatively assume that an action with a
628  // free-form user provided Predicate properly handles all type indices:
629  markAllIdxsAsCovered();
630  return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
631  }
632  /// Narrow the scalar to the one selected by the mutation if the predicate is
633  /// true.
635  LegalizeMutation Mutation) {
636  // We have no choice but conservatively assume that an action with a
637  // free-form user provided Predicate properly handles all type indices:
638  markAllIdxsAsCovered();
639  return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
640  }
641 
642  /// Add more elements to reach the type selected by the mutation if the
643  /// predicate is true.
645  LegalizeMutation Mutation) {
646  // We have no choice but conservatively assume that an action with a
647  // free-form user provided Predicate properly handles all type indices:
648  markAllIdxsAsCovered();
649  return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
650  }
651  /// Remove elements to reach the type selected by the mutation if the
652  /// predicate is true.
654  LegalizeMutation Mutation) {
655  // We have no choice but conservatively assume that an action with a
656  // free-form user provided Predicate properly handles all type indices:
657  markAllIdxsAsCovered();
658  return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
659  }
660 
661  /// The instruction is unsupported.
663  return actionIf(LegalizeAction::Unsupported, always);
664  }
666  return actionIf(LegalizeAction::Unsupported, Predicate);
667  }
669  return actionIf(LegalizeAction::Unsupported,
671  }
673  return actionIf(LegalizeAction::Lower,
675  }
676 
678  // We have no choice but conservatively assume that a custom action with a
679  // free-form user provided Predicate properly handles all type indices:
680  markAllIdxsAsCovered();
681  return actionIf(LegalizeAction::Custom, Predicate);
682  }
683  LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
684  return actionFor(LegalizeAction::Custom, Types);
685  }
686 
687  /// The instruction is custom when type indexes 0 and 1 is any type pair in the
688  /// given list.
689  LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
690  return actionFor(LegalizeAction::Custom, Types);
691  }
692 
693  LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
694  return actionForCartesianProduct(LegalizeAction::Custom, Types);
695  }
697  customForCartesianProduct(std::initializer_list<LLT> Types0,
698  std::initializer_list<LLT> Types1) {
699  return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
700  }
701 
702  /// Unconditionally custom lower.
704  return customIf(always);
705  }
706 
707  /// Widen the scalar to the next power of two that is at least MinSize.
708  /// No effect if the type is not a scalar or is a power of two.
710  unsigned MinSize = 0) {
711  using namespace LegalityPredicates;
712  return actionIf(
713  LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
715  }
716 
717  /// Widen the scalar or vector element type to the next power of two that is
718  /// at least MinSize. No effect if the scalar size is a power of two.
720  unsigned MinSize = 0) {
721  using namespace LegalityPredicates;
722  return actionIf(
725  }
726 
727  LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
728  using namespace LegalityPredicates;
729  return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
730  Mutation);
731  }
732 
733  LegalizeRuleSet &scalarize(unsigned TypeIdx) {
734  using namespace LegalityPredicates;
735  return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
737  }
738 
739  /// Ensure the scalar or element is at least as wide as Ty.
740  LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
741  using namespace LegalityPredicates;
742  using namespace LegalizeMutations;
743  return actionIf(LegalizeAction::WidenScalar,
745  changeElementTo(typeIdx(TypeIdx), Ty));
746  }
747 
748  /// Ensure the scalar or element is at least as wide as Ty.
750  unsigned TypeIdx, const LLT &Ty) {
751  using namespace LegalityPredicates;
752  using namespace LegalizeMutations;
753  return actionIf(LegalizeAction::WidenScalar,
754  all(Predicate, scalarOrEltNarrowerThan(
755  TypeIdx, Ty.getScalarSizeInBits())),
756  changeElementTo(typeIdx(TypeIdx), Ty));
757  }
758 
759  /// Ensure the scalar is at least as wide as Ty.
760  LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
761  using namespace LegalityPredicates;
762  using namespace LegalizeMutations;
763  return actionIf(LegalizeAction::WidenScalar,
764  narrowerThan(TypeIdx, Ty.getSizeInBits()),
765  changeTo(typeIdx(TypeIdx), Ty));
766  }
767 
768  /// Ensure the scalar is at most as wide as Ty.
769  LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
770  using namespace LegalityPredicates;
771  using namespace LegalizeMutations;
772  return actionIf(LegalizeAction::NarrowScalar,
774  changeElementTo(typeIdx(TypeIdx), Ty));
775  }
776 
777  /// Ensure the scalar is at most as wide as Ty.
778  LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
779  using namespace LegalityPredicates;
780  using namespace LegalizeMutations;
781  return actionIf(LegalizeAction::NarrowScalar,
782  widerThan(TypeIdx, Ty.getSizeInBits()),
783  changeTo(typeIdx(TypeIdx), Ty));
784  }
785 
786  /// Conditionally limit the maximum size of the scalar.
787  /// For example, when the maximum size of one type depends on the size of
788  /// another such as extracting N bits from an M bit container.
789  LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
790  const LLT &Ty) {
791  using namespace LegalityPredicates;
792  using namespace LegalizeMutations;
793  return actionIf(
795  [=](const LegalityQuery &Query) {
796  return widerThan(TypeIdx, Ty.getSizeInBits()) && Predicate(Query);
797  },
798  changeElementTo(typeIdx(TypeIdx), Ty));
799  }
800 
801  /// Limit the range of scalar sizes to MinTy and MaxTy.
802  LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy,
803  const LLT &MaxTy) {
804  assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
805  return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
806  }
807 
808  /// Limit the range of scalar sizes to MinTy and MaxTy.
809  LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT &MinTy,
810  const LLT &MaxTy) {
811  return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
812  }
813 
814  /// Widen the scalar to match the size of another.
815  LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
816  typeIdx(TypeIdx);
817  return widenScalarIf(
818  [=](const LegalityQuery &Query) {
819  return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
820  Query.Types[TypeIdx].getSizeInBits();
821  },
822  [=](const LegalityQuery &Query) {
823  LLT T = Query.Types[LargeTypeIdx];
824  return std::make_pair(TypeIdx,
825  T.isVector() ? T.getElementType() : T);
826  });
827  }
828 
829  /// Conditionally widen the scalar or elt to match the size of another.
831  unsigned TypeIdx, unsigned LargeTypeIdx) {
832  typeIdx(TypeIdx);
833  return widenScalarIf(
834  [=](const LegalityQuery &Query) {
835  return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
836  Query.Types[TypeIdx].getScalarSizeInBits() &&
837  Predicate(Query);
838  },
839  [=](const LegalityQuery &Query) {
840  LLT T = Query.Types[LargeTypeIdx];
841  return std::make_pair(TypeIdx, T);
842  });
843  }
844 
845  /// Add more elements to the vector to reach the next power of two.
846  /// No effect if the type is not a vector or the element count is a power of
847  /// two.
849  using namespace LegalityPredicates;
850  return actionIf(LegalizeAction::MoreElements,
851  numElementsNotPow2(typeIdx(TypeIdx)),
853  }
854 
855  /// Limit the number of elements in EltTy vectors to at least MinElements.
856  LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy,
857  unsigned MinElements) {
858  // Mark the type index as covered:
859  typeIdx(TypeIdx);
860  return actionIf(
862  [=](const LegalityQuery &Query) {
863  LLT VecTy = Query.Types[TypeIdx];
864  return VecTy.isVector() && VecTy.getElementType() == EltTy &&
865  VecTy.getNumElements() < MinElements;
866  },
867  [=](const LegalityQuery &Query) {
868  LLT VecTy = Query.Types[TypeIdx];
869  return std::make_pair(
870  TypeIdx, LLT::vector(MinElements, VecTy.getElementType()));
871  });
872  }
873  /// Limit the number of elements in EltTy vectors to at most MaxElements.
874  LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy,
875  unsigned MaxElements) {
876  // Mark the type index as covered:
877  typeIdx(TypeIdx);
878  return actionIf(
880  [=](const LegalityQuery &Query) {
881  LLT VecTy = Query.Types[TypeIdx];
882  return VecTy.isVector() && VecTy.getElementType() == EltTy &&
883  VecTy.getNumElements() > MaxElements;
884  },
885  [=](const LegalityQuery &Query) {
886  LLT VecTy = Query.Types[TypeIdx];
887  LLT NewTy = LLT::scalarOrVector(MaxElements, VecTy.getElementType());
888  return std::make_pair(TypeIdx, NewTy);
889  });
890  }
891  /// Limit the number of elements for the given vectors to at least MinTy's
892  /// number of elements and at most MaxTy's number of elements.
893  ///
894  /// No effect if the type is not a vector or does not have the same element
895  /// type as the constraints.
896  /// The element type of MinTy and MaxTy must match.
897  LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT &MinTy,
898  const LLT &MaxTy) {
899  assert(MinTy.getElementType() == MaxTy.getElementType() &&
900  "Expected element types to agree");
901 
902  const LLT &EltTy = MinTy.getElementType();
903  return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
904  .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
905  }
906 
907  /// Fallback on the previous implementation. This should only be used while
908  /// porting a rule.
911  return *this;
912  }
913 
914  /// Check if there is no type index which is obviously not handled by the
915  /// LegalizeRuleSet in any way at all.
916  /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
917  bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
918  /// Check if there is no imm index which is obviously not handled by the
919  /// LegalizeRuleSet in any way at all.
920  /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
921  bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
922 
923  /// Apply the ruleset to the given LegalityQuery.
924  LegalizeActionStep apply(const LegalityQuery &Query) const;
925 };
926 
928 public:
929  LegalizerInfo();
930  virtual ~LegalizerInfo() = default;
931 
932  unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
933  unsigned getActionDefinitionsIdx(unsigned Opcode) const;
934 
935  /// Compute any ancillary tables needed to quickly decide how an operation
936  /// should be handled. This must be called after all "set*Action"methods but
937  /// before any query is made or incorrect results may be returned.
938  void computeTables();
939 
940  /// Perform simple self-diagnostic and assert if there is anything obviously
941  /// wrong with the actions set up.
942  void verify(const MCInstrInfo &MII) const;
943 
944  static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
945  using namespace LegalizeActions;
946  switch (Action) {
947  case NarrowScalar:
948  case WidenScalar:
949  case FewerElements:
950  case MoreElements:
951  case Unsupported:
952  return true;
953  default:
954  return false;
955  }
956  }
957 
958  using SizeAndAction = std::pair<uint16_t, LegalizeAction>;
959  using SizeAndActionsVec = std::vector<SizeAndAction>;
960  using SizeChangeStrategy =
961  std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
962 
963  /// More friendly way to set an action for common types that have an LLT
964  /// representation.
965  /// The LegalizeAction must be one for which NeedsLegalizingToDifferentSize
966  /// returns false.
967  void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
968  assert(!needsLegalizingToDifferentSize(Action));
969  TablesInitialized = false;
970  const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
971  if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
972  SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
973  SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
974  }
975 
976  /// The setAction calls record the non-size-changing legalization actions
977  /// to take on specificly-sized types. The SizeChangeStrategy defines what
978  /// to do when the size of the type needs to be changed to reach a legally
979  /// sized type (i.e., one that was defined through a setAction call).
980  /// e.g.
981  /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
982  /// setLegalizeScalarToDifferentSizeStrategy(
983  /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
984  /// will end up defining getAction({G_ADD, 0, T}) to return the following
985  /// actions for different scalar types T:
986  /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
987  /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
988  /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
989  ///
990  /// If no SizeChangeAction gets defined, through this function,
991  /// the default is unsupportedForDifferentSizes.
992  void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
993  const unsigned TypeIdx,
994  SizeChangeStrategy S) {
995  const unsigned OpcodeIdx = Opcode - FirstOp;
996  if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
997  ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
998  ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
999  }
1000 
1001  /// See also setLegalizeScalarToDifferentSizeStrategy.
1002  /// This function allows to set the SizeChangeStrategy for vector elements.
1004  const unsigned TypeIdx,
1005  SizeChangeStrategy S) {
1006  const unsigned OpcodeIdx = Opcode - FirstOp;
1007  if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
1008  VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
1009  VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
1010  }
1011 
1012  /// A SizeChangeStrategy for the common case where legalization for a
1013  /// particular operation consists of only supporting a specific set of type
1014  /// sizes. E.g.
1015  /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
1016  /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
1017  /// setLegalizeScalarToDifferentSizeStrategy(
1018  /// G_DIV, 0, unsupportedForDifferentSizes);
1019  /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
1020  /// and Unsupported for all other scalar types T.
1021  static SizeAndActionsVec
1023  using namespace LegalizeActions;
1024  return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
1025  Unsupported);
1026  }
1027 
1028  /// A SizeChangeStrategy for the common case where legalization for a
1029  /// particular operation consists of widening the type to a large legal type,
1030  /// unless there is no such type and then instead it should be narrowed to the
1031  /// largest legal type.
1032  static SizeAndActionsVec
1034  using namespace LegalizeActions;
1035  assert(v.size() > 0 &&
1036  "At least one size that can be legalized towards is needed"
1037  " for this SizeChangeStrategy");
1038  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
1039  NarrowScalar);
1040  }
1041 
1042  static SizeAndActionsVec
1044  using namespace LegalizeActions;
1045  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
1046  Unsupported);
1047  }
1048 
1049  static SizeAndActionsVec
1051  using namespace LegalizeActions;
1052  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
1053  Unsupported);
1054  }
1055 
1056  static SizeAndActionsVec
1058  using namespace LegalizeActions;
1059  assert(v.size() > 0 &&
1060  "At least one size that can be legalized towards is needed"
1061  " for this SizeChangeStrategy");
1062  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
1063  WidenScalar);
1064  }
1065 
1066  /// A SizeChangeStrategy for the common case where legalization for a
1067  /// particular vector operation consists of having more elements in the
1068  /// vector, to a type that is legal. Unless there is no such type and then
1069  /// instead it should be legalized towards the widest vector that's still
1070  /// legal. E.g.
1071  /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
1072  /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
1073  /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
1074  /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
1075  /// setLegalizeVectorElementToDifferentSizeStrategy(
1076  /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
1077  /// will result in the following getAction results:
1078  /// * getAction({G_ADD, LLT::vector(8,8)}) returns
1079  /// (Legal, vector(8,8)).
1080  /// * getAction({G_ADD, LLT::vector(9,8)}) returns
1081  /// (MoreElements, vector(16,8)).
1082  /// * getAction({G_ADD, LLT::vector(8,32)}) returns
1083  /// (FewerElements, vector(4,32)).
1084  static SizeAndActionsVec
1086  using namespace LegalizeActions;
1087  return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
1088  FewerElements);
1089  }
1090 
1091  /// Helper function to implement many typical SizeChangeStrategy functions.
1092  static SizeAndActionsVec
1093  increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v,
1094  LegalizeAction IncreaseAction,
1095  LegalizeAction DecreaseAction);
1096  /// Helper function to implement many typical SizeChangeStrategy functions.
1097  static SizeAndActionsVec
1098  decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v,
1099  LegalizeAction DecreaseAction,
1100  LegalizeAction IncreaseAction);
1101 
1102  /// Get the action definitions for the given opcode. Use this to run a
1103  /// LegalityQuery through the definitions.
1104  const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1105 
1106  /// Get the action definition builder for the given opcode. Use this to define
1107  /// the action definitions.
1108  ///
1109  /// It is an error to request an opcode that has already been requested by the
1110  /// multiple-opcode variant.
1111  LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
1112 
1113  /// Get the action definition builder for the given set of opcodes. Use this
1114  /// to define the action definitions for multiple opcodes at once. The first
1115  /// opcode given will be considered the representative opcode and will hold
1116  /// the definitions whereas the other opcodes will be configured to refer to
1117  /// the representative opcode. This lowers memory requirements and very
1118  /// slightly improves performance.
1119  ///
1120  /// It would be very easy to introduce unexpected side-effects as a result of
1121  /// this aliasing if it were permitted to request different but intersecting
1122  /// sets of opcodes but that is difficult to keep track of. It is therefore an
1123  /// error to request the same opcode twice using this API, to request an
1124  /// opcode that already has definitions, or to use the single-opcode API on an
1125  /// opcode that has already been requested by this API.
1126  LegalizeRuleSet &
1127  getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1128  void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1129 
1130  /// Determine what action should be taken to legalize the described
1131  /// instruction. Requires computeTables to have been called.
1132  ///
1133  /// \returns a description of the next legalization step to perform.
1134  LegalizeActionStep getAction(const LegalityQuery &Query) const;
1135 
1136  /// Determine what action should be taken to legalize the given generic
1137  /// instruction.
1138  ///
1139  /// \returns a description of the next legalization step to perform.
1140  LegalizeActionStep getAction(const MachineInstr &MI,
1141  const MachineRegisterInfo &MRI) const;
1142 
1143  bool isLegal(const LegalityQuery &Query) const {
1144  return getAction(Query).Action == LegalizeAction::Legal;
1145  }
1146  bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1147  bool isLegalOrCustom(const MachineInstr &MI,
1148  const MachineRegisterInfo &MRI) const;
1149 
1150  virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
1151  MachineIRBuilder &MIRBuilder,
1152  GISelChangeObserver &Observer) const;
1153 
1154  /// Return true if MI is either legal or has been legalized and false
1155  /// if not legal.
1156  virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI,
1157  MachineIRBuilder &MIRBuilder) const;
1158 
1159 private:
1160  /// Determine what action should be taken to legalize the given generic
1161  /// instruction opcode, type-index and type. Requires computeTables to have
1162  /// been called.
1163  ///
1164  /// \returns a pair consisting of the kind of legalization that should be
1165  /// performed and the destination type.
1166  std::pair<LegalizeAction, LLT>
1167  getAspectAction(const InstrAspect &Aspect) const;
1168 
1169  /// The SizeAndActionsVec is a representation mapping between all natural
1170  /// numbers and an Action. The natural number represents the bit size of
1171  /// the InstrAspect. For example, for a target with native support for 32-bit
1172  /// and 64-bit additions, you'd express that as:
1173  /// setScalarAction(G_ADD, 0,
1174  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
1175  /// {32, Legal}, // bit sizes [32, 33[
1176  /// {33, WidenScalar}, // bit sizes [33, 64[
1177  /// {64, Legal}, // bit sizes [64, 65[
1178  /// {65, NarrowScalar} // bit sizes [65, +inf[
1179  /// });
1180  /// It may be that only 64-bit pointers are supported on your target:
1181  /// setPointerAction(G_GEP, 0, LLT:pointer(1),
1182  /// {{1, Unsupported}, // bit sizes [ 1, 63[
1183  /// {64, Legal}, // bit sizes [64, 65[
1184  /// {65, Unsupported}, // bit sizes [65, +inf[
1185  /// });
1186  void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
1187  const SizeAndActionsVec &SizeAndActions) {
1188  const unsigned OpcodeIdx = Opcode - FirstOp;
1189  SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
1190  setActions(TypeIndex, Actions, SizeAndActions);
1191  }
1192  void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
1193  const unsigned AddressSpace,
1194  const SizeAndActionsVec &SizeAndActions) {
1195  const unsigned OpcodeIdx = Opcode - FirstOp;
1196  if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
1197  AddrSpace2PointerActions[OpcodeIdx].end())
1198  AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
1200  AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
1201  setActions(TypeIndex, Actions, SizeAndActions);
1202  }
1203 
1204  /// If an operation on a given vector type (say <M x iN>) isn't explicitly
1205  /// specified, we proceed in 2 stages. First we legalize the underlying scalar
1206  /// (so that there's at least one legal vector with that scalar), then we
1207  /// adjust the number of elements in the vector so that it is legal. The
1208  /// desired action in the first step is controlled by this function.
1209  void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
1210  const SizeAndActionsVec &SizeAndActions) {
1211  unsigned OpcodeIdx = Opcode - FirstOp;
1213  ScalarInVectorActions[OpcodeIdx];
1214  setActions(TypeIndex, Actions, SizeAndActions);
1215  }
1216 
1217  /// See also setScalarInVectorAction.
1218  /// This function let's you specify the number of elements in a vector that
1219  /// are legal for a legal element size.
1220  void setVectorNumElementAction(const unsigned Opcode,
1221  const unsigned TypeIndex,
1222  const unsigned ElementSize,
1223  const SizeAndActionsVec &SizeAndActions) {
1224  const unsigned OpcodeIdx = Opcode - FirstOp;
1225  if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
1226  NumElements2Actions[OpcodeIdx].end())
1227  NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
1229  NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
1230  setActions(TypeIndex, Actions, SizeAndActions);
1231  }
1232 
1233  /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
1234  /// i.e. it's OK if it doesn't start from size 1.
1235  static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
1236  using namespace LegalizeActions;
1237 #ifndef NDEBUG
1238  // The sizes should be in increasing order
1239  int prev_size = -1;
1240  for(auto SizeAndAction: v) {
1241  assert(SizeAndAction.first > prev_size);
1242  prev_size = SizeAndAction.first;
1243  }
1244  // - for every Widen action, there should be a larger bitsize that
1245  // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
1246  // action).
1247  // - for every Narrow action, there should be a smaller bitsize that
1248  // can be legalized towards.
1249  int SmallestNarrowIdx = -1;
1250  int LargestWidenIdx = -1;
1251  int SmallestLegalizableToSameSizeIdx = -1;
1252  int LargestLegalizableToSameSizeIdx = -1;
1253  for(size_t i=0; i<v.size(); ++i) {
1254  switch (v[i].second) {
1255  case FewerElements:
1256  case NarrowScalar:
1257  if (SmallestNarrowIdx == -1)
1258  SmallestNarrowIdx = i;
1259  break;
1260  case WidenScalar:
1261  case MoreElements:
1262  LargestWidenIdx = i;
1263  break;
1264  case Unsupported:
1265  break;
1266  default:
1267  if (SmallestLegalizableToSameSizeIdx == -1)
1268  SmallestLegalizableToSameSizeIdx = i;
1269  LargestLegalizableToSameSizeIdx = i;
1270  }
1271  }
1272  if (SmallestNarrowIdx != -1) {
1273  assert(SmallestLegalizableToSameSizeIdx != -1);
1274  assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
1275  }
1276  if (LargestWidenIdx != -1)
1277  assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
1278 #endif
1279  }
1280 
1281  /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
1282  /// from size 1.
1283  static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
1284 #ifndef NDEBUG
1285  // Data structure invariant: The first bit size must be size 1.
1286  assert(v.size() >= 1);
1287  assert(v[0].first == 1);
1288  checkPartialSizeAndActionsVector(v);
1289 #endif
1290  }
1291 
1292  /// Sets actions for all bit sizes on a particular generic opcode, type
1293  /// index and scalar or pointer type.
1294  void setActions(unsigned TypeIndex,
1296  const SizeAndActionsVec &SizeAndActions) {
1297  checkFullSizeAndActionsVector(SizeAndActions);
1298  if (Actions.size() <= TypeIndex)
1299  Actions.resize(TypeIndex + 1);
1300  Actions[TypeIndex] = SizeAndActions;
1301  }
1302 
1303  static SizeAndAction findAction(const SizeAndActionsVec &Vec,
1304  const uint32_t Size);
1305 
1306  /// Returns the next action needed to get the scalar or pointer type closer
1307  /// to being legal
1308  /// E.g. findLegalAction({G_REM, 13}) should return
1309  /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
1310  /// probably be called, which should return (Lower, 32).
1311  /// This is assuming the setScalarAction on G_REM was something like:
1312  /// setScalarAction(G_REM, 0,
1313  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
1314  /// {32, Lower}, // bit sizes [32, 33[
1315  /// {33, NarrowScalar} // bit sizes [65, +inf[
1316  /// });
1317  std::pair<LegalizeAction, LLT>
1318  findScalarLegalAction(const InstrAspect &Aspect) const;
1319 
1320  /// Returns the next action needed towards legalizing the vector type.
1321  std::pair<LegalizeAction, LLT>
1322  findVectorLegalAction(const InstrAspect &Aspect) const;
1323 
1324  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1325  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1326 
1327  // Data structures used temporarily during construction of legality data:
1329  SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
1331  ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
1333  VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
1334  bool TablesInitialized;
1335 
1336  // Data structures used by getAction:
1337  SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
1338  SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
1339  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
1340  AddrSpace2PointerActions[LastOp - FirstOp + 1];
1341  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
1342  NumElements2Actions[LastOp - FirstOp + 1];
1343 
1344  LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1345 };
1346 
1347 #ifndef NDEBUG
1348 /// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1349 /// nullptr otherwise
1351 #endif
1352 
1353 } // end namespace llvm.
1354 
1355 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
constexpr LegalityQuery(unsigned Opcode, const ArrayRef< LLT > Types)
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT &Ty)
Ensure the scalar or element is at least as wide as Ty.
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
This is a &#39;bitvector&#39; (really, a variable-sized bit array), optimized for the case when the array is ...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
The result of a query.
unsigned getScalarSizeInBits() const
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:57
Predicate all(Predicate P0, Predicate P1, Args... args)
True iff all given predicates are true.
std::function< SizeAndActionsVec(const SizeAndActionsVec &v)> SizeChangeStrategy
LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list< std::pair< LLT, LLT >> TypesInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs...
The LegalityQuery object bundles together all the information that&#39;s needed to decide whether a given...
bool isScalar() const
std::vector< SizeAndAction > SizeAndActionsVec
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:62
static SizeAndActionsVec narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v)
unsigned second
unsigned getAlias() const
LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or a vector with an element type that&#39;s wider than the ...
LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified types.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LLT NewType
If describing an action, the new type for TypeIdx. Otherwise LLT{}.
LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or vector with an element type that&#39;s narrower than the...
LegalizeRuleSet & scalarize(unsigned TypeIdx)
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LegalizeRuleSet & custom()
Unconditionally custom lower.
constexpr LegalityQuery(unsigned Opcode, const ArrayRef< LLT > Types, const ArrayRef< MemDesc > MMODescrs)
static SizeAndActionsVec unsupportedForDifferentSizes(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of on...
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
Definition: LegalizerInfo.h:52
bool isVector() const
static SizeAndActionsVec widenToLargerTypesUnsupportedOtherwise(const SizeAndActionsVec &v)
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The instruction is lowered if predicate is true.
LegalizeRuleSet & narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation)
LegalizeRuleSet & maxScalarOrElt(unsigned TypeIdx, const LLT &Ty)
Ensure the scalar is at most as wide as Ty.
bool match(const LegalityQuery &Query) const
Test whether the LegalityQuery matches.
LegalizeAction getAction() const
LegalizeRuleSet & minScalarOrElt(unsigned TypeIdx, const LLT &Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty)
Select this specific type for the given type index.
void apply(Opt *O, const Mod &M, const Mods &... Ms)
Definition: CommandLine.h:1217
bool operator==(const TypePairAndMemDesc &Other) const
LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:85
LLT getElementType() const
Returns the vector&#39;s element type. Only valid for vector types.
AtomicOrdering
Atomic ordering for LLVM&#39;s memory model.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
PowerPC VSX FMA Mutation
LegalizeRuleSet & libcallIf(LegalityPredicate Predicate)
Like legalIf, but for the Libcall action.
LegalizeRuleSet & legalFor(std::initializer_list< std::pair< LLT, LLT >> Types)
The instruction is legal when type indexes 0 and 1 is any type pair in the given list.
InstrAspect(unsigned Opcode, LLT Type)
LegalityPredicate typePairAndMemDescInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemDesc > TypesAndMemDescInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs...
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
Definition: LegalizerInfo.h:68
LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2...
LegalizeRuleSet & clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy, unsigned MaxElements)
Limit the number of elements in EltTy vectors to at most MaxElements.
LegalizeRuleSet & clampMinNumElements(unsigned TypeIdx, const LLT &EltTy, unsigned MinElements)
Limit the number of elements in EltTy vectors to at least MinElements.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
bool operator==(const LegalizeActionStep &RHS) const
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:72
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & customFor(std::initializer_list< std::pair< LLT, LLT >> Types)
The instruction is custom when type indexes 0 and 1 is any type pair in the given list...
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
LegalizeMutation scalarize(unsigned TypeIdx)
Break up the vector type for the given type index into the element type.
LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty)
Keep the same scalar or element type as the given type.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is lowered when type indexes 0 and 1 are both in their respective lists...
Abstract class that contains various methods for clients to notify about changes. ...
unsigned const MachineRegisterInfo * MRI
static LLT scalarOrVector(uint16_t NumElements, LLT ScalarTy)
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:88
LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that&#39;s narrower than the given size.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is legal when type indexes 0 and 1 are both their respective lists.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
Helper class to build MachineInstr.
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
bool isLegal(const LegalityQuery &Query) const
LegalizeRuleSet & lowerIfMemSizeNotPow2()
LegalizeRuleSet & clampNumElements(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy)
Limit the number of elements for the given vectors to at least MinTy&#39;s number of elements and at most...
LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size that is not a power of 2.
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT &Ty)
Ensure the scalar is at most as wide as Ty.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
Legalization is decided based on an instruction&#39;s opcode, which type slot we&#39;re considering, and what the existing type is.
LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx, const LLT &NewType)
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT &Ty)
Ensure the scalar is at least as wide as Ty.
size_t size() const
Definition: SmallVector.h:52
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1198
cl::opt< bool > DisableGISelLegalityCheck
LegalizeRuleSet & unsupportedIfMemSizeNotPow2()
bool verify(const TargetRegisterInfo &TRI) const
Check that information hold by this instance make sense for the given TRI.
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
unsigned first
static SizeAndActionsVec narrowToSmallerAndWidenToSmallest(const SizeAndActionsVec &v)
LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2...
const MachineInstr * machineFunctionIsIllegal(const MachineFunction &MF)
Checks that MIR is fully legal, returns an illegal instruction if it&#39;s not, nullptr otherwise...
void setLegalizeVectorElementToDifferentSizeStrategy(const unsigned Opcode, const unsigned TypeIdx, SizeChangeStrategy S)
See also setLegalizeScalarToDifferentSizeStrategy.
LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same type as the given type index.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1158
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT >> Types)
static uint64_t add(uint64_t LeftOp, uint64_t RightOp)
Definition: FileCheck.cpp:243
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:837
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
AddressSpace
Definition: NVPTXBaseInfo.h:21
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:26
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:77
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
LegalizeRuleSet & widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize...
LegalizeRuleSet & unsupported()
The instruction is unsupported.
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:81
LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT >> Types, LegalizeMutation Mutation)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list...
LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action, LegalizeMutation Mutation=nullptr)
LegalizeRuleSet & minScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned LargeTypeIdx)
Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything...
A single rule in a legalizer info ruleset.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
Representation of each machine instruction.
Definition: MachineInstr.h:64
LegalizeAction Action
The action to take or the final answer.
LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min=0)
Widen the scalar type or vector element type for the given type index to the next power of 2...
static bool needsLegalizingToDifferentSize(const LegalizeAction Action)
Fall back onto the old rules.
Definition: LegalizerInfo.h:92
LegalizeRuleSet & fallback()
Fallback on the previous implementation.
static SizeAndActionsVec widenToLargerTypesAndNarrowToLargest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular operation consists of wi...
static SizeAndActionsVec moreToWiderTypesAndLessToWidest(const SizeAndActionsVec &v)
A SizeChangeStrategy for the common case where legalization for a particular vector operation consist...
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT >> Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list...
LegalizeRuleSet & lower()
The instruction is lowered.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
ArrayRef< LLT > Types
void aliasTo(unsigned Opcode)
void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode, const unsigned TypeIdx, SizeChangeStrategy S)
The setAction calls record the non-size-changing legalization actions to take on specificly-sized typ...
LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LegalizeRuleSet & alwaysLegal()
LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min=0)
Add more elements to the type for the given type index to the next power of.
uint32_t Size
Definition: Profile.cpp:46
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2045
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is legal when type indexes 0, 1, and 2 are both their respective lists.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isCompatible(const TypePairAndMemDesc &Other) const
LegalizeRuleSet & maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT &Ty)
Conditionally limit the maximum size of the scalar.
LegalizeRuleSet & moreElementsToNextPow2(unsigned TypeIdx)
Add more elements to the vector to reach the next power of two.
uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
bool operator==(const InstrAspect &RHS) const
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
std::function< bool(const LegalityQuery &)> LegalityPredicate
static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
ArrayRef< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO...
std::pair< unsigned, LLT > determineMutation(const LegalityQuery &Query) const
Determine the change to make.
void setAction(const InstrAspect &Aspect, LegalizeAction Action)
More friendly way to set an action for common types that have an LLT representation.
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:47
LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
std::pair< uint16_t, LegalizeAction > SizeAndAction
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when when type indexes 0, 1, and 2 are all in their respective lists...
LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace)
True iff the specified type index is a pointer with the specified address space.
LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
LegalizeRuleSet & narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Narrow the scalar to the one selected by the mutation if the predicate is true.
LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that&#39;s wider than the given size.
void resize(size_type N)
Definition: SmallVector.h:344