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