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