diff options
author | jofrn <jofernau@amd.com> | 2024-05-20 06:18:49 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-20 06:18:49 -0800 |
commit | d0dc29c2084a18c33b1b5b1cad9fd42215869746 (patch) | |
tree | cd009a9ebefa8a2f682aff82a103cdfb0add9120 /llvm/utils/TableGen/Common | |
parent | 1553b21f6d3b620b8e32121b974793342820ab8c (diff) | |
download | llvm-d0dc29c2084a18c33b1b5b1cad9fd42215869746.zip llvm-d0dc29c2084a18c33b1b5b1cad9fd42215869746.tar.gz llvm-d0dc29c2084a18c33b1b5b1cad9fd42215869746.tar.bz2 |
[TableGen] HasOneUse builtin predicate on PatFrags (#91578)
This predicate tells GlobalISelEmitter and DAGISelEmitter to check that
the instruction to emit has only one use of its result. This can be used
on a PatFrag instead of defining custom predicates for both emitters per
record that requires it.
Diffstat (limited to 'llvm/utils/TableGen/Common')
-rw-r--r-- | llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp | 7 | ||||
-rw-r--r-- | llvm/utils/TableGen/Common/CodeGenDAGPatterns.h | 2 | ||||
-rw-r--r-- | llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h | 23 |
3 files changed, 31 insertions, 1 deletions
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp index 88d353e..709aa00 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp @@ -903,7 +903,7 @@ TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) { } bool TreePredicateFn::hasPredCode() const { - return isLoad() || isStore() || isAtomic() || hasNoUse() || + return isLoad() || isStore() || isAtomic() || hasNoUse() || hasOneUse() || !PatFragRec->getRecord()->getValueAsString("PredicateCode").empty(); } @@ -1140,6 +1140,8 @@ std::string TreePredicateFn::getPredCode() const { if (hasNoUse()) Code += "if (!SDValue(N, 0).use_empty()) return false;\n"; + if (hasOneUse()) + Code += "if (!SDValue(N, 0).hasOneUse()) return false;\n"; std::string PredicateCode = std::string(PatFragRec->getRecord()->getValueAsString("PredicateCode")); @@ -1187,6 +1189,9 @@ bool TreePredicateFn::usesOperands() const { bool TreePredicateFn::hasNoUse() const { return isPredefinedPredicateEqualTo("HasNoUse", true); } +bool TreePredicateFn::hasOneUse() const { + return isPredefinedPredicateEqualTo("HasOneUse", true); +} bool TreePredicateFn::isLoad() const { return isPredefinedPredicateEqualTo("IsLoad", true); } diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h index 7f94db0..1f4d45d8 100644 --- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h +++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h @@ -533,6 +533,8 @@ public: // Check if the HasNoUse predicate is set. bool hasNoUse() const; + // Check if the HasOneUse predicate is set. + bool hasOneUse() const; // Is the desired predefined predicate for a load? bool isLoad() const; diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h index 5fe3f9a..edddc05 100644 --- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h +++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h @@ -806,6 +806,7 @@ public: IPM_MemoryAlignment, IPM_VectorSplatImm, IPM_NoUse, + IPM_OneUse, IPM_GenericPredicate, IPM_MIFlags, OPM_SameOperand, @@ -1691,6 +1692,28 @@ public: } }; +/// Generates code to check that the first result has only one use. +class OneUsePredicateMatcher : public InstructionPredicateMatcher { +public: + OneUsePredicateMatcher(unsigned InsnVarID) + : InstructionPredicateMatcher(IPM_OneUse, InsnVarID) {} + + static bool classof(const PredicateMatcher *P) { + return P->getKind() == IPM_OneUse; + } + + bool isIdentical(const PredicateMatcher &B) const override { + return InstructionPredicateMatcher::isIdentical(B); + } + + void emitPredicateOpcodes(MatchTable &Table, + RuleMatcher &Rule) const override { + Table << MatchTable::Opcode("GIM_CheckHasOneUse") + << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID) + << MatchTable::LineBreak; + } +}; + /// Generates code to check that a set of predicates and operands match for a /// particular instruction. /// |