LLVM  7.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"
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 
41 namespace LegalizeActions {
42 enum LegalizeAction : std::uint8_t {
43  /// The operation is expected to be selectable directly by the target, and
44  /// no transformation is necessary.
46 
47  /// The operation should be synthesized from multiple instructions acting on
48  /// a narrower scalar base-type. For example a 64-bit add might be
49  /// implemented in terms of 32-bit add-with-carry.
51 
52  /// The operation should be implemented in terms of a wider scalar
53  /// base-type. For example a <2 x s8> add could be implemented as a <2
54  /// x s32> add (ignoring the high bits).
56 
57  /// The (vector) operation should be implemented by splitting it into
58  /// sub-vectors where the operation is legal. For example a <8 x s64> add
59  /// might be implemented as 4 separate <2 x s64> adds.
61 
62  /// The (vector) operation should be implemented by widening the input
63  /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
64  /// rarely legal, but you might perform an <8 x i8> and then only look at
65  /// the first two results.
67 
68  /// The operation itself must be expressed in terms of simpler actions on
69  /// this target. E.g. a SREM replaced by an SDIV and subtraction.
71 
72  /// The operation should be implemented as a call to some kind of runtime
73  /// support library. For example this usually happens on machines that don't
74  /// support floating-point operations natively.
76 
77  /// The target wants to do something special with this combination of
78  /// operand and type. A callback will be issued when it is needed.
80 
81  /// This operation is completely unsupported on the target. A programming
82  /// error has occurred.
84 
85  /// Sentinel value for when no action was found in the specified table.
87 
88  /// Fall back onto the old rules.
89  /// TODO: Remove this once we've migrated
91 };
92 } // end namespace LegalizeActions
93 
95 
96 /// Legalization is decided based on an instruction's opcode, which type slot
97 /// we're considering, and what the existing type is. These aspects are gathered
98 /// together for convenience in the InstrAspect class.
99 struct InstrAspect {
100  unsigned Opcode;
101  unsigned Idx = 0;
103 
104  InstrAspect(unsigned Opcode, LLT Type) : Opcode(Opcode), Type(Type) {}
105  InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
106  : Opcode(Opcode), Idx(Idx), Type(Type) {}
107 
108  bool operator==(const InstrAspect &RHS) const {
109  return Opcode == RHS.Opcode && Idx == RHS.Idx && Type == RHS.Type;
110  }
111 };
112 
113 /// The LegalityQuery object bundles together all the information that's needed
114 /// to decide whether a given operation is legal or not.
115 /// For efficiency, it doesn't make a copy of Types so care must be taken not
116 /// to free it before using the query.
118  unsigned Opcode;
120 
121  raw_ostream &print(raw_ostream &OS) const;
122 };
123 
124 /// The result of a query. It either indicates a final answer of Legal or
125 /// Unsupported or describes an action that must be taken to make an operation
126 /// more legal.
128  /// The action to take or the final answer.
130  /// If describing an action, the type index to change. Otherwise zero.
131  unsigned TypeIdx;
132  /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
134 
135  LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
136  const LLT &NewType)
137  : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
138 
139  bool operator==(const LegalizeActionStep &RHS) const {
140  return std::tie(Action, TypeIdx, NewType) ==
141  std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
142  }
143 };
144 
145 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
146 using LegalizeMutation =
147  std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
148 
150 /// True iff P0 and P1 are true.
152 /// True iff the given type index is one of the specified types.
153 LegalityPredicate typeInSet(unsigned TypeIdx,
154  std::initializer_list<LLT> TypesInit);
155 /// True iff the given types for the given pair of type indexes is one of the
156 /// specified type pairs.
158 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
159  std::initializer_list<std::pair<LLT, LLT>> TypesInit);
160 /// True iff the specified type index is a scalar.
161 LegalityPredicate isScalar(unsigned TypeIdx);
162 /// True iff the specified type index is a scalar that's narrower than the given
163 /// size.
164 LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
165 /// True iff the specified type index is a scalar that's wider than the given
166 /// size.
167 LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
168 /// True iff the specified type index is a scalar whose size is not a power of
169 /// 2.
170 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
171 /// True iff the specified type index is a vector whose element count is not a
172 /// power of 2.
173 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
174 } // end namespace LegalityPredicates
175 
176 namespace LegalizeMutations {
177 /// Select this specific type for the given type index.
178 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
179 /// Keep the same type as the given type index.
180 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
181 /// Widen the type for the given type index to the next power of 2.
182 LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
183 /// Add more elements to the type for the given type index to the next power of
184 /// 2.
185 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
186 } // end namespace LegalizeMutations
187 
188 /// A single rule in a legalizer info ruleset.
189 /// The specified action is chosen when the predicate is true. Where appropriate
190 /// for the action (e.g. for WidenScalar) the new type is selected using the
191 /// given mutator.
194  LegalizeAction Action;
196 
197 public:
199  LegalizeMutation Mutation = nullptr)
200  : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
201 
202  /// Test whether the LegalityQuery matches.
203  bool match(const LegalityQuery &Query) const {
204  return Predicate(Query);
205  }
206 
207  LegalizeAction getAction() const { return Action; }
208 
209  /// Determine the change to make.
210  std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
211  if (Mutation)
212  return Mutation(Query);
213  return std::make_pair(0, LLT{});
214  }
215 };
216 
218  /// When non-zero, the opcode we are an alias of
219  unsigned AliasOf;
220  /// If true, there is another opcode that aliases this one
221  bool IsAliasedByAnother;
223 
224  void add(const LegalizeRule &Rule) {
225  assert(AliasOf == 0 &&
226  "RuleSet is aliased, change the representative opcode instead");
227  Rules.push_back(Rule);
228  }
229 
230  static bool always(const LegalityQuery &) { return true; }
231 
232  /// Use the given action when the predicate is true.
233  /// Action should not be an action that requires mutation.
234  LegalizeRuleSet &actionIf(LegalizeAction Action,
236  add({Predicate, Action});
237  return *this;
238  }
239  /// Use the given action when the predicate is true.
240  /// Action should be an action that requires mutation.
241  LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
243  add({Predicate, Action, Mutation});
244  return *this;
245  }
246  /// Use the given action when type index 0 is any type in the given list.
247  /// Action should not be an action that requires mutation.
248  LegalizeRuleSet &actionFor(LegalizeAction Action,
249  std::initializer_list<LLT> Types) {
250  using namespace LegalityPredicates;
251  return actionIf(Action, typeInSet(0, Types));
252  }
253  /// Use the given action when type index 0 is any type in the given list.
254  /// Action should be an action that requires mutation.
255  LegalizeRuleSet &actionFor(LegalizeAction Action,
256  std::initializer_list<LLT> Types,
257  LegalizeMutation Mutation) {
258  using namespace LegalityPredicates;
259  return actionIf(Action, typeInSet(0, Types), Mutation);
260  }
261  /// Use the given action when type indexes 0 and 1 is any type pair in the
262  /// given list.
263  /// Action should not be an action that requires mutation.
265  actionFor(LegalizeAction Action,
266  std::initializer_list<std::pair<LLT, LLT>> Types) {
267  using namespace LegalityPredicates;
268  return actionIf(Action, typePairInSet(0, 1, Types));
269  }
270  /// Use the given action when type indexes 0 and 1 is any type pair in the
271  /// given list.
272  /// Action should be an action that requires mutation.
273  LegalizeRuleSet &actionFor(LegalizeAction Action,
274  std::initializer_list<std::pair<LLT, LLT>> Types,
275  LegalizeMutation Mutation) {
276  using namespace LegalityPredicates;
277  return actionIf(Action, typePairInSet(0, 1, Types), Mutation);
278  }
279  /// Use the given action when type indexes 0 and 1 are both in the given list.
280  /// That is, the type pair is in the cartesian product of the list.
281  /// Action should not be an action that requires mutation.
282  LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
283  std::initializer_list<LLT> Types) {
284  using namespace LegalityPredicates;
285  return actionIf(Action, all(typeInSet(0, Types), typeInSet(1, Types)));
286  }
287  /// Use the given action when type indexes 0 and 1 are both their respective
288  /// lists.
289  /// That is, the type pair is in the cartesian product of the lists
290  /// Action should not be an action that requires mutation.
292  actionForCartesianProduct(LegalizeAction Action,
293  std::initializer_list<LLT> Types0,
294  std::initializer_list<LLT> Types1) {
295  using namespace LegalityPredicates;
296  return actionIf(Action, all(typeInSet(0, Types0), typeInSet(1, Types1)));
297  }
298 
299 public:
300  LegalizeRuleSet() : AliasOf(0), IsAliasedByAnother(false), Rules() {}
301 
302  bool isAliasedByAnother() { return IsAliasedByAnother; }
303  void setIsAliasedByAnother() { IsAliasedByAnother = true; }
304  void aliasTo(unsigned Opcode) {
305  assert((AliasOf == 0 || AliasOf == Opcode) &&
306  "Opcode is already aliased to another opcode");
307  assert(Rules.empty() && "Aliasing will discard rules");
308  AliasOf = Opcode;
309  }
310  unsigned getAlias() const { return AliasOf; }
311 
312  /// The instruction is legal if predicate is true.
314  return actionIf(LegalizeAction::Legal, Predicate);
315  }
316  /// The instruction is legal when type index 0 is any type in the given list.
317  LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
318  return actionFor(LegalizeAction::Legal, Types);
319  }
320  /// The instruction is legal when type indexes 0 and 1 is any type pair in the
321  /// given list.
322  LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
323  return actionFor(LegalizeAction::Legal, Types);
324  }
325  /// The instruction is legal when type indexes 0 and 1 are both in the given
326  /// list. That is, the type pair is in the cartesian product of the list.
327  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
328  return actionForCartesianProduct(LegalizeAction::Legal, Types);
329  }
330  /// The instruction is legal when type indexes 0 and 1 are both their
331  /// respective lists.
332  LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
333  std::initializer_list<LLT> Types1) {
334  return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
335  }
336 
337  /// The instruction is lowered.
339  using namespace LegalizeMutations;
340  return actionIf(LegalizeAction::Lower, always, changeTo(0, 0));
341  }
342  /// The instruction is lowered if predicate is true. Keep type index 0 as the
343  /// same type.
345  using namespace LegalizeMutations;
346  return actionIf(LegalizeAction::Lower, Predicate, changeTo(0, 0));
347  }
348  /// The instruction is lowered when type index 0 is any type in the given
349  /// list. Keep type index 0 as the same type.
350  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
351  using namespace LegalizeMutations;
352  return lowerFor(Types, changeTo(0, 0));
353  }
354  /// The instruction is lowered when type indexes 0 and 1 is any type pair in the
355  /// given list. Keep type index 0 as the same type.
356  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
357  return lowerFor(Types, LegalizeMutations::changeTo(0, 0));
358  }
359  /// The instruction is lowered when type indexes 0 and 1 is any type pair in the
360  /// given list.
361  LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
362  LegalizeMutation Mutation) {
363  return actionFor(LegalizeAction::Lower, Types, Mutation);
364  }
365  /// The instruction is lowered if predicate is true.
367  LegalizeMutation Mutation) {
368  return actionIf(LegalizeAction::Lower, Predicate, Mutation);
369  }
370  /// The instruction is lowered when type index 0 is any type in the given list.
371  LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
372  LegalizeMutation Mutation) {
373  return actionFor(LegalizeAction::Lower, Types, Mutation);
374  }
375 
376  /// Like legalIf, but for the Libcall action.
378  return actionIf(LegalizeAction::Libcall, Predicate);
379  }
380  LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
381  return actionFor(LegalizeAction::Libcall, Types);
382  }
384  libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
385  return actionFor(LegalizeAction::Libcall, Types);
386  }
388  libcallForCartesianProduct(std::initializer_list<LLT> Types) {
389  return actionForCartesianProduct(LegalizeAction::Libcall, Types);
390  }
392  libcallForCartesianProduct(std::initializer_list<LLT> Types0,
393  std::initializer_list<LLT> Types1) {
394  return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
395  }
396 
397  /// Widen the scalar to the one selected by the mutation if the predicate is
398  /// true.
400  LegalizeMutation Mutation) {
401  return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
402  }
403  /// Narrow the scalar to the one selected by the mutation if the predicate is
404  /// true.
406  LegalizeMutation Mutation) {
407  return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
408  }
409 
410  /// Add more elements to reach the type selected by the mutation if the
411  /// predicate is true.
413  LegalizeMutation Mutation) {
414  return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
415  }
416  /// Remove elements to reach the type selected by the mutation if the
417  /// predicate is true.
419  LegalizeMutation Mutation) {
420  return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
421  }
422 
423  /// The instruction is unsupported.
425  return actionIf(LegalizeAction::Unsupported, always);
426  }
428  return actionIf(LegalizeAction::Unsupported, Predicate);
429  }
430 
432  return actionIf(LegalizeAction::Custom, Predicate);
433  }
434  LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
435  return actionFor(LegalizeAction::Custom, Types);
436  }
437  LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
438  return actionForCartesianProduct(LegalizeAction::Custom, Types);
439  }
441  customForCartesianProduct(std::initializer_list<LLT> Types0,
442  std::initializer_list<LLT> Types1) {
443  return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
444  }
445 
446  /// Widen the scalar to the next power of two that is at least MinSize.
447  /// No effect if the type is not a scalar or is a power of two.
448  LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize = 0) {
449  using namespace LegalityPredicates;
450  return widenScalarIf(
451  sizeNotPow2(TypeIdx),
452  LegalizeMutations::widenScalarToNextPow2(TypeIdx, MinSize));
453  }
454 
455  LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
456  using namespace LegalityPredicates;
457  return narrowScalarIf(isScalar(TypeIdx), Mutation);
458  }
459 
460  /// Ensure the scalar is at least as wide as Ty.
461  LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
462  using namespace LegalityPredicates;
463  using namespace LegalizeMutations;
464  return widenScalarIf(narrowerThan(TypeIdx, Ty.getSizeInBits()),
465  changeTo(TypeIdx, Ty));
466  }
467 
468  /// Ensure the scalar is at most as wide as Ty.
469  LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
470  using namespace LegalityPredicates;
471  using namespace LegalizeMutations;
472  return narrowScalarIf(widerThan(TypeIdx, Ty.getSizeInBits()),
473  changeTo(TypeIdx, Ty));
474  }
475 
476  /// Conditionally limit the maximum size of the scalar.
477  /// For example, when the maximum size of one type depends on the size of
478  /// another such as extracting N bits from an M bit container.
479  LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT &Ty) {
480  using namespace LegalityPredicates;
481  using namespace LegalizeMutations;
482  return narrowScalarIf(
483  [=](const LegalityQuery &Query) {
484  return widerThan(TypeIdx, Ty.getSizeInBits()) &&
485  Predicate(Query);
486  },
487  changeTo(TypeIdx, Ty));
488  }
489 
490  /// Limit the range of scalar sizes to MinTy and MaxTy.
491  LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy) {
492  assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
493 
494  return minScalar(TypeIdx, MinTy)
495  .maxScalar(TypeIdx, MaxTy);
496  }
497 
498  /// Add more elements to the vector to reach the next power of two.
499  /// No effect if the type is not a vector or the element count is a power of
500  /// two.
502  using namespace LegalityPredicates;
503  return moreElementsIf(numElementsNotPow2(TypeIdx),
505  }
506 
507  /// Limit the number of elements in EltTy vectors to at least MinElements.
508  LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy,
509  unsigned MinElements) {
510  return moreElementsIf(
511  [=](const LegalityQuery &Query) {
512  LLT VecTy = Query.Types[TypeIdx];
513  return VecTy.getElementType() == EltTy &&
514  VecTy.getNumElements() < MinElements;
515  },
516  [=](const LegalityQuery &Query) {
517  LLT VecTy = Query.Types[TypeIdx];
518  return std::make_pair(
519  TypeIdx, LLT::vector(MinElements, VecTy.getScalarSizeInBits()));
520  });
521  }
522  /// Limit the number of elements in EltTy vectors to at most MaxElements.
523  LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy,
524  unsigned MaxElements) {
525  return fewerElementsIf(
526  [=](const LegalityQuery &Query) {
527  LLT VecTy = Query.Types[TypeIdx];
528  return VecTy.getElementType() == EltTy &&
529  VecTy.getNumElements() > MaxElements;
530  },
531  [=](const LegalityQuery &Query) {
532  LLT VecTy = Query.Types[TypeIdx];
533  return std::make_pair(
534  TypeIdx, LLT::vector(MaxElements, VecTy.getScalarSizeInBits()));
535  });
536  }
537  /// Limit the number of elements for the given vectors to at least MinTy's
538  /// number of elements and at most MaxTy's number of elements.
539  ///
540  /// No effect if the type is not a vector or does not have the same element
541  /// type as the constraints.
542  /// The element type of MinTy and MaxTy must match.
543  LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT &MinTy,
544  const LLT &MaxTy) {
545  assert(MinTy.getElementType() == MaxTy.getElementType() &&
546  "Expected element types to agree");
547 
548  const LLT &EltTy = MinTy.getElementType();
549  return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
550  .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
551  }
552 
553  /// Fallback on the previous implementation. This should only be used while
554  /// porting a rule.
557  return *this;
558  }
559 
560  /// Apply the ruleset to the given LegalityQuery.
562 };
563 
565 public:
566  LegalizerInfo();
567  virtual ~LegalizerInfo() = default;
568 
569  unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
570  unsigned getActionDefinitionsIdx(unsigned Opcode) const;
571 
572  /// Compute any ancillary tables needed to quickly decide how an operation
573  /// should be handled. This must be called after all "set*Action"methods but
574  /// before any query is made or incorrect results may be returned.
575  void computeTables();
576 
577  static bool needsLegalizingToDifferentSize(const LegalizeAction Action) {
578  using namespace LegalizeActions;
579  switch (Action) {
580  case NarrowScalar:
581  case WidenScalar:
582  case FewerElements:
583  case MoreElements:
584  case Unsupported:
585  return true;
586  default:
587  return false;
588  }
589  }
590 
591  using SizeAndAction = std::pair<uint16_t, LegalizeAction>;
592  using SizeAndActionsVec = std::vector<SizeAndAction>;
593  using SizeChangeStrategy =
594  std::function<SizeAndActionsVec(const SizeAndActionsVec &v)>;
595 
596  /// More friendly way to set an action for common types that have an LLT
597  /// representation.
598  /// The LegalizeAction must be one for which NeedsLegalizingToDifferentSize
599  /// returns false.
600  void setAction(const InstrAspect &Aspect, LegalizeAction Action) {
601  assert(!needsLegalizingToDifferentSize(Action));
602  TablesInitialized = false;
603  const unsigned OpcodeIdx = Aspect.Opcode - FirstOp;
604  if (SpecifiedActions[OpcodeIdx].size() <= Aspect.Idx)
605  SpecifiedActions[OpcodeIdx].resize(Aspect.Idx + 1);
606  SpecifiedActions[OpcodeIdx][Aspect.Idx][Aspect.Type] = Action;
607  }
608 
609  /// The setAction calls record the non-size-changing legalization actions
610  /// to take on specificly-sized types. The SizeChangeStrategy defines what
611  /// to do when the size of the type needs to be changed to reach a legally
612  /// sized type (i.e., one that was defined through a setAction call).
613  /// e.g.
614  /// setAction ({G_ADD, 0, LLT::scalar(32)}, Legal);
615  /// setLegalizeScalarToDifferentSizeStrategy(
616  /// G_ADD, 0, widenToLargerTypesAndNarrowToLargest);
617  /// will end up defining getAction({G_ADD, 0, T}) to return the following
618  /// actions for different scalar types T:
619  /// LLT::scalar(1)..LLT::scalar(31): {WidenScalar, 0, LLT::scalar(32)}
620  /// LLT::scalar(32): {Legal, 0, LLT::scalar(32)}
621  /// LLT::scalar(33)..: {NarrowScalar, 0, LLT::scalar(32)}
622  ///
623  /// If no SizeChangeAction gets defined, through this function,
624  /// the default is unsupportedForDifferentSizes.
625  void setLegalizeScalarToDifferentSizeStrategy(const unsigned Opcode,
626  const unsigned TypeIdx,
627  SizeChangeStrategy S) {
628  const unsigned OpcodeIdx = Opcode - FirstOp;
629  if (ScalarSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
630  ScalarSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
631  ScalarSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
632  }
633 
634  /// See also setLegalizeScalarToDifferentSizeStrategy.
635  /// This function allows to set the SizeChangeStrategy for vector elements.
637  const unsigned TypeIdx,
638  SizeChangeStrategy S) {
639  const unsigned OpcodeIdx = Opcode - FirstOp;
640  if (VectorElementSizeChangeStrategies[OpcodeIdx].size() <= TypeIdx)
641  VectorElementSizeChangeStrategies[OpcodeIdx].resize(TypeIdx + 1);
642  VectorElementSizeChangeStrategies[OpcodeIdx][TypeIdx] = S;
643  }
644 
645  /// A SizeChangeStrategy for the common case where legalization for a
646  /// particular operation consists of only supporting a specific set of type
647  /// sizes. E.g.
648  /// setAction ({G_DIV, 0, LLT::scalar(32)}, Legal);
649  /// setAction ({G_DIV, 0, LLT::scalar(64)}, Legal);
650  /// setLegalizeScalarToDifferentSizeStrategy(
651  /// G_DIV, 0, unsupportedForDifferentSizes);
652  /// will result in getAction({G_DIV, 0, T}) to return Legal for s32 and s64,
653  /// and Unsupported for all other scalar types T.
654  static SizeAndActionsVec
656  using namespace LegalizeActions;
657  return increaseToLargerTypesAndDecreaseToLargest(v, Unsupported,
658  Unsupported);
659  }
660 
661  /// A SizeChangeStrategy for the common case where legalization for a
662  /// particular operation consists of widening the type to a large legal type,
663  /// unless there is no such type and then instead it should be narrowed to the
664  /// largest legal type.
665  static SizeAndActionsVec
667  using namespace LegalizeActions;
668  assert(v.size() > 0 &&
669  "At least one size that can be legalized towards is needed"
670  " for this SizeChangeStrategy");
671  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
672  NarrowScalar);
673  }
674 
675  static SizeAndActionsVec
677  using namespace LegalizeActions;
678  return increaseToLargerTypesAndDecreaseToLargest(v, WidenScalar,
679  Unsupported);
680  }
681 
682  static SizeAndActionsVec
684  using namespace LegalizeActions;
685  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
686  Unsupported);
687  }
688 
689  static SizeAndActionsVec
691  using namespace LegalizeActions;
692  assert(v.size() > 0 &&
693  "At least one size that can be legalized towards is needed"
694  " for this SizeChangeStrategy");
695  return decreaseToSmallerTypesAndIncreaseToSmallest(v, NarrowScalar,
696  WidenScalar);
697  }
698 
699  /// A SizeChangeStrategy for the common case where legalization for a
700  /// particular vector operation consists of having more elements in the
701  /// vector, to a type that is legal. Unless there is no such type and then
702  /// instead it should be legalized towards the widest vector that's still
703  /// legal. E.g.
704  /// setAction({G_ADD, LLT::vector(8, 8)}, Legal);
705  /// setAction({G_ADD, LLT::vector(16, 8)}, Legal);
706  /// setAction({G_ADD, LLT::vector(2, 32)}, Legal);
707  /// setAction({G_ADD, LLT::vector(4, 32)}, Legal);
708  /// setLegalizeVectorElementToDifferentSizeStrategy(
709  /// G_ADD, 0, moreToWiderTypesAndLessToWidest);
710  /// will result in the following getAction results:
711  /// * getAction({G_ADD, LLT::vector(8,8)}) returns
712  /// (Legal, vector(8,8)).
713  /// * getAction({G_ADD, LLT::vector(9,8)}) returns
714  /// (MoreElements, vector(16,8)).
715  /// * getAction({G_ADD, LLT::vector(8,32)}) returns
716  /// (FewerElements, vector(4,32)).
717  static SizeAndActionsVec
719  using namespace LegalizeActions;
720  return increaseToLargerTypesAndDecreaseToLargest(v, MoreElements,
721  FewerElements);
722  }
723 
724  /// Helper function to implement many typical SizeChangeStrategy functions.
725  static SizeAndActionsVec
726  increaseToLargerTypesAndDecreaseToLargest(const SizeAndActionsVec &v,
727  LegalizeAction IncreaseAction,
728  LegalizeAction DecreaseAction);
729  /// Helper function to implement many typical SizeChangeStrategy functions.
730  static SizeAndActionsVec
731  decreaseToSmallerTypesAndIncreaseToSmallest(const SizeAndActionsVec &v,
732  LegalizeAction DecreaseAction,
733  LegalizeAction IncreaseAction);
734 
735  /// Get the action definitions for the given opcode. Use this to run a
736  /// LegalityQuery through the definitions.
737  const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
738 
739  /// Get the action definition builder for the given opcode. Use this to define
740  /// the action definitions.
741  ///
742  /// It is an error to request an opcode that has already been requested by the
743  /// multiple-opcode variant.
744  LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
745 
746  /// Get the action definition builder for the given set of opcodes. Use this
747  /// to define the action definitions for multiple opcodes at once. The first
748  /// opcode given will be considered the representative opcode and will hold
749  /// the definitions whereas the other opcodes will be configured to refer to
750  /// the representative opcode. This lowers memory requirements and very
751  /// slightly improves performance.
752  ///
753  /// It would be very easy to introduce unexpected side-effects as a result of
754  /// this aliasing if it were permitted to request different but intersecting
755  /// sets of opcodes but that is difficult to keep track of. It is therefore an
756  /// error to request the same opcode twice using this API, to request an
757  /// opcode that already has definitions, or to use the single-opcode API on an
758  /// opcode that has already been requested by this API.
760  getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
761  void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
762 
763  /// Determine what action should be taken to legalize the described
764  /// instruction. Requires computeTables to have been called.
765  ///
766  /// \returns a description of the next legalization step to perform.
767  LegalizeActionStep getAction(const LegalityQuery &Query) const;
768 
769  /// Determine what action should be taken to legalize the given generic
770  /// instruction.
771  ///
772  /// \returns a description of the next legalization step to perform.
773  LegalizeActionStep getAction(const MachineInstr &MI,
774  const MachineRegisterInfo &MRI) const;
775 
776  bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
777 
778  virtual bool legalizeCustom(MachineInstr &MI,
779  MachineRegisterInfo &MRI,
780  MachineIRBuilder &MIRBuilder) const;
781 
782 private:
783  /// Determine what action should be taken to legalize the given generic
784  /// instruction opcode, type-index and type. Requires computeTables to have
785  /// been called.
786  ///
787  /// \returns a pair consisting of the kind of legalization that should be
788  /// performed and the destination type.
789  std::pair<LegalizeAction, LLT>
790  getAspectAction(const InstrAspect &Aspect) const;
791 
792  /// The SizeAndActionsVec is a representation mapping between all natural
793  /// numbers and an Action. The natural number represents the bit size of
794  /// the InstrAspect. For example, for a target with native support for 32-bit
795  /// and 64-bit additions, you'd express that as:
796  /// setScalarAction(G_ADD, 0,
797  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
798  /// {32, Legal}, // bit sizes [32, 33[
799  /// {33, WidenScalar}, // bit sizes [33, 64[
800  /// {64, Legal}, // bit sizes [64, 65[
801  /// {65, NarrowScalar} // bit sizes [65, +inf[
802  /// });
803  /// It may be that only 64-bit pointers are supported on your target:
804  /// setPointerAction(G_GEP, 0, LLT:pointer(1),
805  /// {{1, Unsupported}, // bit sizes [ 1, 63[
806  /// {64, Legal}, // bit sizes [64, 65[
807  /// {65, Unsupported}, // bit sizes [65, +inf[
808  /// });
809  void setScalarAction(const unsigned Opcode, const unsigned TypeIndex,
810  const SizeAndActionsVec &SizeAndActions) {
811  const unsigned OpcodeIdx = Opcode - FirstOp;
812  SmallVector<SizeAndActionsVec, 1> &Actions = ScalarActions[OpcodeIdx];
813  setActions(TypeIndex, Actions, SizeAndActions);
814  }
815  void setPointerAction(const unsigned Opcode, const unsigned TypeIndex,
816  const unsigned AddressSpace,
817  const SizeAndActionsVec &SizeAndActions) {
818  const unsigned OpcodeIdx = Opcode - FirstOp;
819  if (AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace) ==
820  AddrSpace2PointerActions[OpcodeIdx].end())
821  AddrSpace2PointerActions[OpcodeIdx][AddressSpace] = {{}};
823  AddrSpace2PointerActions[OpcodeIdx].find(AddressSpace)->second;
824  setActions(TypeIndex, Actions, SizeAndActions);
825  }
826 
827  /// If an operation on a given vector type (say <M x iN>) isn't explicitly
828  /// specified, we proceed in 2 stages. First we legalize the underlying scalar
829  /// (so that there's at least one legal vector with that scalar), then we
830  /// adjust the number of elements in the vector so that it is legal. The
831  /// desired action in the first step is controlled by this function.
832  void setScalarInVectorAction(const unsigned Opcode, const unsigned TypeIndex,
833  const SizeAndActionsVec &SizeAndActions) {
834  unsigned OpcodeIdx = Opcode - FirstOp;
836  ScalarInVectorActions[OpcodeIdx];
837  setActions(TypeIndex, Actions, SizeAndActions);
838  }
839 
840  /// See also setScalarInVectorAction.
841  /// This function let's you specify the number of elements in a vector that
842  /// are legal for a legal element size.
843  void setVectorNumElementAction(const unsigned Opcode,
844  const unsigned TypeIndex,
845  const unsigned ElementSize,
846  const SizeAndActionsVec &SizeAndActions) {
847  const unsigned OpcodeIdx = Opcode - FirstOp;
848  if (NumElements2Actions[OpcodeIdx].find(ElementSize) ==
849  NumElements2Actions[OpcodeIdx].end())
850  NumElements2Actions[OpcodeIdx][ElementSize] = {{}};
852  NumElements2Actions[OpcodeIdx].find(ElementSize)->second;
853  setActions(TypeIndex, Actions, SizeAndActions);
854  }
855 
856  /// A partial SizeAndActionsVec potentially doesn't cover all bit sizes,
857  /// i.e. it's OK if it doesn't start from size 1.
858  static void checkPartialSizeAndActionsVector(const SizeAndActionsVec& v) {
859  using namespace LegalizeActions;
860 #ifndef NDEBUG
861  // The sizes should be in increasing order
862  int prev_size = -1;
863  for(auto SizeAndAction: v) {
864  assert(SizeAndAction.first > prev_size);
865  prev_size = SizeAndAction.first;
866  }
867  // - for every Widen action, there should be a larger bitsize that
868  // can be legalized towards (e.g. Legal, Lower, Libcall or Custom
869  // action).
870  // - for every Narrow action, there should be a smaller bitsize that
871  // can be legalized towards.
872  int SmallestNarrowIdx = -1;
873  int LargestWidenIdx = -1;
874  int SmallestLegalizableToSameSizeIdx = -1;
875  int LargestLegalizableToSameSizeIdx = -1;
876  for(size_t i=0; i<v.size(); ++i) {
877  switch (v[i].second) {
878  case FewerElements:
879  case NarrowScalar:
880  if (SmallestNarrowIdx == -1)
881  SmallestNarrowIdx = i;
882  break;
883  case WidenScalar:
884  case MoreElements:
885  LargestWidenIdx = i;
886  break;
887  case Unsupported:
888  break;
889  default:
890  if (SmallestLegalizableToSameSizeIdx == -1)
891  SmallestLegalizableToSameSizeIdx = i;
892  LargestLegalizableToSameSizeIdx = i;
893  }
894  }
895  if (SmallestNarrowIdx != -1) {
896  assert(SmallestLegalizableToSameSizeIdx != -1);
897  assert(SmallestNarrowIdx > SmallestLegalizableToSameSizeIdx);
898  }
899  if (LargestWidenIdx != -1)
900  assert(LargestWidenIdx < LargestLegalizableToSameSizeIdx);
901 #endif
902  }
903 
904  /// A full SizeAndActionsVec must cover all bit sizes, i.e. must start with
905  /// from size 1.
906  static void checkFullSizeAndActionsVector(const SizeAndActionsVec& v) {
907 #ifndef NDEBUG
908  // Data structure invariant: The first bit size must be size 1.
909  assert(v.size() >= 1);
910  assert(v[0].first == 1);
911  checkPartialSizeAndActionsVector(v);
912 #endif
913  }
914 
915  /// Sets actions for all bit sizes on a particular generic opcode, type
916  /// index and scalar or pointer type.
917  void setActions(unsigned TypeIndex,
919  const SizeAndActionsVec &SizeAndActions) {
920  checkFullSizeAndActionsVector(SizeAndActions);
921  if (Actions.size() <= TypeIndex)
922  Actions.resize(TypeIndex + 1);
923  Actions[TypeIndex] = SizeAndActions;
924  }
925 
926  static SizeAndAction findAction(const SizeAndActionsVec &Vec,
927  const uint32_t Size);
928 
929  /// Returns the next action needed to get the scalar or pointer type closer
930  /// to being legal
931  /// E.g. findLegalAction({G_REM, 13}) should return
932  /// (WidenScalar, 32). After that, findLegalAction({G_REM, 32}) will
933  /// probably be called, which should return (Lower, 32).
934  /// This is assuming the setScalarAction on G_REM was something like:
935  /// setScalarAction(G_REM, 0,
936  /// {{1, WidenScalar}, // bit sizes [ 1, 31[
937  /// {32, Lower}, // bit sizes [32, 33[
938  /// {33, NarrowScalar} // bit sizes [65, +inf[
939  /// });
940  std::pair<LegalizeAction, LLT>
941  findScalarLegalAction(const InstrAspect &Aspect) const;
942 
943  /// Returns the next action needed towards legalizing the vector type.
944  std::pair<LegalizeAction, LLT>
945  findVectorLegalAction(const InstrAspect &Aspect) const;
946 
947  static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
948  static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
949 
950  // Data structures used temporarily during construction of legality data:
952  SmallVector<TypeMap, 1> SpecifiedActions[LastOp - FirstOp + 1];
954  ScalarSizeChangeStrategies[LastOp - FirstOp + 1];
956  VectorElementSizeChangeStrategies[LastOp - FirstOp + 1];
957  bool TablesInitialized;
958 
959  // Data structures used by getAction:
960  SmallVector<SizeAndActionsVec, 1> ScalarActions[LastOp - FirstOp + 1];
961  SmallVector<SizeAndActionsVec, 1> ScalarInVectorActions[LastOp - FirstOp + 1];
962  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
963  AddrSpace2PointerActions[LastOp - FirstOp + 1];
964  std::unordered_map<uint16_t, SmallVector<SizeAndActionsVec, 1>>
965  NumElements2Actions[LastOp - FirstOp + 1];
966 
967  LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
968 };
969 
970 #ifndef NDEBUG
971 /// Checks that MIR is fully legal, returns an illegal instruction if it's not,
972 /// nullptr otherwise
974 #endif
975 
976 } // end namespace llvm.
977 
978 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
InstrAspect(unsigned Opcode, unsigned Idx, LLT Type)
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:245
unsigned TypeIdx
If describing an action, the type index to change. Otherwise zero.
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
The result of a query.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
unsigned getScalarSizeInBits() const
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:55
LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min=0)
Widen the type for the given type index to the next power of 2.
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:60
static SizeAndActionsVec narrowToSmallerAndUnsupportedIfTooSmall(const SizeAndActionsVec &v)
unsigned second
unsigned getAlias() const
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.
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:50
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:1169
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:83
LLT getElementType() const
Returns the vector&#39;s element type. Only valid for vector types.
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:66
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
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:70
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
unsigned const MachineRegisterInfo * MRI
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:86
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)
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...
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.
Definition: LegalizerInfo.h:99
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.
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:867
cl::opt< bool > DisableGISelLegalityCheck
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.
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:862
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:75
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:79
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.
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:60
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:90
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:61
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.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalityPredicate all(LegalityPredicate P0, LegalityPredicate P1)
True iff P0 and P1 are 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.
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
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:44
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.
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:45
LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
std::pair< uint16_t, LegalizeAction > SizeAndAction
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:353