Skip to content

Commit c56b743

Browse files
authored
[TableGen][GISel] Reuse importNodeRenderer for OperandWithDefaultOps (#121285)
This avoids some code duplication (handling `Register`, `zero_reg` and immediate operands).
1 parent fd38a95 commit c56b743

File tree

2 files changed

+43
-56
lines changed

2 files changed

+43
-56
lines changed

llvm/test/TableGen/GlobalISelEmitter/undef-tied-input.td

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1-
// RUN: llvm-tblgen -gen-global-isel -I %p/../../../include -I %p/../Common %s | FileCheck %s
1+
// RUN: llvm-tblgen -gen-global-isel -warn-on-skipped-patterns \
2+
// RUN: -I %p/../../../include -I %p/../Common %s 2> %t | FileCheck %s
3+
// RUN: FileCheck -check-prefix=ERR %s < %t
24

35
include "llvm/Target/Target.td"
46
include "GlobalISelEmitterCommon.td"
57

6-
def undef_tied : OperandWithDefaultOps<untyped, (ops (i32 undef_tied_input))> {
8+
def undef_tied_1 : OperandWithDefaultOps<untyped, (ops (i32 undef_tied_input))> {
79
let MIOperandInfo = (ops GPR32:$inactive);
810
}
911

12+
def undef_tied_2 : OperandWithDefaultOps<i32, (ops (untyped undef_tied_input))> {
13+
let MIOperandInfo = (ops GPR32:$inactive);
14+
}
15+
16+
let Constraints = "$opt.inactive = $rd" in
17+
def I1 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied_1:$opt),
18+
[(set GPR32:$rd, (abs i32:$rs))]>;
19+
20+
// ERR: [[#@LINE+2]]:5: warning: Skipped pattern: unsupported type
1021
let Constraints = "$opt.inactive = $rd" in
11-
def I1 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied:$opt),
22+
def I2 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied_2:$opt),
1223
[(set GPR32:$rd, (abs i32:$rs))]>;
1324

1425
// CHECK-LABEL: // (abs:{ *:[i32] } i32:{ *:[i32] }:$rs) => (I1:{ *:[i32] } i32:{ *:[i32] }:$rs)

llvm/utils/TableGen/GlobalISelEmitter.cpp

Lines changed: 29 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,8 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
418418
const TreePatternNode &N) const;
419419

420420
Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
421-
const TreePatternNode &N) const;
421+
const TreePatternNode &N,
422+
action_iterator InsertPt) const;
422423

423424
Error importXFormNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
424425
const TreePatternNode &N) const;
@@ -431,9 +432,6 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
431432
const TreePatternNode &N,
432433
action_iterator &InsertPt) const;
433434

434-
Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
435-
BuildMIAction &DstMIBuilder,
436-
const DAGDefaultOperand &DefaultOp) const;
437435
Error importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
438436
ArrayRef<const Record *> ImplicitDefs) const;
439437

