@@ -581,6 +581,16 @@ class InstructionPattern : public Pattern {
581
581
InstructionOperand &getOperand (unsigned K) { return Operands[K]; }
582
582
const InstructionOperand &getOperand (unsigned K) const { return Operands[K]; }
583
583
584
+ // / When this InstructionPattern is used as the match root, returns the
585
+ // / operands that must be redefined in the 'apply' pattern for the rule to be
586
+ // / valid.
587
+ // /
588
+ // / For CodeGenInstructionPatterns, this just returns the defs of the CGI.
589
+ // / For PatFrag this only returns the root of the PF.
590
+ // /
591
+ // / Returns an empty array on error.
592
+ virtual ArrayRef<InstructionOperand> getApplyDefsNeeded () const = 0;
593
+
584
594
auto named_operands () {
585
595
return make_filter_range (Operands,
586
596
[&](auto &O) { return O.isNamedOperand (); });
@@ -760,6 +770,8 @@ class CodeGenInstructionPattern : public InstructionPattern {
760
770
unsigned getNumInstDefs () const override ;
761
771
unsigned getNumInstOperands () const override ;
762
772
773
+ ArrayRef<InstructionOperand> getApplyDefsNeeded () const override ;
774
+
763
775
const CodeGenInstruction &getInst () const { return I; }
764
776
StringRef getInstName () const override { return I.TheDef ->getName (); }
765
777
@@ -798,6 +810,11 @@ unsigned CodeGenInstructionPattern::getNumInstOperands() const {
798
810
: NumCGIOps;
799
811
}
800
812
813
+ ArrayRef<InstructionOperand>
814
+ CodeGenInstructionPattern::getApplyDefsNeeded () const {
815
+ return {operands ().begin (), getNumInstDefs ()};
816
+ }
817
+
801
818
// ===- OperandTypeChecker -------------------------------------------------===//
802
819
803
820
// / This is a trivial type checker for all operands in a set of
@@ -1078,12 +1095,24 @@ bool PatFrag::checkSemantics() {
1078
1095
1079
1096
// Check this operand is defined in all alternative's patterns.
1080
1097
for (const auto &Alt : Alts) {
1081
- if (!Alt.OpTable .getDef (Op.Name )) {
1098
+ const auto *OpDef = Alt.OpTable .getDef (Op.Name );
1099
+ if (!OpDef) {
1082
1100
PrintError (" output parameter '" + Op.Name +
1083
1101
" ' must be defined by all alternative patterns in '" +
1084
1102
Def.getName () + " '" );
1085
1103
return false ;
1086
1104
}
1105
+
1106
+ if (Op.Kind == PK_Root && OpDef->getNumInstDefs () != 1 ) {
1107
+ // The instruction that defines the root must have a single def.
1108
+ // Otherwise we'd need to support multiple roots and it gets messy.
1109
+ //
1110
+ // e.g. this is not supported:
1111
+ // (pattern (G_UNMERGE_VALUES $x, $root, $vec))
1112
+ PrintError (" all instructions that define root '" + Op.Name + " ' in '" +
1113
+ Def.getName () + " ' can only have a single output operand" );
1114
+ return false ;
1115
+ }
1087
1116
}
1088
1117
1089
1118
SeenOps.insert (Op.Name );
@@ -1232,6 +1261,8 @@ class PatFragPattern : public InstructionPattern {
1232
1261
unsigned getNumInstDefs () const override { return PF.num_out_params (); }
1233
1262
unsigned getNumInstOperands () const override { return PF.num_params (); }
1234
1263
1264
+ ArrayRef<InstructionOperand> getApplyDefsNeeded () const override ;
1265
+
1235
1266
bool checkSemantics (ArrayRef<SMLoc> DiagLoc) override ;
1236
1267
1237
1268
// / Before emitting the patterns inside the PatFrag, add all necessary code
@@ -1258,6 +1289,16 @@ class PatFragPattern : public InstructionPattern {
1258
1289
const PatFrag &PF;
1259
1290
};
1260
1291
1292
+ ArrayRef<InstructionOperand> PatFragPattern::getApplyDefsNeeded () const {
1293
+ assert (PF.num_roots () == 1 );
1294
+ // Only roots need to be redef.
1295
+ for (auto [Idx, Param] : enumerate(PF.out_params ())) {
1296
+ if (Param.Kind == PatFrag::PK_Root)
1297
+ return getOperand (Idx);
1298
+ }
1299
+ llvm_unreachable (" root not found!" );
1300
+ }
1301
+
1261
1302
bool PatFragPattern::checkSemantics (ArrayRef<SMLoc> DiagLoc) {
1262
1303
if (!InstructionPattern::checkSemantics (DiagLoc))
1263
1304
return false ;
@@ -1990,16 +2031,14 @@ bool CombineRuleBuilder::findRoots() {
1990
2031
1991
2032
// Collect all redefinitions of the MatchRoot's defs and put them in
1992
2033
// ApplyRoots.
1993
- for ( unsigned K = 0 ; K < IPRoot->getNumInstDefs (); ++K) {
1994
- auto &O = IPRoot-> getOperand (K);
1995
- assert (O .isDef () && O .isNamedOperand ());
1996
- StringRef Name = O .getOperandName ();
2034
+ const auto DefsNeeded = IPRoot->getApplyDefsNeeded ();
2035
+ for ( auto &Op : DefsNeeded) {
2036
+ assert (Op .isDef () && Op .isNamedOperand ());
2037
+ StringRef Name = Op .getOperandName ();
1997
2038
1998
2039
auto *ApplyRedef = ApplyOpTable.getDef (Name);
1999
2040
if (!ApplyRedef) {
2000
- PrintError (" def of pattern root '" + Name +
2001
- " ' is not redefined in the apply pattern!" );
2002
- PrintNote (" match pattern root is '" + MatchRoot->getName () + " '" );
2041
+ PrintError (" '" + Name + " ' must be redefined in the 'apply' pattern" );
2003
2042
return false ;
2004
2043
}
2005
2044
0 commit comments