@@ -459,6 +459,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
459459 const CodeGenRegisterClass *
460460 inferRegClassFromPattern (const TreePatternNode &N);
461461
462+ const CodeGenRegisterClass *
463+ inferRegClassFromInstructionPattern (const TreePatternNode &N,
464+ unsigned ResIdx);
465+
462466 Error constrainOperands (action_iterator InsertPt, RuleMatcher &M,
463467 unsigned InsnID, const TreePatternNode &Dst);
464468
@@ -1856,46 +1860,85 @@ GlobalISelEmitter::inferRegClassFromPattern(const TreePatternNode &N) {
18561860
18571861 // Don't want to try and infer things when there could potentially be more
18581862 // than one candidate register class.
1859- auto &Inst = Target.getInstruction (OpRec);
1863+ return inferRegClassFromInstructionPattern (N, /* ResIdx=*/ 0 );
1864+ }
1865+
1866+ const CodeGenRegisterClass *
1867+ GlobalISelEmitter::inferRegClassFromInstructionPattern (const TreePatternNode &N,
1868+ unsigned ResIdx) {
1869+ const CodeGenInstruction &Inst = Target.getInstruction (N.getOperator ());
1870+ assert (ResIdx < Inst.Operands .NumDefs &&
1871+ " Can only infer register class for explicit defs" );
18601872
18611873 // Handle any special-case instructions which we can safely infer register
18621874 // classes from.
18631875 StringRef InstName = Inst.TheDef ->getName ();
1864- bool IsRegSequence = InstName == " REG_SEQUENCE" ;
1865- if (IsRegSequence || InstName == " COPY_TO_REGCLASS" ) {
1866- // If we have a COPY_TO_REGCLASS, then we need to handle it specially. It
1867- // has the desired register class as the first child.
1868- const TreePatternNode &RCChild = N.getChild (IsRegSequence ? 0 : 1 );
1876+ if (InstName == " REG_SEQUENCE" ) {
1877+ // (outs $super_dst), (ins $dst_regclass, variable_ops)
1878+ // Destination register class is explicitly specified by the first operand.
1879+ const TreePatternNode &RCChild = N.getChild (0 );
18691880 if (!RCChild.isLeaf ())
18701881 return nullptr ;
18711882 return getRegClassFromLeaf (RCChild);
18721883 }
1884+
1885+ if (InstName == " COPY_TO_REGCLASS" ) {
1886+ // (outs $dst), (ins $src, $dst_regclass)
1887+ // Destination register class is explicitly specified by the second operand.
1888+ const TreePatternNode &RCChild = N.getChild (1 );
1889+ if (!RCChild.isLeaf ())
1890+ return nullptr ;
1891+ return getRegClassFromLeaf (RCChild);
1892+ }
1893+
18731894 if (InstName == " INSERT_SUBREG" ) {
1895+ // (outs $super_dst), (ins $super_src, $sub_src, $sub_idx);
1896+ // If we can infer the register class for the first operand, use that.
1897+ // Otherwise, find a register class that supports both the specified
1898+ // sub-register index and the type of the instruction's result.
18741899 const TreePatternNode &Child0 = N.getChild (0 );
18751900 assert (Child0.getNumTypes () == 1 && " Unexpected number of types!" );
1876- const TypeSetByHwMode &VTy = Child0 .getExtType (0 );
1877- return inferSuperRegisterClassForNode (VTy, Child0, N.getChild (2 ));
1901+ return inferSuperRegisterClassForNode (N .getExtType (0 ), Child0,
1902+ N.getChild (2 ));
18781903 }
1904+
18791905 if (InstName == " EXTRACT_SUBREG" ) {
1880- assert (N.getNumTypes () == 1 && " Unexpected number of types!" );
1881- const TypeSetByHwMode &VTy = N.getExtType (0 );
1882- return inferSuperRegisterClass (VTy, N.getChild (1 ));
1906+ // (outs $sub_dst), (ins $super_src, $sub_idx)
1907+ // Find a register class that can be used for a sub-register copy from
1908+ // the specified source at the specified sub-register index.
1909+ const CodeGenRegisterClass *SuperRC =
1910+ inferRegClassFromPattern (N.getChild (0 ));
1911+ if (!SuperRC)
1912+ return nullptr ;
1913+
1914+ const CodeGenSubRegIndex *SubIdx = inferSubRegIndexForNode (N.getChild (1 ));
1915+ if (!SubIdx)
1916+ return nullptr ;
1917+
1918+ const auto SubRCAndSubRegRC =
1919+ SuperRC->getMatchingSubClassWithSubRegs (CGRegs, SubIdx);
1920+ if (!SubRCAndSubRegRC)
1921+ return nullptr ;
1922+
1923+ return SubRCAndSubRegRC->second ;
1924+ }
1925+
1926+ if (InstName == " SUBREG_TO_REG" ) {
1927+ // (outs $super_dst), (ins $super_src, $sub_src, $sub_idx)
1928+ // Find a register class that supports both the specified sub-register
1929+ // index and the type of the instruction's result.
1930+ return inferSuperRegisterClass (N.getExtType (0 ), N.getChild (2 ));
18831931 }
18841932
18851933 // Handle destination record types that we can safely infer a register class
18861934 // from.
1887- const auto &DstIOperand = Inst.Operands [0 ];
1935+ const auto &DstIOperand = Inst.Operands [ResIdx ];
18881936 const Record *DstIOpRec = DstIOperand.Rec ;
1889- if (DstIOpRec->isSubClassOf (" RegisterOperand" )) {
1890- DstIOpRec = DstIOpRec->getValueAsDef (" RegClass" );
1891- const CodeGenRegisterClass &RC = Target.getRegisterClass (DstIOpRec);
1892- return &RC;
1893- }
1937+ if (DstIOpRec->isSubClassOf (" RegisterOperand" ))
1938+ return &Target.getRegisterClass (DstIOpRec->getValueAsDef (" RegClass" ));
18941939
1895- if (DstIOpRec->isSubClassOf (" RegisterClass" )) {
1896- const CodeGenRegisterClass &RC = Target.getRegisterClass (DstIOpRec);
1897- return &RC;
1898- }
1940+ if (DstIOpRec->isSubClassOf (" RegisterClass" ))
1941+ return &Target.getRegisterClass (DstIOpRec);
18991942
19001943 return nullptr ;
19011944}
@@ -2043,8 +2086,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
20432086 if (!DstOp->isSubClassOf (" Instruction" ))
20442087 return failedImport (" Pattern operator isn't an instruction" );
20452088
2046- auto &DstI = Target.getInstruction (DstOp);
2047- StringRef DstIName = DstI.TheDef ->getName ();
2089+ const CodeGenInstruction &DstI = Target.getInstruction (DstOp);
20482090
20492091 // Count both implicit and explicit defs in the dst instruction.
20502092 // This avoids errors importing patterns that have inherent implicit defs.
@@ -2070,68 +2112,24 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
20702112
20712113 // The root of the match also has constraints on the register bank so that it
20722114 // matches the result instruction.
2073- unsigned OpIdx = 0 ;
20742115 unsigned N = std::min (DstExpDefs, SrcNumDefs);
20752116 for (unsigned I = 0 ; I < N; ++I) {
2076- const TypeSetByHwMode &VTy = Src. getExtType (I) ;
2117+ const auto &DstIOperand = DstI. Operands [I] ;
20772118
2078- const auto &DstIOperand = DstI.Operands [OpIdx];
2079- PointerUnion<const Record *, const CodeGenRegisterClass *> MatchedRC =
2080- DstIOperand.Rec ;
2081- if (DstIName == " COPY_TO_REGCLASS" ) {
2082- MatchedRC = getInitValueAsRegClass (Dst.getChild (1 ).getLeafValue ());
2083-
2084- if (MatchedRC.isNull ())
2085- return failedImport (
2086- " COPY_TO_REGCLASS operand #1 isn't a register class" );
2087- } else if (DstIName == " REG_SEQUENCE" ) {
2088- MatchedRC = getInitValueAsRegClass (Dst.getChild (0 ).getLeafValue ());
2089- if (MatchedRC.isNull ())
2090- return failedImport (" REG_SEQUENCE operand #0 isn't a register class" );
2091- } else if (DstIName == " EXTRACT_SUBREG" ) {
2092- const CodeGenRegisterClass *InferredClass =
2093- inferRegClassFromPattern (Dst.getChild (0 ));
2094- if (!InferredClass)
2095- return failedImport (
2096- " Could not infer class for EXTRACT_SUBREG operand #0" );
2097-
2098- // We can assume that a subregister is in the same bank as it's super
2099- // register.
2100- MatchedRC = InferredClass->getDef ();
2101- } else if (DstIName == " INSERT_SUBREG" ) {
2102- const CodeGenRegisterClass *MaybeSuperClass =
2103- inferSuperRegisterClassForNode (VTy, Dst.getChild (0 ), Dst.getChild (2 ));
2104- if (!MaybeSuperClass)
2105- return failedImport (
2106- " Cannot infer register class for INSERT_SUBREG operand #0" );
2107- // Move to the next pattern here, because the register class we found
2108- // doesn't necessarily have a record associated with it. So, we can't
2109- // set DstIOpRec using this.
2110- MatchedRC = MaybeSuperClass;
2111- } else if (DstIName == " SUBREG_TO_REG" ) {
2112- const CodeGenRegisterClass *MaybeRegClass =
2113- inferSuperRegisterClass (VTy, Dst.getChild (2 ));
2114- if (!MaybeRegClass)
2115- return failedImport (
2116- " Cannot infer register class for SUBREG_TO_REG operand #0" );
2117- MatchedRC = MaybeRegClass;
2118- } else if (cast<const Record *>(MatchedRC)->isSubClassOf (" RegisterOperand" ))
2119- MatchedRC = cast<const Record *>(MatchedRC)->getValueAsDef (" RegClass" );
2120- else if (!cast<const Record *>(MatchedRC)->isSubClassOf (" RegisterClass" ))
2121- return failedImport (" Dst MI def isn't a register class" + to_string (Dst));
2122-
2123- OperandMatcher &OM = InsnMatcher.getOperand (OpIdx);
2119+ OperandMatcher &OM = InsnMatcher.getOperand (I);
21242120 // The operand names declared in the DstI instruction are unrelated to
21252121 // those used in pattern's source and destination DAGs, so mangle the
21262122 // former to prevent implicitly adding unexpected
21272123 // GIM_CheckIsSameOperand predicates by the defineOperand method.
21282124 OM.setSymbolicName (getMangledRootDefName (DstIOperand.Name ));
21292125 M.defineOperand (OM.getSymbolicName (), OM);
2130- if (auto *R = dyn_cast<const Record *>(MatchedRC))
2131- MatchedRC = &Target.getRegisterClass (R);
2132- OM.addPredicate <RegisterBankOperandMatcher>(
2133- *cast<const CodeGenRegisterClass *>(MatchedRC));
2134- ++OpIdx;
2126+
2127+ const CodeGenRegisterClass *RC =
2128+ inferRegClassFromInstructionPattern (Dst, I);
2129+ if (!RC)
2130+ return failedImport (" Could not infer register class for result #" +
2131+ Twine (I) + " from pattern " + to_string (Dst));
2132+ OM.addPredicate <RegisterBankOperandMatcher>(*RC);
21352133 }
21362134
21372135 auto DstMIBuilderOrError =
0 commit comments