@@ -155,6 +155,10 @@ static std::string getEncodedEmitStr(StringRef NamedValue, unsigned NumBytes) {
155155 llvm_unreachable (" Unsupported number of bytes!" );
156156}
157157
158+ template <class Range > static bool matchersRecordOperand (Range &&R) {
159+ return any_of (R, [](const auto &I) { return I->recordsOperand (); });
160+ }
161+
158162// ===- Global Data --------------------------------------------------------===//
159163
160164std::set<LLTCodeGen> llvm::gi::KnownTypes;
@@ -457,6 +461,10 @@ Matcher::~Matcher() {}
457461
458462// ===- GroupMatcher -------------------------------------------------------===//
459463
464+ bool GroupMatcher::recordsOperand () const {
465+ return matchersRecordOperand (Conditions) || matchersRecordOperand (Matchers);
466+ }
467+
460468bool GroupMatcher::candidateConditionMatches (
461469 const PredicateMatcher &Predicate) const {
462470
@@ -486,12 +494,24 @@ std::unique_ptr<PredicateMatcher> GroupMatcher::popFirstCondition() {
486494 return P;
487495}
488496
497+ // / Check if the Condition, which is a predicate of M, cannot be hoisted outside
498+ // / of (i.e., checked before) M.
499+ static bool cannotHoistCondition (const PredicateMatcher &Condition,
500+ const Matcher &M) {
501+ // The condition can't be hoisted if it is a C++ predicate that refers to
502+ // operands and the operands are registered within the matcher.
503+ return Condition.dependsOnOperands () && M.recordsOperand ();
504+ }
505+
489506bool GroupMatcher::addMatcher (Matcher &Candidate) {
490507 if (!Candidate.hasFirstCondition ())
491508 return false ;
492509
510+ // Only add candidates that have a matching first condition that can be
511+ // hoisted into the GroupMatcher.
493512 const PredicateMatcher &Predicate = Candidate.getFirstCondition ();
494- if (!candidateConditionMatches (Predicate))
513+ if (!candidateConditionMatches (Predicate) ||
514+ cannotHoistCondition (Predicate, Candidate))
495515 return false ;
496516
497517 Matchers.push_back (&Candidate);
@@ -509,10 +529,17 @@ void GroupMatcher::finalize() {
509529 for (const auto &Rule : Matchers)
510530 if (!Rule->hasFirstCondition ())
511531 return ;
532+ // Hoist the first condition if it is identical in all matchers in the group
533+ // and it can be hoisted in every matcher.
512534 const auto &FirstCondition = FirstRule.getFirstCondition ();
513- for (unsigned I = 1 , E = Matchers.size (); I < E; ++I)
514- if (!Matchers[I]->getFirstCondition ().isIdentical (FirstCondition))
535+ if (cannotHoistCondition (FirstCondition, FirstRule))
536+ return ;
537+ for (unsigned I = 1 , E = Matchers.size (); I < E; ++I) {
538+ const auto &OtherFirstCondition = Matchers[I]->getFirstCondition ();
539+ if (!OtherFirstCondition.isIdentical (FirstCondition) ||
540+ cannotHoistCondition (OtherFirstCondition, *Matchers[I]))
515541 return ;
542+ }
516543
517544 Conditions.push_back (FirstRule.popFirstCondition ());
518545 for (unsigned I = 1 , E = Matchers.size (); I < E; ++I)
@@ -569,6 +596,12 @@ void GroupMatcher::optimize() {
569596
570597// ===- SwitchMatcher ------------------------------------------------------===//
571598
599+ bool SwitchMatcher::recordsOperand () const {
600+ assert (!isa_and_present<RecordNamedOperandMatcher>(Condition.get ()) &&
601+ " Switch conditions should not record named operands" );
602+ return matchersRecordOperand (Matchers);
603+ }
604+
572605bool SwitchMatcher::isSupportedPredicateType (const PredicateMatcher &P) {
573606 return isa<InstructionOpcodeMatcher>(P) || isa<LLTOperandMatcher>(P);
574607}
@@ -709,6 +742,10 @@ StringRef RuleMatcher::getOpcode() const {
709742 return Matchers.front ()->getOpcode ();
710743}
711744
745+ bool RuleMatcher::recordsOperand () const {
746+ return matchersRecordOperand (Matchers);
747+ }
748+
712749LLTCodeGen RuleMatcher::getFirstConditionAsRootType () {
713750 InstructionMatcher &InsnMatcher = *Matchers.front ();
714751 if (!InsnMatcher.predicates_empty ())
@@ -1378,6 +1415,10 @@ TempTypeIdx OperandMatcher::getTempTypeIdx(RuleMatcher &Rule) {
13781415 return TTIdx;
13791416}
13801417
1418+ bool OperandMatcher::recordsOperand () const {
1419+ return matchersRecordOperand (Predicates);
1420+ }
1421+
13811422void OperandMatcher::emitPredicateOpcodes (MatchTable &Table,
13821423 RuleMatcher &Rule) {
13831424 if (!Optimized) {
@@ -1759,6 +1800,10 @@ OperandMatcher &InstructionMatcher::addPhysRegInput(const Record *Reg,
17591800 return *OM;
17601801}
17611802
1803+ bool InstructionMatcher::recordsOperand () const {
1804+ return matchersRecordOperand (Predicates) || matchersRecordOperand (operands ());
1805+ }
1806+
17621807void InstructionMatcher::emitPredicateOpcodes (MatchTable &Table,
17631808 RuleMatcher &Rule) {
17641809 if (canAddNumOperandsCheck ()) {
0 commit comments