@@ -155,6 +155,10 @@ static std::string getEncodedEmitStr(StringRef NamedValue, unsigned NumBytes) {
155
155
llvm_unreachable (" Unsupported number of bytes!" );
156
156
}
157
157
158
+ template <class Range > static bool matchersRecordOperand (Range &&R) {
159
+ return any_of (R, [](const auto &I) { return I->recordsOperand (); });
160
+ }
161
+
158
162
// ===- Global Data --------------------------------------------------------===//
159
163
160
164
std::set<LLTCodeGen> llvm::gi::KnownTypes;
@@ -457,6 +461,10 @@ Matcher::~Matcher() {}
457
461
458
462
// ===- GroupMatcher -------------------------------------------------------===//
459
463
464
+ bool GroupMatcher::recordsOperand () const {
465
+ return matchersRecordOperand (Conditions) || matchersRecordOperand (Matchers);
466
+ }
467
+
460
468
bool GroupMatcher::candidateConditionMatches (
461
469
const PredicateMatcher &Predicate) const {
462
470
@@ -486,12 +494,24 @@ std::unique_ptr<PredicateMatcher> GroupMatcher::popFirstCondition() {
486
494
return P;
487
495
}
488
496
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
+
489
506
bool GroupMatcher::addMatcher (Matcher &Candidate) {
490
507
if (!Candidate.hasFirstCondition ())
491
508
return false ;
492
509
510
+ // Only add candidates that have a matching first condition that can be
511
+ // hoisted into the GroupMatcher.
493
512
const PredicateMatcher &Predicate = Candidate.getFirstCondition ();
494
- if (!candidateConditionMatches (Predicate))
513
+ if (!candidateConditionMatches (Predicate) ||
514
+ cannotHoistCondition (Predicate, Candidate))
495
515
return false ;
496
516
497
517
Matchers.push_back (&Candidate);
@@ -509,10 +529,17 @@ void GroupMatcher::finalize() {
509
529
for (const auto &Rule : Matchers)
510
530
if (!Rule->hasFirstCondition ())
511
531
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.
512
534
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]))
515
541
return ;
542
+ }
516
543
517
544
Conditions.push_back (FirstRule.popFirstCondition ());
518
545
for (unsigned I = 1 , E = Matchers.size (); I < E; ++I)
@@ -569,6 +596,12 @@ void GroupMatcher::optimize() {
569
596
570
597
// ===- SwitchMatcher ------------------------------------------------------===//
571
598
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
+
572
605
bool SwitchMatcher::isSupportedPredicateType (const PredicateMatcher &P) {
573
606
return isa<InstructionOpcodeMatcher>(P) || isa<LLTOperandMatcher>(P);
574
607
}
@@ -709,6 +742,10 @@ StringRef RuleMatcher::getOpcode() const {
709
742
return Matchers.front ()->getOpcode ();
710
743
}
711
744
745
+ bool RuleMatcher::recordsOperand () const {
746
+ return matchersRecordOperand (Matchers);
747
+ }
748
+
712
749
LLTCodeGen RuleMatcher::getFirstConditionAsRootType () {
713
750
InstructionMatcher &InsnMatcher = *Matchers.front ();
714
751
if (!InsnMatcher.predicates_empty ())
@@ -1378,6 +1415,10 @@ TempTypeIdx OperandMatcher::getTempTypeIdx(RuleMatcher &Rule) {
1378
1415
return TTIdx;
1379
1416
}
1380
1417
1418
+ bool OperandMatcher::recordsOperand () const {
1419
+ return matchersRecordOperand (Predicates);
1420
+ }
1421
+
1381
1422
void OperandMatcher::emitPredicateOpcodes (MatchTable &Table,
1382
1423
RuleMatcher &Rule) {
1383
1424
if (!Optimized) {
@@ -1759,6 +1800,10 @@ OperandMatcher &InstructionMatcher::addPhysRegInput(const Record *Reg,
1759
1800
return *OM;
1760
1801
}
1761
1802
1803
+ bool InstructionMatcher::recordsOperand () const {
1804
+ return matchersRecordOperand (Predicates) || matchersRecordOperand (operands ());
1805
+ }
1806
+
1762
1807
void InstructionMatcher::emitPredicateOpcodes (MatchTable &Table,
1763
1808
RuleMatcher &Rule) {
1764
1809
if (canAddNumOperandsCheck ()) {
0 commit comments