@@ -1291,7 +1289,8 @@ Error GlobalISelEmitter::importNamedNodeRenderer(
12911289

12921290
// Equivalent of MatcherGen::EmitResultLeafAsOperand.
12931291
Error GlobalISelEmitter::importLeafNodeRenderer(
1294-
RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const {
1292+
RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N,
1293+
action_iterator InsertPt) const {
12951294
if (const auto *II = dyn_cast<IntInit>(N.getLeafValue())) {
12961295
MIBuilder.addRenderer<ImmRenderer>(II->getValue());
12971296
return Error::success();
@@ -1300,11 +1299,29 @@ Error GlobalISelEmitter::importLeafNodeRenderer(
13001299
if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue())) {
13011300
const Record *R = DI->getDef();
13021301

1303-
if (R->isSubClassOf("Register")) {
1302+
if (R->isSubClassOf("Register") || R->getName() == "zero_reg") {
13041303
MIBuilder.addRenderer<AddRegisterRenderer>(Target, R);
13051304
return Error::success();
13061305
}
13071306

1307+
if (R->getName() == "undef_tied_input") {
1308+
std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
1309+
if (!OpTyOrNone)
1310+
return failedImport("unsupported type");
1311+
1312+
unsigned TempRegID = M.allocateTempRegID();
1313+
M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, TempRegID);
1314+
1315+
auto I = M.insertAction<BuildMIAction>(
1316+
InsertPt, M.allocateOutputInsnID(),
1317+
&Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
1318+
auto &ImpDefBuilder = static_cast<BuildMIAction &>(**I);
1319+
ImpDefBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
1320+
1321+
MIBuilder.addRenderer<TempRegRenderer>(TempRegID);
1322+
return Error::success();
1323+
}
1324+
13081325
if (R->isSubClassOf("SubRegIndex")) {
13091326
const CodeGenSubRegIndex *SubRegIndex = CGRegs.getSubRegIdx(R);
13101327
MIBuilder.addRenderer<ImmRenderer>(SubRegIndex->EnumValue);
@@ -1386,7 +1403,7 @@ Error GlobalISelEmitter::importNodeRenderer(RuleMatcher &M,
13861403
return importNamedNodeRenderer(M, MIBuilder, N);
13871404

13881405
if (N.isLeaf())
1389-
return importLeafNodeRenderer(M, MIBuilder, N);
1406+
return importLeafNodeRenderer(M, MIBuilder, N, InsertPt);
13901407

13911408
if (N.getOperator()->isSubClassOf("SDNodeXForm"))
13921409
return importXFormNodeRenderer(M, MIBuilder, N);
@@ -1707,11 +1724,11 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
17071724
// This is a predicate or optional def operand which the pattern has not
17081725
// overridden, or which we aren't letting it override; emit the 'default
17091726
// ops' operands.
1710-
1711-
const Record *OperandNode = DstI->Operands[InstOpNo].Rec;
1712-
if (auto Error = importDefaultOperandRenderers(
1713-
InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode)))
1714-
return std::move(Error);
1727+
for (const TreePatternNode &OpNode :
1728+
make_pointee_range(CGP.getDefaultOperand(OperandNode).DefaultOps)) {
1729+
if (Error Err = importNodeRenderer(M, DstMIBuilder, OpNode, InsertPt))
1730+
return Err;
1731+
}
17151732

17161733
++NumDefaultOps;
17171734
continue;
@@ -1734,47 +1751,6 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
17341751
return InsertPt;
17351752
}
17361753

1737-
Error GlobalISelEmitter::importDefaultOperandRenderers(
1738-
action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
1739-
const DAGDefaultOperand &DefaultOp) const {
1740-
for (const auto &Op : DefaultOp.DefaultOps) {
1741-
const auto &N = *Op;
1742-
if (!N.isLeaf())
1743-
return failedImport("Could not add default op");
1744-
1745-
const auto *DefaultOp = N.getLeafValue();
1746-
1747-
if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
1748-
std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
1749-
auto *Def = DefaultDefOp->getDef();
1750-
if (Def->getName() == "undef_tied_input") {
1751-
unsigned TempRegID = M.allocateTempRegID();
1752-
M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone,
1753-
TempRegID);
1754-
InsertPt = M.insertAction<BuildMIAction>(
1755-
InsertPt, M.allocateOutputInsnID(),
1756-
&Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
1757-
BuildMIAction &IDMIBuilder =
1758-
*static_cast<BuildMIAction *>(InsertPt->get());
1759-
IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
1760-
DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
1761-
} else {
1762-
DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
1763-
}
1764-
continue;
1765-
}
1766-
1767-
if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
1768-
DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
1769-
continue;
1770-
}
1771-
1772-
return failedImport("Could not add default op");
1773-
}
1774-
1775-
return Error::success();
1776-
}
1777-
17781754
Error GlobalISelEmitter::importImplicitDefRenderers(
17791755
BuildMIAction &DstMIBuilder, ArrayRef<const Record *> ImplicitDefs) const {
17801756
if (!ImplicitDefs.empty())

0 commit comments

Comments
 (0)