@@ -459,6 +459,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
459
459
const CodeGenRegisterClass *
460
460
inferRegClassFromPattern (const TreePatternNode &N);
461
461
462
+ const CodeGenRegisterClass *
463
+ inferRegClassFromInstructionPattern (const TreePatternNode &N,
464
+ unsigned ResIdx);
465
+
462
466
Error constrainOperands (action_iterator InsertPt, RuleMatcher &M,
463
467
unsigned InsnID, const TreePatternNode &Dst);
464
468
@@ -1856,46 +1860,85 @@ GlobalISelEmitter::inferRegClassFromPattern(const TreePatternNode &N) {
1856
1860
1857
1861
// Don't want to try and infer things when there could potentially be more
1858
1862
// 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" );
1860
1872
1861
1873
// Handle any special-case instructions which we can safely infer register
1862
1874
// classes from.
1863
1875
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 );
1869
1880
if (!RCChild.isLeaf ())
1870
1881
return nullptr ;
1871
1882
return getRegClassFromLeaf (RCChild);
1872
1883
}
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
+
1873
1894
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.
1874
1899
const TreePatternNode &Child0 = N.getChild (0 );
1875
1900
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 ));
1878
1903
}
1904
+
1879
1905
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 ));
1883
1931
}
1884
1932
1885
1933
// Handle destination record types that we can safely infer a register class
1886
1934
// from.
1887
- const auto &DstIOperand = Inst.Operands [0 ];
1935
+ const auto &DstIOperand = Inst.Operands [ResIdx ];
1888
1936
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" ));
1894
1939
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);
1899
1942
1900
1943
return nullptr ;
1901
1944
}
@@ -2043,8 +2086,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
2043
2086
if (!DstOp->isSubClassOf (" Instruction" ))
2044
2087
return failedImport (" Pattern operator isn't an instruction" );
2045
2088
2046
- auto &DstI = Target.getInstruction (DstOp);
2047
- StringRef DstIName = DstI.TheDef ->getName ();
2089
+ const CodeGenInstruction &DstI = Target.getInstruction (DstOp);
2048
2090
2049
2091
// Count both implicit and explicit defs in the dst instruction.
2050
2092
// This avoids errors importing patterns that have inherent implicit defs.
@@ -2070,68 +2112,24 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
2070
2112
2071
2113
// The root of the match also has constraints on the register bank so that it
2072
2114
// matches the result instruction.
2073
- unsigned OpIdx = 0 ;
2074
2115
unsigned N = std::min (DstExpDefs, SrcNumDefs);
2075
2116
for (unsigned I = 0 ; I < N; ++I) {
2076
- const TypeSetByHwMode &VTy = Src. getExtType (I) ;
2117
+ const auto &DstIOperand = DstI. Operands [I] ;
2077
2118
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);
2124
2120
// The operand names declared in the DstI instruction are unrelated to
2125
2121
// those used in pattern's source and destination DAGs, so mangle the
2126
2122
// former to prevent implicitly adding unexpected
2127
2123
// GIM_CheckIsSameOperand predicates by the defineOperand method.
2128
2124
OM.setSymbolicName (getMangledRootDefName (DstIOperand.Name ));
2129
2125
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);
2135
2133
}
2136
2134
2137
2135
auto DstMIBuilderOrError =
0 commit comments