1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

[globalisel][legalizerinfo] Add support for the Lower action in getActionDefinitionsBuilder() and use it in AArch64.

Lower is slightly odd. It often doesn't change the type but the lowerings
do use the new type to decide what code to create. Treat it like a mutation
but provide convenience functions that re-use the existing type.

Re-uses the existing tests:
test/CodeGen/AArch64/GlobalISel/legalize-rem.mir
test/CodeGen/AArch64/GlobalISel//legalize-mul.mir
test/CodeGen/AArch64/GlobalISel//legalize-cmpxchg-with-success.mir

llvm-svn: 329623
This commit is contained in:
Daniel Sanders 2018-04-09 21:10:09 +00:00
parent f45a8841a1
commit e813b4c7f0
4 changed files with 73 additions and 11 deletions

View File

@ -176,6 +176,8 @@ LegalityPredicate numElementsNotPow2(unsigned TypeIdx);
namespace LegalizeMutations {
/// Select this specific type for the given type index.
LegalizeMutation changeTo(unsigned TypeIdx, LLT Ty);
/// Keep the same type as the given type index.
LegalizeMutation changeTo(unsigned TypeIdx, unsigned FromTypeIdx);
/// Widen the type for the given type index to the next power of 2.
LegalizeMutation widenScalarToNextPow2(unsigned TypeIdx, unsigned Min = 0);
/// Add more elements to the type for the given type index to the next power of
@ -235,7 +237,7 @@ class LegalizeRuleSet {
return *this;
}
/// Use the given action when the predicate is true.
/// Action should not be an action that requires mutation.
/// Action should be an action that requires mutation.
LegalizeRuleSet &actionIf(LegalizeAction Action, LegalityPredicate Predicate,
LegalizeMutation Mutation) {
add({Predicate, Action, Mutation});
@ -248,6 +250,14 @@ class LegalizeRuleSet {
using namespace LegalityPredicates;
return actionIf(Action, typeInSet(0, Types));
}
/// Use the given action when type index 0 is any type in the given list.
/// Action should be an action that requires mutation.
LegalizeRuleSet &actionFor(LegalizeAction Action,
std::initializer_list<LLT> Types,
LegalizeMutation Mutation) {
using namespace LegalityPredicates;
return actionIf(Action, typeInSet(0, Types), Mutation);
}
/// Use the given action when type indexes 0 and 1 is any type pair in the
/// given list.
/// Action should not be an action that requires mutation.
@ -257,6 +267,15 @@ class LegalizeRuleSet {
using namespace LegalityPredicates;
return actionIf(Action, typePairInSet(0, 1, Types));
}
/// Use the given action when type indexes 0 and 1 is any type pair in the
/// given list.
/// Action should be an action that requires mutation.
LegalizeRuleSet &actionFor(LegalizeAction Action,
std::initializer_list<std::pair<LLT, LLT>> Types,
LegalizeMutation Mutation) {
using namespace LegalityPredicates;
return actionIf(Action, typePairInSet(0, 1, Types), Mutation);
}
/// Use the given action when type indexes 0 and 1 are both in the given list.
/// That is, the type pair is in the cartesian product of the list.
/// Action should not be an action that requires mutation.
@ -315,6 +334,45 @@ public:
return actionForCartesianProduct(LegalizeAction::Legal, Types0, Types1);
}
/// The instruction is lowered.
LegalizeRuleSet &lower() {
using namespace LegalizeMutations;
return actionIf(LegalizeAction::Lower, always, changeTo(0, 0));
}
/// The instruction is lowered if predicate is true. Keep type index 0 as the
/// same type.
LegalizeRuleSet &lowerIf(LegalityPredicate Predicate) {
using namespace LegalizeMutations;
return actionIf(LegalizeAction::Lower, Predicate, changeTo(0, 0));
}
/// The instruction is lowered when type index 0 is any type in the given
/// list. Keep type index 0 as the same type.
LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types) {
using namespace LegalizeMutations;
return lowerFor(Types, changeTo(0, 0));
}
/// The instruction is lowered when type indexes 0 and 1 is any type pair in the
/// given list. Keep type index 0 as the same type.
LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types) {
return lowerFor(Types, LegalizeMutations::changeTo(0, 0));
}
/// The instruction is lowered when type indexes 0 and 1 is any type pair in the
/// given list.
LegalizeRuleSet &lowerFor(std::initializer_list<std::pair<LLT, LLT>> Types,
LegalizeMutation Mutation) {
return actionFor(LegalizeAction::Lower, Types, Mutation);
}
/// The instruction is lowered if predicate is true.
LegalizeRuleSet &lowerIf(LegalityPredicate Predicate,
LegalizeMutation Mutation) {
return actionIf(LegalizeAction::Lower, Predicate, Mutation);
}
/// The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet &lowerFor(std::initializer_list<LLT> Types,
LegalizeMutation Mutation) {
return actionFor(LegalizeAction::Lower, Types, Mutation);
}
/// Like legalIf, but for the Libcall action.
LegalizeRuleSet &libcallIf(LegalityPredicate Predicate) {
return actionIf(LegalizeAction::Libcall, Predicate);

View File

@ -20,6 +20,13 @@ LegalizeMutation LegalizeMutations::changeTo(unsigned TypeIdx, LLT Ty) {
[=](const LegalityQuery &Query) { return std::make_pair(TypeIdx, Ty); };
}
LegalizeMutation LegalizeMutations::changeTo(unsigned TypeIdx,
unsigned FromTypeIdx) {
return [=](const LegalityQuery &Query) {
return std::make_pair(TypeIdx, Query.Types[FromTypeIdx]);
};
}
LegalizeMutation LegalizeMutations::widenScalarToNextPow2(unsigned TypeIdx,
unsigned Min) {
return [=](const LegalityQuery &Query) {

View File

@ -64,6 +64,7 @@ LegalizeActionStep LegalizeRuleSet::apply(const LegalityQuery &Query) const {
DEBUG(dbgs() << ".. .. " << (unsigned)Rule.getAction() << ", "
<< Mutation.first << ", " << Mutation.second << "\n");
assert((Query.Types[Mutation.first] != Mutation.second ||
Rule.getAction() == Lower ||
Rule.getAction() == MoreElements ||
Rule.getAction() == FewerElements) &&
"Simple loop detected");

View File

@ -81,14 +81,11 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
.clampScalar(0, s32, s64)
.widenScalarToNextPow2(0);
for (unsigned BinOp : {G_SREM, G_UREM})
for (auto Ty : { s1, s8, s16, s32, s64 })
setAction({BinOp, Ty}, Lower);
getActionDefinitionsBuilder({G_SREM, G_UREM})
.lowerFor({s1, s8, s16, s32, s64});
for (unsigned Op : {G_SMULO, G_UMULO}) {
setAction({Op, 0, s64}, Lower);
setAction({Op, 1, s1}, Legal);
}
getActionDefinitionsBuilder({G_SMULO, G_UMULO})
.lowerFor({{s64, s1}});
getActionDefinitionsBuilder({G_SMULH, G_UMULH}).legalFor({s32, s64});
@ -242,9 +239,8 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
}
if (ST.hasLSE()) {
for (auto Ty : {s8, s16, s32, s64}) {
setAction({G_ATOMIC_CMPXCHG_WITH_SUCCESS, Ty}, Lower);
}
getActionDefinitionsBuilder(G_ATOMIC_CMPXCHG_WITH_SUCCESS)
.lowerFor({s8, s16, s32, s64});
getActionDefinitionsBuilder(
{G_ATOMICRMW_XCHG, G_ATOMICRMW_ADD, G_ATOMICRMW_SUB, G_ATOMICRMW_AND,