14#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
38class LostDebugLocObserver;
40class MachineRegisterInfo;
43namespace LegalizeActions {
124 Ordering(MMO.getSuccessOrdering()) {}
137 raw_ostream &
print(raw_ostream &
OS)
const;
196 std::tie(
RHS.Action,
RHS.TypeIdx,
RHS.NewType);
202 std::function<std::pair<unsigned, LLT>(
const LegalityQuery &)>;
204namespace LegalityPredicates {
228template <
typename Predicate> Predicate
predNot(Predicate
P) {
233template<
typename Predicate>
234Predicate
all(Predicate P0, Predicate P1) {
236 return P0(Query) && P1(Query);
240template<
typename Predicate,
typename... Args>
241Predicate
all(Predicate P0, Predicate P1, Args...
args) {
246template<
typename Predicate>
247Predicate
any(Predicate P0, Predicate P1) {
249 return P0(Query) || P1(Query);
253template<
typename Predicate,
typename... Args>
254Predicate
any(Predicate P0, Predicate P1, Args...
args) {
262 std::initializer_list<LLT> TypesInit);
267 return Query.Types[TypeIdx] !=
Type;
275 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
280 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
284 unsigned TypeIdx0,
unsigned TypeIdx1,
unsigned MMOIdx,
285 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
361namespace LegalizeMutations {
409 LegalizeAction Action;
419 return Predicate(Query);
428 return std::make_pair(0,
LLT{});
434 unsigned AliasOf = 0;
436 bool IsAliasedByAnother =
false;
453 unsigned typeIdx(
unsigned TypeIdx) {
456 "Type Index is out of bounds");
458 TypeIdxsCovered.
set(TypeIdx);
463 void markAllIdxsAsCovered() {
465 TypeIdxsCovered.
set();
466 ImmIdxsCovered.
set();
472 "RuleSet is aliased, change the representative opcode instead");
482 add({Predicate, Action});
495 std::initializer_list<LLT> Types) {
496 using namespace LegalityPredicates;
497 return actionIf(Action, typeInSet(typeIdx(0), Types));
502 std::initializer_list<LLT> Types,
504 using namespace LegalityPredicates;
505 return actionIf(Action, typeInSet(typeIdx(0), Types),
Mutation);
511 std::initializer_list<std::pair<LLT, LLT>> Types) {
512 using namespace LegalityPredicates;
513 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
517 actionFor(LegalizeAction Action,
518 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
519 using namespace LegalityPredicates;
520 return actionIf(Action,
521 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
528 std::initializer_list<std::pair<LLT, LLT>> Types,
530 using namespace LegalityPredicates;
531 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
538 std::initializer_list<LLT> Types) {
539 using namespace LegalityPredicates;
541 return actionIf(Action, typeInSet(typeIdx(0), Types));
545 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
546 using namespace LegalityPredicates;
548 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
555 std::initializer_list<LLT> Types) {
556 using namespace LegalityPredicates;
557 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
558 typeInSet(typeIdx(1), Types)));
565 actionForCartesianProduct(LegalizeAction Action,
566 std::initializer_list<LLT> Types0,
567 std::initializer_list<LLT> Types1) {
568 using namespace LegalityPredicates;
569 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
570 typeInSet(typeIdx(1), Types1)));
577 LegalizeAction Action, std::initializer_list<LLT> Types0,
578 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
579 using namespace LegalityPredicates;
580 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
581 all(typeInSet(typeIdx(1), Types1),
582 typeInSet(typeIdx(2), Types2))));
591 assert((AliasOf == 0 || AliasOf == Opcode) &&
592 "Opcode is already aliased to another opcode");
593 assert(Rules.
empty() &&
"Aliasing will discard rules");
601 "Imm Index is out of bounds");
603 ImmIdxsCovered.
set(ImmIdx);
612 markAllIdxsAsCovered();
613 return actionIf(LegalizeAction::Legal, Predicate);
617 return actionFor(LegalizeAction::Legal, Types);
622 return actionFor(LegalizeAction::Legal, Types);
627 return actionFor(LegalizeAction::Legal, Types);
630 std::initializer_list<std::pair<LLT, LLT>> Types) {
633 return actionFor(LegalizeAction::Legal, Types);
636 legalFor(
bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
639 return actionFor(LegalizeAction::Legal, Types);
644 markAllIdxsAsCovered();
645 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
649 std::initializer_list<std::pair<LLT, LLT>> Types) {
650 markAllIdxsAsCovered();
651 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
657 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
659 return actionIf(LegalizeAction::Legal,
661 typeIdx(0), typeIdx(1), 0, TypesAndMemDesc));
666 return actionForCartesianProduct(LegalizeAction::Legal, Types);
671 std::initializer_list<LLT> Types1) {
672 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
677 std::initializer_list<LLT> Types1,
678 std::initializer_list<LLT> Types2) {
679 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
684 using namespace LegalizeMutations;
685 markAllIdxsAsCovered();
686 return actionIf(LegalizeAction::Legal, always);
694 markAllIdxsAsCovered();
695 return actionIf(LegalizeAction::Bitcast, Predicate,
Mutation);
700 using namespace LegalizeMutations;
703 markAllIdxsAsCovered();
704 return actionIf(LegalizeAction::Lower, always);
709 using namespace LegalizeMutations;
712 markAllIdxsAsCovered();
713 return actionIf(LegalizeAction::Lower, Predicate);
720 markAllIdxsAsCovered();
721 return actionIf(LegalizeAction::Lower, Predicate,
Mutation);
726 return actionFor(LegalizeAction::Lower, Types);
732 return actionFor(LegalizeAction::Lower, Types,
Mutation);
737 return actionFor(LegalizeAction::Lower, Types);
743 return actionFor(LegalizeAction::Lower, Types,
Mutation);
748 std::initializer_list<LLT> Types1) {
749 using namespace LegalityPredicates;
750 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
755 std::initializer_list<LLT> Types1,
756 std::initializer_list<LLT> Types2) {
757 using namespace LegalityPredicates;
758 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
764 using namespace LegalizeMutations;
767 markAllIdxsAsCovered();
768 return actionIf(LegalizeAction::Libcall, always);
775 markAllIdxsAsCovered();
776 return actionIf(LegalizeAction::Libcall, Predicate);
779 return actionFor(LegalizeAction::Libcall, Types);
784 return actionFor(LegalizeAction::Libcall, Types);
787 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
788 return actionFor(LegalizeAction::Libcall, Types);
791 libcallFor(
bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
794 return actionFor(LegalizeAction::Libcall, Types);
798 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
802 std::initializer_list<LLT> Types1) {
803 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
812 markAllIdxsAsCovered();
813 return actionIf(LegalizeAction::WidenScalar, Predicate,
Mutation);
821 markAllIdxsAsCovered();
822 return actionIf(LegalizeAction::NarrowScalar, Predicate,
Mutation);
829 return actionFor(LegalizeAction::NarrowScalar, Types,
Mutation);
838 markAllIdxsAsCovered();
839 return actionIf(LegalizeAction::MoreElements, Predicate,
Mutation);
847 markAllIdxsAsCovered();
848 return actionIf(LegalizeAction::FewerElements, Predicate,
Mutation);
853 markAllIdxsAsCovered();
854 return actionIf(LegalizeAction::Unsupported, always);
857 return actionIf(LegalizeAction::Unsupported, Predicate);
861 return actionFor(LegalizeAction::Unsupported, Types);
865 return actionIf(LegalizeAction::Unsupported,
873 return actionIf(LegalizeAction::Lower,
881 return actionIf(LegalizeAction::Lower,
888 markAllIdxsAsCovered();
889 return actionIf(LegalizeAction::Custom, Predicate);
892 return actionFor(LegalizeAction::Custom, Types);
897 return actionFor(LegalizeAction::Custom, Types);
903 return actionFor(LegalizeAction::Custom, Types);
906 std::initializer_list<std::pair<LLT, LLT>> Types) {
909 return actionFor(LegalizeAction::Custom, Types);
913 return actionForCartesianProduct(LegalizeAction::Custom, Types);
919 std::initializer_list<LLT> Types1) {
920 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
926 std::initializer_list<LLT> Types1,
927 std::initializer_list<LLT> Types2) {
928 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
941 unsigned MinSize = 0) {
942 using namespace LegalityPredicates;
944 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
952 using namespace LegalityPredicates;
954 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx),
Size),
961 unsigned MinSize = 0) {
962 using namespace LegalityPredicates;
964 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
971 unsigned MinSize = 0) {
972 using namespace LegalityPredicates;
974 LegalizeAction::WidenScalar,
975 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
976 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
981 using namespace LegalityPredicates;
982 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
987 using namespace LegalityPredicates;
988 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
993 using namespace LegalityPredicates;
994 return actionIf(LegalizeAction::FewerElements,
995 all(Predicate, isVector(typeIdx(TypeIdx))),
1001 using namespace LegalityPredicates;
1002 using namespace LegalizeMutations;
1003 return actionIf(LegalizeAction::WidenScalar,
1005 changeElementTo(typeIdx(TypeIdx), Ty));
1010 unsigned TypeIdx,
const LLT Ty) {
1011 using namespace LegalityPredicates;
1012 using namespace LegalizeMutations;
1013 return actionIf(LegalizeAction::WidenScalar,
1014 all(Predicate, scalarOrEltNarrowerThan(
1016 changeElementTo(typeIdx(TypeIdx), Ty));
1022 unsigned VectorSize) {
1023 using namespace LegalityPredicates;
1024 using namespace LegalizeMutations;
1026 LegalizeAction::WidenScalar,
1028 const LLT VecTy = Query.
Types[TypeIdx];
1032 const LLT VecTy = Query.
Types[TypeIdx];
1034 unsigned MinSize = VectorSize / NumElts;
1036 return std::make_pair(TypeIdx, NewTy);
1042 using namespace LegalityPredicates;
1043 using namespace LegalizeMutations;
1044 return actionIf(LegalizeAction::WidenScalar,
1046 changeTo(typeIdx(TypeIdx), Ty));
1057 using namespace LegalityPredicates;
1058 using namespace LegalizeMutations;
1060 LegalizeAction::WidenScalar,
1062 const LLT QueryTy = Query.
Types[TypeIdx];
1067 changeTo(typeIdx(TypeIdx), Ty));
1072 using namespace LegalityPredicates;
1073 using namespace LegalizeMutations;
1074 return actionIf(LegalizeAction::NarrowScalar,
1076 changeElementTo(typeIdx(TypeIdx), Ty));
1081 using namespace LegalityPredicates;
1082 using namespace LegalizeMutations;
1083 return actionIf(LegalizeAction::NarrowScalar,
1085 changeTo(typeIdx(TypeIdx), Ty));
1093 using namespace LegalityPredicates;
1094 using namespace LegalizeMutations;
1096 LegalizeAction::NarrowScalar,
1098 const LLT QueryTy = Query.
Types[TypeIdx];
1103 changeElementTo(typeIdx(TypeIdx), Ty));
1130 LegalizeAction::WidenScalar,
1132 return Query.
Types[LargeTypeIdx].getScalarSizeInBits() >
1133 Query.
Types[TypeIdx].getSizeInBits();
1142 LegalizeAction::NarrowScalar,
1144 return Query.
Types[NarrowTypeIdx].getScalarSizeInBits() <
1145 Query.
Types[TypeIdx].getSizeInBits();
1159 unsigned TypeIdx,
unsigned LargeTypeIdx) {
1163 return Query.
Types[LargeTypeIdx].getScalarSizeInBits() >
1164 Query.
Types[TypeIdx].getScalarSizeInBits() &&
1169 if (
T.isPointerVector())
1171 return std::make_pair(TypeIdx,
T);
1178 unsigned SmallTypeIdx) {
1182 return Query.
Types[SmallTypeIdx].getScalarSizeInBits() <
1183 Query.
Types[TypeIdx].getScalarSizeInBits() &&
1188 return std::make_pair(TypeIdx,
T);
1196 using namespace LegalityPredicates;
1197 return actionIf(LegalizeAction::MoreElements,
1198 numElementsNotPow2(typeIdx(TypeIdx)),
1204 unsigned MinElements) {
1208 LegalizeAction::MoreElements,
1216 return std::make_pair(
1226 LegalizeAction::MoreElements,
1235 return std::make_pair(
1242 unsigned MaxElements) {
1246 LegalizeAction::FewerElements,
1256 return std::make_pair(TypeIdx, NewTy);
1268 "Expected element types to agree");
1271 "Unexpected scalable vectors");
1294 add({always, LegalizeAction::UseLegacyRules});
1374 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1403 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1404 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
unsigned const MachineRegisterInfo * MRI
Atomic ordering constants.
Given that RA is a live value
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the SmallBitVector class.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static constexpr ElementCount getFixed(ScalarTy MinVal)
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
LegalizeRuleSet & maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx)
Narrow the scalar to match the size of another.
LegalizeRuleSet & widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & maxScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned SmallTypeIdx)
Conditionally narrow the scalar or elt to match the size of another.
LegalizeRuleSet & unsupported()
The instruction is unsupported.
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::tuple< LLT, LLT, LLT > > Types)
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
void aliasTo(unsigned Opcode)
LegalizeRuleSet & bitcastIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The specified type index is coerced if predicate is true.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
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()=default
LegalizeRuleSet & clampMaxNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MaxElements)
Limit the number of elements in EltTy vectors to at most MaxElements.
LegalizeRuleSet & clampMinNumElements(unsigned TypeIdx, const LLT EltTy, unsigned MinElements)
Limit the number of elements in EltTy vectors to at least MinElements.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & unsupportedFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & widenVectorEltsToVectorMinSize(unsigned TypeIdx, unsigned VectorSize)
Ensure the vector size is at least as wide as VectorSize by promoting the element.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is legal when type indexes 0 and 1 are both their respective lists.
LegalizeRuleSet & lowerIfMemSizeNotPow2()
Lower a memory operation if the memory size, rounded to bytes, is not a power of 2.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types, LegalizeMutation Mutation)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & minScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned LargeTypeIdx)
Conditionally widen the scalar or elt to match the size of another.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & lowerIfMemSizeNotByteSizePow2()
Lower a memory operation if the memory access size is not a round power of 2 byte size.
LegalizeRuleSet & minScalar(bool Pred, unsigned TypeIdx, const LLT Ty)
LegalizeRuleSet & moreElementsToNextPow2(unsigned TypeIdx)
Add more elements to the vector to reach the next power of two.
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when type indexes 0 and 1 are both in their respective lists.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & narrowScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Narrow the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & lower()
The instruction is lowered.
LegalizeRuleSet & moreElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Add more elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & narrowScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Narrow the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given lis...
LegalizeRuleSet & narrowScalar(unsigned TypeIdx, LegalizeMutation Mutation)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & scalarizeIf(LegalityPredicate Predicate, unsigned TypeIdx)
LegalizeRuleSet & lowerIf(LegalityPredicate Predicate)
The instruction is lowered if predicate is true.
bool isAliasedByAnother()
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is legal when type indexes 0, 1, and 2 are both their respective lists.
LegalizeRuleSet & alignNumElementsTo(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Set number of elements to nearest larger multiple of NumElts.
LegalizeRuleSet & custom()
Unconditionally custom lower.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
LegalizeRuleSet & clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Express EltTy vectors strictly using vectors with NumElts elements (or scalars when NumElts equals 1)...
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & fallback()
Fallback on the previous implementation.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & legalFor(std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is legal when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & libcallFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & alwaysLegal()
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
unsigned getAlias() const
LegalizeRuleSet & clampNumElements(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the number of elements for the given vectors to at least MinTy's number of elements and at most...
LegalizeRuleSet & unsupportedIfMemSizeNotPow2()
LegalizeRuleSet & maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Conditionally limit the maximum size of the scalar.
LegalizeRuleSet & customIf(LegalityPredicate Predicate)
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is custom when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & widenScalarToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar to the next power of two that is at least MinSize.
LegalizeRuleSet & scalarize(unsigned TypeIdx)
void setIsAliasedByAnother()
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.
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements an extremely fast bulk output stream that can only output to a stream.
#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 isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
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.
LegalityPredicate typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, std::initializer_list< std::tuple< LLT, LLT, LLT > > TypesInit)
True iff the given types for the given tuple of type indexes is one of the specified type tuple.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
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 ...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
@ Unsupported
This operation is completely unsupported on the target.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ UseLegacyRules
Fall back onto the old rules.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Custom
The target wants to do something special with this combination of operand and type.
@ NotFound
Sentinel value for when no action was found in the specified table.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
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_FIRST_GENERIC_IMM
@ OPERAND_LAST_GENERIC_IMM
This is an optimization pass for GlobalISel generic memory operations.
MaybeAlign getAlign(const Function &F, unsigned Index)
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.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
std::function< bool(const LegalityQuery &)> LegalityPredicate
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.
raw_ostream & print(raw_ostream &OS) const
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