@@ -412,6 +412,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
412
412
importExplicitUseRenderers (action_iterator InsertPt, RuleMatcher &M,
413
413
BuildMIAction &DstMIBuilder,
414
414
const TreePatternNode &Dst) const ;
415
+
416
+ Error importNamedNodeRenderer (RuleMatcher &M, BuildMIAction &MIBuilder,
417
+ const TreePatternNode &N) const ;
418
+
415
419
Expected<action_iterator>
416
420
importExplicitUseRenderer (action_iterator InsertPt, RuleMatcher &Rule,
417
421
BuildMIAction &DstMIBuilder,
@@ -1192,15 +1196,106 @@ Error GlobalISelEmitter::importChildMatcher(
1192
1196
return failedImport (" Src pattern child is an unsupported kind" );
1193
1197
}
1194
1198
1199
+ // Equivalent of MatcherGen::EmitResultOfNamedOperand.
1200
+ Error GlobalISelEmitter::importNamedNodeRenderer (
1201
+ RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const {
1202
+ StringRef NodeName = N.getName ();
1203
+
1204
+ if (auto SubOperand = M.getComplexSubOperand (NodeName)) {
1205
+ auto [ComplexPatternRec, RendererID, SubOperandIdx] = *SubOperand;
1206
+ MIBuilder.addRenderer <RenderComplexPatternOperand>(
1207
+ *ComplexPatternRec, NodeName, RendererID, SubOperandIdx);
1208
+ return Error::success ();
1209
+ }
1210
+
1211
+ if (!N.isLeaf ()) {
1212
+ StringRef OperatorName = N.getOperator ()->getName ();
1213
+
1214
+ if (OperatorName == " imm" ) {
1215
+ MIBuilder.addRenderer <CopyConstantAsImmRenderer>(NodeName);
1216
+ return Error::success ();
1217
+ }
1218
+
1219
+ if (OperatorName == " fpimm" ) {
1220
+ MIBuilder.addRenderer <CopyFConstantAsFPImmRenderer>(NodeName);
1221
+ return Error::success ();
1222
+ }
1223
+
1224
+ // TODO: 'imm' and 'fpimm' are the only nodes that need special treatment.
1225
+ // Remove this check and add CopyRenderer unconditionally for other nodes.
1226
+ if (OperatorName == " bb" || OperatorName == " timm" ||
1227
+ OperatorName == " tframeindex" ) {
1228
+ MIBuilder.addRenderer <CopyRenderer>(NodeName);
1229
+ return Error::success ();
1230
+ }
1231
+
1232
+ return failedImport (" node has unsupported operator " + to_string (N));
1233
+ }
1234
+
1235
+ if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue ())) {
1236
+ const Record *R = DI->getDef ();
1237
+
1238
+ if (N.getNumResults () != 1 )
1239
+ return failedImport (" node does not have one result " + to_string (N));
1240
+
1241
+ std::optional<LLTCodeGen> OpTyOrNone;
1242
+ ArrayRef<TypeSetByHwMode> ChildTypes = N.getExtTypes ();
1243
+ if (ChildTypes.front ().isMachineValueType ())
1244
+ OpTyOrNone = MVTToLLT (ChildTypes.front ().getMachineValueType ().SimpleTy );
1245
+
1246
+ // TODO: Remove this check. Types in the destination DAG should not matter.
1247
+ if (!OpTyOrNone)
1248
+ return failedImport (" node has unsupported type " + to_string (N));
1249
+
1250
+ if (R->isSubClassOf (" ComplexPattern" )) {
1251
+ auto I = ComplexPatternEquivs.find (R);
1252
+ if (I == ComplexPatternEquivs.end ())
1253
+ return failedImport (" ComplexPattern " + R->getName () +
1254
+ " does not have GISel equivalent" );
1255
+
1256
+ const OperandMatcher &OM = M.getOperandMatcher (NodeName);
1257
+ MIBuilder.addRenderer <RenderComplexPatternOperand>(
1258
+ *I->second , NodeName, OM.getAllocatedTemporariesBaseID ());
1259
+ return Error::success ();
1260
+ }
1261
+
1262
+ if (R->isSubClassOf (" RegisterOperand" ) &&
1263
+ !R->isValueUnset (" GIZeroRegister" )) {
1264
+ MIBuilder.addRenderer <CopyOrAddZeroRegRenderer>(
1265
+ NodeName, R->getValueAsDef (" GIZeroRegister" ));
1266
+ return Error::success ();
1267
+ }
1268
+
1269
+ // TODO: All special cases are handled above. Remove this check and add
1270
+ // CopyRenderer unconditionally.
1271
+ if (R->isSubClassOf (" RegisterClass" ) ||
1272
+ R->isSubClassOf (" RegisterOperand" ) || R->isSubClassOf (" ValueType" )) {
1273
+ MIBuilder.addRenderer <CopyRenderer>(NodeName);
1274
+ return Error::success ();
1275
+ }
1276
+ }
1277
+
1278
+ // TODO: Change this to assert and move to the beginning of the function.
1279
+ if (!M.hasOperand (NodeName))
1280
+ return failedImport (" could not find node $" + NodeName +
1281
+ " in the source DAG" );
1282
+
1283
+ // TODO: Remove this check and add CopyRenderer unconditionally.
1284
+ // TODO: Handle nodes with multiple results (provided they can reach here).
1285
+ if (isa<UnsetInit>(N.getLeafValue ())) {
1286
+ MIBuilder.addRenderer <CopyRenderer>(NodeName);
1287
+ return Error::success ();
1288
+ }
1289
+
1290
+ return failedImport (" unsupported node " + to_string (N));
1291
+ }
1292
+
1195
1293
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer (
1196
1294
action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
1197
1295
const TreePatternNode &Dst) const {
1198
-
1199
- const auto &SubOperand = Rule.getComplexSubOperand (Dst.getName ());
1200
- if (SubOperand) {
1201
- DstMIBuilder.addRenderer <RenderComplexPatternOperand>(
1202
- *std::get<0 >(*SubOperand), Dst.getName (), std::get<1 >(*SubOperand),
1203
- std::get<2 >(*SubOperand));
1296
+ if (Dst.hasName ()) {
1297
+ if (Error Err = importNamedNodeRenderer (Rule, DstMIBuilder, Dst))
1298
+ return Err;
1204
1299
return InsertPt;
1205
1300
}
1206
1301
@@ -1226,37 +1321,6 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
1226
1321
" has no custom renderer" );
1227
1322
}
1228
1323
1229
- // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't
1230
- // inline, but in MI it's just another operand.
1231
- if (Dst.getOperator ()->isSubClassOf (" SDNode" )) {
1232
- auto &ChildSDNI = CGP.getSDNodeInfo (Dst.getOperator ());
1233
- if (ChildSDNI.getSDClassName () == " BasicBlockSDNode" ) {
1234
- DstMIBuilder.addRenderer <CopyRenderer>(Dst.getName ());
1235
- return InsertPt;
1236
- }
1237
- }
1238
-
1239
- // Similarly, imm is an operator in TreePatternNode's view but must be
1240
- // rendered as operands.
1241
- // FIXME: The target should be able to choose sign-extended when appropriate
1242
- // (e.g. on Mips).
1243
- if (Dst.getOperator ()->getName () == " timm" ) {
1244
- DstMIBuilder.addRenderer <CopyRenderer>(Dst.getName ());
1245
- return InsertPt;
1246
- }
1247
- if (Dst.getOperator ()->getName () == " tframeindex" ) {
1248
- DstMIBuilder.addRenderer <CopyRenderer>(Dst.getName ());
1249
- return InsertPt;
1250
- }
1251
- if (Dst.getOperator ()->getName () == " imm" ) {
1252
- DstMIBuilder.addRenderer <CopyConstantAsImmRenderer>(Dst.getName ());
1253
- return InsertPt;
1254
- }
1255
- if (Dst.getOperator ()->getName () == " fpimm" ) {
1256
- DstMIBuilder.addRenderer <CopyFConstantAsFPImmRenderer>(Dst.getName ());
1257
- return InsertPt;
1258
- }
1259
-
1260
1324
if (Dst.getOperator ()->isSubClassOf (" Instruction" )) {
1261
1325
auto OpTy = getInstResultType (Dst, Target);
1262
1326
if (!OpTy)
@@ -1274,8 +1338,8 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
1274
1338
return InsertPtOrError.get ();
1275
1339
}
1276
1340
1277
- return failedImport ( " Dst pattern child isn't a leaf node or an MBB " +
1278
- llvm::to_string (Dst));
1341
+ // Should not reach here.
1342
+ return failedImport ( " unrecognized node " + llvm::to_string (Dst));
1279
1343
}
1280
1344
1281
1345
// It could be a specific immediate in which case we should just check for
@@ -1289,64 +1353,21 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
1289
1353
if (auto *ChildDefInit = dyn_cast<DefInit>(Dst.getLeafValue ())) {
1290
1354
auto *ChildRec = ChildDefInit->getDef ();
1291
1355
1292
- ArrayRef<TypeSetByHwMode> ChildTypes = Dst.getExtTypes ();
1293
- if (ChildTypes.size () != 1 )
1294
- return failedImport (" Dst pattern child has multiple results" );
1295
-
1296
- std::optional<LLTCodeGen> OpTyOrNone;
1297
- if (ChildTypes.front ().isMachineValueType ())
1298
- OpTyOrNone = MVTToLLT (ChildTypes.front ().getMachineValueType ().SimpleTy );
1299
- if (!OpTyOrNone)
1300
- return failedImport (" Dst operand has an unsupported type" );
1301
-
1302
1356
if (ChildRec->isSubClassOf (" Register" )) {
1303
1357
DstMIBuilder.addRenderer <AddRegisterRenderer>(Target, ChildRec);
1304
1358
return InsertPt;
1305
1359
}
1306
1360
1307
- if (ChildRec->isSubClassOf (" RegisterClass" ) ||
1308
- ChildRec->isSubClassOf (" RegisterOperand" ) ||
1309
- ChildRec->isSubClassOf (" ValueType" )) {
1310
- if (ChildRec->isSubClassOf (" RegisterOperand" ) &&
1311
- !ChildRec->isValueUnset (" GIZeroRegister" )) {
1312
- DstMIBuilder.addRenderer <CopyOrAddZeroRegRenderer>(
1313
- Dst.getName (), ChildRec->getValueAsDef (" GIZeroRegister" ));
1314
- return InsertPt;
1315
- }
1316
-
1317
- DstMIBuilder.addRenderer <CopyRenderer>(Dst.getName ());
1318
- return InsertPt;
1319
- }
1320
-
1321
1361
if (ChildRec->isSubClassOf (" SubRegIndex" )) {
1322
1362
CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx (ChildRec);
1323
1363
DstMIBuilder.addRenderer <ImmRenderer>(SubIdx->EnumValue );
1324
1364
return InsertPt;
1325
1365
}
1326
1366
1327
- if (ChildRec->isSubClassOf (" ComplexPattern" )) {
1328
- const auto &ComplexPattern = ComplexPatternEquivs.find (ChildRec);
1329
- if (ComplexPattern == ComplexPatternEquivs.end ())
1330
- return failedImport (
1331
- " SelectionDAG ComplexPattern not mapped to GlobalISel" );
1332
-
1333
- const OperandMatcher &OM = Rule.getOperandMatcher (Dst.getName ());
1334
- DstMIBuilder.addRenderer <RenderComplexPatternOperand>(
1335
- *ComplexPattern->second , Dst.getName (),
1336
- OM.getAllocatedTemporariesBaseID ());
1337
- return InsertPt;
1338
- }
1339
-
1340
1367
return failedImport (
1341
1368
" Dst pattern child def is an unsupported tablegen class" );
1342
1369
}
1343
1370
1344
- // Handle the case where the MVT/register class is omitted in the dest pattern
1345
- // but MVT exists in the source pattern.
1346
- if (isa<UnsetInit>(Dst.getLeafValue ()) && Rule.hasOperand (Dst.getName ())) {
1347
- DstMIBuilder.addRenderer <CopyRenderer>(Dst.getName ());
1348
- return InsertPt;
1349
- }
1350
1371
return failedImport (" Dst pattern child is an unsupported kind" );
1351
1372
}
1352
1373
0 commit comments