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