|
14 | 14 | #ifndef LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H |
15 | 15 | #define LLVM_CODEGEN_GLOBALISEL_LEGALIZERINFO_H |
16 | 16 |
|
| 17 | +#include "llvm/ADT/STLExtras.h" |
17 | 18 | #include "llvm/ADT/SmallBitVector.h" |
18 | 19 | #include "llvm/ADT/SmallVector.h" |
19 | 20 | #include "llvm/CodeGen/GlobalISel/LegacyLegalizerInfo.h" |
@@ -365,6 +366,8 @@ LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty); |
365 | 366 | /// Keep the same type as the given type index. |
366 | 367 | LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx); |
367 | 368 |
|
| 369 | +LegalizeMutation changeToInteger(unsigned TypeIdx); |
| 370 | + |
368 | 371 | /// Keep the same scalar or element type as the given type index. |
369 | 372 | LegalizeMutation changeElementTo(unsigned TypeIdx, unsigned FromTypeIdx); |
370 | 373 |
|
@@ -695,6 +698,57 @@ class LegalizeRuleSet { |
695 | 698 | return actionIf(LegalizeAction::Bitcast, Predicate, Mutation); |
696 | 699 | } |
697 | 700 |
|
| 701 | + LegalizeRuleSet &bitcast(unsigned TypeIdx, LLT From, LLT To) { |
| 702 | + assert(From.getScalarSizeInBits() == To.getScalarSizeInBits()); |
| 703 | + return actionIf(LegalizeActions::Bitcast, |
| 704 | + LegalityPredicates::typeIs(TypeIdx, From), |
| 705 | + LegalizeMutations::changeTo(TypeIdx, To)); |
| 706 | + } |
| 707 | + |
| 708 | + LegalizeRuleSet &bitcast(unsigned TypeIdx, LLT To) { |
| 709 | + return actionIf( |
| 710 | + LegalizeActions::Bitcast, |
| 711 | + LegalityPredicates::sizeIs(TypeIdx, To.getScalarSizeInBits()), |
| 712 | + LegalizeMutations::changeTo(TypeIdx, To)); |
| 713 | + } |
| 714 | + |
| 715 | + LegalizeRuleSet &bitcast(unsigned TypeIdx, |
| 716 | + std::initializer_list<std::pair<LLT, LLT>> TypeMap) { |
| 717 | + assert(all_of(TypeMap, |
| 718 | + [](auto &P) { |
| 719 | + return P.first.getScalarSizeInBits() == |
| 720 | + P.second.getScalarSizeInBits(); |
| 721 | + }) && |
| 722 | + "All type pairs must have the same scalar size"); |
| 723 | + |
| 724 | + SmallVector<std::pair<LLT, LLT>, 4> Types = TypeMap; |
| 725 | + auto Predicate = [=](const LegalityQuery &Query) { |
| 726 | + LLT Ty = Query.Types[TypeIdx]; |
| 727 | + return llvm::any_of(Types, [&](auto P) { return P.first == Ty; }); |
| 728 | + }; |
| 729 | + |
| 730 | + auto Mutation = [=](const LegalityQuery &Query) { |
| 731 | + LLT Ty = Query.Types[TypeIdx]; |
| 732 | + auto Map = llvm::find_if(Types, [&](auto P) { return P.first == Ty; }); |
| 733 | + return std::make_pair(TypeIdx, Map->second); |
| 734 | + }; |
| 735 | + |
| 736 | + return actionIf(LegalizeActions::Bitcast, Predicate, Mutation); |
| 737 | + } |
| 738 | + |
| 739 | + LegalizeRuleSet &bitcastToInteger(unsigned TypeIdx) { |
| 740 | + return actionIf(LegalizeActions::Bitcast, |
| 741 | + LegalityPredicates::isScalar(TypeIdx), |
| 742 | + LegalizeMutations::changeToInteger(TypeIdx)); |
| 743 | + } |
| 744 | + |
| 745 | + LegalizeRuleSet &bitcastToInteger(unsigned TypeIdx, |
| 746 | + std::initializer_list<LLT> TypesInit) { |
| 747 | + return actionIf(LegalizeActions::Bitcast, |
| 748 | + LegalityPredicates::typeInSet(TypeIdx, TypesInit), |
| 749 | + LegalizeMutations::changeToInteger(TypeIdx)); |
| 750 | + } |
| 751 | + |
698 | 752 | /// The instruction is lowered. |
699 | 753 | LegalizeRuleSet &lower() { |
700 | 754 | using namespace LegalizeMutations; |
@@ -1117,6 +1171,35 @@ class LegalizeRuleSet { |
1117 | 1171 | return clampScalar(TypeIdx, MinTy, MaxTy); |
1118 | 1172 | } |
1119 | 1173 |
|
| 1174 | + template <typename Func> LegalizeRuleSet &compose(Func F) { |
| 1175 | + LegalizeRuleSet RuleSet; |
| 1176 | + F(RuleSet); |
| 1177 | + |
| 1178 | + for (auto &&[Idx, Rule] : enumerate(RuleSet.Rules)) { |
| 1179 | + LegalityPredicate All = [=](const LegalityQuery &Q) { |
| 1180 | + SmallVector<LLT> Tys(Q.Types); |
| 1181 | + for (auto &Rule : drop_begin(RuleSet.Rules, Idx)) { |
| 1182 | + LegalityQuery NewQ(Q.Opcode, Tys, Q.MMODescrs); |
| 1183 | + if (!Rule.match(NewQ)) |
| 1184 | + return false; |
| 1185 | + |
| 1186 | + auto &&[Idx, Ty] = Rule.determineMutation(Q); |
| 1187 | + Tys[Idx] = Ty; |
| 1188 | + } |
| 1189 | + |
| 1190 | + return true; |
| 1191 | + }; |
| 1192 | + |
| 1193 | + LegalizeMutation Mutation = [=](const LegalityQuery &Q) { |
| 1194 | + return Rule.determineMutation(Q); |
| 1195 | + }; |
| 1196 | + |
| 1197 | + add({All, Rule.getAction(), Mutation}); |
| 1198 | + } |
| 1199 | + |
| 1200 | + return *this; |
| 1201 | + } |
| 1202 | + |
1120 | 1203 | /// Limit the range of scalar sizes to MinTy and MaxTy. |
1121 | 1204 | LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy, |
1122 | 1205 | const LLT MaxTy) { |
|
0 commit comments