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