LLVM 22.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;
39class LostDebugLocObserver;
40class MachineInstr;
41class MachineRegisterInfo;
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
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 {
119
120 MemDesc() = default;
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.
131
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.
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{}.
149
150 LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
151 const LLT NewType)
153
155 : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
156 switch (Step.Action) {
159 break;
162 break;
165 break;
168 break;
171 break;
174 break;
177 break;
180 break;
183 break;
186 break;
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
199using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
201 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
202
203namespace LegalityPredicates {
209
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).
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.
227template <typename Predicate> Predicate predNot(Predicate P) {
228 return [=](const LegalityQuery &Query) { return !P(Query); };
229}
230
231/// True iff P0 and P1 are true.
232template<typename Predicate>
234 return [=](const LegalityQuery &Query) {
235 return P0(Query) && P1(Query);
236 };
237}
238/// True iff all given predicates are true.
239template<typename Predicate, typename... Args>
241 return all(all(P0, P1), args...);
242}
243
244/// True iff P0 or P1 are true.
245template<typename Predicate>
247 return [=](const LegalityQuery &Query) {
248 return P0(Query) || P1(Query);
249 };
250}
251/// True iff any given predicates are true.
252template<typename Predicate, typename... Args>
254 return any(any(P0, P1), args...);
255}
256
257/// True iff the given type index is the specified type.
258LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
259/// True iff the given type index is one of the specified types.
260LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx,
261 std::initializer_list<LLT> TypesInit);
262
263/// True iff the given type index is not the specified type.
264inline 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.
273typePairInSet(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.
278typeTupleInSet(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.
283 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
284 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
285/// True iff the specified type index is a scalar.
286LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx);
287/// True iff the specified type index is a vector.
288LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx);
289/// True iff the specified type index is a pointer (with any address space).
290LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx);
291/// True iff the specified type index is a pointer with the specified address
292/// space.
293LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
294/// True iff the specified type index is a vector of pointers (with any address
295/// space).
297
298/// True if the type index is a vector with element type \p EltTy
299LLVM_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.
303LLVM_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.
307LLVM_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.
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.
317 unsigned Size);
318
319/// True iff the specified type index is a scalar whose size is not a multiple
320/// of Size.
321LLVM_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.
325LLVM_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.
330
331/// True if the total bitwidth of the specified type index is \p Size bits.
332LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
333
334/// True iff the specified type indices are both the same bit size.
335LLVM_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.
339LLVM_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.
343LLVM_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.
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.
352
353/// True iff the specified type index is a vector whose element count is not a
354/// power of 2.
356/// True iff the specified MMO index has at an atomic ordering of at Ordering or
357/// stronger.
359atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering);
360} // end namespace LegalityPredicates
361
362namespace LegalizeMutations {
363/// Select this specific type for the given type index.
364LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
365
366/// Keep the same type as the given type index.
367LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
368
369/// Keep the same scalar or element type as the given type index.
371 unsigned FromTypeIdx);
372
373/// Keep the same scalar or element type as the given type.
374LLVM_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.
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.
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.
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.
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.
399 unsigned Size);
400
401/// Add more elements to the type for the given type index to the next power of
402/// 2.
404 unsigned Min = 0);
405/// Break up the vector type for the given type index into the element type.
406LLVM_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.
415 LegalizeAction Action;
416 LegalizeMutation Mutation;
417
418public:
420 LegalizeMutation Mutation = nullptr)
421 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
422
423 /// Test whether the LegalityQuery matches.
424 bool match(const LegalityQuery &Query) const {
425 return Predicate(Query);
426 }
427
428 LegalizeAction getAction() const { return Action; }
429
430 /// Determine the change to make.
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
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;
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.
457#endif
458
459 unsigned typeIdx(unsigned TypeIdx) {
460 assert(TypeIdx <=
462 "Type Index is out of bounds");
463#ifndef NDEBUG
464 TypeIdxsCovered.set(TypeIdx);
465#endif
466 return TypeIdx;
467 }
468
469 void markAllIdxsAsCovered() {
470#ifndef NDEBUG
471 TypeIdxsCovered.set();
472 ImmIdxsCovered.set();
473#endif
474 }
475
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
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.
486 LegalizeRuleSet &actionIf(LegalizeAction Action,
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.
493 LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
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.
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.
507 LegalizeRuleSet &actionFor(LegalizeAction Action,
508 std::initializer_list<LLT> Types,
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.
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
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.
533 LegalizeRuleSet &actionFor(LegalizeAction Action,
534 std::initializer_list<std::pair<LLT, LLT>> Types,
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.
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
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.
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.
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.
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
591public:
592 LegalizeRuleSet() = default;
593
594 bool isAliasedByAnother() { return IsAliasedByAnother; }
595 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
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 }
602 unsigned getAlias() const { return AliasOf; }
603
604 unsigned immIdx(unsigned ImmIdx) {
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.
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.
622 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
623 return actionFor(LegalizeAction::Legal, Types);
624 }
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.
632 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
633 return actionFor(LegalizeAction::Legal, Types);
634 }
636 std::initializer_list<std::pair<LLT, LLT>> Types) {
637 if (!Pred)
638 return *this;
639 return actionFor(LegalizeAction::Legal, Types);
640 }
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.
649 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
650 markAllIdxsAsCovered();
651 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
652 }
653
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.
663 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
664 TypesAndMemDesc) {
665 return actionIf(LegalizeAction::Legal,
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
736 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
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.
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.
747 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
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.
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.
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.
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.
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 }
784 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
785 return actionFor(LegalizeAction::Libcall, Types);
786 }
787 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
788 if (!Pred)
789 return *this;
790 return actionFor(LegalizeAction::Libcall, Types);
791 }
793 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
794 return actionFor(LegalizeAction::Libcall, Types);
795 }
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 }
803 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
804 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
805 }
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.
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.
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.
833 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
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.
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.
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.
859 markAllIdxsAsCovered();
860 return actionIf(LegalizeAction::Unsupported, always);
861 }
863 return actionIf(LegalizeAction::Unsupported, Predicate);
864 }
865
866 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
867 return actionFor(LegalizeAction::Unsupported, Types);
868 }
869
871 return actionIf(LegalizeAction::Unsupported,
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.
879 return actionIf(LegalizeAction::Lower,
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).
887 return actionIf(LegalizeAction::Lower,
889 }
890
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 }
897 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
898 return actionFor(LegalizeAction::Custom, Types);
899 }
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.
908 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
909 return actionFor(LegalizeAction::Custom, Types);
910 }
912 std::initializer_list<std::pair<LLT, LLT>> Types) {
913 if (!Pred)
914 return *this;
915 return actionFor(LegalizeAction::Custom, Types);
916 }
917
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.
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.
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.
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.
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.
957 unsigned MinSize = 0) {
958 using namespace LegalityPredicates;
959 return actionIf(
960 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
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.
967 unsigned Size) {
968 using namespace LegalityPredicates;
969 return actionIf(
970 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(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.
977 unsigned MinSize = 0) {
978 using namespace LegalityPredicates;
979 return actionIf(
980 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
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.
987 unsigned MinSize = 0) {
988 using namespace LegalityPredicates;
989 return actionIf(
990 LegalizeAction::WidenScalar,
991 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
992 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
994 }
995
997 using namespace LegalityPredicates;
998 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
999 Mutation);
1000 }
1001
1002 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
1003 using namespace LegalityPredicates;
1004 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1006 }
1007
1009 using namespace LegalityPredicates;
1010 return actionIf(LegalizeAction::FewerElements,
1011 all(Predicate, isVector(typeIdx(TypeIdx))),
1013 }
1014
1015 /// Ensure the scalar or element is at least as wide as 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.
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.
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.
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 }
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
1212 using namespace LegalityPredicates;
1213 return actionIf(LegalizeAction::MoreElements,
1214 numElementsNotPow2(typeIdx(TypeIdx)),
1216 }
1217
1218 /// Limit the number of elements in EltTy vectors to at least 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.
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.
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.
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.
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.
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
1328public:
1329 virtual ~LegalizerInfo() = default;
1330
1332 return LegacyInfo;
1333 }
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.
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
1384 bool isLegal(const LegalityQuery &Query) const {
1385 return getAction(Query).Action == LegalizeAction::Legal;
1386 }
1387
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.
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.
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
1418private:
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
1429const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1430#endif
1431
1432} // end namespace llvm.
1433
1434#endif // LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Atomic ordering constants.
#define LLVM_ABI
Definition: Compiler.h:213
Given that RA is a live value
uint64_t Size
ELFYAML::ELF_REL Type2
Definition: ELFYAML.cpp:1850
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.
nvptx lower args
#define P(N)
ppc ctr loops verify
PowerPC VSX FMA Mutation
raw_pwrite_stream & OS
This file implements the SmallBitVector class.
This file defines the SmallVector class.
Value * RHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:312
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:182
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:265
constexpr bool isScalar() const
Definition: LowLevelType.h:147
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:43
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:160
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:191
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:278
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:101
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Definition: LowLevelType.h:178
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
Definition: LowLevelType.h:125
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 & 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 & 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 & 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 & 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
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:27
Representation of each machine instruction.
Definition: MachineInstr.h:72
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 ...
SmallBitVector & set()
bool empty() const
Definition: SmallVector.h:82
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
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.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Unsupported
This operation is completely unsupported on the target.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ 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.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
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 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 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 ...
Definition: LegalizerInfo.h:66
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:48
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:84
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:92
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:79
@ UseLegacyRules
Fall back onto the old rules.
Definition: LegalizerInfo.h:99
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:58
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegalizerInfo.h:75
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
Definition: LegalizerInfo.h:53
@ Custom
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:88
@ NotFound
Sentinel value for when no action was found in the specified table.
Definition: LegalizerInfo.h:95
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
Definition: LegalizerInfo.h:72
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
template class LLVM_TEMPLATE_ABI opt< bool >
Definition: CommandLine.cpp:79
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MaybeAlign getAlign(const CallInst &I, unsigned Index)
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:312
std::function< bool(const LegalityQuery &)> LegalityPredicate
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
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)
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