xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- llvm/CodeGen/GlobalISel/LegalizerInfo.h ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// Interface for Targets to specify which operations they can successfully
10 /// select and how the others should be expanded most efficiently.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
16 
17 #include "llvm/ADT/SmallBitVector.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
20 #include "llvm/CodeGen/MachineMemOperand.h"
21 #include "llvm/CodeGen/TargetOpcodes.h"
22 #include "llvm/CodeGenTypes/LowLevelType.h"
23 #include "llvm/MC/MCInstrDesc.h"
24 #include "llvm/Support/AtomicOrdering.h"
25 #include "llvm/Support/CommandLine.h"
26 #include "llvm/Support/Compiler.h"
27 #include <cassert>
28 #include <cstdint>
29 #include <tuple>
30 #include <utility>
31 
32 namespace llvm {
33 
34 LLVM_ABI extern cl::opt<bool> DisableGISelLegalityCheck;
35 
36 class MachineFunction;
37 class raw_ostream;
38 class LegalizerHelper;
39 class LostDebugLocObserver;
40 class MachineInstr;
41 class MachineRegisterInfo;
42 class MCInstrInfo;
43 
44 namespace LegalizeActions {
45 enum LegalizeAction : std::uint8_t {
46   /// The operation is expected to be selectable directly by the target, and
47   /// no transformation is necessary.
48   Legal,
49 
50   /// The operation should be synthesized from multiple instructions acting on
51   /// a narrower scalar base-type. For example a 64-bit add might be
52   /// implemented in terms of 32-bit add-with-carry.
53   NarrowScalar,
54 
55   /// The operation should be implemented in terms of a wider scalar
56   /// base-type. For example a <2 x s8> add could be implemented as a <2
57   /// x s32> add (ignoring the high bits).
58   WidenScalar,
59 
60   /// The (vector) operation should be implemented by splitting it into
61   /// sub-vectors where the operation is legal. For example a <8 x s64> add
62   /// might be implemented as 4 separate <2 x s64> adds. There can be a leftover
63   /// if there are not enough elements for last sub-vector e.g. <7 x s64> add
64   /// will be implemented as 3 separate <2 x s64> adds and one s64 add. Leftover
65   /// types can be avoided by doing MoreElements first.
66   FewerElements,
67 
68   /// The (vector) operation should be implemented by widening the input
69   /// vector and ignoring the lanes added by doing so. For example <2 x i8> is
70   /// rarely legal, but you might perform an <8 x i8> and then only look at
71   /// the first two results.
72   MoreElements,
73 
74   /// Perform the operation on a different, but equivalently sized type.
75   Bitcast,
76 
77   /// The operation itself must be expressed in terms of simpler actions on
78   /// this target. E.g. a SREM replaced by an SDIV and subtraction.
79   Lower,
80 
81   /// The operation should be implemented as a call to some kind of runtime
82   /// support library. For example this usually happens on machines that don't
83   /// support floating-point operations natively.
84   Libcall,
85 
86   /// The target wants to do something special with this combination of
87   /// operand and type. A callback will be issued when it is needed.
88   Custom,
89 
90   /// This operation is completely unsupported on the target. A programming
91   /// error has occurred.
92   Unsupported,
93 
94   /// Sentinel value for when no action was found in the specified table.
95   NotFound,
96 
97   /// Fall back onto the old rules.
98   /// TODO: Remove this once we've migrated
99   UseLegacyRules,
100 };
101 } // end namespace LegalizeActions
102 LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
103                                  LegalizeActions::LegalizeAction Action);
104 
105 using LegalizeActions::LegalizeAction;
106 
107 /// The LegalityQuery object bundles together all the information that's needed
108 /// to decide whether a given operation is legal or not.
109 /// For efficiency, it doesn't make a copy of Types so care must be taken not
110 /// to free it before using the query.
111 struct LegalityQuery {
112   unsigned Opcode;
113   ArrayRef<LLT> Types;
114 
115   struct MemDesc {
116     LLT MemoryTy;
117     uint64_t AlignInBits;
118     AtomicOrdering Ordering;
119 
120     MemDesc() = default;
MemDescLegalityQuery::MemDesc121     MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering)
122         : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {}
MemDescLegalityQuery::MemDesc123     MemDesc(const MachineMemOperand &MMO)
124         : MemDesc(MMO.getMemoryType(), MMO.getAlign().value() * 8,
125                   MMO.getSuccessOrdering()) {}
126   };
127 
128   /// Operations which require memory can use this to place requirements on the
129   /// memory type for each MMO.
130   ArrayRef<MemDesc> MMODescrs;
131 
132   constexpr LegalityQuery(unsigned Opcode, ArrayRef<LLT> Types,
133                           ArrayRef<MemDesc> MMODescrs = {})
OpcodeLegalityQuery134       : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
135 
136   LLVM_ABI raw_ostream &print(raw_ostream &OS) const;
137 };
138 
139 /// The result of a query. It either indicates a final answer of Legal or
140 /// Unsupported or describes an action that must be taken to make an operation
141 /// more legal.
142 struct LegalizeActionStep {
143   /// The action to take or the final answer.
144   LegalizeAction Action;
145   /// If describing an action, the type index to change. Otherwise zero.
146   unsigned TypeIdx;
147   /// If describing an action, the new type for TypeIdx. Otherwise LLT{}.
148   LLT NewType;
149 
LegalizeActionStepLegalizeActionStep150   LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
151                      const LLT NewType)
152       : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
153 
LegalizeActionStepLegalizeActionStep154   LegalizeActionStep(LegacyLegalizeActionStep Step)
155       : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
156     switch (Step.Action) {
157     case LegacyLegalizeActions::Legal:
158       Action = LegalizeActions::Legal;
159       break;
160     case LegacyLegalizeActions::NarrowScalar:
161       Action = LegalizeActions::NarrowScalar;
162       break;
163     case LegacyLegalizeActions::WidenScalar:
164       Action = LegalizeActions::WidenScalar;
165       break;
166     case LegacyLegalizeActions::FewerElements:
167       Action = LegalizeActions::FewerElements;
168       break;
169     case LegacyLegalizeActions::MoreElements:
170       Action = LegalizeActions::MoreElements;
171       break;
172     case LegacyLegalizeActions::Bitcast:
173       Action = LegalizeActions::Bitcast;
174       break;
175     case LegacyLegalizeActions::Lower:
176       Action = LegalizeActions::Lower;
177       break;
178     case LegacyLegalizeActions::Libcall:
179       Action = LegalizeActions::Libcall;
180       break;
181     case LegacyLegalizeActions::Custom:
182       Action = LegalizeActions::Custom;
183       break;
184     case LegacyLegalizeActions::Unsupported:
185       Action = LegalizeActions::Unsupported;
186       break;
187     case LegacyLegalizeActions::NotFound:
188       Action = LegalizeActions::NotFound;
189       break;
190     }
191   }
192 
193   bool operator==(const LegalizeActionStep &RHS) const {
194     return std::tie(Action, TypeIdx, NewType) ==
195         std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
196   }
197 };
198 
199 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
200 using LegalizeMutation =
201     std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
202 
203 namespace LegalityPredicates {
204 struct TypePairAndMemDesc {
205   LLT Type0;
206   LLT Type1;
207   LLT MemTy;
208   uint64_t Align;
209 
210   bool operator==(const TypePairAndMemDesc &Other) const {
211     return Type0 == Other.Type0 && Type1 == Other.Type1 &&
212            Align == Other.Align && MemTy == Other.MemTy;
213   }
214 
215   /// \returns true if this memory access is legal with for the access described
216   /// by \p Other (The alignment is sufficient for the size and result type).
isCompatibleTypePairAndMemDesc217   bool isCompatible(const TypePairAndMemDesc &Other) const {
218     return Type0 == Other.Type0 && Type1 == Other.Type1 &&
219            Align >= Other.Align &&
220            // FIXME: This perhaps should be stricter, but the current legality
221            // rules are written only considering the size.
222            MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
223   }
224 };
225 
226 /// True iff P is false.
predNot(Predicate P)227 template <typename Predicate> Predicate predNot(Predicate P) {
228   return [=](const LegalityQuery &Query) { return !P(Query); };
229 }
230 
231 /// True iff P0 and P1 are true.
232 template<typename Predicate>
all(Predicate P0,Predicate P1)233 Predicate all(Predicate P0, Predicate P1) {
234   return [=](const LegalityQuery &Query) {
235     return P0(Query) && P1(Query);
236   };
237 }
238 /// True iff all given predicates are true.
239 template<typename Predicate, typename... Args>
all(Predicate P0,Predicate P1,Args...args)240 Predicate all(Predicate P0, Predicate P1, Args... args) {
241   return all(all(P0, P1), args...);
242 }
243 
244 /// True iff P0 or P1 are true.
245 template<typename Predicate>
any(Predicate P0,Predicate P1)246 Predicate any(Predicate P0, Predicate P1) {
247   return [=](const LegalityQuery &Query) {
248     return P0(Query) || P1(Query);
249   };
250 }
251 /// True iff any given predicates are true.
252 template<typename Predicate, typename... Args>
any(Predicate P0,Predicate P1,Args...args)253 Predicate any(Predicate P0, Predicate P1, Args... args) {
254   return any(any(P0, P1), args...);
255 }
256 
257 /// True iff the given type index is the specified type.
258 LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
259 /// True iff the given type index is one of the specified types.
260 LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx,
261                                      std::initializer_list<LLT> TypesInit);
262 
263 /// True iff the given type index is not the specified type.
typeIsNot(unsigned TypeIdx,LLT Type)264 inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
265   return [=](const LegalityQuery &Query) {
266            return Query.Types[TypeIdx] != Type;
267          };
268 }
269 
270 /// True iff the given types for the given pair of type indexes is one of the
271 /// specified type pairs.
272 LLVM_ABI LegalityPredicate
273 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
274               std::initializer_list<std::pair<LLT, LLT>> TypesInit);
275 /// True iff the given types for the given tuple of type indexes is one of the
276 /// specified type tuple.
277 LLVM_ABI LegalityPredicate
278 typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
279                std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
280 /// True iff the given types for the given pair of type indexes is one of the
281 /// specified type pairs.
282 LLVM_ABI LegalityPredicate typePairAndMemDescInSet(
283     unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
284     std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
285 /// True iff the specified type index is a scalar.
286 LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx);
287 /// True iff the specified type index is a vector.
288 LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx);
289 /// True iff the specified type index is a pointer (with any address space).
290 LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx);
291 /// True iff the specified type index is a pointer with the specified address
292 /// space.
293 LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
294 /// True iff the specified type index is a vector of pointers (with any address
295 /// space).
296 LLVM_ABI LegalityPredicate isPointerVector(unsigned TypeIdx);
297 
298 /// True if the type index is a vector with element type \p EltTy
299 LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
300 
301 /// True iff the specified type index is a scalar that's narrower than the given
302 /// size.
303 LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
304 
305 /// True iff the specified type index is a scalar that's wider than the given
306 /// size.
307 LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
308 
309 /// True iff the specified type index is a scalar or vector with an element type
310 /// that's narrower than the given size.
311 LLVM_ABI LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx,
312                                                    unsigned Size);
313 
314 /// True iff the specified type index is a scalar or a vector with an element
315 /// type that's wider than the given size.
316 LLVM_ABI LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx,
317                                                 unsigned Size);
318 
319 /// True iff the specified type index is a scalar whose size is not a multiple
320 /// of Size.
321 LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
322 
323 /// True iff the specified type index is a scalar whose size is not a power of
324 /// 2.
325 LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx);
326 
327 /// True iff the specified type index is a scalar or vector whose element size
328 /// is not a power of 2.
329 LLVM_ABI LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
330 
331 /// True if the total bitwidth of the specified type index is \p Size bits.
332 LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
333 
334 /// True iff the specified type indices are both the same bit size.
335 LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
336 
337 /// True iff the first type index has a larger total bit size than second type
338 /// index.
339 LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
340 
341 /// True iff the first type index has a smaller total bit size than second type
342 /// index.
343 LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
344 
345 /// True iff the specified MMO index has a size (rounded to bytes) that is not a
346 /// power of 2.
347 LLVM_ABI LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
348 
349 /// True iff the specified MMO index has a size that is not an even byte size,
350 /// or that even byte size is not a power of 2.
351 LLVM_ABI LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx);
352 
353 /// True iff the specified type index is a vector whose element count is not a
354 /// power of 2.
355 LLVM_ABI LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
356 /// True iff the specified MMO index has at an atomic ordering of at Ordering or
357 /// stronger.
358 LLVM_ABI LegalityPredicate
359 atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering);
360 } // end namespace LegalityPredicates
361 
362 namespace LegalizeMutations {
363 /// Select this specific type for the given type index.
364 LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
365 
366 /// Keep the same type as the given type index.
367 LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
368 
369 /// Keep the same scalar or element type as the given type index.
370 LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx,
371                                           unsigned FromTypeIdx);
372 
373 /// Keep the same scalar or element type as the given type.
374 LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
375 
376 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
377 /// elements from \p FromTypeIdx.
378 LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx,
379                                                unsigned FromTypeIdx);
380 
381 /// Keep the same scalar or element type as \p TypeIdx, but take the number of
382 /// elements from \p Ty.
383 LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
384 
385 /// Change the scalar size or element size to have the same scalar size as type
386 /// index \p FromIndex. Unlike changeElementTo, this discards pointer types and
387 /// only changes the size.
388 LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx,
389                                               unsigned FromTypeIdx);
390 
391 /// Widen the scalar type or vector element type for the given type index to the
392 /// next power of 2.
393 LLVM_ABI LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx,
394                                                      unsigned Min = 0);
395 
396 /// Widen the scalar type or vector element type for the given type index to
397 /// next multiple of \p Size.
398 LLVM_ABI LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx,
399                                                            unsigned Size);
400 
401 /// Add more elements to the type for the given type index to the next power of
402 /// 2.
403 LLVM_ABI LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx,
404                                                  unsigned Min = 0);
405 /// Break up the vector type for the given type index into the element type.
406 LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx);
407 } // end namespace LegalizeMutations
408 
409 /// A single rule in a legalizer info ruleset.
410 /// The specified action is chosen when the predicate is true. Where appropriate
411 /// for the action (e.g. for WidenScalar) the new type is selected using the
412 /// given mutator.
413 class LegalizeRule {
414   LegalityPredicate Predicate;
415   LegalizeAction Action;
416   LegalizeMutation Mutation;
417 
418 public:
419   LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action,
420                LegalizeMutation Mutation = nullptr)
Predicate(Predicate)421       : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
422 
423   /// Test whether the LegalityQuery matches.
match(const LegalityQuery & Query)424   bool match(const LegalityQuery &Query) const {
425     return Predicate(Query);
426   }
427 
getAction()428   LegalizeAction getAction() const { return Action; }
429 
430   /// Determine the change to make.
determineMutation(const LegalityQuery & Query)431   std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
432     if (Mutation)
433       return Mutation(Query);
434     return std::make_pair(0, LLT{});
435   }
436 };
437 
438 class LegalizeRuleSet {
439   /// When non-zero, the opcode we are an alias of
440   unsigned AliasOf = 0;
441   /// If true, there is another opcode that aliases this one
442   bool IsAliasedByAnother = false;
443   SmallVector<LegalizeRule, 2> Rules;
444 
445 #ifndef NDEBUG
446   /// If bit I is set, this rule set contains a rule that may handle (predicate
447   /// or perform an action upon (or both)) the type index I. The uncertainty
448   /// comes from free-form rules executing user-provided lambda functions. We
449   /// conservatively assume such rules do the right thing and cover all type
450   /// indices. The bitset is intentionally 1 bit wider than it absolutely needs
451   /// to be to distinguish such cases from the cases where all type indices are
452   /// individually handled.
453   SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC -
454                                  MCOI::OPERAND_FIRST_GENERIC + 2};
455   SmallBitVector ImmIdxsCovered{MCOI::OPERAND_LAST_GENERIC_IMM -
456                                 MCOI::OPERAND_FIRST_GENERIC_IMM + 2};
457 #endif
458 
typeIdx(unsigned TypeIdx)459   unsigned typeIdx(unsigned TypeIdx) {
460     assert(TypeIdx <=
461                (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
462            "Type Index is out of bounds");
463 #ifndef NDEBUG
464     TypeIdxsCovered.set(TypeIdx);
465 #endif
466     return TypeIdx;
467   }
468 
markAllIdxsAsCovered()469   void markAllIdxsAsCovered() {
470 #ifndef NDEBUG
471     TypeIdxsCovered.set();
472     ImmIdxsCovered.set();
473 #endif
474   }
475 
add(const LegalizeRule & Rule)476   void add(const LegalizeRule &Rule) {
477     assert(AliasOf == 0 &&
478            "RuleSet is aliased, change the representative opcode instead");
479     Rules.push_back(Rule);
480   }
481 
always(const LegalityQuery &)482   static bool always(const LegalityQuery &) { return true; }
483 
484   /// Use the given action when the predicate is true.
485   /// Action should not be an action that requires mutation.
actionIf(LegalizeAction Action,LegalityPredicate Predicate)486   LegalizeRuleSet &actionIf(LegalizeAction Action,
487                             LegalityPredicate Predicate) {
488     add({Predicate, Action});
489     return *this;
490   }
491   /// Use the given action when the predicate is true.
492   /// Action should be an action that requires mutation.
actionIf(LegalizeAction Action,LegalityPredicate Predicate,LegalizeMutation Mutation)493   LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
494                             LegalizeMutation Mutation) {
495     add({Predicate, Action, Mutation});
496     return *this;
497   }
498   /// Use the given action when type index 0 is any type in the given list.
499   /// Action should not be an action that requires mutation.
actionFor(LegalizeAction Action,std::initializer_list<LLT> Types)500   LegalizeRuleSet &actionFor(LegalizeAction Action,
501                              std::initializer_list<LLT> Types) {
502     using namespace LegalityPredicates;
503     return actionIf(Action, typeInSet(typeIdx(0), Types));
504   }
505   /// Use the given action when type index 0 is any type in the given list.
506   /// Action should be an action that requires mutation.
actionFor(LegalizeAction Action,std::initializer_list<LLT> Types,LegalizeMutation Mutation)507   LegalizeRuleSet &actionFor(LegalizeAction Action,
508                              std::initializer_list<LLT> Types,
509                              LegalizeMutation Mutation) {
510     using namespace LegalityPredicates;
511     return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
512   }
513   /// Use the given action when type indexes 0 and 1 is any type pair in the
514   /// given list.
515   /// Action should not be an action that requires mutation.
actionFor(LegalizeAction Action,std::initializer_list<std::pair<LLT,LLT>> Types)516   LegalizeRuleSet &actionFor(LegalizeAction Action,
517                              std::initializer_list<std::pair<LLT, LLT>> Types) {
518     using namespace LegalityPredicates;
519     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
520   }
521 
522   LegalizeRuleSet &
actionFor(LegalizeAction Action,std::initializer_list<std::tuple<LLT,LLT,LLT>> Types)523   actionFor(LegalizeAction Action,
524             std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
525     using namespace LegalityPredicates;
526     return actionIf(Action,
527                     typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
528   }
529 
530   /// Use the given action when type indexes 0 and 1 is any type pair in the
531   /// given list.
532   /// Action should be an action that requires mutation.
actionFor(LegalizeAction Action,std::initializer_list<std::pair<LLT,LLT>> Types,LegalizeMutation Mutation)533   LegalizeRuleSet &actionFor(LegalizeAction Action,
534                              std::initializer_list<std::pair<LLT, LLT>> Types,
535                              LegalizeMutation Mutation) {
536     using namespace LegalityPredicates;
537     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
538                     Mutation);
539   }
540   /// Use the given action when type index 0 is any type in the given list and
541   /// imm index 0 is anything. Action should not be an action that requires
542   /// mutation.
actionForTypeWithAnyImm(LegalizeAction Action,std::initializer_list<LLT> Types)543   LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
544                                            std::initializer_list<LLT> Types) {
545     using namespace LegalityPredicates;
546     immIdx(0); // Inform verifier imm idx 0 is handled.
547     return actionIf(Action, typeInSet(typeIdx(0), Types));
548   }
549 
actionForTypeWithAnyImm(LegalizeAction Action,std::initializer_list<std::pair<LLT,LLT>> Types)550   LegalizeRuleSet &actionForTypeWithAnyImm(
551     LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
552     using namespace LegalityPredicates;
553     immIdx(0); // Inform verifier imm idx 0 is handled.
554     return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
555   }
556 
557   /// Use the given action when type indexes 0 and 1 are both in the given list.
558   /// That is, the type pair is in the cartesian product of the list.
559   /// Action should not be an action that requires mutation.
actionForCartesianProduct(LegalizeAction Action,std::initializer_list<LLT> Types)560   LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
561                                              std::initializer_list<LLT> Types) {
562     using namespace LegalityPredicates;
563     return actionIf(Action, all(typeInSet(typeIdx(0), Types),
564                                 typeInSet(typeIdx(1), Types)));
565   }
566   /// Use the given action when type indexes 0 and 1 are both in their
567   /// respective lists.
568   /// That is, the type pair is in the cartesian product of the lists
569   /// Action should not be an action that requires mutation.
570   LegalizeRuleSet &
actionForCartesianProduct(LegalizeAction Action,std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)571   actionForCartesianProduct(LegalizeAction Action,
572                             std::initializer_list<LLT> Types0,
573                             std::initializer_list<LLT> Types1) {
574     using namespace LegalityPredicates;
575     return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
576                                 typeInSet(typeIdx(1), Types1)));
577   }
578   /// Use the given action when type indexes 0, 1, and 2 are all in their
579   /// respective lists.
580   /// That is, the type triple is in the cartesian product of the lists
581   /// Action should not be an action that requires mutation.
actionForCartesianProduct(LegalizeAction Action,std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1,std::initializer_list<LLT> Types2)582   LegalizeRuleSet &actionForCartesianProduct(
583       LegalizeAction Action, std::initializer_list<LLT> Types0,
584       std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
585     using namespace LegalityPredicates;
586     return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
587                                 all(typeInSet(typeIdx(1), Types1),
588                                     typeInSet(typeIdx(2), Types2))));
589   }
590 
591 public:
592   LegalizeRuleSet() = default;
593 
isAliasedByAnother()594   bool isAliasedByAnother() { return IsAliasedByAnother; }
setIsAliasedByAnother()595   void setIsAliasedByAnother() { IsAliasedByAnother = true; }
aliasTo(unsigned Opcode)596   void aliasTo(unsigned Opcode) {
597     assert((AliasOf == 0 || AliasOf == Opcode) &&
598            "Opcode is already aliased to another opcode");
599     assert(Rules.empty() && "Aliasing will discard rules");
600     AliasOf = Opcode;
601   }
getAlias()602   unsigned getAlias() const { return AliasOf; }
603 
immIdx(unsigned ImmIdx)604   unsigned immIdx(unsigned ImmIdx) {
605     assert(ImmIdx <= (MCOI::OPERAND_LAST_GENERIC_IMM -
606                       MCOI::OPERAND_FIRST_GENERIC_IMM) &&
607            "Imm Index is out of bounds");
608 #ifndef NDEBUG
609     ImmIdxsCovered.set(ImmIdx);
610 #endif
611     return ImmIdx;
612   }
613 
614   /// The instruction is legal if predicate is true.
legalIf(LegalityPredicate Predicate)615   LegalizeRuleSet &legalIf(LegalityPredicate Predicate) {
616     // We have no choice but conservatively assume that the free-form
617     // user-provided Predicate properly handles all type indices:
618     markAllIdxsAsCovered();
619     return actionIf(LegalizeAction::Legal, Predicate);
620   }
621   /// The instruction is legal when type index 0 is any type in the given list.
legalFor(std::initializer_list<LLT> Types)622   LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
623     return actionFor(LegalizeAction::Legal, Types);
624   }
legalFor(bool Pred,std::initializer_list<LLT> Types)625   LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
626     if (!Pred)
627       return *this;
628     return actionFor(LegalizeAction::Legal, Types);
629   }
630   /// The instruction is legal when type indexes 0 and 1 is any type pair in the
631   /// given list.
legalFor(std::initializer_list<std::pair<LLT,LLT>> Types)632   LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
633     return actionFor(LegalizeAction::Legal, Types);
634   }
legalFor(bool Pred,std::initializer_list<std::pair<LLT,LLT>> Types)635   LegalizeRuleSet &legalFor(bool Pred,
636                             std::initializer_list<std::pair<LLT, LLT>> Types) {
637     if (!Pred)
638       return *this;
639     return actionFor(LegalizeAction::Legal, Types);
640   }
641   LegalizeRuleSet &
legalFor(bool Pred,std::initializer_list<std::tuple<LLT,LLT,LLT>> Types)642   legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
643     if (!Pred)
644       return *this;
645     return actionFor(LegalizeAction::Legal, Types);
646   }
647   /// The instruction is legal when type index 0 is any type in the given list
648   /// and imm index 0 is anything.
legalForTypeWithAnyImm(std::initializer_list<LLT> Types)649   LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
650     markAllIdxsAsCovered();
651     return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
652   }
653 
legalForTypeWithAnyImm(std::initializer_list<std::pair<LLT,LLT>> Types)654   LegalizeRuleSet &legalForTypeWithAnyImm(
655     std::initializer_list<std::pair<LLT, LLT>> Types) {
656     markAllIdxsAsCovered();
657     return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
658   }
659 
660   /// The instruction is legal when type indexes 0 and 1 along with the memory
661   /// size and minimum alignment is any type and size tuple in the given list.
legalForTypesWithMemDesc(std::initializer_list<LegalityPredicates::TypePairAndMemDesc> TypesAndMemDesc)662   LegalizeRuleSet &legalForTypesWithMemDesc(
663       std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
664           TypesAndMemDesc) {
665     return actionIf(LegalizeAction::Legal,
666                     LegalityPredicates::typePairAndMemDescInSet(
667                         typeIdx(0), typeIdx(1), /*MMOIdx*/ 0, TypesAndMemDesc));
668   }
669   /// The instruction is legal when type indexes 0 and 1 are both in the given
670   /// list. That is, the type pair is in the cartesian product of the list.
legalForCartesianProduct(std::initializer_list<LLT> Types)671   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
672     return actionForCartesianProduct(LegalizeAction::Legal, Types);
673   }
674   /// The instruction is legal when type indexes 0 and 1 are both their
675   /// respective lists.
legalForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)676   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
677                                             std::initializer_list<LLT> Types1) {
678     return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
679   }
680   /// The instruction is legal when type indexes 0, 1, and 2 are both their
681   /// respective lists.
legalForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1,std::initializer_list<LLT> Types2)682   LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
683                                             std::initializer_list<LLT> Types1,
684                                             std::initializer_list<LLT> Types2) {
685     return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
686                                      Types2);
687   }
688 
alwaysLegal()689   LegalizeRuleSet &alwaysLegal() {
690     using namespace LegalizeMutations;
691     markAllIdxsAsCovered();
692     return actionIf(LegalizeAction::Legal, always);
693   }
694 
695   /// The specified type index is coerced if predicate is true.
bitcastIf(LegalityPredicate Predicate,LegalizeMutation Mutation)696   LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate,
697                              LegalizeMutation Mutation) {
698     // We have no choice but conservatively assume that lowering with a
699     // free-form user provided Predicate properly handles all type indices:
700     markAllIdxsAsCovered();
701     return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
702   }
703 
704   /// The instruction is lowered.
lower()705   LegalizeRuleSet &lower() {
706     using namespace LegalizeMutations;
707     // We have no choice but conservatively assume that predicate-less lowering
708     // properly handles all type indices by design:
709     markAllIdxsAsCovered();
710     return actionIf(LegalizeAction::Lower, always);
711   }
712   /// The instruction is lowered if predicate is true. Keep type index 0 as the
713   /// same type.
lowerIf(LegalityPredicate Predicate)714   LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) {
715     using namespace LegalizeMutations;
716     // We have no choice but conservatively assume that lowering with a
717     // free-form user provided Predicate properly handles all type indices:
718     markAllIdxsAsCovered();
719     return actionIf(LegalizeAction::Lower, Predicate);
720   }
721   /// The instruction is lowered if predicate is true.
lowerIf(LegalityPredicate Predicate,LegalizeMutation Mutation)722   LegalizeRuleSet &lowerIf(LegalityPredicate Predicate,
723                            LegalizeMutation Mutation) {
724     // We have no choice but conservatively assume that lowering with a
725     // free-form user provided Predicate properly handles all type indices:
726     markAllIdxsAsCovered();
727     return actionIf(LegalizeAction::Lower, Predicate, Mutation);
728   }
729   /// The instruction is lowered when type index 0 is any type in the given
730   /// list. Keep type index 0 as the same type.
lowerFor(std::initializer_list<LLT> Types)731   LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
732     return actionFor(LegalizeAction::Lower, Types);
733   }
734   /// The instruction is lowered when type index 0 is any type in the given
735   /// list.
lowerFor(std::initializer_list<LLT> Types,LegalizeMutation Mutation)736   LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
737                             LegalizeMutation Mutation) {
738     return actionFor(LegalizeAction::Lower, Types, Mutation);
739   }
740   /// The instruction is lowered when type indexes 0 and 1 is any type pair in
741   /// the given list. Keep type index 0 as the same type.
lowerFor(std::initializer_list<std::pair<LLT,LLT>> Types)742   LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
743     return actionFor(LegalizeAction::Lower, Types);
744   }
745   /// The instruction is lowered when type indexes 0 and 1 is any type pair in
746   /// the given list.
lowerFor(std::initializer_list<std::pair<LLT,LLT>> Types,LegalizeMutation Mutation)747   LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
748                             LegalizeMutation Mutation) {
749     return actionFor(LegalizeAction::Lower, Types, Mutation);
750   }
751   /// The instruction is lowered when type indexes 0 and 1 are both in their
752   /// respective lists.
lowerForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)753   LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
754                                             std::initializer_list<LLT> Types1) {
755     using namespace LegalityPredicates;
756     return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
757   }
758   /// The instruction is lowered when type indexes 0, 1, and 2 are all in
759   /// their respective lists.
lowerForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1,std::initializer_list<LLT> Types2)760   LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
761                                             std::initializer_list<LLT> Types1,
762                                             std::initializer_list<LLT> Types2) {
763     using namespace LegalityPredicates;
764     return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
765                                      Types2);
766   }
767 
768   /// The instruction is emitted as a library call.
libcall()769   LegalizeRuleSet &libcall() {
770     using namespace LegalizeMutations;
771     // We have no choice but conservatively assume that predicate-less lowering
772     // properly handles all type indices by design:
773     markAllIdxsAsCovered();
774     return actionIf(LegalizeAction::Libcall, always);
775   }
776 
777   /// Like legalIf, but for the Libcall action.
libcallIf(LegalityPredicate Predicate)778   LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
779     // We have no choice but conservatively assume that a libcall with a
780     // free-form user provided Predicate properly handles all type indices:
781     markAllIdxsAsCovered();
782     return actionIf(LegalizeAction::Libcall, Predicate);
783   }
libcallFor(std::initializer_list<LLT> Types)784   LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
785     return actionFor(LegalizeAction::Libcall, Types);
786   }
libcallFor(bool Pred,std::initializer_list<LLT> Types)787   LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
788     if (!Pred)
789       return *this;
790     return actionFor(LegalizeAction::Libcall, Types);
791   }
792   LegalizeRuleSet &
libcallFor(std::initializer_list<std::pair<LLT,LLT>> Types)793   libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
794     return actionFor(LegalizeAction::Libcall, Types);
795   }
796   LegalizeRuleSet &
libcallFor(bool Pred,std::initializer_list<std::pair<LLT,LLT>> Types)797   libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
798     if (!Pred)
799       return *this;
800     return actionFor(LegalizeAction::Libcall, Types);
801   }
802   LegalizeRuleSet &
libcallForCartesianProduct(std::initializer_list<LLT> Types)803   libcallForCartesianProduct(std::initializer_list<LLT> Types) {
804     return actionForCartesianProduct(LegalizeAction::Libcall, Types);
805   }
806   LegalizeRuleSet &
libcallForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)807   libcallForCartesianProduct(std::initializer_list<LLT> Types0,
808                              std::initializer_list<LLT> Types1) {
809     return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
810   }
811 
812   /// Widen the scalar to the one selected by the mutation if the predicate is
813   /// true.
widenScalarIf(LegalityPredicate Predicate,LegalizeMutation Mutation)814   LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate,
815                                  LegalizeMutation Mutation) {
816     // We have no choice but conservatively assume that an action with a
817     // free-form user provided Predicate properly handles all type indices:
818     markAllIdxsAsCovered();
819     return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
820   }
821   /// Narrow the scalar to the one selected by the mutation if the predicate is
822   /// true.
narrowScalarIf(LegalityPredicate Predicate,LegalizeMutation Mutation)823   LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate,
824                                   LegalizeMutation Mutation) {
825     // We have no choice but conservatively assume that an action with a
826     // free-form user provided Predicate properly handles all type indices:
827     markAllIdxsAsCovered();
828     return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
829   }
830   /// Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any
831   /// type pair in the given list.
832   LegalizeRuleSet &
narrowScalarFor(std::initializer_list<std::pair<LLT,LLT>> Types,LegalizeMutation Mutation)833   narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
834                   LegalizeMutation Mutation) {
835     return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
836   }
837 
838   /// Add more elements to reach the type selected by the mutation if the
839   /// predicate is true.
moreElementsIf(LegalityPredicate Predicate,LegalizeMutation Mutation)840   LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate,
841                                   LegalizeMutation Mutation) {
842     // We have no choice but conservatively assume that an action with a
843     // free-form user provided Predicate properly handles all type indices:
844     markAllIdxsAsCovered();
845     return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
846   }
847   /// Remove elements to reach the type selected by the mutation if the
848   /// predicate is true.
fewerElementsIf(LegalityPredicate Predicate,LegalizeMutation Mutation)849   LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate,
850                                    LegalizeMutation Mutation) {
851     // We have no choice but conservatively assume that an action with a
852     // free-form user provided Predicate properly handles all type indices:
853     markAllIdxsAsCovered();
854     return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
855   }
856 
857   /// The instruction is unsupported.
unsupported()858   LegalizeRuleSet &unsupported() {
859     markAllIdxsAsCovered();
860     return actionIf(LegalizeAction::Unsupported, always);
861   }
unsupportedIf(LegalityPredicate Predicate)862   LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) {
863     return actionIf(LegalizeAction::Unsupported, Predicate);
864   }
865 
unsupportedFor(std::initializer_list<LLT> Types)866   LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
867     return actionFor(LegalizeAction::Unsupported, Types);
868   }
869 
unsupportedIfMemSizeNotPow2()870   LegalizeRuleSet &unsupportedIfMemSizeNotPow2() {
871     return actionIf(LegalizeAction::Unsupported,
872                     LegalityPredicates::memSizeInBytesNotPow2(0));
873   }
874 
875   /// Lower a memory operation if the memory size, rounded to bytes, is not a
876   /// power of 2. For example, this will not trigger for s1 or s7, but will for
877   /// s24.
lowerIfMemSizeNotPow2()878   LegalizeRuleSet &lowerIfMemSizeNotPow2() {
879     return actionIf(LegalizeAction::Lower,
880                     LegalityPredicates::memSizeInBytesNotPow2(0));
881   }
882 
883   /// Lower a memory operation if the memory access size is not a round power of
884   /// 2 byte size. This is stricter than lowerIfMemSizeNotPow2, and more likely
885   /// what you want (e.g. this will lower s1, s7 and s24).
lowerIfMemSizeNotByteSizePow2()886   LegalizeRuleSet &lowerIfMemSizeNotByteSizePow2() {
887     return actionIf(LegalizeAction::Lower,
888                     LegalityPredicates::memSizeNotByteSizePow2(0));
889   }
890 
customIf(LegalityPredicate Predicate)891   LegalizeRuleSet &customIf(LegalityPredicate Predicate) {
892     // We have no choice but conservatively assume that a custom action with a
893     // free-form user provided Predicate properly handles all type indices:
894     markAllIdxsAsCovered();
895     return actionIf(LegalizeAction::Custom, Predicate);
896   }
customFor(std::initializer_list<LLT> Types)897   LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
898     return actionFor(LegalizeAction::Custom, Types);
899   }
customFor(bool Pred,std::initializer_list<LLT> Types)900   LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
901     if (!Pred)
902       return *this;
903     return actionFor(LegalizeAction::Custom, Types);
904   }
905 
906   /// The instruction is custom when type indexes 0 and 1 is any type pair in
907   /// the given list.
customFor(std::initializer_list<std::pair<LLT,LLT>> Types)908   LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
909     return actionFor(LegalizeAction::Custom, Types);
910   }
customFor(bool Pred,std::initializer_list<std::pair<LLT,LLT>> Types)911   LegalizeRuleSet &customFor(bool Pred,
912                              std::initializer_list<std::pair<LLT, LLT>> Types) {
913     if (!Pred)
914       return *this;
915     return actionFor(LegalizeAction::Custom, Types);
916   }
917 
customForCartesianProduct(std::initializer_list<LLT> Types)918   LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
919     return actionForCartesianProduct(LegalizeAction::Custom, Types);
920   }
921   /// The instruction is custom when type indexes 0 and 1 are both in their
922   /// respective lists.
923   LegalizeRuleSet &
customForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)924   customForCartesianProduct(std::initializer_list<LLT> Types0,
925                             std::initializer_list<LLT> Types1) {
926     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
927   }
928   /// The instruction is custom when type indexes 0, 1, and 2 are all in
929   /// their respective lists.
930   LegalizeRuleSet &
customForCartesianProduct(std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1,std::initializer_list<LLT> Types2)931   customForCartesianProduct(std::initializer_list<LLT> Types0,
932                             std::initializer_list<LLT> Types1,
933                             std::initializer_list<LLT> Types2) {
934     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
935                                      Types2);
936   }
937 
938   /// The instruction is custom when the predicate is true and type indexes 0
939   /// and 1 are all in their respective lists.
940   LegalizeRuleSet &
customForCartesianProduct(bool Pred,std::initializer_list<LLT> Types0,std::initializer_list<LLT> Types1)941   customForCartesianProduct(bool Pred, std::initializer_list<LLT> Types0,
942                             std::initializer_list<LLT> Types1) {
943     if (!Pred)
944       return *this;
945     return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
946   }
947 
948   /// Unconditionally custom lower.
custom()949   LegalizeRuleSet &custom() {
950     return customIf(always);
951   }
952 
953   /// Widen the scalar to the next power of two that is at least MinSize.
954   /// No effect if the type is a power of two, except if the type is smaller
955   /// than MinSize, or if the type is a vector type.
956   LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
957                                          unsigned MinSize = 0) {
958     using namespace LegalityPredicates;
959     return actionIf(
960         LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
961         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
962   }
963 
964   /// Widen the scalar to the next multiple of Size. No effect if the
965   /// type is not a scalar or is a multiple of Size.
widenScalarToNextMultipleOf(unsigned TypeIdx,unsigned Size)966   LegalizeRuleSet &widenScalarToNextMultipleOf(unsigned TypeIdx,
967                                                unsigned Size) {
968     using namespace LegalityPredicates;
969     return actionIf(
970         LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
971         LegalizeMutations::widenScalarOrEltToNextMultipleOf(TypeIdx, Size));
972   }
973 
974   /// Widen the scalar or vector element type to the next power of two that is
975   /// at least MinSize.  No effect if the scalar size is a power of two.
976   LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
977                                               unsigned MinSize = 0) {
978     using namespace LegalityPredicates;
979     return actionIf(
980         LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
981         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
982   }
983 
984   /// Widen the scalar or vector element type to the next power of two that is
985   /// at least MinSize.  No effect if the scalar size is a power of two.
986   LegalizeRuleSet &widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx,
987                                                        unsigned MinSize = 0) {
988     using namespace LegalityPredicates;
989     return actionIf(
990         LegalizeAction::WidenScalar,
991         any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
992             scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
993         LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
994   }
995 
narrowScalar(unsigned TypeIdx,LegalizeMutation Mutation)996   LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
997     using namespace LegalityPredicates;
998     return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
999                     Mutation);
1000   }
1001 
scalarize(unsigned TypeIdx)1002   LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1003     using namespace LegalityPredicates;
1004     return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1005                     LegalizeMutations::scalarize(TypeIdx));
1006   }
1007 
scalarizeIf(LegalityPredicate Predicate,unsigned TypeIdx)1008   LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
1009     using namespace LegalityPredicates;
1010     return actionIf(LegalizeAction::FewerElements,
1011                     all(Predicate, isVector(typeIdx(TypeIdx))),
1012                     LegalizeMutations::scalarize(TypeIdx));
1013   }
1014 
1015   /// Ensure the scalar or element is at least as wide as Ty.
minScalarOrElt(unsigned TypeIdx,const LLT Ty)1016   LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1017     using namespace LegalityPredicates;
1018     using namespace LegalizeMutations;
1019     return actionIf(LegalizeAction::WidenScalar,
1020                     scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1021                     changeElementTo(typeIdx(TypeIdx), Ty));
1022   }
1023 
1024   /// Ensure the scalar or element is at least as wide as Ty.
minScalarOrEltIf(LegalityPredicate Predicate,unsigned TypeIdx,const LLT Ty)1025   LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate,
1026                                     unsigned TypeIdx, const LLT Ty) {
1027     using namespace LegalityPredicates;
1028     using namespace LegalizeMutations;
1029     return actionIf(LegalizeAction::WidenScalar,
1030                     all(Predicate, scalarOrEltNarrowerThan(
1031                                        TypeIdx, Ty.getScalarSizeInBits())),
1032                     changeElementTo(typeIdx(TypeIdx), Ty));
1033   }
1034 
1035   /// Ensure the vector size is at least as wide as VectorSize by promoting the
1036   /// element.
widenVectorEltsToVectorMinSize(unsigned TypeIdx,unsigned VectorSize)1037   LegalizeRuleSet &widenVectorEltsToVectorMinSize(unsigned TypeIdx,
1038                                                   unsigned VectorSize) {
1039     using namespace LegalityPredicates;
1040     using namespace LegalizeMutations;
1041     return actionIf(
1042         LegalizeAction::WidenScalar,
1043         [=](const LegalityQuery &Query) {
1044           const LLT VecTy = Query.Types[TypeIdx];
1045           return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1046         },
1047         [=](const LegalityQuery &Query) {
1048           const LLT VecTy = Query.Types[TypeIdx];
1049           unsigned NumElts = VecTy.getNumElements();
1050           unsigned MinSize = VectorSize / NumElts;
1051           LLT NewTy = LLT::fixed_vector(NumElts, LLT::scalar(MinSize));
1052           return std::make_pair(TypeIdx, NewTy);
1053         });
1054   }
1055 
1056   /// Ensure the scalar is at least as wide as Ty.
minScalar(unsigned TypeIdx,const LLT Ty)1057   LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1058     using namespace LegalityPredicates;
1059     using namespace LegalizeMutations;
1060     return actionIf(LegalizeAction::WidenScalar,
1061                     scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1062                     changeTo(typeIdx(TypeIdx), Ty));
1063   }
minScalar(bool Pred,unsigned TypeIdx,const LLT Ty)1064   LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1065     if (!Pred)
1066       return *this;
1067     return minScalar(TypeIdx, Ty);
1068   }
1069 
1070   /// Ensure the scalar is at least as wide as Ty if condition is met.
minScalarIf(LegalityPredicate Predicate,unsigned TypeIdx,const LLT Ty)1071   LegalizeRuleSet &minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
1072                                const LLT Ty) {
1073     using namespace LegalityPredicates;
1074     using namespace LegalizeMutations;
1075     return actionIf(
1076         LegalizeAction::WidenScalar,
1077         [=](const LegalityQuery &Query) {
1078           const LLT QueryTy = Query.Types[TypeIdx];
1079           return QueryTy.isScalar() &&
1080                  QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1081                  Predicate(Query);
1082         },
1083         changeTo(typeIdx(TypeIdx), Ty));
1084   }
1085 
1086   /// Ensure the scalar is at most as wide as Ty.
maxScalarOrElt(unsigned TypeIdx,const LLT Ty)1087   LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1088     using namespace LegalityPredicates;
1089     using namespace LegalizeMutations;
1090     return actionIf(LegalizeAction::NarrowScalar,
1091                     scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1092                     changeElementTo(typeIdx(TypeIdx), Ty));
1093   }
1094 
1095   /// Ensure the scalar is at most as wide as Ty.
maxScalar(unsigned TypeIdx,const LLT Ty)1096   LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1097     using namespace LegalityPredicates;
1098     using namespace LegalizeMutations;
1099     return actionIf(LegalizeAction::NarrowScalar,
1100                     scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1101                     changeTo(typeIdx(TypeIdx), Ty));
1102   }
1103 
1104   /// Conditionally limit the maximum size of the scalar.
1105   /// For example, when the maximum size of one type depends on the size of
1106   /// another such as extracting N bits from an M bit container.
maxScalarIf(LegalityPredicate Predicate,unsigned TypeIdx,const LLT Ty)1107   LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
1108                                const LLT Ty) {
1109     using namespace LegalityPredicates;
1110     using namespace LegalizeMutations;
1111     return actionIf(
1112         LegalizeAction::NarrowScalar,
1113         [=](const LegalityQuery &Query) {
1114           const LLT QueryTy = Query.Types[TypeIdx];
1115           return QueryTy.isScalar() &&
1116                  QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1117                  Predicate(Query);
1118         },
1119         changeElementTo(typeIdx(TypeIdx), Ty));
1120   }
1121 
1122   /// Limit the range of scalar sizes to MinTy and MaxTy.
clampScalar(unsigned TypeIdx,const LLT MinTy,const LLT MaxTy)1123   LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1124                                const LLT MaxTy) {
1125     assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1126     return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1127   }
1128 
clampScalar(bool Pred,unsigned TypeIdx,const LLT MinTy,const LLT MaxTy)1129   LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1130                                const LLT MaxTy) {
1131     if (!Pred)
1132       return *this;
1133     return clampScalar(TypeIdx, MinTy, MaxTy);
1134   }
1135 
1136   /// Limit the range of scalar sizes to MinTy and MaxTy.
clampScalarOrElt(unsigned TypeIdx,const LLT MinTy,const LLT MaxTy)1137   LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1138                                     const LLT MaxTy) {
1139     return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1140   }
1141 
1142   /// Widen the scalar to match the size of another.
minScalarSameAs(unsigned TypeIdx,unsigned LargeTypeIdx)1143   LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1144     typeIdx(TypeIdx);
1145     return actionIf(
1146         LegalizeAction::WidenScalar,
1147         [=](const LegalityQuery &Query) {
1148           return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1149                  Query.Types[TypeIdx].getSizeInBits();
1150         },
1151         LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1152   }
1153 
1154   /// Narrow the scalar to match the size of another.
maxScalarSameAs(unsigned TypeIdx,unsigned NarrowTypeIdx)1155   LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1156     typeIdx(TypeIdx);
1157     return actionIf(
1158         LegalizeAction::NarrowScalar,
1159         [=](const LegalityQuery &Query) {
1160           return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1161                  Query.Types[TypeIdx].getSizeInBits();
1162         },
1163         LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1164   }
1165 
1166   /// Change the type \p TypeIdx to have the same scalar size as type \p
1167   /// SameSizeIdx.
scalarSameSizeAs(unsigned TypeIdx,unsigned SameSizeIdx)1168   LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1169     return minScalarSameAs(TypeIdx, SameSizeIdx)
1170           .maxScalarSameAs(TypeIdx, SameSizeIdx);
1171   }
1172 
1173   /// Conditionally widen the scalar or elt to match the size of another.
minScalarEltSameAsIf(LegalityPredicate Predicate,unsigned TypeIdx,unsigned LargeTypeIdx)1174   LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate,
1175                                    unsigned TypeIdx, unsigned LargeTypeIdx) {
1176     typeIdx(TypeIdx);
1177     return widenScalarIf(
1178         [=](const LegalityQuery &Query) {
1179           return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1180                      Query.Types[TypeIdx].getScalarSizeInBits() &&
1181                  Predicate(Query);
1182         },
1183         [=](const LegalityQuery &Query) {
1184           LLT T = Query.Types[LargeTypeIdx];
1185           if (T.isPointerVector())
1186             T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits()));
1187           return std::make_pair(TypeIdx, T);
1188         });
1189   }
1190 
1191   /// Conditionally narrow the scalar or elt to match the size of another.
maxScalarEltSameAsIf(LegalityPredicate Predicate,unsigned TypeIdx,unsigned SmallTypeIdx)1192   LegalizeRuleSet &maxScalarEltSameAsIf(LegalityPredicate Predicate,
1193                                         unsigned TypeIdx,
1194                                         unsigned SmallTypeIdx) {
1195     typeIdx(TypeIdx);
1196     return narrowScalarIf(
1197         [=](const LegalityQuery &Query) {
1198           return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1199                      Query.Types[TypeIdx].getScalarSizeInBits() &&
1200                  Predicate(Query);
1201         },
1202         [=](const LegalityQuery &Query) {
1203           LLT T = Query.Types[SmallTypeIdx];
1204           return std::make_pair(TypeIdx, T);
1205         });
1206   }
1207 
1208   /// Add more elements to the vector to reach the next power of two.
1209   /// No effect if the type is not a vector or the element count is a power of
1210   /// two.
moreElementsToNextPow2(unsigned TypeIdx)1211   LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) {
1212     using namespace LegalityPredicates;
1213     return actionIf(LegalizeAction::MoreElements,
1214                     numElementsNotPow2(typeIdx(TypeIdx)),
1215                     LegalizeMutations::moreElementsToNextPow2(TypeIdx));
1216   }
1217 
1218   /// Limit the number of elements in EltTy vectors to at least MinElements.
clampMinNumElements(unsigned TypeIdx,const LLT EltTy,unsigned MinElements)1219   LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1220                                        unsigned MinElements) {
1221     // Mark the type index as covered:
1222     typeIdx(TypeIdx);
1223     return actionIf(
1224         LegalizeAction::MoreElements,
1225         [=](const LegalityQuery &Query) {
1226           LLT VecTy = Query.Types[TypeIdx];
1227           return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1228                  VecTy.getNumElements() < MinElements;
1229         },
1230         [=](const LegalityQuery &Query) {
1231           LLT VecTy = Query.Types[TypeIdx];
1232           return std::make_pair(
1233               TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1234         });
1235   }
1236 
1237   /// Set number of elements to nearest larger multiple of NumElts.
alignNumElementsTo(unsigned TypeIdx,const LLT EltTy,unsigned NumElts)1238   LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1239                                       unsigned NumElts) {
1240     typeIdx(TypeIdx);
1241     return actionIf(
1242         LegalizeAction::MoreElements,
1243         [=](const LegalityQuery &Query) {
1244           LLT VecTy = Query.Types[TypeIdx];
1245           return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1246                  (VecTy.getNumElements() % NumElts != 0);
1247         },
1248         [=](const LegalityQuery &Query) {
1249           LLT VecTy = Query.Types[TypeIdx];
1250           unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1251           return std::make_pair(
1252               TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1253         });
1254   }
1255 
1256   /// Limit the number of elements in EltTy vectors to at most MaxElements.
clampMaxNumElements(unsigned TypeIdx,const LLT EltTy,unsigned MaxElements)1257   LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1258                                        unsigned MaxElements) {
1259     // Mark the type index as covered:
1260     typeIdx(TypeIdx);
1261     return actionIf(
1262         LegalizeAction::FewerElements,
1263         [=](const LegalityQuery &Query) {
1264           LLT VecTy = Query.Types[TypeIdx];
1265           return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1266                  VecTy.getNumElements() > MaxElements;
1267         },
1268         [=](const LegalityQuery &Query) {
1269           LLT VecTy = Query.Types[TypeIdx];
1270           LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1271                                           VecTy.getElementType());
1272           return std::make_pair(TypeIdx, NewTy);
1273         });
1274   }
1275   /// Limit the number of elements for the given vectors to at least MinTy's
1276   /// number of elements and at most MaxTy's number of elements.
1277   ///
1278   /// No effect if the type is not a vector or does not have the same element
1279   /// type as the constraints.
1280   /// The element type of MinTy and MaxTy must match.
clampNumElements(unsigned TypeIdx,const LLT MinTy,const LLT MaxTy)1281   LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1282                                     const LLT MaxTy) {
1283     assert(MinTy.getElementType() == MaxTy.getElementType() &&
1284            "Expected element types to agree");
1285 
1286     assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1287            "Unexpected scalable vectors");
1288 
1289     const LLT EltTy = MinTy.getElementType();
1290     return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1291         .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1292   }
1293 
1294   /// Express \p EltTy vectors strictly using vectors with \p NumElts elements
1295   /// (or scalars when \p NumElts equals 1).
1296   /// First pad with undef elements to nearest larger multiple of \p NumElts.
1297   /// Then perform split with all sub-instructions having the same type.
1298   /// Using clampMaxNumElements (non-strict) can result in leftover instruction
1299   /// with different type (fewer elements then \p NumElts or scalar).
1300   /// No effect if the type is not a vector.
clampMaxNumElementsStrict(unsigned TypeIdx,const LLT EltTy,unsigned NumElts)1301   LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1302                                              unsigned NumElts) {
1303     return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1304         .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1305   }
1306 
1307   /// Fallback on the previous implementation. This should only be used while
1308   /// porting a rule.
fallback()1309   LegalizeRuleSet &fallback() {
1310     add({always, LegalizeAction::UseLegacyRules});
1311     return *this;
1312   }
1313 
1314   /// Check if there is no type index which is obviously not handled by the
1315   /// LegalizeRuleSet in any way at all.
1316   /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1317   LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1318   /// Check if there is no imm index which is obviously not handled by the
1319   /// LegalizeRuleSet in any way at all.
1320   /// \pre Type indices of the opcode form a dense [0, \p NumTypeIdxs) set.
1321   LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1322 
1323   /// Apply the ruleset to the given LegalityQuery.
1324   LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const;
1325 };
1326 
1327 class LLVM_ABI LegalizerInfo {
1328 public:
1329   virtual ~LegalizerInfo() = default;
1330 
getLegacyLegalizerInfo()1331   const LegacyLegalizerInfo &getLegacyLegalizerInfo() const {
1332     return LegacyInfo;
1333   }
getLegacyLegalizerInfo()1334   LegacyLegalizerInfo &getLegacyLegalizerInfo() { return LegacyInfo; }
1335 
1336   unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1337   unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1338 
1339   /// Perform simple self-diagnostic and assert if there is anything obviously
1340   /// wrong with the actions set up.
1341   void verify(const MCInstrInfo &MII) const;
1342 
1343   /// Get the action definitions for the given opcode. Use this to run a
1344   /// LegalityQuery through the definitions.
1345   const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1346 
1347   /// Get the action definition builder for the given opcode. Use this to define
1348   /// the action definitions.
1349   ///
1350   /// It is an error to request an opcode that has already been requested by the
1351   /// multiple-opcode variant.
1352   LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
1353 
1354   /// Get the action definition builder for the given set of opcodes. Use this
1355   /// to define the action definitions for multiple opcodes at once. The first
1356   /// opcode given will be considered the representative opcode and will hold
1357   /// the definitions whereas the other opcodes will be configured to refer to
1358   /// the representative opcode. This lowers memory requirements and very
1359   /// slightly improves performance.
1360   ///
1361   /// It would be very easy to introduce unexpected side-effects as a result of
1362   /// this aliasing if it were permitted to request different but intersecting
1363   /// sets of opcodes but that is difficult to keep track of. It is therefore an
1364   /// error to request the same opcode twice using this API, to request an
1365   /// opcode that already has definitions, or to use the single-opcode API on an
1366   /// opcode that has already been requested by this API.
1367   LegalizeRuleSet &
1368   getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1369   void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1370 
1371   /// Determine what action should be taken to legalize the described
1372   /// instruction. Requires computeTables to have been called.
1373   ///
1374   /// \returns a description of the next legalization step to perform.
1375   LegalizeActionStep getAction(const LegalityQuery &Query) const;
1376 
1377   /// Determine what action should be taken to legalize the given generic
1378   /// instruction.
1379   ///
1380   /// \returns a description of the next legalization step to perform.
1381   LegalizeActionStep getAction(const MachineInstr &MI,
1382                                const MachineRegisterInfo &MRI) const;
1383 
isLegal(const LegalityQuery & Query)1384   bool isLegal(const LegalityQuery &Query) const {
1385     return getAction(Query).Action == LegalizeAction::Legal;
1386   }
1387 
isLegalOrCustom(const LegalityQuery & Query)1388   bool isLegalOrCustom(const LegalityQuery &Query) const {
1389     auto Action = getAction(Query).Action;
1390     return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1391   }
1392 
1393   bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1394   bool isLegalOrCustom(const MachineInstr &MI,
1395                        const MachineRegisterInfo &MRI) const;
1396 
1397   /// Called for instructions with the Custom LegalizationAction.
legalizeCustom(LegalizerHelper & Helper,MachineInstr & MI,LostDebugLocObserver & LocObserver)1398   virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
1399                               LostDebugLocObserver &LocObserver) const {
1400     llvm_unreachable("must implement this if custom action is used");
1401   }
1402 
1403   /// \returns true if MI is either legal or has been legalized and false if not
1404   /// legal.
1405   /// Return true if MI is either legal or has been legalized and false
1406   /// if not legal.
legalizeIntrinsic(LegalizerHelper & Helper,MachineInstr & MI)1407   virtual bool legalizeIntrinsic(LegalizerHelper &Helper,
1408                                  MachineInstr &MI) const {
1409     return true;
1410   }
1411 
1412   /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1413   /// widening a constant of type SmallTy which targets can override.
1414   /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1415   /// will be the default.
1416   virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1417 
1418 private:
1419   static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1420   static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1421 
1422   LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1423   LegacyLegalizerInfo LegacyInfo;
1424 };
1425 
1426 #ifndef NDEBUG
1427 /// Checks that MIR is fully legal, returns an illegal instruction if it's not,
1428 /// nullptr otherwise
1429 const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1430 #endif
1431 
1432 } // end namespace llvm.
1433 
1434 #endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
1435