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