@@ -419,6 +419,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
419
419
Error importLeafNodeRenderer (RuleMatcher &M, BuildMIAction &MIBuilder,
420
420
const TreePatternNode &N) const ;
421
421
422
+ Error importXFormNodeRenderer (RuleMatcher &M, BuildMIAction &MIBuilder,
423
+ const TreePatternNode &N) const ;
424
+
422
425
Expected<action_iterator>
423
426
importExplicitUseRenderer (action_iterator InsertPt, RuleMatcher &Rule,
424
427
BuildMIAction &DstMIBuilder,
@@ -1319,6 +1322,41 @@ Error GlobalISelEmitter::importLeafNodeRenderer(
1319
1322
return failedImport (" unrecognized node " + to_string (N));
1320
1323
}
1321
1324
1325
+ // Equivalent of MatcherGen::EmitResultSDNodeXFormAsOperand.
1326
+ Error GlobalISelEmitter::importXFormNodeRenderer (
1327
+ RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const {
1328
+ const Record *XFormRec = N.getOperator ();
1329
+ auto I = SDNodeXFormEquivs.find (XFormRec);
1330
+ if (I == SDNodeXFormEquivs.end ())
1331
+ return failedImport (" SDNodeXForm " + XFormRec->getName () +
1332
+ " does not have GISel equivalent" );
1333
+
1334
+ // TODO: Fail to import if GISDNodeXForm does not have RendererFn.
1335
+ // This currently results in a fatal error in emitRenderOpcodes.
1336
+ const Record *XFormEquivRec = I->second ;
1337
+
1338
+ // The node to apply the transformation function to.
1339
+ // FIXME: The node may not have a name and may be a leaf. It should be
1340
+ // rendered first, like any other nodes. This may or may not require
1341
+ // introducing a temporary register, and we can't tell that without
1342
+ // inspecting the node (possibly recursively). This is a general drawback
1343
+ // of appending renderers directly to BuildMIAction.
1344
+ const TreePatternNode &Node = N.getChild (0 );
1345
+ StringRef NodeName = Node.getName ();
1346
+
1347
+ const Record *XFormOpc = CGP.getSDNodeTransform (XFormRec).first ;
1348
+ if (XFormOpc->getName () == " timm" ) {
1349
+ // If this is a TargetConstant, there won't be a corresponding
1350
+ // instruction to transform. Instead, this will refer directly to an
1351
+ // operand in an instruction's operand list.
1352
+ MIBuilder.addRenderer <CustomOperandRenderer>(*XFormEquivRec, NodeName);
1353
+ } else {
1354
+ MIBuilder.addRenderer <CustomRenderer>(*XFormEquivRec, NodeName);
1355
+ }
1356
+
1357
+ return Error::success ();
1358
+ }
1359
+
1322
1360
Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer (
1323
1361
action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder,
1324
1362
const TreePatternNode &Dst) const {
@@ -1335,24 +1373,9 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer(
1335
1373
}
1336
1374
1337
1375
if (Dst.getOperator ()->isSubClassOf (" SDNodeXForm" )) {
1338
- auto &Child = Dst.getChild (0 );
1339
- auto I = SDNodeXFormEquivs.find (Dst.getOperator ());
1340
- if (I != SDNodeXFormEquivs.end ()) {
1341
- const Record *XFormOpc = Dst.getOperator ()->getValueAsDef (" Opcode" );
1342
- if (XFormOpc->getName () == " timm" ) {
1343
- // If this is a TargetConstant, there won't be a corresponding
1344
- // instruction to transform. Instead, this will refer directly to an
1345
- // operand in an instruction's operand list.
1346
- DstMIBuilder.addRenderer <CustomOperandRenderer>(*I->second ,
1347
- Child.getName ());
1348
- } else {
1349
- DstMIBuilder.addRenderer <CustomRenderer>(*I->second , Child.getName ());
1350
- }
1351
-
1352
- return InsertPt;
1353
- }
1354
- return failedImport (" SDNodeXForm " + Child.getName () +
1355
- " has no custom renderer" );
1376
+ if (Error Err = importXFormNodeRenderer (Rule, DstMIBuilder, Dst))
1377
+ return Err;
1378
+ return InsertPt;
1356
1379
}
1357
1380
1358
1381
if (Dst.getOperator ()->isSubClassOf (" Instruction" )) {
0 commit comments