LLVM  8.0.0svn
LegalizerInfo.h
Go to the documentation of this file.
1 //===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// Interface for Targets to specify which operations they can successfully
11 /// select and how the others should be expanded most efficiently.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
17 
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/None.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/SmallVector.h"
28 #include <cassert>
29 #include <cstdint>
30 #include <tuple>
31 #include <unordered_map>
32 #include <utility>
33 
34 namespace llvm {
35 
36 extern cl::opt<bool> DisableGISelLegalityCheck;
37 
38 class MachineInstr;
39 class MachineIRBuilder;
40 class MachineRegisterInfo;
41 class MCInstrInfo;
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
95 
97 
98 /// Legalization is decided based on an instruction's opcode, which type slot
99 /// we're considering, and what the existing type is. These aspects are gathered
100 /// together for convenience in the InstrAspect class.
101 struct InstrAspect {
102  unsigned Opcode;
103  unsigned Idx = 0;
105 
106  InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
107  InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
108  : Opcode(Opcode), Idx(Idx), Type(Type) {}
109 
110  bool operator==(const InstrAspect &RHS) const {
111  return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
112  }
113 };
114 
115 /// The LegalityQuery object bundles together all the information that's needed
116 /// to decide whether a given operation is legal or not.
117 /// For efficiency, it doesn't make a copy of Types so care must be taken not
118 /// to free it before using the query.
120  unsigned Opcode;
122 
123  struct MemDesc {
124  uint64_t Size;
126  };
127 
128  /// Operations which require memory can use this to place requirements on the
129  /// memory type for each MMO.
131 
132  constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types,
133  const ArrayRef<MemDesc> MMODescrs)
134  : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
135  constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types)
136  : LegalityQuery(Opcode, Types, {}) {}
137 
138  raw_ostream &print(raw_ostream &OS) const;
139 };
140 
141 /// The result of a query. It either indicates a final answer of Legal or
142 /// Unsupported or describes an action that must be taken to make an operation
143 /// more legal.
145  /// The action to take or the final answer.
147  /// If describing an action, the type index to change. Otherwise zero.
148  unsigned TypeIdx;
149  /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
151 
152  LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
153  const LLT &NewType)
154  : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
155 
156  bool operator==(const LegalizeActionStep &RHS) const {
157  return std::tie(Action, TypeIdx, NewType) ==
158  std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
159  }
160 };
161 
162 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
163 using LegalizeMutation =
164  std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
165 
170  uint64_t MemSize;
171 
172  bool operator==(const TypePairAndMemSize &Other) const {
173  return Type0 == Other.Type0 && Type1 == Other.Type1 &&
174  MemSize == Other.MemSize;
175  }
176 };
177 
178 /// True iff P0 and P1 are true.
179 template<typename Predicate>
181  return [=](const LegalityQuery &Query) {
182  return P0(Query) && P1(Query);
183  };
184 }
185 /// True iff all given predicates are true.
186 template<typename Predicate, typename... Args>
188  return all(all(P0, P1), args...);
189 }
190 /// True iff the given type index is the specified types.
191 LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
192 /// True iff the given type index is one of the specified types.
193 LegalityPredicate typeInSet(unsigned TypeIdx,
194  std::initializer_list<LLT> TypesInit);
195 /// True iff the given types for the given pair of type indexes is one of the
196 /// specified type pairs.
198 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
199  std::initializer_list<std::pair<LLT, LLT>> TypesInit);
200 /// True iff the given types for the given pair of type indexes is one of the
201 /// specified type pairs.
203  unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
204  std::initializer_list<TypePairAndMemSize> TypesAndMemSizeInit);
205 /// True iff the specified type index is a scalar.
206 LegalityPredicate isScalar(unsigned TypeIdx);
207 /// True iff the specified type index is a scalar that's narrower than the given
208 /// size.
209 LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
210 /// True iff the specified type index is a scalar that's wider than the given
211 /// size.
212 LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
213 /// True iff the specified type index is a scalar whose size is not a power of
214 /// 2.
215 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
216 /// True iff the specified MMO index has a size that is not a power of 2
218 /// True iff the specified type index is a vector whose element count is not a
219 /// power of 2.
220 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
221 /// True iff the specified MMO index has at an atomic ordering of at Ordering or
222 /// stronger.
224  AtomicOrdering Ordering);
225 } // end namespace LegalityPredicates
226 
227 namespace LegalizeMutations {
228 /// Select this specific type for the given type index.
229 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
230 /// Keep the same type as the given type index.
231 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
232 /// Widen the type for the given type index to the next power of 2.
233 LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
234 /// Add more elements to the type for the given type index to the next power of
235 /// 2.
236 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
237 } // end namespace LegalizeMutations
238 
239 /// A single rule in a legalizer info ruleset.
240 /// The specified action is chosen when the predicate is true. Where appropriate
241 /// for the action (e.g. for WidenScalar) the new type is selected using the
242 /// given mutator.
245  LegalizeAction Action;
247 
248 public:
250  LegalizeMutation Mutation = nullptr)
251  : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
252 
253  /// Test whether the LegalityQuery matches.
254  bool match(const LegalityQuery &Query) const {
255  return Predicate(Query);
256  }
257 
258  LegalizeAction getAction() const { return Action; }
259 
260  /// Determine the change to make.
261  std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
262  if (Mutation)
263  return Mutation(Query);
264  return std::make_pair(0, LLT{});
265  }
266 };
267 
269  /// When non-zero, the opcode we are an alias of
270  unsigned AliasOf;
271  /// If true, there is another opcode that aliases this one
272  bool IsAliasedByAnother;
274 
275 #ifndef NDEBUG
276  /// If bit I is set, this rule set contains a rule that may handle (predicate
277  /// or perform an action upon (or both)) the type index I. The uncertainty
278  /// comes from free-form rules executing user-provided lambda functions. We
279  /// conservatively assume such rules do the right thing and cover all type
280  /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
281  /// to be to distinguish such cases from the cases where all type indices are
282  /// individually handled.
285 #endif
286 
287  unsigned typeIdx(unsigned TypeIdx) {
288  assert(TypeIdx <=
289  (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
290  "Type Index is out of bounds");
291 #ifndef NDEBUG
292  TypeIdxsCovered.set(TypeIdx);
293 #endif
294  return TypeIdx;
295  }
296  void markAllTypeIdxsAsCovered() {
297 #ifndef NDEBUG
298  TypeIdxsCovered.set();
299 #endif
300  }
301 
302  void add(const LegalizeRule &Rule) {
303  assert(AliasOf == 0 &&
304  "RuleSet is aliased, change the representative opcode instead");
305  Rules.push_back(Rule);
306  }
307 
308  static bool always(const LegalityQuery &) { return true; }
309 
310  /// Use the given action when the predicate is true.
311  /// Action should not be an action that requires mutation.
312  LegalizeRuleSet &actionIf(LegalizeAction Action,
314  add({Predicate, Action});
315  return *this;
316  }
317  /// Use the given action when the predicate is true.
318  /// Action should be an action that requires mutation.
319  LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
321  add({Predicate, Action, Mutation});
322  return *this;
323  }
324  /// Use the given action when type index 0 is any type in the given list.
325  /// Action should not be an action that requires mutation.
326  LegalizeRuleSet &actionFor(LegalizeAction Action,
327  std::initializer_list<LLT> Types) {
328  using namespace LegalityPredicates;
329  return actionIf(Action, typeInSet(typeIdx(0), Types));
330  }
331  /// Use the given action when type index 0 is any type in the given list.
332  /// Action should be an action that requires mutation.
333  LegalizeRuleSet &actionFor(LegalizeAction Action,
334  std::initializer_list<LLT> Types,
335  LegalizeMutation Mutation) {
336  using namespace LegalityPredicates;
337  return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
338  }
339  /// Use the given action when type indexes 0 and 1 is any type pair in the
340  /// given list.
341  /// Action should not be an action that requires mutation.
342  LegalizeRuleSet &actionFor(LegalizeAction Action,
343  std::initializer_list<std::pair<LLT, LLT>> Types) {
344  using namespace LegalityPredicates;
345  return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
346  }
347  /// Use the given action when type indexes 0 and 1 is any type pair in the
348  /// given list.
349  /// Action should be an action that requires mutation.
350  LegalizeRuleSet &actionFor(LegalizeAction Action,
351  std::initializer_list<std::pair<LLT, LLT>> Types,
352  LegalizeMutation Mutation) {
353  using namespace LegalityPredicates;
354  return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
355  Mutation);
356  }
357  /// Use the given action when type indexes 0 and 1 are both in the given list.
358  /// That is, the type pair is in the cartesian product of the list.
359  /// Action should not be an action that requires mutation.
360  LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
361  std::initializer_list<LLT> Types) {
362  using namespace LegalityPredicates;
363  return actionIf(Action, all(typeInSet(typeIdx(0), Types),
364  typeInSet(typeIdx(1), Types)));
365  }
366  /// Use the given action when type indexes 0 and 1 are both in their
367  /// respective lists.
368  /// That is, the type pair is in the cartesian product of the lists
369  /// Action should not be an action that requires mutation.
371  actionForCartesianProduct(LegalizeAction Action,
372  std::initializer_list<LLT> Types0,
373  std::initializer_list<LLT> Types1) {
374  using namespace LegalityPredicates;
375  return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
376  typeInSet(typeIdx(1), Types1)));
377  }
378  /// Use the given action when type indexes 0, 1, and 2 are all in their
379  /// respective lists.
380  /// That is, the type triple is in the cartesian product of the lists
381  /// Action should not be an action that requires mutation.
382  LegalizeRuleSet &actionForCartesianProduct(
383  LegalizeAction Action, std::initializer_list<LLT> Types0,
384  std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
385  using namespace LegalityPredicates;
386  return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
387  all(typeInSet(typeIdx(1), Types1),
388  typeInSet(typeIdx(2), Types2))));
389  }
390 
391 public:
392  LegalizeRuleSet() : AliasOf(0), IsAliasedByAnother(false), Rules() {}
393 
394  bool isAliasedByAnother() { return IsAliasedByAnother; }
395  void setIsAliasedByAnother() { IsAliasedByAnother = true; }
396  void aliasTo(unsigned Opcode) {
397  assert((AliasOf == 0 || AliasOf == Opcode) &&
398  "Opcode is already aliased to another opcode");
399  assert(Rules.empty() && "Aliasing will discard rules");
400  AliasOf = Opcode;
401  }
402  unsigned getAlias() const { return AliasOf; }
403 
404  /// The instruction is legal if predicate is true.
406  // We have no choice but conservatively assume that the free-form
407  // user-provided Predicate properly handles all type indices:
408  markAllTypeIdxsAsCovered();
409  return actionIf(LegalizeAction::Legal, Predicate);
410  }
411  /// The instruction is legal when type index 0 is any type in the given list.
412  LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
413  return actionFor(LegalizeAction::Legal, Types);
414  }
415  /// The instruction is legal when type indexes 0 and 1 is any type pair in the
416  /// given list.
417  LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
418  return actionFor(LegalizeAction::Legal, Types);
419  }
420  /// The instruction is legal when type indexes 0 and 1 along with the memory
421  /// size is any type and size tuple in the given list.
423  std::initializer_list<LegalityPredicates::TypePairAndMemSize>
424  TypesAndMemSize) {
425  return actionIf(LegalizeAction::Legal,
427  typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemSize));
428  }
429  /// The instruction is legal when type indexes 0 and 1 are both in the given
430  /// list. That is, the type pair is in the cartesian product of the list.
431  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
432  return actionForCartesianProduct(LegalizeAction::Legal, Types);
433  }
434  /// The instruction is legal when type indexes 0 and 1 are both their
435  /// respective lists.
436  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
437  std::initializer_list<LLT> Types1) {
438  return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
439  }
440 
441  /// The instruction is lowered.
443  using namespace LegalizeMutations;
444  // We have no choice but conservatively assume that predicate-less lowering
445  // properly handles all type indices by design:
446  markAllTypeIdxsAsCovered();
447  return actionIf(LegalizeAction::Lower, always);
448  }
449  /// The instruction is lowered if predicate is true. Keep type index 0 as the
450  /// same type.
452  using namespace LegalizeMutations;
453  // We have no choice but conservatively assume that lowering with a
454  // free-form user provided Predicate properly handles all type indices:
455  markAllTypeIdxsAsCovered();
456  return actionIf(LegalizeAction::Lower, Predicate);
457  }
458  /// The instruction is lowered if predicate is true.
460  LegalizeMutation Mutation) {
461  // We have no choice but conservatively assume that lowering with a
462  // free-form user provided Predicate properly handles all type indices:
463  markAllTypeIdxsAsCovered();
464  return actionIf(LegalizeAction::Lower, Predicate, Mutation);
465  }
466  /// The instruction is lowered when type index 0 is any type in the given
467  /// list. Keep type index 0 as the same type.
468  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
469  return actionFor(LegalizeAction::Lower, Types,
471  }
472  /// The instruction is lowered when type index 0 is any type in the given
473  /// list.
474  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
475  LegalizeMutation Mutation) {
476  return actionFor(LegalizeAction::Lower, Types, Mutation);
477  }
478  /// The instruction is lowered when type indexes 0 and 1 is any type pair in
479  /// the given list. Keep type index 0 as the same type.
480  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
481  return actionFor(LegalizeAction::Lower, Types,
483  }
484  /// The instruction is lowered when type indexes 0 and 1 is any type pair in
485  /// the given list.
486  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
487  LegalizeMutation Mutation) {
488  return actionFor(LegalizeAction::Lower, Types, Mutation);
489  }
490  /// The instruction is lowered when type indexes 0 and 1 are both in their
491  /// respective lists.
492  LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
493  std::initializer_list<LLT> Types1) {
494  using namespace LegalityPredicates;
495  return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
496  }
497  /// The instruction is lowered when when type indexes 0, 1, and 2 are all in
498  /// their respective lists.
499  LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
500  std::initializer_list<LLT> Types1,
501  std::initializer_list<LLT> Types2) {
502  using namespace LegalityPredicates;
503  return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
504  Types2);
505  }
506 
507  /// Like legalIf, but for the Libcall action.
509  // We have no choice but conservatively assume that a libcall with a
510  // free-form user provided Predicate properly handles all type indices:
511  markAllTypeIdxsAsCovered();
512  return actionIf(LegalizeAction::Libcall, Predicate);
513  }
514  LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
515  return actionFor(LegalizeAction::Libcall, Types);
516  }
518  libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
519  return actionFor(LegalizeAction::Libcall, Types);
520  }
522  libcallForCartesianProduct(std::initializer_list<LLT> Types) {
523  return actionForCartesianProduct(LegalizeAction::Libcall, Types);
524  }
526  libcallForCartesianProduct(std::initializer_list<LLT> Types0,
527  std::initializer_list<LLT> Types1) {
528  return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
529  }
530 
531  /// Widen the scalar to the one selected by the mutation if the predicate is
532  /// true.
534  LegalizeMutation Mutation) {
535  // We have no choice but conservatively assume that an action with a
536  // free-form user provided Predicate properly handles all type indices:
537  markAllTypeIdxsAsCovered();
538  return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
539  }
540  /// Narrow the scalar to the one selected by the mutation if the predicate is
541  /// true.
543  LegalizeMutation Mutation) {
544  // We have no choice but conservatively assume that an action with a
545  // free-form user provided Predicate properly handles all type indices:
546  markAllTypeIdxsAsCovered();
547  return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
548  }
549 
550  /// Add more elements to reach the type selected by the mutation if the
551  /// predicate is true.
553  LegalizeMutation Mutation) {
554  // We have no choice but conservatively assume that an action with a
555  // free-form user provided Predicate properly handles all type indices:
556  markAllTypeIdxsAsCovered();
557  return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
558  }
559  /// Remove elements to reach the type selected by the mutation if the
560  /// predicate is true.
562  LegalizeMutation Mutation) {
563  // We have no choice but conservatively assume that an action with a
564  // free-form user provided Predicate properly handles all type indices:
565  markAllTypeIdxsAsCovered();
566  return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
567  }
568 
569  /// The instruction is unsupported.
571  return actionIf(LegalizeAction::Unsupported, always);
572  }
574  return actionIf(LegalizeAction::Unsupported, Predicate);
575  }
577  return actionIf(LegalizeAction::Unsupported,
579  }
580 
582  // We have no choice but conservatively assume that a custom action with a
583  // free-form user provided Predicate properly handles all type indices:
584  markAllTypeIdxsAsCovered();
585  return actionIf(LegalizeAction::Custom, Predicate);
586  }
587  LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
588  return actionFor(LegalizeAction::Custom, Types);
589  }
590  LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
591  return actionForCartesianProduct(LegalizeAction::Custom, Types);
592  }
594  customForCartesianProduct(std::initializer_list<LLT> Types0,
595  std::initializer_list<LLT> Types1) {
596  return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
597  }
598 
599  /// Widen the scalar to the next power of two that is at least MinSize.
600  /// No effect if the type is not a scalar or is a power of two.
602  unsigned MinSize = 0) {
603  using namespace LegalityPredicates;
604  return actionIf(LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
605  LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize));
606  }
607 
608  LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
609  using namespace LegalityPredicates;
610  return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
611  Mutation);
612  }
613 
614  /// Ensure the scalar is at least as wide as Ty.
615  LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
616  using namespace LegalityPredicates;
617  using namespace LegalizeMutations;
618  return actionIf(LegalizeAction::WidenScalar,
619  narrowerThan(TypeIdx, Ty.getSizeInBits()),
620  changeTo(typeIdx(TypeIdx), Ty));
621  }
622 
623  /// Ensure the scalar is at most as wide as Ty.
624  LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
625  using namespace LegalityPredicates;
626  using namespace LegalizeMutations;
627  return actionIf(LegalizeAction::NarrowScalar,
628  widerThan(TypeIdx, Ty.getSizeInBits()),
629  changeTo(typeIdx(TypeIdx), Ty));
630  }
631 
632  /// Conditionally limit the maximum size of the scalar.
633  /// For example, when the maximum size of one type depends on the size of
634  /// another such as extracting N bits from an M bit container.
635  LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
636  const LLT &Ty) {
637  using namespace LegalityPredicates;
638  using namespace LegalizeMutations;
639  return actionIf(LegalizeAction::NarrowScalar,
640  [=](const LegalityQuery &Query) {
641  return widerThan(TypeIdx, Ty.getSizeInBits()) &&
642  Predicate(Query);
643  },
644  changeTo(typeIdx(TypeIdx), Ty));
645  }
646 
647  /// Limit the range of scalar sizes to MinTy and MaxTy.
648  LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy,
649  const LLT &MaxTy) {
650  assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
651  return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
652  }
653 
654  /// Add more elements to the vector to reach the next power of two.
655  /// No effect if the type is not a vector or the element count is a power of
656  /// two.
658  using namespace LegalityPredicates;
659  return actionIf(LegalizeAction::MoreElements,
660  numElementsNotPow2(typeIdx(TypeIdx)),
662  }
663 
664  /// Limit the number of elements in EltTy vectors to at least MinElements.
665  LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy,
666  unsigned MinElements) {
667  // Mark the type index as covered:
668  typeIdx(TypeIdx);
669  return actionIf(
671  [=](const LegalityQuery &Query) {
672  LLT VecTy = Query.Types[TypeIdx];
673  return VecTy.isVector() && VecTy.getElementType() == EltTy &&
674  VecTy.getNumElements() < MinElements;
675  },
676  [=](const LegalityQuery &Query) {
677  LLT VecTy = Query.Types[TypeIdx];
678  return std::make_pair(
679  TypeIdx, LLT::vector(MinElements, VecTy.getScalarSizeInBits()));
680  });
681  }
682  /// Limit the number of elements in EltTy vectors to at most MaxElements.
683  LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy,
684  unsigned MaxElements) {
685  // Mark the type index as covered:
686  typeIdx(TypeIdx);
687  return actionIf(
689  [=](const LegalityQuery &Query) {
690  LLT VecTy = Query.Types[TypeIdx];
691  return VecTy.isVector() && VecTy.getElementType() == EltTy &&
692  VecTy.getNumElements() > MaxElements;
693  },
694  [=](const LegalityQuery &Query) {
695  LLT VecTy = Query.Types[TypeIdx];
696  return std::make_pair(
697  TypeIdx, LLT::vector(MaxElements, VecTy.getScalarSizeInBits()));
698  });
699  }
700  /// Limit the number of elements for the given vectors to at least MinTy's
701  /// number of elements and at most MaxTy's number of elements.
702  ///
703  /// No effect if the type is not a vector or does not have the same element
704  /// type as the constraints.
705  /// The element type of MinTy and MaxTy must match.
706  LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT &MinTy,
707  const LLT &MaxTy) {
708  assert(MinTy.getElementType() == MaxTy.getElementType() &&
709  "Expected element types to agree");
710 
711  const LLT &EltTy = MinTy.getElementType();
712  return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
713  .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
714  }
715 
716  /// Fallback on the previous implementation. This should only be used while
717  /// porting a rule.
720  return *this;
721  }
722 
723  /// Check if there is no type index which is obviously not handled by the
724  /// LegalizeRuleSet in any way at all.
725  /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
726  bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
727 
728  /// Apply the ruleset to the given LegalityQuery.
730 };
731 
733 public:
734  LegalizerInfo();
735  virtual ~LegalizerInfo() = default;
736 
737  unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
738  unsigned getActionDefinitionsIdx(unsigned Opcode) const;
739 
740  /// Compute any ancillary tables needed to quickly decide how an operation
741  /// should be handled. This must be called after all "set*Action"methods but
742  /// before any query is made or incorrect results may be returned.
743  void computeTables();
744 
745  /// Perform simple self-diagnostic and assert if there is anything obviously
746  /// wrong with the actions set up.
747  void verify(const MCInstrInfo &MII) const;
748 
749  static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
750  using namespace LegalizeActions;
751  switch (Action) {
752  case NarrowScalar:
753  case WidenScalar:
754  case FewerElements:
755  case MoreElements:
756  case Unsupported:
757  return true;
758  default:
759  return false;
760  }
761  }
762 
763  using SizeAndAction = std::pair<uint16_t, LegalizeAction>;
764  using SizeAndActionsVec = std::vector<SizeAndAction>;
765  using SizeChangeStrategy =
766  std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
767 
768  /// More friendly way to set an action for common types that have an LLT
769  /// representation.
770  /// The LegalizeAction must be one for which NeedsLegalizingToDifferentSize
771  /// returns false.
772  void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
773  assert(!needsLegalizingToDifferentSize(Action));
774  TablesInitialized = false;
775  const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
776  if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
777  SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
778  SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
779  }
780 
781  /// The setAction calls record the non-size-changing legalization actions
782  /// to take on specificly-sized types. The SizeChangeStrategy defines what
783  /// to do when the size of the type needs to be changed to reach a legally
784  /// sized type (i.e., one that was defined through a setAction call).
785  /// e.g.
786  /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
787  /// setLegalizeScalarToDifferentSizeStrategy(
788  /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
789  /// will end up defining getAction({G_ADD, 0, T}) to return the following
790  /// actions for different scalar types T:
791  /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
792  /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
793  /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
794  ///
795  /// If no SizeChangeAction gets defined, through this function,
796  /// the default is unsupportedForDifferentSizes.
797  void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
798  const unsigned TypeIdx,
799  SizeChangeStrategy S) {
800  const unsigned OpcodeIdx = Opcode - FirstOp;
801  if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
802  ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
803  ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
804  }
805 
806  /// See also setLegalizeScalarToDifferentSizeStrategy.
807  /// This function allows to set the SizeChangeStrategy for vector elements.
809  const unsigned TypeIdx,
810  SizeChangeStrategy S) {
811  const unsigned OpcodeIdx = Opcode - FirstOp;
812  if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
813  VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
814  VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
815  }
816 
817  /// A SizeChangeStrategy for the common case where legalization for a
818  /// particular operation consists of only supporting a specific set of type
819  /// sizes. E.g.
820  /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
821  /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
822  /// setLegalizeScalarToDifferentSizeStrategy(
823  /// G_DIV, 0, unsupportedForDifferentSizes);
824  /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
825  /// and Unsupported for all other scalar types T.
826  static SizeAndActionsVec
828  using namespace LegalizeActions;
829  return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
830  Unsupported);
831  }
832 
833  /// A SizeChangeStrategy for the common case where legalization for a
834  /// particular operation consists of widening the type to a large legal type,
835  /// unless there is no such type and then instead it should be narrowed to the
836  /// largest legal type.
837  static SizeAndActionsVec
839  using namespace LegalizeActions;
840  assert(v.size() > 0 &&
841  "At least one size that can be legalized towards is needed"
842  " for this SizeChangeStrategy");
843  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
844  NarrowScalar);
845  }
846 
847  static SizeAndActionsVec
849  using namespace LegalizeActions;
850  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
851  Unsupported);
852  }
853 
854  static SizeAndActionsVec
856  using namespace LegalizeActions;
857  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
858  Unsupported);
859  }
860 
861  static SizeAndActionsVec
863  using namespace LegalizeActions;
864  assert(v.size() > 0 &&
865  "At least one size that can be legalized towards is needed"
866  " for this SizeChangeStrategy");
867  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
868  WidenScalar);
869  }
870 
871  /// A SizeChangeStrategy for the common case where legalization for a
872  /// particular vector operation consists of having more elements in the
873  /// vector, to a type that is legal. Unless there is no such type and then
874  /// instead it should be legalized towards the widest vector that's still
875  /// legal. E.g.
876  /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
877  /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
878  /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
879  /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
880  /// setLegalizeVectorElementToDifferentSizeStrategy(
881  /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
882  /// will result in the following getAction results:
883  /// * getAction({G_ADD, LLT::vector(8,8)}) returns
884  /// (Legal, vector(8,8)).
885  /// * getAction({G_ADD, LLT::vector(9,8)}) returns
886  /// (MoreElements, vector(16,8)).
887  /// * getAction({G_ADD, LLT::vector(8,32)}) returns
888  /// (FewerElements, vector(4,32)).
889  static SizeAndActionsVec
891  using namespace LegalizeActions;
892  return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
893  FewerElements);
894  }
895 
896  /// Helper function to implement many typical SizeChangeStrategy functions.
897  static SizeAndActionsVec
898  increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v,
899  LegalizeAction IncreaseAction,
900  LegalizeAction DecreaseAction);
901  /// Helper function to implement many typical SizeChangeStrategy functions.
902  static SizeAndActionsVec
903  decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v,
904  LegalizeAction DecreaseAction,
905  LegalizeAction IncreaseAction);
906 
907  /// Get the action definitions for the given opcode. Use this to run a
908  /// LegalityQuery through the definitions.
909  const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
910 
911  /// Get the action definition builder for the given opcode. Use this to define
912  /// the action definitions.
913  ///
914  /// It is an error to request an opcode that has already been requested by the
915  /// multiple-opcode variant.
916  LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
917 
918  /// Get the action definition builder for the given set of opcodes. Use this
919  /// to define the action definitions for multiple opcodes at once. The first
920  /// opcode given will be considered the representative opcode and will hold
921  /// the definitions whereas the other opcodes will be configured to refer to
922  /// the representative opcode. This lowers memory requirements and very
923  /// slightly improves performance.
924  ///
925  /// It would be very easy to introduce unexpected side-effects as a result of
926  /// this aliasing if it were permitted to request different but intersecting
927  /// sets of opcodes but that is difficult to keep track of. It is therefore an
928  /// error to request the same opcode twice using this API, to request an
929  /// opcode that already has definitions, or to use the single-opcode API on an
930  /// opcode that has already been requested by this API.
932  getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
933  void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
934 
935  /// Determine what action should be taken to legalize the described
936  /// instruction. Requires computeTables to have been called.
937  ///
938  /// \returns a description of the next legalization step to perform.
939  LegalizeActionStep getAction(const LegalityQuery &Query) const;
940 
941  /// Determine what action should be taken to legalize the given generic
942  /// instruction.
943  ///
944  /// \returns a description of the next legalization step to perform.
945  LegalizeActionStep getAction(const MachineInstr &MI,
946  const MachineRegisterInfo &MRI) const;
947 
948  bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
949 
950  virtual bool legalizeCustom(MachineInstr &MI,
951  MachineRegisterInfo &MRI,
952  MachineIRBuilder &MIRBuilder) const;
953 
954 private:
955  /// Determine what action should be taken to legalize the given generic
956  /// instruction opcode, type-index and type. Requires computeTables to have
957  /// been called.
958  ///
959  /// \returns a pair consisting of the kind of legalization that should be
960  /// performed and the destination type.
961  std::pair<LegalizeAction, LLT>
962  getAspectAction(const InstrAspect &Aspect) const;
963 
964  /// The SizeAndActionsVec is a representation mapping between all natural
965  /// numbers and an Action. The natural number represents the bit size of
966  /// the InstrAspect. For example, for a target with native support for 32-bit
967  /// and 64-bit additions, you'd express that as:
968  /// setScalarAction(G_ADD, 0,
969  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
970  /// {32, Legal}, // bit sizes [32, 33[
971  /// {33, WidenScalar}, // bit sizes [33, 64[
972  /// {64, Legal}, // bit sizes [64, 65[
973  /// {65, NarrowScalar} // bit sizes [65, +inf[
974  /// });
975  /// It may be that only 64-bit pointers are supported on your target:
976  /// setPointerAction(G_GEP, 0, LLT:pointer(1),
977  /// {{1, Unsupported}, // bit sizes [ 1, 63[
978  /// {64, Legal}, // bit sizes [64, 65[
979  /// {65, Unsupported}, // bit sizes [65, +inf[
980  /// });
981  void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
982  const SizeAndActionsVec &SizeAndActions) {
983  const unsigned OpcodeIdx = Opcode - FirstOp;
984  SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
985  setActions(TypeIndex, Actions, SizeAndActions);
986  }
987  void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
988  const unsigned AddressSpace,
989  const SizeAndActionsVec &SizeAndActions) {
990  const unsigned OpcodeIdx = Opcode - FirstOp;
991  if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
992  AddrSpace2PointerActions[OpcodeIdx].end())
993  AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
995  AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
996  setActions(TypeIndex, Actions, SizeAndActions);
997  }
998 
999  /// If an operation on a given vector type (say <M x iN>) isn't explicitly
1000  /// specified, we proceed in 2 stages. First we legalize the underlying scalar
1001  /// (so that there's at least one legal vector with that scalar), then we
1002  /// adjust the number of elements in the vector so that it is legal. The
1003  /// desired action in the first step is controlled by this function.
1004  void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
1005  const SizeAndActionsVec &SizeAndActions) {
1006  unsigned OpcodeIdx = Opcode - FirstOp;
1008  ScalarInVectorActions[OpcodeIdx];
1009  setActions(TypeIndex, Actions, SizeAndActions);
1010  }
1011 
1012  /// See also setScalarInVectorAction.
1013  /// This function let's you specify the number of elements in a vector that
1014  /// are legal for a legal element size.
1015  void setVectorNumElementAction(const unsigned Opcode,
1016  const unsigned TypeIndex,
1017  const unsigned ElementSize,
1018  const SizeAndActionsVec &SizeAndActions) {
1019  const unsigned OpcodeIdx = Opcode - FirstOp;
1020  if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
1021  NumElements2Actions[OpcodeIdx].end())
1022  NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
1024  NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
1025  setActions(TypeIndex, Actions, SizeAndActions);
1026  }
1027 
1028  /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
1029  /// i.e. it's OK if it doesn't start from size 1.
1030  static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
1031  using namespace LegalizeActions;
1032 #ifndef NDEBUG
1033  // The sizes should be in increasing order
1034  int prev_size = -1;
1035  for(auto SizeAndAction: v) {
1036  assert(SizeAndAction.first > prev_size);
1037  prev_size = SizeAndAction.first;
1038  }
1039  // - for every Widen action, there should be a larger bitsize that
1040  // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
1041  // action).
1042  // - for every Narrow action, there should be a smaller bitsize that
1043  // can be legalized towards.
1044  int SmallestNarrowIdx = -1;
1045  int LargestWidenIdx = -1;
1046  int SmallestLegalizableToSameSizeIdx = -1;
1047  int LargestLegalizableToSameSizeIdx = -1;
1048  for(size_t i=0; i<v.size(); ++i) {
1049  switch (v[i].second) {
1050  case FewerElements:
1051  case NarrowScalar:
1052  if (SmallestNarrowIdx == -1)
1053  SmallestNarrowIdx = i;
1054  break;
1055  case WidenScalar:
1056  case MoreElements:
1057  LargestWidenIdx = i;
1058  break;
1059  case Unsupported:
1060  break;
1061  default:
1062  if (SmallestLegalizableToSameSizeIdx == -1)
1063  SmallestLegalizableToSameSizeIdx = i;
1064  LargestLegalizableToSameSizeIdx = i;
1065  }
1066  }
1067  if (SmallestNarrowIdx != -1) {
1068  assert(SmallestLegalizableToSameSizeIdx != -1);
1069  assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
1070  }
1071  if (LargestWidenIdx != -1)
1072  assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
1073 #endif
1074  }
1075 
1076  /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
1077  /// from size 1.
1078  static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
1079 #ifndef NDEBUG
1080  // Data structure invariant: The first bit size must be size 1.
1081  assert(v.size() >= 1);
1082  assert(v[0].first == 1);
1083  checkPartialSizeAndActionsVector(v);
1084 #endif
1085  }
1086 
1087  /// Sets actions for all bit sizes on a particular generic opcode, type
1088  /// index and scalar or pointer type.
1089  void setActions(unsigned TypeIndex,
1091  const SizeAndActionsVec &SizeAndActions) {
1092  checkFullSizeAndActionsVector(SizeAndActions);
1093  if (Actions.size() <= TypeIndex)
1094  Actions.resize(TypeIndex + 1);
1095  Actions[TypeIndex] = SizeAndActions;
1096  }
1097 
1098  static SizeAndAction findAction(const SizeAndActionsVec &Vec,
1099  const uint32_t Size);
1100 
1101  /// Returns the next action needed to get the scalar or pointer type closer
1102  /// to being legal
1103  /// E.g. findLegalAction({G_REM, 13}) should return
1104  /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
1105  /// probably be called, which should return (Lower, 32).
1106  /// This is assuming the setScalarAction on G_REM was something like:
1107  /// setScalarAction(G_REM, 0,
1108  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
1109  /// {32, Lower}, // bit sizes [32, 33[
1110  /// {33, NarrowScalar} // bit sizes [65, +inf[
1111  /// });
1112  std::pair<LegalizeAction, LLT>
1113  findScalarLegalAction(const InstrAspect &Aspect) const;
1114 
1115  /// Returns the next action needed towards legalizing the vector type.
1116  std::pair<LegalizeAction, LLT>
1117  findVectorLegalAction(const InstrAspect &Aspect) const;
1118 
1119  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1120  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1121 
1122  // Data structures used temporarily during construction of legality data:
1124  SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
1126  ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
1128  VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
1129  bool TablesInitialized;
1130 
1131  // Data structures used by getAction:
1132  SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
1133  SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
1134  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
1135  AddrSpace2PointerActions[LastOp - FirstOp + 1];
1136  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
1137  NumElements2Actions[LastOp - FirstOp + 1];
1138 
1139  LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1140 };
1141 
1142 #ifndef NDEBUG
1143 /// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1144 /// nullptr otherwise
1146 #endif
1147 
1148 } // end namespace llvm.
1149 
1150 #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:259
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 ...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
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
LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min=0)
Widen the type for the given type index to the next power of 2.
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 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{}.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
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)
bool match(const LegalityQuery &Query) const
Test whether the LegalityQuery matches.
LegalizeAction getAction() const
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:1173
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.
LegalityPredicate typePairAndMemSizeInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemSize > TypesAndMemSizeInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs...
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)
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:33
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
bool operator==(const LegalizeActionStep &RHS) const
LegalizeRuleSet & legalForTypesWithMemSize(std::initializer_list< LegalityPredicates::TypePairAndMemSize > TypesAndMemSize)
The instruction is legal when type indexes 0 and 1 along with the memory size is any type and size tu...
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 & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
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...
unsigned const MachineRegisterInfo * MRI
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)
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
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 & 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:53
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:1063
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)
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:1023
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT >> Types)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
AddressSpace
Definition: NVPTXBaseInfo.h:22
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:27
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 & 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 & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
A single rule in a legalizer info ruleset.
bool operator==(const TypePairAndMemSize &Other) const
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.
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:56
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.
static void Query(const MachineInstr &MI, AliasAnalysis &AA, bool &Read, bool &Write, bool &Effects, bool &StackPointer)
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:47
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
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...
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:351