14#ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
15#define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H
128 MMO.getSuccessOrdering(), MMO.getFailureOrdering()) {}
160 case LegacyLegalizeActions::Legal:
161 Action = LegalizeActions::Legal;
163 case LegacyLegalizeActions::NarrowScalar:
164 Action = LegalizeActions::NarrowScalar;
166 case LegacyLegalizeActions::WidenScalar:
167 Action = LegalizeActions::WidenScalar;
169 case LegacyLegalizeActions::FewerElements:
170 Action = LegalizeActions::FewerElements;
172 case LegacyLegalizeActions::MoreElements:
173 Action = LegalizeActions::MoreElements;
175 case LegacyLegalizeActions::Bitcast:
176 Action = LegalizeActions::Bitcast;
178 case LegacyLegalizeActions::Lower:
179 Action = LegalizeActions::Lower;
181 case LegacyLegalizeActions::Libcall:
182 Action = LegalizeActions::Libcall;
184 case LegacyLegalizeActions::Custom:
185 Action = LegalizeActions::Custom;
187 case LegacyLegalizeActions::Unsupported:
188 Action = LegalizeActions::Unsupported;
190 case LegacyLegalizeActions::NotFound:
191 Action = LegalizeActions::NotFound;
198 std::tie(
RHS.Action,
RHS.TypeIdx,
RHS.NewType);
204 std::function<std::pair<unsigned, LLT>(
const LegalityQuery &)>;
225 MemTy.getSizeInBits() ==
Other.MemTy.getSizeInBits();
235template<
typename Predicate>
238 return P0(Query) && P1(Query);
242template<
typename Predicate,
typename... Args>
248template<
typename Predicate>
251 return P0(Query) || P1(Query);
255template<
typename Predicate,
typename... Args>
264 std::initializer_list<LLT> TypesInit);
269 return Query.Types[TypeIdx] !=
Type;
277 std::initializer_list<std::pair<LLT, LLT>> TypesInit);
281typeTupleInSet(
unsigned TypeIdx0,
unsigned TypeIdx1,
unsigned Type2,
282 std::initializer_list<std::tuple<LLT, LLT, LLT>> TypesInit);
286 unsigned TypeIdx0,
unsigned TypeIdx1,
unsigned MMOIdx,
287 std::initializer_list<TypePairAndMemDesc> TypesAndMemDescInit);
384 unsigned FromTypeIdx);
392 unsigned FromTypeIdx);
403 unsigned FromTypeIdx);
440 : Predicate(Predicate), Action(Action), Mutation(Mutation) {}
444 return Predicate(Query);
453 return std::make_pair(0,
LLT{});
459 unsigned AliasOf = 0;
461 bool IsAliasedByAnother =
false;
478 unsigned typeIdx(
unsigned TypeIdx) {
481 "Type Index is out of bounds");
483 TypeIdxsCovered.set(TypeIdx);
488 void markAllIdxsAsCovered() {
490 TypeIdxsCovered.set();
491 ImmIdxsCovered.set();
497 "RuleSet is aliased, change the representative opcode instead");
498 Rules.push_back(Rule);
520 std::initializer_list<LLT> Types) {
522 return actionIf(Action, typeInSet(typeIdx(0), Types));
527 std::initializer_list<LLT> Types,
530 return actionIf(Action, typeInSet(typeIdx(0), Types),
Mutation);
536 std::initializer_list<std::pair<LLT, LLT>> Types) {
538 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
543 std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
545 return actionIf(Action,
546 typeTupleInSet(typeIdx(0), typeIdx(1), typeIdx(2), Types));
553 std::initializer_list<std::pair<LLT, LLT>> Types,
556 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types),
563 std::initializer_list<LLT> Types) {
566 return actionIf(Action, typeInSet(typeIdx(0), Types));
570 LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
573 return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
580 std::initializer_list<LLT> Types) {
582 return actionIf(Action, all(typeInSet(typeIdx(0), Types),
583 typeInSet(typeIdx(1), Types)));
591 std::initializer_list<LLT> Types0,
592 std::initializer_list<LLT> Types1) {
594 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
595 typeInSet(typeIdx(1), Types1)));
603 std::initializer_list<LLT> Types1, std::initializer_list<LLT> Types2) {
605 return actionIf(Action, all(typeInSet(typeIdx(0), Types0),
606 all(typeInSet(typeIdx(1), Types1),
607 typeInSet(typeIdx(2), Types2))));
616 assert((AliasOf == 0 || AliasOf == Opcode) &&
617 "Opcode is already aliased to another opcode");
618 assert(Rules.empty() &&
"Aliasing will discard rules");
626 "Imm Index is out of bounds");
628 ImmIdxsCovered.set(ImmIdx);
637 markAllIdxsAsCovered();
638 return actionIf(LegalizeAction::Legal,
Predicate);
642 return actionFor(LegalizeAction::Legal, Types);
647 return actionFor(LegalizeAction::Legal, Types);
652 return actionFor(LegalizeAction::Legal, Types);
655 std::initializer_list<std::pair<LLT, LLT>> Types) {
658 return actionFor(LegalizeAction::Legal, Types);
661 legalFor(
bool Pred, std::initializer_list<std::tuple<LLT, LLT, LLT>> Types) {
664 return actionFor(LegalizeAction::Legal, Types);
669 markAllIdxsAsCovered();
670 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
674 std::initializer_list<std::pair<LLT, LLT>> Types) {
675 markAllIdxsAsCovered();
676 return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
682 std::initializer_list<LegalityPredicates::TypePairAndMemDesc>
684 return actionIf(LegalizeAction::Legal,
686 typeIdx(0), typeIdx(1), 0, TypesAndMemDesc));
691 return actionForCartesianProduct(LegalizeAction::Legal, Types);
696 std::initializer_list<LLT> Types1) {
697 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
702 std::initializer_list<LLT> Types1,
703 std::initializer_list<LLT> Types2) {
704 return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1,
710 markAllIdxsAsCovered();
711 return actionIf(LegalizeAction::Legal, always);
719 markAllIdxsAsCovered();
728 markAllIdxsAsCovered();
729 return actionIf(LegalizeAction::Lower, always);
737 markAllIdxsAsCovered();
738 return actionIf(LegalizeAction::Lower,
Predicate);
745 markAllIdxsAsCovered();
751 return actionFor(LegalizeAction::Lower, Types);
757 return actionFor(LegalizeAction::Lower, Types,
Mutation);
762 return actionFor(LegalizeAction::Lower, Types);
767 std::initializer_list<std::pair<LLT, LLT>> Types) {
770 return actionFor(LegalizeAction::Lower, Types);
776 return actionFor(LegalizeAction::Lower, Types,
Mutation);
781 std::initializer_list<LLT> Types1) {
783 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1);
788 std::initializer_list<LLT> Types1,
789 std::initializer_list<LLT> Types2) {
791 return actionForCartesianProduct(LegalizeAction::Lower, Types0, Types1,
800 markAllIdxsAsCovered();
801 return actionIf(LegalizeAction::Libcall, always);
808 markAllIdxsAsCovered();
809 return actionIf(LegalizeAction::Libcall,
Predicate);
812 return actionFor(LegalizeAction::Libcall, Types);
817 return actionFor(LegalizeAction::Libcall, Types);
820 libcallFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
821 return actionFor(LegalizeAction::Libcall, Types);
824 libcallFor(
bool Pred, std::initializer_list<std::pair<LLT, LLT>> Types) {
827 return actionFor(LegalizeAction::Libcall, Types);
831 return actionForCartesianProduct(LegalizeAction::Libcall, Types);
835 std::initializer_list<LLT> Types1) {
836 return actionForCartesianProduct(LegalizeAction::Libcall, Types0, Types1);
845 markAllIdxsAsCovered();
853 return actionFor(LegalizeAction::WidenScalar, Types,
Mutation);
862 markAllIdxsAsCovered();
870 return actionFor(LegalizeAction::NarrowScalar, Types,
Mutation);
879 markAllIdxsAsCovered();
888 markAllIdxsAsCovered();
894 markAllIdxsAsCovered();
895 return actionIf(LegalizeAction::Unsupported, always);
898 return actionIf(LegalizeAction::Unsupported,
Predicate);
902 return actionFor(LegalizeAction::Unsupported, Types);
906 return actionIf(LegalizeAction::Unsupported,
914 return actionIf(LegalizeAction::Lower,
922 return actionIf(LegalizeAction::Lower,
929 markAllIdxsAsCovered();
930 return actionIf(LegalizeAction::Custom,
Predicate);
933 return actionFor(LegalizeAction::Custom, Types);
938 return actionFor(LegalizeAction::Custom, Types);
944 return actionFor(LegalizeAction::Custom, Types);
947 std::initializer_list<std::pair<LLT, LLT>> Types) {
950 return actionFor(LegalizeAction::Custom, Types);
954 return actionForCartesianProduct(LegalizeAction::Custom, Types);
960 std::initializer_list<LLT> Types1) {
961 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
967 std::initializer_list<LLT> Types1,
968 std::initializer_list<LLT> Types2) {
969 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1,
977 std::initializer_list<LLT> Types1) {
980 return actionForCartesianProduct(LegalizeAction::Custom, Types0, Types1);
992 unsigned MinSize = 0) {
995 LegalizeAction::WidenScalar, sizeNotPow2(typeIdx(TypeIdx)),
1005 LegalizeAction::WidenScalar, sizeNotMultipleOf(typeIdx(TypeIdx),
Size),
1012 unsigned MinSize = 0) {
1015 LegalizeAction::WidenScalar, scalarOrEltSizeNotPow2(typeIdx(TypeIdx)),
1022 unsigned MinSize = 0) {
1025 LegalizeAction::WidenScalar,
1026 any(scalarOrEltNarrowerThan(TypeIdx, MinSize),
1027 scalarOrEltSizeNotPow2(typeIdx(TypeIdx))),
1033 return actionIf(LegalizeAction::NarrowScalar, isScalar(typeIdx(TypeIdx)),
1039 return actionIf(LegalizeAction::FewerElements, isVector(typeIdx(TypeIdx)),
1045 return actionIf(LegalizeAction::FewerElements,
1046 all(
Predicate, isVector(typeIdx(TypeIdx))),
1054 return actionIf(LegalizeAction::WidenScalar,
1055 scalarOrEltNarrowerThan(TypeIdx, Ty.getScalarSizeInBits()),
1056 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1061 unsigned TypeIdx,
const LLT Ty) {
1064 return actionIf(LegalizeAction::WidenScalar,
1066 TypeIdx, Ty.getScalarSizeInBits())),
1067 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1073 unsigned VectorSize) {
1077 LegalizeAction::WidenScalar,
1079 const LLT VecTy = Query.
Types[TypeIdx];
1083 const LLT VecTy = Query.
Types[TypeIdx];
1085 unsigned MinSize = VectorSize / NumElts;
1088 return std::make_pair(TypeIdx, NewTy);
1096 return actionIf(LegalizeAction::WidenScalar,
1097 scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
1098 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1112 LegalizeAction::WidenScalar,
1114 const LLT QueryTy = Query.
Types[TypeIdx];
1119 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1126 return actionIf(LegalizeAction::NarrowScalar,
1127 scalarOrEltWiderThan(TypeIdx, Ty.getScalarSizeInBits()),
1128 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1135 return actionIf(LegalizeAction::NarrowScalar,
1136 scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
1137 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1148 LegalizeAction::NarrowScalar,
1150 const LLT QueryTy = Query.
Types[TypeIdx];
1155 changeElementSizeTo(typeIdx(TypeIdx), Ty));
1182 LegalizeAction::WidenScalar,
1184 return Query.
Types[LargeTypeIdx].getScalarSizeInBits() >
1185 Query.
Types[TypeIdx].getSizeInBits();
1194 LegalizeAction::NarrowScalar,
1196 return Query.
Types[NarrowTypeIdx].getScalarSizeInBits() <
1197 Query.
Types[TypeIdx].getSizeInBits();
1211 unsigned TypeIdx,
unsigned LargeTypeIdx) {
1215 return Query.
Types[LargeTypeIdx].getScalarSizeInBits() >
1216 Query.
Types[TypeIdx].getScalarSizeInBits() &&
1220 LLT T = Query.
Types[TypeIdx].changeElementSize(
1221 Query.
Types[LargeTypeIdx].getScalarSizeInBits());
1222 return std::make_pair(TypeIdx,
T);
1229 unsigned SmallTypeIdx) {
1233 return Query.
Types[SmallTypeIdx].getScalarSizeInBits() <
1234 Query.
Types[TypeIdx].getScalarSizeInBits() &&
1239 return std::make_pair(TypeIdx,
T);
1248 return actionIf(LegalizeAction::MoreElements,
1249 numElementsNotPow2(typeIdx(TypeIdx)),
1255 unsigned MinElements) {
1259 LegalizeAction::MoreElements,
1267 return std::make_pair(
1277 LegalizeAction::MoreElements,
1286 return std::make_pair(
1293 unsigned MaxElements) {
1297 LegalizeAction::FewerElements,
1307 return std::make_pair(TypeIdx, NewTy);
1319 "Expected element types to agree");
1322 "Unexpected scalable vectors");
1345 add({always, LegalizeAction::UseLegacyRules});
1371 unsigned getOpcodeIdxForOpcode(
unsigned Opcode)
const;
1372 unsigned getActionDefinitionsIdx(
unsigned Opcode)
const;
1403 getActionDefinitionsBuilder(std::initializer_list<unsigned> Opcodes);
1404 void aliasActionDefinitions(
unsigned OpcodeTo,
unsigned OpcodeFrom);
1420 return getAction(Query).Action == LegalizeAction::Legal;
1425 return Action == LegalizeAction::Legal || Action == LegalizeAction::Custom;
1451 virtual unsigned getExtOpcodeForWideningConstant(
LLT SmallTy)
const;
1454 static const int FirstOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_START;
1455 static const int LastOp = TargetOpcode::PRE_ISEL_GENERIC_OPCODE_END;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Atomic ordering constants.
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.
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 bool isScalar() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & clampScalar(bool Pred, unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
LegalizeRuleSet & maxScalarSameAs(unsigned TypeIdx, unsigned NarrowTypeIdx)
Narrow the scalar to match the size of another.
LegalizeRuleSet & widenScalarOrEltToNextPow2OrMinSize(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LegalizeRuleSet & customForCartesianProduct(bool Pred, std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
The instruction is custom when the predicate is true and type indexes 0 and 1 are all in their respec...
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
LegalizeRuleSet & lowerFor(bool Pred, std::initializer_list< std::pair< LLT, LLT > > Types)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list,...
LegalizeRuleSet & maxScalarEltSameAsIf(LegalityPredicate Predicate, unsigned TypeIdx, unsigned SmallTypeIdx)
Conditionally narrow the scalar or elt to match the size of another.
LegalizeRuleSet & unsupported()
The instruction is unsupported.
LegalizeRuleSet & legalFor(bool Pred, std::initializer_list< std::tuple< LLT, LLT, LLT > > Types)
LegalizeRuleSet & scalarSameSizeAs(unsigned TypeIdx, unsigned SameSizeIdx)
Change the type TypeIdx to have the same scalar size as type SameSizeIdx.
LegalizeRuleSet & fewerElementsIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Remove elements to reach the type selected by the mutation if the predicate is true.
LegalizeRuleSet & clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
void aliasTo(unsigned Opcode)
LegalizeRuleSet & bitcastIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
The specified type index is coerced if predicate is true.
LegalizeRuleSet & libcall()
The instruction is emitted as a library call.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
LLVM_ABI bool verifyImmIdxsCoverage(unsigned NumImmIdxs) const
Check if there is no imm index which is obviously not handled by the LegalizeRuleSet in any way at al...
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
LegalizeRuleSet & minScalarOrElt(unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet()=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 & widenScalarFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
Widen the scalar, specified in mutation, when type indexes 0 and 1 is any type pair in the given list...
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1)
LegalizeRuleSet & clampMaxNumElementsStrict(unsigned TypeIdx, const LLT EltTy, unsigned NumElts)
Express EltTy vectors strictly using vectors with NumElts elements (or scalars when NumElts equals 1)...
LegalizeRuleSet & minScalarSameAs(unsigned TypeIdx, unsigned LargeTypeIdx)
Widen the scalar to match the size of another.
LegalizeRuleSet & unsupportedIf(LegalityPredicate Predicate)
LegalizeRuleSet & minScalarOrEltIf(LegalityPredicate Predicate, unsigned TypeIdx, const LLT Ty)
Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet & widenScalarIf(LegalityPredicate Predicate, LegalizeMutation Mutation)
Widen the scalar to the one selected by the mutation if the predicate is true.
LegalizeRuleSet & libcallFor(std::initializer_list< std::pair< LLT, LLT > > Types)
LegalizeRuleSet & customFor(bool Pred, std::initializer_list< LLT > Types)
LegalizeRuleSet & fallback()
Fallback on the previous implementation.
LegalizeRuleSet & legalForTypeWithAnyImm(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list and imm index 0 is anything.
LegalizeRuleSet & lowerForCartesianProduct(std::initializer_list< LLT > Types0, std::initializer_list< LLT > Types1, std::initializer_list< LLT > Types2)
The instruction is lowered when type indexes 0, 1, and 2 are all in their respective lists.
LegalizeRuleSet & 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)
LLVM_ABI bool verifyTypeIdxsCoverage(unsigned NumTypeIdxs) const
Check if there is no type index which is obviously not handled by the LegalizeRuleSet in any way at a...
LegalizeRuleSet & widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned MinSize=0)
Widen the scalar or vector element type to the next power of two that is at least MinSize.
LLVM_ABI LegalizeActionStep apply(const LegalityQuery &Query) const
Apply the ruleset to the given LegalityQuery.
LegalizeRuleSet & lowerFor(std::initializer_list< std::pair< LLT, LLT > > Types, LegalizeMutation Mutation)
The instruction is lowered when type indexes 0 and 1 is any type pair in the given list.
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
LegalizeRuleSet & widenScalarToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar to the next multiple of Size.
A single rule in a legalizer info ruleset.
std::pair< unsigned, LLT > determineMutation(const LegalityQuery &Query) const
Determine the change to make.
bool match(const LegalityQuery &Query) const
Test whether the LegalityQuery matches.
LegalizeRule(LegalityPredicate Predicate, LegalizeAction Action, LegalizeMutation Mutation=nullptr)
LegalizeAction getAction() const
virtual ~LegalizerInfo()=default
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
LegacyLegalizerInfo & getLegacyLegalizerInfo()
bool isLegalOrCustom(const LegalityQuery &Query) const
virtual bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const
Called for instructions with the Custom LegalizationAction.
bool isLegal(const LegalityQuery &Query) const
virtual bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Interface to description of machine instruction set.
Representation of each machine instruction.
A description of a memory reference used in the backend.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
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.
LLVM_ABI LegalityPredicate scalarOrEltWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or a vector with an element type that's wider than the ...
LLVM_ABI LegalityPredicate isScalar(unsigned TypeIdx)
True iff the specified type index is a scalar.
LLVM_ABI LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx)
True iff the specified MMO index has a size (rounded to bytes) that is not a power of 2.
LLVM_ABI LegalityPredicate numElementsNotPow2(unsigned TypeIdx)
True iff the specified type index is a vector whose element count is not a power of 2.
LLVM_ABI LegalityPredicate isPointerVector(unsigned TypeIdx)
True iff the specified type index is a vector of pointers (with any address space).
LLVM_ABI LegalityPredicate isPointer(unsigned TypeIdx)
True iff the specified type index is a pointer (with any address space).
LLVM_ABI LegalityPredicate vectorElementCountIsLessThanOrEqualTo(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's less than or equal to ...
LLVM_ABI LegalityPredicate typeInSet(unsigned TypeIdx, std::initializer_list< LLT > TypesInit)
True iff the given type index is one of the specified types.
LLVM_ABI LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a smaller total bit size than second type index.
LLVM_ABI LegalityPredicate atomicOrderingAtLeastOrStrongerThan(unsigned MMOIdx, AtomicOrdering Ordering)
True iff the specified MMO index has at an atomic ordering of at Ordering or stronger.
LLVM_ABI LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar or vector whose element size is not a power of 2.
LLVM_ABI LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the first type index has a larger total bit size than second type index.
LLVM_ABI LegalityPredicate typePairInSet(unsigned TypeIdx0, unsigned TypeIdx1, std::initializer_list< std::pair< LLT, LLT > > TypesInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate vectorElementCountIsGreaterThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a vector with a number of elements that's greater than the given...
LLVM_ABI LegalityPredicate memSizeNotByteSizePow2(unsigned MMOIdx)
True iff the specified MMO index has a size that is not an even byte size, or that even byte size is ...
Predicate any(Predicate P0, Predicate P1)
True iff P0 or P1 are true.
LLVM_ABI LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy)
True if the type index is a vector with element type EltTy.
LLVM_ABI LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1)
True iff the specified type indices are both the same bit size.
LLVM_ABI LegalityPredicate scalarOrEltNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar or vector with an element type that's narrower than the...
LLVM_ABI LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size)
True if the total bitwidth of the specified type index is Size bits.
LegalityPredicate typeIsNot(unsigned TypeIdx, LLT Type)
True iff the given type index is not the specified type.
LLVM_ABI LegalityPredicate isVector(unsigned TypeIdx)
True iff the specified type index is a vector.
LLVM_ABI LegalityPredicate sizeNotPow2(unsigned TypeIdx)
True iff the specified type index is a scalar whose size is not a power of.
LLVM_ABI LegalityPredicate typeTupleInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned Type2, std::initializer_list< std::tuple< LLT, LLT, LLT > > TypesInit)
True iff the given types for the given tuple of type indexes is one of the specified type tuple.
Predicate all(Predicate P0, Predicate P1)
True iff P0 and P1 are true.
LLVM_ABI LegalityPredicate typePairAndMemDescInSet(unsigned TypeIdx0, unsigned TypeIdx1, unsigned MMOIdx, std::initializer_list< TypePairAndMemDesc > TypesAndMemDescInit)
True iff the given types for the given pair of type indexes is one of the specified type pairs.
LLVM_ABI LegalityPredicate sizeNotMultipleOf(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar whose size is not a multiple of Size.
LLVM_ABI LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit)
True iff the given type index is the specified type.
Predicate predNot(Predicate P)
True iff P is false.
LLVM_ABI LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's wider than the given size.
LLVM_ABI LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size)
True iff the specified type index is a scalar that's narrower than the given size.
@ FewerElements
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
@ Unsupported
This operation is completely unsupported on the target.
@ Lower
The operation itself must be expressed in terms of simpler actions on this target.
@ UseLegacyRules
Fall back onto the old rules.
@ WidenScalar
The operation should be implemented in terms of a wider scalar base-type.
@ Bitcast
Perform the operation on a different, but equivalently sized type.
@ NarrowScalar
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type.
@ Custom
The target wants to do something special with this combination of operand and type.
@ NotFound
Sentinel value for when no action was found in the specified table.
@ MoreElements
The (vector) operation should be implemented by widening the input vector and ignoring the lanes adde...
LLVM_ABI LegalizeMutation moreElementsToNextPow2(unsigned TypeIdx, unsigned Min=0)
Add more elements to the type for the given type index to the next power of.
LLVM_ABI LegalizeMutation changeElementCountTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as TypeIdx, but take the number of elements from FromTypeIdx.
LLVM_ABI LegalizeMutation scalarize(unsigned TypeIdx)
Break up the vector type for the given type index into the element type.
LLVM_ABI LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx)
Keep the same scalar or element type as the given type index.
LLVM_ABI LegalizeMutation widenScalarOrEltToNextPow2(unsigned TypeIdx, unsigned Min=0)
Widen the scalar type or vector element type for the given type index to the next power of 2.
LLVM_ABI LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty)
Select this specific type for the given type index.
LLVM_ABI LegalizeMutation widenScalarOrEltToNextMultipleOf(unsigned TypeIdx, unsigned Size)
Widen the scalar type or vector element type for the given type index to next multiple of Size.
LLVM_ABI LegalizeMutation changeElementSizeTo(unsigned TypeIdx, unsigned FromTypeIdx)
Change the scalar size or element size to have the same scalar size as type index FromIndex.
@ OPERAND_FIRST_GENERIC_IMM
@ OPERAND_LAST_GENERIC_IMM
This is an optimization pass for GlobalISel generic memory operations.
MaybeAlign getAlign(const CallInst &I, unsigned Index)
std::function< std::pair< unsigned, LLT >(const LegalityQuery &)> LegalizeMutation
std::function< bool(const LegalityQuery &)> LegalityPredicate
LLVM_ABI cl::opt< bool > DisableGISelLegalityCheck
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LegacyLegalizeActions::LegacyLegalizeAction Action
The action to take or the final answer.
bool operator==(const TypePairAndMemDesc &Other) const
bool isCompatible(const TypePairAndMemDesc &Other) const
MemDesc(const MachineMemOperand &MMO)
MemDesc(LLT MemoryTy, uint64_t AlignInBits, AtomicOrdering Ordering, AtomicOrdering FailureOrdering)
AtomicOrdering FailureOrdering
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
ArrayRef< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO.
LLVM_ABI raw_ostream & print(raw_ostream &OS) const
constexpr LegalityQuery(unsigned Opcode, ArrayRef< LLT > Types, ArrayRef< MemDesc > MMODescrs={})
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