@@ -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,25 @@ 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+
504+ return Condition.dependsOnOperands () && M.recordsOperand ();
505+ }
506+
489507bool GroupMatcher::addMatcher (Matcher &Candidate) {
490508 if (!Candidate.hasFirstCondition ())
491509 return false ;
492510
511+ // Only add candidates that have a matching first condition that can be
512+ // hoisted into the GroupMatcher.
493513 const PredicateMatcher &Predicate = Candidate.getFirstCondition ();
494- if (!candidateConditionMatches (Predicate))
514+ if (!candidateConditionMatches (Predicate) ||
515+ cannotHoistCondition (Predicate, Candidate))
495516 return false ;
496517
497518 Matchers.push_back (&Candidate);
@@ -509,10 +530,17 @@ void GroupMatcher::finalize() {
509530 for (const auto &Rule : Matchers)
510531 if (!Rule->hasFirstCondition ())
511532 return ;
533+ // Hoist the first condition if it is identical in all matchers in the group
534+ // and it can be hoisted in every matcher.
512535 const auto &FirstCondition = FirstRule.getFirstCondition ();
513- for (unsigned I = 1 , E = Matchers.size (); I < E; ++I)
514- if (!Matchers[I]->getFirstCondition ().isIdentical (FirstCondition))
536+ if (cannotHoistCondition (FirstCondition, FirstRule))
537+ return ;
538+ for (unsigned I = 1 , E = Matchers.size (); I < E; ++I) {
539+ const auto &OtherFirstCondition = Matchers[I]->getFirstCondition ();
540+ if (!OtherFirstCondition.isIdentical (FirstCondition) ||
541+ cannotHoistCondition (OtherFirstCondition, *Matchers[I]))
515542 return ;
543+ }
516544
517545 Conditions.push_back (FirstRule.popFirstCondition ());
518546 for (unsigned I = 1 , E = Matchers.size (); I < E; ++I)
@@ -569,6 +597,12 @@ void GroupMatcher::optimize() {
569597
570598// ===- SwitchMatcher ------------------------------------------------------===//
571599
600+ bool SwitchMatcher::recordsOperand () const {
601+ assert (!isa_and_present<RecordNamedOperandMatcher>(Condition.get ()) &&
602+ " Switch conditions should not record named operands" );
603+ return matchersRecordOperand (Matchers);
604+ }
605+
572606bool SwitchMatcher::isSupportedPredicateType (const PredicateMatcher &P) {
573607 return isa<InstructionOpcodeMatcher>(P) || isa<LLTOperandMatcher>(P);
574608}
@@ -709,6 +743,10 @@ StringRef RuleMatcher::getOpcode() const {
709743 return Matchers.front ()->getOpcode ();
710744}
711745
746+ bool RuleMatcher::recordsOperand () const {
747+ return matchersRecordOperand (Matchers);
748+ }
749+
712750LLTCodeGen RuleMatcher::getFirstConditionAsRootType () {
713751 InstructionMatcher &InsnMatcher = *Matchers.front ();
714752 if (!InsnMatcher.predicates_empty ())
@@ -1378,6 +1416,10 @@ TempTypeIdx OperandMatcher::getTempTypeIdx(RuleMatcher &Rule) {
13781416 return TTIdx;
13791417}
13801418
1419+ bool OperandMatcher::recordsOperand () const {
1420+ return matchersRecordOperand (Predicates);
1421+ }
1422+
13811423void OperandMatcher::emitPredicateOpcodes (MatchTable &Table,
13821424 RuleMatcher &Rule) {
13831425 if (!Optimized) {
@@ -1759,6 +1801,10 @@ OperandMatcher &InstructionMatcher::addPhysRegInput(const Record *Reg,
17591801 return *OM;
17601802}
17611803
1804+ bool InstructionMatcher::recordsOperand () const {
1805+ return matchersRecordOperand (Predicates) || matchersRecordOperand (operands ());
1806+ }
1807+
17621808void InstructionMatcher::emitPredicateOpcodes (MatchTable &Table,
17631809 RuleMatcher &Rule) {
17641810 if (canAddNumOperandsCheck ()) {
0 commit comments