[llvm] 97ed1b6 - [GISel] Teach TableGen to check predicates of immediate operands in patterns
Dominik Montada via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 30 01:18:52 PDT 2021
Author: Dominik Montada
Date: 2021-04-30T10:18:45+02:00
New Revision: 97ed1b6036074e66dd926b6720f087b9964a7286
URL: https://github.com/llvm/llvm-project/commit/97ed1b6036074e66dd926b6720f087b9964a7286
DIFF: https://github.com/llvm/llvm-project/commit/97ed1b6036074e66dd926b6720f087b9964a7286.diff
LOG: [GISel] Teach TableGen to check predicates of immediate operands in patterns
Reviewed By: dsanders
Differential Revision: https://reviews.llvm.org/D91703
Added:
llvm/test/TableGen/immarg-predicated.td
Modified:
llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
llvm/utils/TableGen/GlobalISelEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index baa32d95eae60..03f4f3bf0b199 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -140,6 +140,11 @@ enum {
/// - InsnID - Instruction ID
/// - The predicate to test
GIM_CheckAPFloatImmPredicate,
+ /// Check an immediate predicate on the specified instruction
+ /// - InsnID - Instruction ID
+ /// - OpIdx - Operand index
+ /// - The predicate to test
+ GIM_CheckImmOperandPredicate,
/// Check a memory operation has the specified atomic ordering.
/// - InsnID - Instruction ID
/// - Ordering - The AtomicOrdering value
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index 82e26b0bc355d..25c07f8b4f28b 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -263,22 +263,27 @@ bool InstructionSelector::executeMatchTable(
}
break;
}
- case GIM_CheckI64ImmPredicate: {
+ case GIM_CheckI64ImmPredicate:
+ case GIM_CheckImmOperandPredicate: {
int64_t InsnID = MatchTable[CurrentIdx++];
+ int64_t OpIdx = MatcherOpcode == GIM_CheckImmOperandPredicate
+ ? MatchTable[CurrentIdx++]
+ : 1;
int64_t Predicate = MatchTable[CurrentIdx++];
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
- dbgs()
- << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs["
- << InsnID << "], Predicate=" << Predicate << ")\n");
+ dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs["
+ << InsnID << "]->getOperand(" << OpIdx
+ << "), Predicate=" << Predicate << ")\n");
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
- assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
- "Expected G_CONSTANT");
+ assert((State.MIs[InsnID]->getOperand(OpIdx).isImm() ||
+ State.MIs[InsnID]->getOperand(OpIdx).isCImm()) &&
+ "Expected immediate operand");
assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
int64_t Value = 0;
- if (State.MIs[InsnID]->getOperand(1).isCImm())
- Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
- else if (State.MIs[InsnID]->getOperand(1).isImm())
- Value = State.MIs[InsnID]->getOperand(1).getImm();
+ if (State.MIs[InsnID]->getOperand(OpIdx).isCImm())
+ Value = State.MIs[InsnID]->getOperand(OpIdx).getCImm()->getSExtValue();
+ else if (State.MIs[InsnID]->getOperand(OpIdx).isImm())
+ Value = State.MIs[InsnID]->getOperand(OpIdx).getImm();
else
llvm_unreachable("Expected Imm or CImm operand");
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index 4c947b5c6696a..8a5052401e9b3 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -50,6 +50,7 @@ def : GINodeEquiv<G_BITCAST, bitconvert>;
// G_INTTOPTR - SelectionDAG has no equivalent.
// G_PTRTOINT - SelectionDAG has no equivalent.
def : GINodeEquiv<G_CONSTANT, imm>;
+// timm must not be materialized and therefore has no GlobalISel equivalent
def : GINodeEquiv<G_FCONSTANT, fpimm>;
def : GINodeEquiv<G_IMPLICIT_DEF, undef>;
def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
diff --git a/llvm/test/TableGen/immarg-predicated.td b/llvm/test/TableGen/immarg-predicated.td
new file mode 100644
index 0000000000000..16db4a80f0597
--- /dev/null
+++ b/llvm/test/TableGen/immarg-predicated.td
@@ -0,0 +1,22 @@
+// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/Common -I %p/../../include %s -o - < %s | FileCheck -check-prefix=GISEL %s
+
+include "llvm/Target/Target.td"
+include "GlobalISelEmitterCommon.td"
+
+let TargetPrefix = "mytarget" in {
+def int_mytarget_sleep0 : Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
+}
+
+// GISEL: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS,
+// GISEL-NEXT: // MIs[0] Operand 0
+// GISEL-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/0, Intrinsic::mytarget_sleep0,
+// GISEL-NEXT: // MIs[0] src
+// GISEL-NEXT: GIM_CheckIsImm, /*MI*/0, /*Op*/1,
+// GISEL-NEXT: GIM_CheckImmOperandPredicate, /*MI*/0, /*MO*/1, /*Predicate*/GIPFP_I64_Predicate_tuimm9,
+// GISEL-NEXT: // (intrinsic_void {{[0-9]+}}:{ *:[iPTR] }, (timm:{ *:[i32] })<<P:Predicate_tuimm9>>:$src) => (SLEEP0 (timm:{ *:[i32] }):$src)
+// GISEL-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SLEEP0,
+// GISEL-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/1, // src
+def tuimm9 : TImmLeaf<i32, [{ return isUInt<9>(Imm); }]>;
+def SLEEP0 : I<(outs), (ins i32imm:$src),
+ [(int_mytarget_sleep0 tuimm9:$src)]
+>;
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index a6bfad1ad8c78..9a869de138f3d 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -90,7 +90,7 @@ std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
}
/// Get the opcode used to check this predicate.
-std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
+std::string getMatchOpcodeForImmPredicate(const TreePredicateFn &Predicate) {
return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
}
@@ -1562,6 +1562,40 @@ class IntrinsicIDOperandMatcher : public OperandPredicateMatcher {
}
};
+/// Generates code to check that this operand is an immediate whose value meets
+/// an immediate predicate.
+class OperandImmPredicateMatcher : public OperandPredicateMatcher {
+protected:
+ TreePredicateFn Predicate;
+
+public:
+ OperandImmPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
+ const TreePredicateFn &Predicate)
+ : OperandPredicateMatcher(IPM_ImmPredicate, InsnVarID, OpIdx),
+ Predicate(Predicate) {}
+
+ bool isIdentical(const PredicateMatcher &B) const override {
+ return OperandPredicateMatcher::isIdentical(B) &&
+ Predicate.getOrigPatFragRecord() ==
+ cast<OperandImmPredicateMatcher>(&B)
+ ->Predicate.getOrigPatFragRecord();
+ }
+
+ static bool classof(const PredicateMatcher *P) {
+ return P->getKind() == IPM_ImmPredicate;
+ }
+
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ Table << MatchTable::Opcode("GIM_CheckImmOperandPredicate")
+ << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
+ << MatchTable::Comment("MO") << MatchTable::IntValue(OpIdx)
+ << MatchTable::Comment("Predicate")
+ << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
+ << MatchTable::LineBreak;
+ }
+};
+
/// Generates code to check that a set of predicates match for a particular
/// operand.
class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
@@ -1924,7 +1958,7 @@ class InstructionImmPredicateMatcher : public InstructionPredicateMatcher {
void emitPredicateOpcodes(MatchTable &Table,
RuleMatcher &Rule) const override {
- Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
+ Table << MatchTable::Opcode(getMatchOpcodeForImmPredicate(Predicate))
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Predicate")
<< MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
@@ -4152,6 +4186,17 @@ Error GlobalISelEmitter::importChildMatcher(
}
if (SrcChild->getOperator()->getName() == "timm") {
OM.addPredicate<ImmOperandMatcher>();
+
+ // Add predicates, if any
+ for (const TreePredicateCall &Call : SrcChild->getPredicateCalls()) {
+ const TreePredicateFn &Predicate = Call.Fn;
+
+ // Only handle immediate patterns for now
+ if (Predicate.isImmediatePattern()) {
+ OM.addPredicate<OperandImmPredicateMatcher>(Predicate);
+ }
+ }
+
return Error::success();
}
}
More information about the llvm-commits
mailing list