@@ -416,6 +416,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
416
416
Error importNamedNodeRenderer (RuleMatcher &M, BuildMIAction &MIBuilder,
417
417
const TreePatternNode &N) const ;
418
418
419
+ Error importLeafNodeRenderer (RuleMatcher &M, BuildMIAction &MIBuilder,
420
+ const TreePatternNode &N) const ;
421
+
419
422
Expected<action_iterator>
420
423
importExplicitUseRenderer (action_iterator InsertPt, RuleMatcher &Rule,
421
424
BuildMIAction &DstMIBuilder,
@@ -1290,85 +1293,90 @@ Error GlobalISelEmitter::importNamedNodeRenderer(
1290
1293
return failedImport (" unsupported node " + to_string (N));
1291
1294
}
1292
1295
1293
- Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer (
1294
- action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
1295
- const TreePatternNode &Dst) const {
1296
- if (Dst.hasName ()) {
1297
- if (Error Err = importNamedNodeRenderer (Rule, DstMIBuilder, Dst))
1298
- return Err;
1299
- return InsertPt;
1296
+ // Equivalent of MatcherGen::EmitResultLeafAsOperand.
1297
+ Error GlobalISelEmitter::importLeafNodeRenderer (
1298
+ RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const {
1299
+ if (const auto *II = dyn_cast<IntInit>(N.getLeafValue ())) {
1300
+ MIBuilder.addRenderer <ImmRenderer>(II->getValue ());
1301
+ return Error::success ();
1300
1302
}
1301
1303
1302
- if (!Dst.isLeaf ()) {
1303
- if (Dst.getOperator ()->isSubClassOf (" SDNodeXForm" )) {
1304
- auto &Child = Dst.getChild (0 );
1305
- auto I = SDNodeXFormEquivs.find (Dst.getOperator ());
1306
- if (I != SDNodeXFormEquivs.end ()) {
1307
- const Record *XFormOpc = Dst.getOperator ()->getValueAsDef (" Opcode" );
1308
- if (XFormOpc->getName () == " timm" ) {
1309
- // If this is a TargetConstant, there won't be a corresponding
1310
- // instruction to transform. Instead, this will refer directly to an
1311
- // operand in an instruction's operand list.
1312
- DstMIBuilder.addRenderer <CustomOperandRenderer>(*I->second ,
1313
- Child.getName ());
1314
- } else {
1315
- DstMIBuilder.addRenderer <CustomRenderer>(*I->second , Child.getName ());
1316
- }
1304
+ if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue ())) {
1305
+ const Record *R = DI->getDef ();
1317
1306
1318
- return InsertPt;
1319
- }
1320
- return failedImport (" SDNodeXForm " + Child.getName () +
1321
- " has no custom renderer" );
1307
+ if (R->isSubClassOf (" Register" )) {
1308
+ MIBuilder.addRenderer <AddRegisterRenderer>(Target, R);
1309
+ return Error::success ();
1322
1310
}
1323
1311
1324
- if (Dst.getOperator ()->isSubClassOf (" Instruction" )) {
1325
- auto OpTy = getInstResultType (Dst, Target);
1326
- if (!OpTy)
1327
- return OpTy.takeError ();
1312
+ if (R->isSubClassOf (" SubRegIndex" )) {
1313
+ const CodeGenSubRegIndex *SubRegIndex = CGRegs.getSubRegIdx (R);
1314
+ MIBuilder.addRenderer <ImmRenderer>(SubRegIndex->EnumValue );
1315
+ return Error::success ();
1316
+ }
1328
1317
1329
- unsigned TempRegID = Rule.allocateTempRegID ();
1330
- InsertPt =
1331
- Rule.insertAction <MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
1332
- DstMIBuilder.addRenderer <TempRegRenderer>(TempRegID);
1318
+ // There are also RegisterClass / RegisterOperand operands of REG_SEQUENCE /
1319
+ // COPY_TO_REGCLASS, but these instructions are currently handled elsewhere.
1320
+ }
1333
1321
1334
- auto InsertPtOrError = createAndImportSubInstructionRenderer (
1335
- ++InsertPt, Rule, Dst, TempRegID);
1336
- if (auto Error = InsertPtOrError.takeError ())
1337
- return std::move (Error);
1338
- return InsertPtOrError.get ();
1339
- }
1322
+ return failedImport (" unrecognized node " + to_string (N));
1323
+ }
1340
1324
1341
- // Should not reach here.
1342
- return failedImport (" unrecognized node " + llvm::to_string (Dst));
1325
+ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer (
1326
+ action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
1327
+ const TreePatternNode &Dst) const {
1328
+ if (Dst.hasName ()) {
1329
+ if (Error Err = importNamedNodeRenderer (Rule, DstMIBuilder, Dst))
1330
+ return Err;
1331
+ return InsertPt;
1343
1332
}
1344
1333
1345
- // It could be a specific immediate in which case we should just check for
1346
- // that immediate.
1347
- if (const IntInit *ChildIntInit = dyn_cast<IntInit>(Dst.getLeafValue ())) {
1348
- DstMIBuilder.addRenderer <ImmRenderer>(ChildIntInit->getValue ());
1334
+ if (Dst.isLeaf ()) {
1335
+ if (Error Err = importLeafNodeRenderer (Rule, DstMIBuilder, Dst))
1336
+ return Err;
1349
1337
return InsertPt;
1350
1338
}
1351
1339
1352
- // Otherwise, we're looking for a bog-standard RegisterClass operand.
1353
- if (auto *ChildDefInit = dyn_cast<DefInit>(Dst.getLeafValue ())) {
1354
- auto *ChildRec = ChildDefInit->getDef ();
1340
+ if (Dst.getOperator ()->isSubClassOf (" SDNodeXForm" )) {
1341
+ auto &Child = Dst.getChild (0 );
1342
+ auto I = SDNodeXFormEquivs.find (Dst.getOperator ());
1343
+ if (I != SDNodeXFormEquivs.end ()) {
1344
+ const Record *XFormOpc = Dst.getOperator ()->getValueAsDef (" Opcode" );
1345
+ if (XFormOpc->getName () == " timm" ) {
1346
+ // If this is a TargetConstant, there won't be a corresponding
1347
+ // instruction to transform. Instead, this will refer directly to an
1348
+ // operand in an instruction's operand list.
1349
+ DstMIBuilder.addRenderer <CustomOperandRenderer>(*I->second ,
1350
+ Child.getName ());
1351
+ } else {
1352
+ DstMIBuilder.addRenderer <CustomRenderer>(*I->second , Child.getName ());
1353
+ }
1355
1354
1356
- if (ChildRec->isSubClassOf (" Register" )) {
1357
- DstMIBuilder.addRenderer <AddRegisterRenderer>(Target, ChildRec);
1358
1355
return InsertPt;
1359
1356
}
1357
+ return failedImport (" SDNodeXForm " + Child.getName () +
1358
+ " has no custom renderer" );
1359
+ }
1360
1360
1361
- if (ChildRec->isSubClassOf (" SubRegIndex" )) {
1362
- CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx (ChildRec);
1363
- DstMIBuilder.addRenderer <ImmRenderer>(SubIdx->EnumValue );
1364
- return InsertPt;
1365
- }
1361
+ if (Dst.getOperator ()->isSubClassOf (" Instruction" )) {
1362
+ auto OpTy = getInstResultType (Dst, Target);
1363
+ if (!OpTy)
1364
+ return OpTy.takeError ();
1366
1365
1367
- return failedImport (
1368
- " Dst pattern child def is an unsupported tablegen class" );
1366
+ unsigned TempRegID = Rule.allocateTempRegID ();
1367
+ InsertPt =
1368
+ Rule.insertAction <MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID);
1369
+ DstMIBuilder.addRenderer <TempRegRenderer>(TempRegID);
1370
+
1371
+ auto InsertPtOrError =
1372
+ createAndImportSubInstructionRenderer (++InsertPt, Rule, Dst, TempRegID);
1373
+ if (auto Error = InsertPtOrError.takeError ())
1374
+ return std::move (Error);
1375
+ return InsertPtOrError.get ();
1369
1376
}
1370
1377
1371
- return failedImport (" Dst pattern child is an unsupported kind" );
1378
+ // Should not reach here.
1379
+ return failedImport (" unrecognized node " + llvm::to_string (Dst));
1372
1380
}
1373
1381
1374
1382
// / Generates code that builds the resulting instruction(s) from the destination
0 commit comments