Skip to content

Commit e01577d

Browse files
committed
importLeafNodeRenderer
1 parent 1f5bd62 commit e01577d

File tree

1 file changed

+67
-59
lines changed

1 file changed

+67
-59
lines changed

llvm/utils/TableGen/GlobalISelEmitter.cpp

Lines changed: 67 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
416416
Error importNamedNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
417417
const TreePatternNode &N) const;
418418

419+
Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
420+
const TreePatternNode &N) const;
421+
419422
Expected<action_iterator>
420423
importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule,
421424
BuildMIAction &DstMIBuilder,
@@ -1290,85 +1293,90 @@ Error GlobalISelEmitter::importNamedNodeRenderer(
12901293
return failedImport("unsupported node " + to_string(N));
12911294
}
12921295

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();
13001302
}
13011303

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();
13171306

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();
13221310
}
13231311

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+
}
13281317

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+
}
13331321

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+
}
13401324

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;
13431332
}
13441333

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;
13491337
return InsertPt;
13501338
}
13511339

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+
}
13551354

1356-
if (ChildRec->isSubClassOf("Register")) {
1357-
DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec);
13581355
return InsertPt;
13591356
}
1357+
return failedImport("SDNodeXForm " + Child.getName() +
1358+
" has no custom renderer");
1359+
}
13601360

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();
13661365

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();
13691376
}
13701377

1371-
return failedImport("Dst pattern child is an unsupported kind");
1378+
// Should not reach here.
1379+
return failedImport("unrecognized node " + llvm::to_string(Dst));
13721380
}
13731381

13741382
/// Generates code that builds the resulting instruction(s) from the destination

0 commit comments

Comments
 (0)