File indexing completed on 2026-05-10 08:43:25
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
0015 #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
0016
0017 #include "llvm/ADT/SmallBitVector.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h"
0020 #include "llvm/CodeGen/MachineMemOperand.h"
0021 #include "llvm/CodeGen/TargetOpcodes.h"
0022 #include "llvm/CodeGenTypes/LowLevelType.h"
0023 #include "llvm/MC/MCInstrDesc.h"
0024 #include "llvm/Support/AtomicOrdering.h"
0025 #include "llvm/Support/CommandLine.h"
0026 #include <cassert>
0027 #include <cstdint>
0028 #include <tuple>
0029 #include <utility>
0030
0031 namespace llvm {
0032
0033 extern cl::opt<bool> DisableGISelLegalityCheck;
0034
0035 class MachineFunction;
0036 class raw_ostream;
0037 class LegalizerHelper;
0038 class LostDebugLocObserver;
0039 class MachineInstr;
0040 class MachineRegisterInfo;
0041 class MCInstrInfo;
0042
0043 namespace LegalizeActions {
0044 enum LegalizeAction : std::uint8_t {
0045
0046
0047 Legal,
0048
0049
0050
0051
0052 NarrowScalar,
0053
0054
0055
0056
0057 WidenScalar,
0058
0059
0060
0061
0062
0063
0064
0065 FewerElements,
0066
0067
0068
0069
0070
0071 MoreElements,
0072
0073
0074 Bitcast,
0075
0076
0077
0078 Lower,
0079
0080
0081
0082
0083 Libcall,
0084
0085
0086
0087 Custom,
0088
0089
0090
0091 Unsupported,
0092
0093
0094 NotFound,
0095
0096
0097
0098 UseLegacyRules,
0099 };
0100 }
0101 raw_ostream &operator<<(raw_ostream &OS, LegalizeActions::LegalizeAction Action);
0102
0103 using LegalizeActions::LegalizeAction;
0104
0105
0106
0107
0108
0109 struct LegalityQuery {
0110 unsigned Opcode;
0111 ArrayRef<LLT> Types;
0112
0113 struct MemDesc {
0114 LLT MemoryTy;
0115 uint64_t AlignInBits;
0116 AtomicOrdering Ordering;
0117
0118 MemDesc() = default;
0119 MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering)
0120 : MemoryTy(MemoryTy), AlignInBits(AlignInBits), Ordering(Ordering) {}
0121 MemDesc(const MachineMemOperand &MMO)
0122 : MemoryTy(MMO.getMemoryType()),
0123 AlignInBits(MMO.getAlign().value() * 8),
0124 Ordering(MMO.getSuccessOrdering()) {}
0125 };
0126
0127
0128
0129 ArrayRef<MemDesc> MMODescrs;
0130
0131 constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types,
0132 const ArrayRef<MemDesc> MMODescrs)
0133 : Opcode(Opcode), Types(Types), MMODescrs(MMODescrs) {}
0134 constexpr LegalityQuery(unsigned Opcode, const ArrayRef<LLT> Types)
0135 : LegalityQuery(Opcode, Types, {}) {}
0136
0137 raw_ostream &print(raw_ostream &OS) const;
0138 };
0139
0140
0141
0142
0143 struct LegalizeActionStep {
0144
0145 LegalizeAction Action;
0146
0147 unsigned TypeIdx;
0148
0149 LLT NewType;
0150
0151 LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
0152 const LLT NewType)
0153 : Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
0154
0155 LegalizeActionStep(LegacyLegalizeActionStep Step)
0156 : TypeIdx(Step.TypeIdx), NewType(Step.NewType) {
0157 switch (Step.Action) {
0158 case LegacyLegalizeActions::Legal:
0159 Action = LegalizeActions::Legal;
0160 break;
0161 case LegacyLegalizeActions::NarrowScalar:
0162 Action = LegalizeActions::NarrowScalar;
0163 break;
0164 case LegacyLegalizeActions::WidenScalar:
0165 Action = LegalizeActions::WidenScalar;
0166 break;
0167 case LegacyLegalizeActions::FewerElements:
0168 Action = LegalizeActions::FewerElements;
0169 break;
0170 case LegacyLegalizeActions::MoreElements:
0171 Action = LegalizeActions::MoreElements;
0172 break;
0173 case LegacyLegalizeActions::Bitcast:
0174 Action = LegalizeActions::Bitcast;
0175 break;
0176 case LegacyLegalizeActions::Lower:
0177 Action = LegalizeActions::Lower;
0178 break;
0179 case LegacyLegalizeActions::Libcall:
0180 Action = LegalizeActions::Libcall;
0181 break;
0182 case LegacyLegalizeActions::Custom:
0183 Action = LegalizeActions::Custom;
0184 break;
0185 case LegacyLegalizeActions::Unsupported:
0186 Action = LegalizeActions::Unsupported;
0187 break;
0188 case LegacyLegalizeActions::NotFound:
0189 Action = LegalizeActions::NotFound;
0190 break;
0191 }
0192 }
0193
0194 bool operator==(const LegalizeActionStep &RHS) const {
0195 return std::tie(Action, TypeIdx, NewType) ==
0196 std::tie(RHS.Action, RHS.TypeIdx, RHS.NewType);
0197 }
0198 };
0199
0200 using LegalityPredicate = std::function<bool (const LegalityQuery &)>;
0201 using LegalizeMutation =
0202 std::function<std::pair<unsigned, LLT>(const LegalityQuery &)>;
0203
0204 namespace LegalityPredicates {
0205 struct TypePairAndMemDesc {
0206 LLT Type0;
0207 LLT Type1;
0208 LLT MemTy;
0209 uint64_t Align;
0210
0211 bool operator==(const TypePairAndMemDesc &Other) const {
0212 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
0213 Align == Other.Align && MemTy == Other.MemTy;
0214 }
0215
0216
0217
0218 bool isCompatible(const TypePairAndMemDesc &Other) const {
0219 return Type0 == Other.Type0 && Type1 == Other.Type1 &&
0220 Align >= Other.Align &&
0221
0222
0223 MemTy.getSizeInBits() == Other.MemTy.getSizeInBits();
0224 }
0225 };
0226
0227
0228 template <typename Predicate> Predicate predNot(Predicate P) {
0229 return [=](const LegalityQuery &Query) { return !P(Query); };
0230 }
0231
0232
0233 template<typename Predicate>
0234 Predicate all(Predicate P0, Predicate P1) {
0235 return [=](const LegalityQuery &Query) {
0236 return P0(Query) && P1(Query);
0237 };
0238 }
0239
0240 template<typename Predicate, typename... Args>
0241 Predicate all(Predicate P0, Predicate P1, Args... args) {
0242 return all(all(P0, P1), args...);
0243 }
0244
0245
0246 template<typename Predicate>
0247 Predicate any(Predicate P0, Predicate P1) {
0248 return [=](const LegalityQuery &Query) {
0249 return P0(Query) || P1(Query);
0250 };
0251 }
0252
0253 template<typename Predicate, typename... Args>
0254 Predicate any(Predicate P0, Predicate P1, Args... args) {
0255 return any(any(P0, P1), args...);
0256 }
0257
0258
0259 LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
0260
0261 LegalityPredicate typeInSet(unsigned TypeIdx,
0262 std::initializer_list<LLT> TypesInit);
0263
0264
0265 inline LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type) {
0266 return [=](const LegalityQuery &Query) {
0267 return Query.Types[TypeIdx] != Type;
0268 };
0269 }
0270
0271
0272
0273 LegalityPredicate
0274 typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1,
0275 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
0276
0277
0278 LegalityPredicate
0279 typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2,
0280 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
0281
0282
0283 LegalityPredicate typePairAndMemDescInSet(
0284 unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx,
0285 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
0286
0287 LegalityPredicate isScalar(unsigned TypeIdx);
0288
0289 LegalityPredicate isVector(unsigned TypeIdx);
0290
0291 LegalityPredicate isPointer(unsigned TypeIdx);
0292
0293
0294 LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
0295
0296
0297 LegalityPredicate isPointerVector(unsigned TypeIdx);
0298
0299
0300 LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
0301
0302
0303
0304 LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
0305
0306
0307
0308 LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
0309
0310
0311
0312 LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size);
0313
0314
0315
0316 LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size);
0317
0318
0319
0320 LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size);
0321
0322
0323
0324 LegalityPredicate sizeNotPow2(unsigned TypeIdx);
0325
0326
0327
0328 LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
0329
0330
0331 LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
0332
0333
0334 LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
0335
0336
0337
0338 LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
0339
0340
0341
0342 LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
0343
0344
0345
0346 LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
0347
0348
0349
0350 LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx);
0351
0352
0353
0354 LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
0355
0356
0357 LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx,
0358 AtomicOrdering Ordering);
0359 }
0360
0361 namespace LegalizeMutations {
0362
0363 LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
0364
0365
0366 LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
0367
0368
0369 LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx);
0370
0371
0372 LegalizeMutation changeElementTo(unsigned TypeIdx, LLT Ty);
0373
0374
0375
0376 LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx);
0377
0378
0379
0380 LegalizeMutation changeElementCountTo(unsigned TypeIdx, LLT Ty);
0381
0382
0383
0384
0385 LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx);
0386
0387
0388
0389 LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min = 0);
0390
0391
0392
0393 LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx,
0394 unsigned Size);
0395
0396
0397
0398 LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min = 0);
0399
0400 LegalizeMutation scalarize(unsigned TypeIdx);
0401 }
0402
0403
0404
0405
0406
0407 class LegalizeRule {
0408 LegalityPredicate Predicate;
0409 LegalizeAction Action;
0410 LegalizeMutation Mutation;
0411
0412 public:
0413 LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action,
0414 LegalizeMutation Mutation = nullptr)
0415 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
0416
0417
0418 bool match(const LegalityQuery &Query) const {
0419 return Predicate(Query);
0420 }
0421
0422 LegalizeAction getAction() const { return Action; }
0423
0424
0425 std::pair<unsigned, LLT> determineMutation(const LegalityQuery &Query) const {
0426 if (Mutation)
0427 return Mutation(Query);
0428 return std::make_pair(0, LLT{});
0429 }
0430 };
0431
0432 class LegalizeRuleSet {
0433
0434 unsigned AliasOf = 0;
0435
0436 bool IsAliasedByAnother = false;
0437 SmallVector<LegalizeRule, 2> Rules;
0438
0439 #ifndef NDEBUG
0440
0441
0442
0443
0444
0445
0446
0447 SmallBitVector TypeIdxsCovered{MCOI::OPERAND_LAST_GENERIC -
0448 MCOI::OPERAND_FIRST_GENERIC + 2};
0449 SmallBitVector ImmIdxsCovered{MCOI::OPERAND_LAST_GENERIC_IMM -
0450 MCOI::OPERAND_FIRST_GENERIC_IMM + 2};
0451 #endif
0452
0453 unsigned typeIdx(unsigned TypeIdx) {
0454 assert(TypeIdx <=
0455 (MCOI::OPERAND_LAST_GENERIC - MCOI::OPERAND_FIRST_GENERIC) &&
0456 "Type Index is out of bounds");
0457 #ifndef NDEBUG
0458 TypeIdxsCovered.set(TypeIdx);
0459 #endif
0460 return TypeIdx;
0461 }
0462
0463 void markAllIdxsAsCovered() {
0464 #ifndef NDEBUG
0465 TypeIdxsCovered.set();
0466 ImmIdxsCovered.set();
0467 #endif
0468 }
0469
0470 void add(const LegalizeRule &Rule) {
0471 assert(AliasOf == 0 &&
0472 "RuleSet is aliased, change the representative opcode instead");
0473 Rules.push_back(Rule);
0474 }
0475
0476 static bool always(const LegalityQuery &) { return true; }
0477
0478
0479
0480 LegalizeRuleSet &actionIf(LegalizeAction Action,
0481 LegalityPredicate Predicate) {
0482 add({Predicate, Action});
0483 return *this;
0484 }
0485
0486
0487 LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
0488 LegalizeMutation Mutation) {
0489 add({Predicate, Action, Mutation});
0490 return *this;
0491 }
0492
0493
0494 LegalizeRuleSet &actionFor(LegalizeAction Action,
0495 std::initializer_list<LLT> Types) {
0496 using namespace LegalityPredicates;
0497 return actionIf(Action, typeInSet(typeIdx(0), Types));
0498 }
0499
0500
0501 LegalizeRuleSet &actionFor(LegalizeAction Action,
0502 std::initializer_list<LLT> Types,
0503 LegalizeMutation Mutation) {
0504 using namespace LegalityPredicates;
0505 return actionIf(Action, typeInSet(typeIdx(0), Types), Mutation);
0506 }
0507
0508
0509
0510 LegalizeRuleSet &actionFor(LegalizeAction Action,
0511 std::initializer_list<std::pair<LLT, LLT>> Types) {
0512 using namespace LegalityPredicates;
0513 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
0514 }
0515
0516 LegalizeRuleSet &
0517 actionFor(LegalizeAction Action,
0518 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
0519 using namespace LegalityPredicates;
0520 return actionIf(Action,
0521 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
0522 }
0523
0524
0525
0526
0527 LegalizeRuleSet &actionFor(LegalizeAction Action,
0528 std::initializer_list<std::pair<LLT, LLT>> Types,
0529 LegalizeMutation Mutation) {
0530 using namespace LegalityPredicates;
0531 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
0532 Mutation);
0533 }
0534
0535
0536
0537 LegalizeRuleSet &actionForTypeWithAnyImm(LegalizeAction Action,
0538 std::initializer_list<LLT> Types) {
0539 using namespace LegalityPredicates;
0540 immIdx(0);
0541 return actionIf(Action, typeInSet(typeIdx(0), Types));
0542 }
0543
0544 LegalizeRuleSet &actionForTypeWithAnyImm(
0545 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
0546 using namespace LegalityPredicates;
0547 immIdx(0);
0548 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
0549 }
0550
0551
0552
0553
0554 LegalizeRuleSet &actionForCartesianProduct(LegalizeAction Action,
0555 std::initializer_list<LLT> Types) {
0556 using namespace LegalityPredicates;
0557 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
0558 typeInSet(typeIdx(1), Types)));
0559 }
0560
0561
0562
0563
0564 LegalizeRuleSet &
0565 actionForCartesianProduct(LegalizeAction Action,
0566 std::initializer_list<LLT> Types0,
0567 std::initializer_list<LLT> Types1) {
0568 using namespace LegalityPredicates;
0569 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
0570 typeInSet(typeIdx(1), Types1)));
0571 }
0572
0573
0574
0575
0576 LegalizeRuleSet &actionForCartesianProduct(
0577 LegalizeAction Action, std::initializer_list<LLT> Types0,
0578 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
0579 using namespace LegalityPredicates;
0580 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
0581 all(typeInSet(typeIdx(1), Types1),
0582 typeInSet(typeIdx(2), Types2))));
0583 }
0584
0585 public:
0586 LegalizeRuleSet() = default;
0587
0588 bool isAliasedByAnother() { return IsAliasedByAnother; }
0589 void setIsAliasedByAnother() { IsAliasedByAnother = true; }
0590 void aliasTo(unsigned Opcode) {
0591 assert((AliasOf == 0 || AliasOf == Opcode) &&
0592 "Opcode is already aliased to another opcode");
0593 assert(Rules.empty() && "Aliasing will discard rules");
0594 AliasOf = Opcode;
0595 }
0596 unsigned getAlias() const { return AliasOf; }
0597
0598 unsigned immIdx(unsigned ImmIdx) {
0599 assert(ImmIdx <= (MCOI::OPERAND_LAST_GENERIC_IMM -
0600 MCOI::OPERAND_FIRST_GENERIC_IMM) &&
0601 "Imm Index is out of bounds");
0602 #ifndef NDEBUG
0603 ImmIdxsCovered.set(ImmIdx);
0604 #endif
0605 return ImmIdx;
0606 }
0607
0608
0609 LegalizeRuleSet &legalIf(LegalityPredicate Predicate) {
0610
0611
0612 markAllIdxsAsCovered();
0613 return actionIf(LegalizeAction::Legal, Predicate);
0614 }
0615
0616 LegalizeRuleSet &legalFor(std::initializer_list<LLT> Types) {
0617 return actionFor(LegalizeAction::Legal, Types);
0618 }
0619 LegalizeRuleSet &legalFor(bool Pred, std::initializer_list<LLT> Types) {
0620 if (!Pred)
0621 return *this;
0622 return actionFor(LegalizeAction::Legal, Types);
0623 }
0624
0625
0626 LegalizeRuleSet &legalFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0627 return actionFor(LegalizeAction::Legal, Types);
0628 }
0629 LegalizeRuleSet &legalFor(bool Pred,
0630 std::initializer_list<std::pair<LLT, LLT>> Types) {
0631 if (!Pred)
0632 return *this;
0633 return actionFor(LegalizeAction::Legal, Types);
0634 }
0635 LegalizeRuleSet &
0636 legalFor(bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
0637 if (!Pred)
0638 return *this;
0639 return actionFor(LegalizeAction::Legal, Types);
0640 }
0641
0642
0643 LegalizeRuleSet &legalForTypeWithAnyImm(std::initializer_list<LLT> Types) {
0644 markAllIdxsAsCovered();
0645 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
0646 }
0647
0648 LegalizeRuleSet &legalForTypeWithAnyImm(
0649 std::initializer_list<std::pair<LLT, LLT>> Types) {
0650 markAllIdxsAsCovered();
0651 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
0652 }
0653
0654
0655
0656 LegalizeRuleSet &legalForTypesWithMemDesc(
0657 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
0658 TypesAndMemDesc) {
0659 return actionIf(LegalizeAction::Legal,
0660 LegalityPredicates::typePairAndMemDescInSet(
0661 typeIdx(0), typeIdx(1), 0, TypesAndMemDesc));
0662 }
0663
0664
0665 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types) {
0666 return actionForCartesianProduct(LegalizeAction::Legal, Types);
0667 }
0668
0669
0670 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
0671 std::initializer_list<LLT> Types1) {
0672 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
0673 }
0674
0675
0676 LegalizeRuleSet &legalForCartesianProduct(std::initializer_list<LLT> Types0,
0677 std::initializer_list<LLT> Types1,
0678 std::initializer_list<LLT> Types2) {
0679 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
0680 Types2);
0681 }
0682
0683 LegalizeRuleSet &alwaysLegal() {
0684 using namespace LegalizeMutations;
0685 markAllIdxsAsCovered();
0686 return actionIf(LegalizeAction::Legal, always);
0687 }
0688
0689
0690 LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate,
0691 LegalizeMutation Mutation) {
0692
0693
0694 markAllIdxsAsCovered();
0695 return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
0696 }
0697
0698
0699 LegalizeRuleSet &lower() {
0700 using namespace LegalizeMutations;
0701
0702
0703 markAllIdxsAsCovered();
0704 return actionIf(LegalizeAction::Lower, always);
0705 }
0706
0707
0708 LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) {
0709 using namespace LegalizeMutations;
0710
0711
0712 markAllIdxsAsCovered();
0713 return actionIf(LegalizeAction::Lower, Predicate);
0714 }
0715
0716 LegalizeRuleSet &lowerIf(LegalityPredicate Predicate,
0717 LegalizeMutation Mutation) {
0718
0719
0720 markAllIdxsAsCovered();
0721 return actionIf(LegalizeAction::Lower, Predicate, Mutation);
0722 }
0723
0724
0725 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
0726 return actionFor(LegalizeAction::Lower, Types);
0727 }
0728
0729
0730 LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
0731 LegalizeMutation Mutation) {
0732 return actionFor(LegalizeAction::Lower, Types, Mutation);
0733 }
0734
0735
0736 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0737 return actionFor(LegalizeAction::Lower, Types);
0738 }
0739
0740
0741 LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
0742 LegalizeMutation Mutation) {
0743 return actionFor(LegalizeAction::Lower, Types, Mutation);
0744 }
0745
0746
0747 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
0748 std::initializer_list<LLT> Types1) {
0749 using namespace LegalityPredicates;
0750 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
0751 }
0752
0753
0754 LegalizeRuleSet &lowerForCartesianProduct(std::initializer_list<LLT> Types0,
0755 std::initializer_list<LLT> Types1,
0756 std::initializer_list<LLT> Types2) {
0757 using namespace LegalityPredicates;
0758 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
0759 Types2);
0760 }
0761
0762
0763 LegalizeRuleSet &libcall() {
0764 using namespace LegalizeMutations;
0765
0766
0767 markAllIdxsAsCovered();
0768 return actionIf(LegalizeAction::Libcall, always);
0769 }
0770
0771
0772 LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
0773
0774
0775 markAllIdxsAsCovered();
0776 return actionIf(LegalizeAction::Libcall, Predicate);
0777 }
0778 LegalizeRuleSet &libcallFor(std::initializer_list<LLT> Types) {
0779 return actionFor(LegalizeAction::Libcall, Types);
0780 }
0781 LegalizeRuleSet &libcallFor(bool Pred, std::initializer_list<LLT> Types) {
0782 if (!Pred)
0783 return *this;
0784 return actionFor(LegalizeAction::Libcall, Types);
0785 }
0786 LegalizeRuleSet &
0787 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0788 return actionFor(LegalizeAction::Libcall, Types);
0789 }
0790 LegalizeRuleSet &
0791 libcallFor(bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
0792 if (!Pred)
0793 return *this;
0794 return actionFor(LegalizeAction::Libcall, Types);
0795 }
0796 LegalizeRuleSet &
0797 libcallForCartesianProduct(std::initializer_list<LLT> Types) {
0798 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
0799 }
0800 LegalizeRuleSet &
0801 libcallForCartesianProduct(std::initializer_list<LLT> Types0,
0802 std::initializer_list<LLT> Types1) {
0803 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
0804 }
0805
0806
0807
0808 LegalizeRuleSet &widenScalarIf(LegalityPredicate Predicate,
0809 LegalizeMutation Mutation) {
0810
0811
0812 markAllIdxsAsCovered();
0813 return actionIf(LegalizeAction::WidenScalar, Predicate, Mutation);
0814 }
0815
0816
0817 LegalizeRuleSet &narrowScalarIf(LegalityPredicate Predicate,
0818 LegalizeMutation Mutation) {
0819
0820
0821 markAllIdxsAsCovered();
0822 return actionIf(LegalizeAction::NarrowScalar, Predicate, Mutation);
0823 }
0824
0825
0826 LegalizeRuleSet &
0827 narrowScalarFor(std::initializer_list<std::pair<LLT, LLT>> Types,
0828 LegalizeMutation Mutation) {
0829 return actionFor(LegalizeAction::NarrowScalar, Types, Mutation);
0830 }
0831
0832
0833
0834 LegalizeRuleSet &moreElementsIf(LegalityPredicate Predicate,
0835 LegalizeMutation Mutation) {
0836
0837
0838 markAllIdxsAsCovered();
0839 return actionIf(LegalizeAction::MoreElements, Predicate, Mutation);
0840 }
0841
0842
0843 LegalizeRuleSet &fewerElementsIf(LegalityPredicate Predicate,
0844 LegalizeMutation Mutation) {
0845
0846
0847 markAllIdxsAsCovered();
0848 return actionIf(LegalizeAction::FewerElements, Predicate, Mutation);
0849 }
0850
0851
0852 LegalizeRuleSet &unsupported() {
0853 markAllIdxsAsCovered();
0854 return actionIf(LegalizeAction::Unsupported, always);
0855 }
0856 LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) {
0857 return actionIf(LegalizeAction::Unsupported, Predicate);
0858 }
0859
0860 LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
0861 return actionFor(LegalizeAction::Unsupported, Types);
0862 }
0863
0864 LegalizeRuleSet &unsupportedIfMemSizeNotPow2() {
0865 return actionIf(LegalizeAction::Unsupported,
0866 LegalityPredicates::memSizeInBytesNotPow2(0));
0867 }
0868
0869
0870
0871
0872 LegalizeRuleSet &lowerIfMemSizeNotPow2() {
0873 return actionIf(LegalizeAction::Lower,
0874 LegalityPredicates::memSizeInBytesNotPow2(0));
0875 }
0876
0877
0878
0879
0880 LegalizeRuleSet &lowerIfMemSizeNotByteSizePow2() {
0881 return actionIf(LegalizeAction::Lower,
0882 LegalityPredicates::memSizeNotByteSizePow2(0));
0883 }
0884
0885 LegalizeRuleSet &customIf(LegalityPredicate Predicate) {
0886
0887
0888 markAllIdxsAsCovered();
0889 return actionIf(LegalizeAction::Custom, Predicate);
0890 }
0891 LegalizeRuleSet &customFor(std::initializer_list<LLT> Types) {
0892 return actionFor(LegalizeAction::Custom, Types);
0893 }
0894 LegalizeRuleSet &customFor(bool Pred, std::initializer_list<LLT> Types) {
0895 if (!Pred)
0896 return *this;
0897 return actionFor(LegalizeAction::Custom, Types);
0898 }
0899
0900
0901
0902 LegalizeRuleSet &customFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
0903 return actionFor(LegalizeAction::Custom, Types);
0904 }
0905 LegalizeRuleSet &customFor(bool Pred,
0906 std::initializer_list<std::pair<LLT, LLT>> Types) {
0907 if (!Pred)
0908 return *this;
0909 return actionFor(LegalizeAction::Custom, Types);
0910 }
0911
0912 LegalizeRuleSet &customForCartesianProduct(std::initializer_list<LLT> Types) {
0913 return actionForCartesianProduct(LegalizeAction::Custom, Types);
0914 }
0915
0916
0917 LegalizeRuleSet &
0918 customForCartesianProduct(std::initializer_list<LLT> Types0,
0919 std::initializer_list<LLT> Types1) {
0920 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
0921 }
0922
0923
0924 LegalizeRuleSet &
0925 customForCartesianProduct(std::initializer_list<LLT> Types0,
0926 std::initializer_list<LLT> Types1,
0927 std::initializer_list<LLT> Types2) {
0928 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
0929 Types2);
0930 }
0931
0932
0933 LegalizeRuleSet &custom() {
0934 return customIf(always);
0935 }
0936
0937
0938
0939
0940 LegalizeRuleSet &widenScalarToNextPow2(unsigned TypeIdx,
0941 unsigned MinSize = 0) {
0942 using namespace LegalityPredicates;
0943 return actionIf(
0944 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
0945 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0946 }
0947
0948
0949
0950 LegalizeRuleSet &widenScalarToNextMultipleOf(unsigned TypeIdx,
0951 unsigned Size) {
0952 using namespace LegalityPredicates;
0953 return actionIf(
0954 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx), Size),
0955 LegalizeMutations::widenScalarOrEltToNextMultipleOf(TypeIdx, Size));
0956 }
0957
0958
0959
0960 LegalizeRuleSet &widenScalarOrEltToNextPow2(unsigned TypeIdx,
0961 unsigned MinSize = 0) {
0962 using namespace LegalityPredicates;
0963 return actionIf(
0964 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
0965 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0966 }
0967
0968
0969
0970 LegalizeRuleSet &widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx,
0971 unsigned MinSize = 0) {
0972 using namespace LegalityPredicates;
0973 return actionIf(
0974 LegalizeAction::WidenScalar,
0975 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
0976 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
0977 LegalizeMutations::widenScalarOrEltToNextPow2(TypeIdx, MinSize));
0978 }
0979
0980 LegalizeRuleSet &narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation) {
0981 using namespace LegalityPredicates;
0982 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
0983 Mutation);
0984 }
0985
0986 LegalizeRuleSet &scalarize(unsigned TypeIdx) {
0987 using namespace LegalityPredicates;
0988 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
0989 LegalizeMutations::scalarize(TypeIdx));
0990 }
0991
0992 LegalizeRuleSet &scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx) {
0993 using namespace LegalityPredicates;
0994 return actionIf(LegalizeAction::FewerElements,
0995 all(Predicate, isVector(typeIdx(TypeIdx))),
0996 LegalizeMutations::scalarize(TypeIdx));
0997 }
0998
0999
1000 LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1001 using namespace LegalityPredicates;
1002 using namespace LegalizeMutations;
1003 return actionIf(LegalizeAction::WidenScalar,
1004 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1005 changeElementTo(typeIdx(TypeIdx), Ty));
1006 }
1007
1008
1009 LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate,
1010 unsigned TypeIdx, const LLT Ty) {
1011 using namespace LegalityPredicates;
1012 using namespace LegalizeMutations;
1013 return actionIf(LegalizeAction::WidenScalar,
1014 all(Predicate, scalarOrEltNarrowerThan(
1015 TypeIdx, Ty.getScalarSizeInBits())),
1016 changeElementTo(typeIdx(TypeIdx), Ty));
1017 }
1018
1019
1020
1021 LegalizeRuleSet &widenVectorEltsToVectorMinSize(unsigned TypeIdx,
1022 unsigned VectorSize) {
1023 using namespace LegalityPredicates;
1024 using namespace LegalizeMutations;
1025 return actionIf(
1026 LegalizeAction::WidenScalar,
1027 [=](const LegalityQuery &Query) {
1028 const LLT VecTy = Query.Types[TypeIdx];
1029 return VecTy.isFixedVector() && VecTy.getSizeInBits() < VectorSize;
1030 },
1031 [=](const LegalityQuery &Query) {
1032 const LLT VecTy = Query.Types[TypeIdx];
1033 unsigned NumElts = VecTy.getNumElements();
1034 unsigned MinSize = VectorSize / NumElts;
1035 LLT NewTy = LLT::fixed_vector(NumElts, LLT::scalar(MinSize));
1036 return std::make_pair(TypeIdx, NewTy);
1037 });
1038 }
1039
1040
1041 LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
1042 using namespace LegalityPredicates;
1043 using namespace LegalizeMutations;
1044 return actionIf(LegalizeAction::WidenScalar,
1045 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1046 changeTo(typeIdx(TypeIdx), Ty));
1047 }
1048 LegalizeRuleSet &minScalar(bool Pred, unsigned TypeIdx, const LLT Ty) {
1049 if (!Pred)
1050 return *this;
1051 return minScalar(TypeIdx, Ty);
1052 }
1053
1054
1055 LegalizeRuleSet &minScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
1056 const LLT Ty) {
1057 using namespace LegalityPredicates;
1058 using namespace LegalizeMutations;
1059 return actionIf(
1060 LegalizeAction::WidenScalar,
1061 [=](const LegalityQuery &Query) {
1062 const LLT QueryTy = Query.Types[TypeIdx];
1063 return QueryTy.isScalar() &&
1064 QueryTy.getSizeInBits() < Ty.getSizeInBits() &&
1065 Predicate(Query);
1066 },
1067 changeTo(typeIdx(TypeIdx), Ty));
1068 }
1069
1070
1071 LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
1072 using namespace LegalityPredicates;
1073 using namespace LegalizeMutations;
1074 return actionIf(LegalizeAction::NarrowScalar,
1075 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1076 changeElementTo(typeIdx(TypeIdx), Ty));
1077 }
1078
1079
1080 LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
1081 using namespace LegalityPredicates;
1082 using namespace LegalizeMutations;
1083 return actionIf(LegalizeAction::NarrowScalar,
1084 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1085 changeTo(typeIdx(TypeIdx), Ty));
1086 }
1087
1088
1089
1090
1091 LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
1092 const LLT Ty) {
1093 using namespace LegalityPredicates;
1094 using namespace LegalizeMutations;
1095 return actionIf(
1096 LegalizeAction::NarrowScalar,
1097 [=](const LegalityQuery &Query) {
1098 const LLT QueryTy = Query.Types[TypeIdx];
1099 return QueryTy.isScalar() &&
1100 QueryTy.getSizeInBits() > Ty.getSizeInBits() &&
1101 Predicate(Query);
1102 },
1103 changeElementTo(typeIdx(TypeIdx), Ty));
1104 }
1105
1106
1107 LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
1108 const LLT MaxTy) {
1109 assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
1110 return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
1111 }
1112
1113 LegalizeRuleSet &clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy,
1114 const LLT MaxTy) {
1115 if (!Pred)
1116 return *this;
1117 return clampScalar(TypeIdx, MinTy, MaxTy);
1118 }
1119
1120
1121 LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
1122 const LLT MaxTy) {
1123 return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
1124 }
1125
1126
1127 LegalizeRuleSet &minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx) {
1128 typeIdx(TypeIdx);
1129 return actionIf(
1130 LegalizeAction::WidenScalar,
1131 [=](const LegalityQuery &Query) {
1132 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1133 Query.Types[TypeIdx].getSizeInBits();
1134 },
1135 LegalizeMutations::changeElementSizeTo(TypeIdx, LargeTypeIdx));
1136 }
1137
1138
1139 LegalizeRuleSet &maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx) {
1140 typeIdx(TypeIdx);
1141 return actionIf(
1142 LegalizeAction::NarrowScalar,
1143 [=](const LegalityQuery &Query) {
1144 return Query.Types[NarrowTypeIdx].getScalarSizeInBits() <
1145 Query.Types[TypeIdx].getSizeInBits();
1146 },
1147 LegalizeMutations::changeElementSizeTo(TypeIdx, NarrowTypeIdx));
1148 }
1149
1150
1151
1152 LegalizeRuleSet &scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx) {
1153 return minScalarSameAs(TypeIdx, SameSizeIdx)
1154 .maxScalarSameAs(TypeIdx, SameSizeIdx);
1155 }
1156
1157
1158 LegalizeRuleSet &minScalarEltSameAsIf(LegalityPredicate Predicate,
1159 unsigned TypeIdx, unsigned LargeTypeIdx) {
1160 typeIdx(TypeIdx);
1161 return widenScalarIf(
1162 [=](const LegalityQuery &Query) {
1163 return Query.Types[LargeTypeIdx].getScalarSizeInBits() >
1164 Query.Types[TypeIdx].getScalarSizeInBits() &&
1165 Predicate(Query);
1166 },
1167 [=](const LegalityQuery &Query) {
1168 LLT T = Query.Types[LargeTypeIdx];
1169 if (T.isPointerVector())
1170 T = T.changeElementType(LLT::scalar(T.getScalarSizeInBits()));
1171 return std::make_pair(TypeIdx, T);
1172 });
1173 }
1174
1175
1176 LegalizeRuleSet &maxScalarEltSameAsIf(LegalityPredicate Predicate,
1177 unsigned TypeIdx,
1178 unsigned SmallTypeIdx) {
1179 typeIdx(TypeIdx);
1180 return narrowScalarIf(
1181 [=](const LegalityQuery &Query) {
1182 return Query.Types[SmallTypeIdx].getScalarSizeInBits() <
1183 Query.Types[TypeIdx].getScalarSizeInBits() &&
1184 Predicate(Query);
1185 },
1186 [=](const LegalityQuery &Query) {
1187 LLT T = Query.Types[SmallTypeIdx];
1188 return std::make_pair(TypeIdx, T);
1189 });
1190 }
1191
1192
1193
1194
1195 LegalizeRuleSet &moreElementsToNextPow2(unsigned TypeIdx) {
1196 using namespace LegalityPredicates;
1197 return actionIf(LegalizeAction::MoreElements,
1198 numElementsNotPow2(typeIdx(TypeIdx)),
1199 LegalizeMutations::moreElementsToNextPow2(TypeIdx));
1200 }
1201
1202
1203 LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
1204 unsigned MinElements) {
1205
1206 typeIdx(TypeIdx);
1207 return actionIf(
1208 LegalizeAction::MoreElements,
1209 [=](const LegalityQuery &Query) {
1210 LLT VecTy = Query.Types[TypeIdx];
1211 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1212 VecTy.getNumElements() < MinElements;
1213 },
1214 [=](const LegalityQuery &Query) {
1215 LLT VecTy = Query.Types[TypeIdx];
1216 return std::make_pair(
1217 TypeIdx, LLT::fixed_vector(MinElements, VecTy.getElementType()));
1218 });
1219 }
1220
1221
1222 LegalizeRuleSet &alignNumElementsTo(unsigned TypeIdx, const LLT EltTy,
1223 unsigned NumElts) {
1224 typeIdx(TypeIdx);
1225 return actionIf(
1226 LegalizeAction::MoreElements,
1227 [=](const LegalityQuery &Query) {
1228 LLT VecTy = Query.Types[TypeIdx];
1229 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1230 (VecTy.getNumElements() % NumElts != 0);
1231 },
1232 [=](const LegalityQuery &Query) {
1233 LLT VecTy = Query.Types[TypeIdx];
1234 unsigned NewSize = alignTo(VecTy.getNumElements(), NumElts);
1235 return std::make_pair(
1236 TypeIdx, LLT::fixed_vector(NewSize, VecTy.getElementType()));
1237 });
1238 }
1239
1240
1241 LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
1242 unsigned MaxElements) {
1243
1244 typeIdx(TypeIdx);
1245 return actionIf(
1246 LegalizeAction::FewerElements,
1247 [=](const LegalityQuery &Query) {
1248 LLT VecTy = Query.Types[TypeIdx];
1249 return VecTy.isFixedVector() && VecTy.getElementType() == EltTy &&
1250 VecTy.getNumElements() > MaxElements;
1251 },
1252 [=](const LegalityQuery &Query) {
1253 LLT VecTy = Query.Types[TypeIdx];
1254 LLT NewTy = LLT::scalarOrVector(ElementCount::getFixed(MaxElements),
1255 VecTy.getElementType());
1256 return std::make_pair(TypeIdx, NewTy);
1257 });
1258 }
1259
1260
1261
1262
1263
1264
1265 LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
1266 const LLT MaxTy) {
1267 assert(MinTy.getElementType() == MaxTy.getElementType() &&
1268 "Expected element types to agree");
1269
1270 assert((!MinTy.isScalableVector() && !MaxTy.isScalableVector()) &&
1271 "Unexpected scalable vectors");
1272
1273 const LLT EltTy = MinTy.getElementType();
1274 return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
1275 .clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
1276 }
1277
1278
1279
1280
1281
1282
1283
1284
1285 LegalizeRuleSet &clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy,
1286 unsigned NumElts) {
1287 return alignNumElementsTo(TypeIdx, EltTy, NumElts)
1288 .clampMaxNumElements(TypeIdx, EltTy, NumElts);
1289 }
1290
1291
1292
1293 LegalizeRuleSet &fallback() {
1294 add({always, LegalizeAction::UseLegacyRules});
1295 return *this;
1296 }
1297
1298
1299
1300
1301 bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const;
1302
1303
1304
1305 bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const;
1306
1307
1308 LegalizeActionStep apply(const LegalityQuery &Query) const;
1309 };
1310
1311 class LegalizerInfo {
1312 public:
1313 virtual ~LegalizerInfo() = default;
1314
1315 const LegacyLegalizerInfo &getLegacyLegalizerInfo() const {
1316 return LegacyInfo;
1317 }
1318 LegacyLegalizerInfo &getLegacyLegalizerInfo() { return LegacyInfo; }
1319
1320 unsigned getOpcodeIdxForOpcode(unsigned Opcode) const;
1321 unsigned getActionDefinitionsIdx(unsigned Opcode) const;
1322
1323
1324
1325 void verify(const MCInstrInfo &MII) const;
1326
1327
1328
1329 const LegalizeRuleSet &getActionDefinitions(unsigned Opcode) const;
1330
1331
1332
1333
1334
1335
1336 LegalizeRuleSet &getActionDefinitionsBuilder(unsigned Opcode);
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351 LegalizeRuleSet &
1352 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1353 void aliasActionDefinitions(unsigned OpcodeTo, unsigned OpcodeFrom);
1354
1355
1356
1357
1358
1359 LegalizeActionStep getAction(const LegalityQuery &Query) const;
1360
1361
1362
1363
1364
1365 LegalizeActionStep getAction(const MachineInstr &MI,
1366 const MachineRegisterInfo &MRI) const;
1367
1368 bool isLegal(const LegalityQuery &Query) const {
1369 return getAction(Query).Action == LegalizeAction::Legal;
1370 }
1371
1372 bool isLegalOrCustom(const LegalityQuery &Query) const {
1373 auto Action = getAction(Query).Action;
1374 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1375 }
1376
1377 bool isLegal(const MachineInstr &MI, const MachineRegisterInfo &MRI) const;
1378 bool isLegalOrCustom(const MachineInstr &MI,
1379 const MachineRegisterInfo &MRI) const;
1380
1381
1382 virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
1383 LostDebugLocObserver &LocObserver) const {
1384 llvm_unreachable("must implement this if custom action is used");
1385 }
1386
1387
1388
1389
1390
1391 virtual bool legalizeIntrinsic(LegalizerHelper &Helper,
1392 MachineInstr &MI) const {
1393 return true;
1394 }
1395
1396
1397
1398
1399
1400 virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1401
1402 private:
1403 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1404 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
1405
1406 LegalizeRuleSet RulesForOpcode[LastOp - FirstOp + 1];
1407 LegacyLegalizerInfo LegacyInfo;
1408 };
1409
1410 #ifndef NDEBUG
1411
1412
1413 const MachineInstr *machineFunctionIsIllegal(const MachineFunction &MF);
1414 #endif
1415
1416 }
1417
1418 #endif