@@ -460,6 +460,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
460
460
std::optional<const CodeGenRegisterClass *>
461
461
inferRegClassFromPattern (const TreePatternNode &N);
462
462
463
+ Error constrainOperands (action_iterator InsertPt, RuleMatcher &M,
464
+ unsigned InsnID, const TreePatternNode &Dst);
465
+
463
466
// / Return the size of the MemoryVT in this predicate, if possible.
464
467
std::optional<unsigned >
465
468
getMemSizeBitsFromPredicate (const TreePredicateFn &Predicate);
@@ -1409,103 +1412,10 @@ GlobalISelEmitter::createAndImportSubInstructionRenderer(
1409
1412
if (auto Error = InsertPtOrError.takeError ())
1410
1413
return std::move (Error);
1411
1414
1412
- // We need to make sure that when we import an INSERT_SUBREG as a
1413
- // subinstruction that it ends up being constrained to the correct super
1414
- // register and subregister classes.
1415
- auto OpName = Target.getInstruction (Dst.getOperator ()).TheDef ->getName ();
1416
- if (OpName == " INSERT_SUBREG" ) {
1417
- auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
1418
- if (!SubClass)
1419
- return failedImport (
1420
- " Cannot infer register class from INSERT_SUBREG operand #1" );
1421
- std::optional<const CodeGenRegisterClass *> SuperClass =
1422
- inferSuperRegisterClassForNode (Dst.getExtType (0 ), Dst.getChild (0 ),
1423
- Dst.getChild (2 ));
1424
- if (!SuperClass)
1425
- return failedImport (
1426
- " Cannot infer register class for INSERT_SUBREG operand #0" );
1427
- // The destination and the super register source of an INSERT_SUBREG must
1428
- // be the same register class.
1429
- M.insertAction <ConstrainOperandToRegClassAction>(
1430
- InsertPt, DstMIBuilder.getInsnID (), 0 , **SuperClass);
1431
- M.insertAction <ConstrainOperandToRegClassAction>(
1432
- InsertPt, DstMIBuilder.getInsnID (), 1 , **SuperClass);
1433
- M.insertAction <ConstrainOperandToRegClassAction>(
1434
- InsertPt, DstMIBuilder.getInsnID (), 2 , **SubClass);
1435
- return InsertPtOrError.get ();
1436
- }
1437
-
1438
- if (OpName == " EXTRACT_SUBREG" ) {
1439
- // EXTRACT_SUBREG selects into a subregister COPY but unlike most
1440
- // instructions, the result register class is controlled by the
1441
- // subregisters of the operand. As a result, we must constrain the result
1442
- // class rather than check that it's already the right one.
1443
- auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
1444
- if (!SuperClass)
1445
- return failedImport (
1446
- " Cannot infer register class from EXTRACT_SUBREG operand #0" );
1447
-
1448
- auto SubIdx = inferSubRegIndexForNode (Dst.getChild (1 ));
1449
- if (!SubIdx)
1450
- return failedImport (" EXTRACT_SUBREG child #1 is not a subreg index" );
1451
-
1452
- const auto SrcRCDstRCPair =
1453
- (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
1454
- assert (SrcRCDstRCPair->second && " Couldn't find a matching subclass" );
1455
- M.insertAction <ConstrainOperandToRegClassAction>(
1456
- InsertPt, DstMIBuilder.getInsnID (), 0 , *SrcRCDstRCPair->second );
1457
- M.insertAction <ConstrainOperandToRegClassAction>(
1458
- InsertPt, DstMIBuilder.getInsnID (), 1 , *SrcRCDstRCPair->first );
1459
-
1460
- // We're done with this pattern! It's eligible for GISel emission; return
1461
- // it.
1462
- return InsertPtOrError.get ();
1463
- }
1464
-
1465
- // Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a
1466
- // subinstruction.
1467
- if (OpName == " SUBREG_TO_REG" ) {
1468
- auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
1469
- if (!SubClass)
1470
- return failedImport (
1471
- " Cannot infer register class from SUBREG_TO_REG child #1" );
1472
- auto SuperClass =
1473
- inferSuperRegisterClass (Dst.getExtType (0 ), Dst.getChild (2 ));
1474
- if (!SuperClass)
1475
- return failedImport (
1476
- " Cannot infer register class for SUBREG_TO_REG operand #0" );
1477
- M.insertAction <ConstrainOperandToRegClassAction>(
1478
- InsertPt, DstMIBuilder.getInsnID (), 0 , **SuperClass);
1479
- M.insertAction <ConstrainOperandToRegClassAction>(
1480
- InsertPt, DstMIBuilder.getInsnID (), 2 , **SubClass);
1481
- return InsertPtOrError.get ();
1482
- }
1483
-
1484
- if (OpName == " REG_SEQUENCE" ) {
1485
- auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
1486
- M.insertAction <ConstrainOperandToRegClassAction>(
1487
- InsertPt, DstMIBuilder.getInsnID (), 0 , **SuperClass);
1488
-
1489
- unsigned Num = Dst.getNumChildren ();
1490
- for (unsigned I = 1 ; I != Num; I += 2 ) {
1491
- const TreePatternNode &SubRegChild = Dst.getChild (I + 1 );
1492
-
1493
- auto SubIdx = inferSubRegIndexForNode (SubRegChild);
1494
- if (!SubIdx)
1495
- return failedImport (" REG_SEQUENCE child is not a subreg index" );
1496
-
1497
- const auto SrcRCDstRCPair =
1498
- (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
1499
- assert (SrcRCDstRCPair->second && " Couldn't find a matching subclass" );
1500
- M.insertAction <ConstrainOperandToRegClassAction>(
1501
- InsertPt, DstMIBuilder.getInsnID (), I, *SrcRCDstRCPair->second );
1502
- }
1503
-
1504
- return InsertPtOrError.get ();
1505
- }
1415
+ if (auto Error =
1416
+ constrainOperands (InsertPt, M, DstMIBuilder.getInsnID (), Dst))
1417
+ return std::move (Error);
1506
1418
1507
- M.insertAction <ConstrainOperandsToDefinitionAction>(InsertPt,
1508
- DstMIBuilder.getInsnID ());
1509
1419
return InsertPtOrError.get ();
1510
1420
}
1511
1421
@@ -1794,6 +1704,116 @@ Error GlobalISelEmitter::importImplicitDefRenderers(
1794
1704
return Error::success ();
1795
1705
}
1796
1706
1707
+ Error GlobalISelEmitter::constrainOperands (action_iterator InsertPt,
1708
+ RuleMatcher &M, unsigned InsnID,
1709
+ const TreePatternNode &Dst) {
1710
+ const Record *DstOp = Dst.getOperator ();
1711
+ const CodeGenInstruction &DstI = Target.getInstruction (DstOp);
1712
+ StringRef DstIName = DstI.TheDef ->getName ();
1713
+
1714
+ if (DstIName == " COPY_TO_REGCLASS" ) {
1715
+ // COPY_TO_REGCLASS does not provide operand constraints itself but the
1716
+ // result is constrained to the class given by the second child.
1717
+ const Record *DstIOpRec =
1718
+ getInitValueAsRegClass (Dst.getChild (1 ).getLeafValue ());
1719
+
1720
+ if (DstIOpRec == nullptr )
1721
+ return failedImport (" COPY_TO_REGCLASS operand #1 isn't a register class" );
1722
+
1723
+ M.insertAction <ConstrainOperandToRegClassAction>(
1724
+ InsertPt, InsnID, 0 , Target.getRegisterClass (DstIOpRec));
1725
+ } else if (DstIName == " EXTRACT_SUBREG" ) {
1726
+ auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
1727
+ if (!SuperClass)
1728
+ return failedImport (
1729
+ " Cannot infer register class from EXTRACT_SUBREG operand #0" );
1730
+
1731
+ auto SubIdx = inferSubRegIndexForNode (Dst.getChild (1 ));
1732
+ if (!SubIdx)
1733
+ return failedImport (" EXTRACT_SUBREG child #1 is not a subreg index" );
1734
+
1735
+ // It would be nice to leave this constraint implicit but we're required
1736
+ // to pick a register class so constrain the result to a register class
1737
+ // that can hold the correct MVT.
1738
+ //
1739
+ // FIXME: This may introduce an extra copy if the chosen class doesn't
1740
+ // actually contain the subregisters.
1741
+ const auto SrcRCDstRCPair =
1742
+ (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
1743
+ if (!SrcRCDstRCPair) {
1744
+ return failedImport (" subreg index is incompatible "
1745
+ " with inferred reg class" );
1746
+ }
1747
+
1748
+ assert (SrcRCDstRCPair->second && " Couldn't find a matching subclass" );
1749
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 0 ,
1750
+ *SrcRCDstRCPair->second );
1751
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 1 ,
1752
+ *SrcRCDstRCPair->first );
1753
+ } else if (DstIName == " INSERT_SUBREG" ) {
1754
+ // We need to constrain the destination, a super regsister source, and a
1755
+ // subregister source.
1756
+ auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
1757
+ if (!SubClass)
1758
+ return failedImport (
1759
+ " Cannot infer register class from INSERT_SUBREG operand #1" );
1760
+ auto SuperClass = inferSuperRegisterClassForNode (
1761
+ Dst.getExtType (0 ), Dst.getChild (0 ), Dst.getChild (2 ));
1762
+ if (!SuperClass)
1763
+ return failedImport (
1764
+ " Cannot infer register class for INSERT_SUBREG operand #0" );
1765
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 0 ,
1766
+ **SuperClass);
1767
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 1 ,
1768
+ **SuperClass);
1769
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 2 ,
1770
+ **SubClass);
1771
+ } else if (DstIName == " SUBREG_TO_REG" ) {
1772
+ // We need to constrain the destination and subregister source.
1773
+ // Attempt to infer the subregister source from the first child. If it has
1774
+ // an explicitly given register class, we'll use that. Otherwise, we will
1775
+ // fail.
1776
+ auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
1777
+ if (!SubClass)
1778
+ return failedImport (
1779
+ " Cannot infer register class from SUBREG_TO_REG child #1" );
1780
+ // We don't have a child to look at that might have a super register node.
1781
+ auto SuperClass =
1782
+ inferSuperRegisterClass (Dst.getExtType (0 ), Dst.getChild (2 ));
1783
+ if (!SuperClass)
1784
+ return failedImport (
1785
+ " Cannot infer register class for SUBREG_TO_REG operand #0" );
1786
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 0 ,
1787
+ **SuperClass);
1788
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 2 ,
1789
+ **SubClass);
1790
+ } else if (DstIName == " REG_SEQUENCE" ) {
1791
+ auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
1792
+
1793
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, 0 ,
1794
+ **SuperClass);
1795
+
1796
+ unsigned Num = Dst.getNumChildren ();
1797
+ for (unsigned I = 1 ; I != Num; I += 2 ) {
1798
+ const TreePatternNode &SubRegChild = Dst.getChild (I + 1 );
1799
+
1800
+ auto SubIdx = inferSubRegIndexForNode (SubRegChild);
1801
+ if (!SubIdx)
1802
+ return failedImport (" REG_SEQUENCE child is not a subreg index" );
1803
+
1804
+ const auto SrcRCDstRCPair =
1805
+ (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
1806
+
1807
+ M.insertAction <ConstrainOperandToRegClassAction>(InsertPt, InsnID, I,
1808
+ *SrcRCDstRCPair->second );
1809
+ }
1810
+ } else {
1811
+ M.insertAction <ConstrainOperandsToDefinitionAction>(InsertPt, InsnID);
1812
+ }
1813
+
1814
+ return Error::success ();
1815
+ }
1816
+
1797
1817
std::optional<const CodeGenRegisterClass *>
1798
1818
GlobalISelEmitter::getRegClassFromLeaf (const TreePatternNode &Leaf) {
1799
1819
assert (Leaf.isLeaf () && " Expected leaf?" );
@@ -2123,106 +2143,9 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) {
2123
2143
2124
2144
// Constrain the registers to classes. This is normally derived from the
2125
2145
// emitted instruction but a few instructions require special handling.
2126
- if (DstIName == " COPY_TO_REGCLASS" ) {
2127
- // COPY_TO_REGCLASS does not provide operand constraints itself but the
2128
- // result is constrained to the class given by the second child.
2129
- const Record *DstIOpRec =
2130
- getInitValueAsRegClass (Dst.getChild (1 ).getLeafValue ());
2131
-
2132
- if (DstIOpRec == nullptr )
2133
- return failedImport (" COPY_TO_REGCLASS operand #1 isn't a register class" );
2134
-
2135
- M.addAction <ConstrainOperandToRegClassAction>(
2136
- 0 , 0 , Target.getRegisterClass (DstIOpRec));
2137
- } else if (DstIName == " EXTRACT_SUBREG" ) {
2138
- auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
2139
- if (!SuperClass)
2140
- return failedImport (
2141
- " Cannot infer register class from EXTRACT_SUBREG operand #0" );
2142
-
2143
- auto SubIdx = inferSubRegIndexForNode (Dst.getChild (1 ));
2144
- if (!SubIdx)
2145
- return failedImport (" EXTRACT_SUBREG child #1 is not a subreg index" );
2146
-
2147
- // It would be nice to leave this constraint implicit but we're required
2148
- // to pick a register class so constrain the result to a register class
2149
- // that can hold the correct MVT.
2150
- //
2151
- // FIXME: This may introduce an extra copy if the chosen class doesn't
2152
- // actually contain the subregisters.
2153
- assert (Src.getExtTypes ().size () == 1 &&
2154
- " Expected Src of EXTRACT_SUBREG to have one result type" );
2155
-
2156
- const auto SrcRCDstRCPair =
2157
- (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
2158
- if (!SrcRCDstRCPair) {
2159
- return failedImport (" subreg index is incompatible "
2160
- " with inferred reg class" );
2161
- }
2162
-
2163
- assert (SrcRCDstRCPair->second && " Couldn't find a matching subclass" );
2164
- M.addAction <ConstrainOperandToRegClassAction>(0 , 0 ,
2165
- *SrcRCDstRCPair->second );
2166
- M.addAction <ConstrainOperandToRegClassAction>(0 , 1 , *SrcRCDstRCPair->first );
2167
- } else if (DstIName == " INSERT_SUBREG" ) {
2168
- assert (Src.getExtTypes ().size () == 1 &&
2169
- " Expected Src of INSERT_SUBREG to have one result type" );
2170
- // We need to constrain the destination, a super regsister source, and a
2171
- // subregister source.
2172
- auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
2173
- if (!SubClass)
2174
- return failedImport (
2175
- " Cannot infer register class from INSERT_SUBREG operand #1" );
2176
- auto SuperClass = inferSuperRegisterClassForNode (
2177
- Src.getExtType (0 ), Dst.getChild (0 ), Dst.getChild (2 ));
2178
- if (!SuperClass)
2179
- return failedImport (
2180
- " Cannot infer register class for INSERT_SUBREG operand #0" );
2181
- M.addAction <ConstrainOperandToRegClassAction>(0 , 0 , **SuperClass);
2182
- M.addAction <ConstrainOperandToRegClassAction>(0 , 1 , **SuperClass);
2183
- M.addAction <ConstrainOperandToRegClassAction>(0 , 2 , **SubClass);
2184
- } else if (DstIName == " SUBREG_TO_REG" ) {
2185
- // We need to constrain the destination and subregister source.
2186
- assert (Src.getExtTypes ().size () == 1 &&
2187
- " Expected Src of SUBREG_TO_REG to have one result type" );
2188
-
2189
- // Attempt to infer the subregister source from the first child. If it has
2190
- // an explicitly given register class, we'll use that. Otherwise, we will
2191
- // fail.
2192
- auto SubClass = inferRegClassFromPattern (Dst.getChild (1 ));
2193
- if (!SubClass)
2194
- return failedImport (
2195
- " Cannot infer register class from SUBREG_TO_REG child #1" );
2196
- // We don't have a child to look at that might have a super register node.
2197
- auto SuperClass =
2198
- inferSuperRegisterClass (Src.getExtType (0 ), Dst.getChild (2 ));
2199
- if (!SuperClass)
2200
- return failedImport (
2201
- " Cannot infer register class for SUBREG_TO_REG operand #0" );
2202
- M.addAction <ConstrainOperandToRegClassAction>(0 , 0 , **SuperClass);
2203
- M.addAction <ConstrainOperandToRegClassAction>(0 , 2 , **SubClass);
2204
- } else if (DstIName == " REG_SEQUENCE" ) {
2205
- auto SuperClass = inferRegClassFromPattern (Dst.getChild (0 ));
2206
-
2207
- M.addAction <ConstrainOperandToRegClassAction>(0 , 0 , **SuperClass);
2208
-
2209
- unsigned Num = Dst.getNumChildren ();
2210
- for (unsigned I = 1 ; I != Num; I += 2 ) {
2211
- TreePatternNode &SubRegChild = Dst.getChild (I + 1 );
2212
-
2213
- auto SubIdx = inferSubRegIndexForNode (SubRegChild);
2214
- if (!SubIdx)
2215
- return failedImport (" REG_SEQUENCE child is not a subreg index" );
2216
-
2217
- const auto SrcRCDstRCPair =
2218
- (*SuperClass)->getMatchingSubClassWithSubRegs (CGRegs, *SubIdx);
2219
-
2220
- M.addAction <ConstrainOperandToRegClassAction>(0 , I,
2221
- *SrcRCDstRCPair->second );
2222
- }
2223
- } else {
2224
- M.addAction <ConstrainOperandsToDefinitionAction>(0 );
2225
- }
2146
+ if (auto Error =
2147
+ constrainOperands (M.actions_end (), M, DstMIBuilder.getInsnID (), Dst))
2148
+ return std::move (Error);
2226
2149
2227
2150
// Erase the root.
2228
2151
unsigned RootInsnID = M.getInsnVarID (InsnMatcher);
0 commit comments