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