[llvm] [TableGen][GISel] Reuse `importNodeRenderer` for `OperandWithDefaultOps` (PR #121285)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 4 12:17:58 PST 2025
https://github.com/s-barannikov updated https://github.com/llvm/llvm-project/pull/121285
>From 0690683a4f5b7a03e77012c954edd528134bbb42 Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sun, 29 Dec 2024 10:35:06 +0300
Subject: [PATCH 1/2] [TableGen][GISel] Reuse `importNodeRenderer` for
`OperandWithDefaultOps`
This avoids some code duplication (handling `Register`, `zero_reg` and
immediate operands).
---
llvm/utils/TableGen/GlobalISelEmitter.cpp | 77 +++++++----------------
1 file changed, 24 insertions(+), 53 deletions(-)
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 092cdd4ad5b435..9f244ca804a08c 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -418,7 +418,8 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
const TreePatternNode &N) const;
Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
- const TreePatternNode &N) const;
+ const TreePatternNode &N,
+ action_iterator InsertPt) const;
Error importXFormNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder,
const TreePatternNode &N) const;
@@ -431,9 +432,6 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter {
const TreePatternNode &N,
action_iterator &InsertPt) const;
- Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M,
- BuildMIAction &DstMIBuilder,
- const DAGDefaultOperand &DefaultOp) const;
Error importImplicitDefRenderers(BuildMIAction &DstMIBuilder,
ArrayRef<const Record *> ImplicitDefs) const;
@@ -1291,7 +1289,8 @@ Error GlobalISelEmitter::importNamedNodeRenderer(
// Equivalent of MatcherGen::EmitResultLeafAsOperand.
Error GlobalISelEmitter::importLeafNodeRenderer(
- RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const {
+ RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N,
+ action_iterator InsertPt) const {
if (const auto *II = dyn_cast<IntInit>(N.getLeafValue())) {
MIBuilder.addRenderer<ImmRenderer>(II->getValue());
return Error::success();
@@ -1300,11 +1299,24 @@ Error GlobalISelEmitter::importLeafNodeRenderer(
if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue())) {
const Record *R = DI->getDef();
- if (R->isSubClassOf("Register")) {
+ if (R->isSubClassOf("Register") || R->getName() == "zero_reg") {
MIBuilder.addRenderer<AddRegisterRenderer>(Target, R);
return Error::success();
}
+ if (R->getName() == "undef_tied_input") {
+ std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
+ unsigned TempRegID = M.allocateTempRegID();
+ M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, TempRegID);
+ auto I = M.insertAction<BuildMIAction>(
+ InsertPt, M.allocateOutputInsnID(),
+ &Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
+ auto &ImpDefBuilder = static_cast<BuildMIAction &>(**I);
+ ImpDefBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
+ MIBuilder.addRenderer<TempRegRenderer>(TempRegID);
+ return Error::success();
+ }
+
if (R->isSubClassOf("SubRegIndex")) {
const CodeGenSubRegIndex *SubRegIndex = CGRegs.getSubRegIdx(R);
MIBuilder.addRenderer<ImmRenderer>(SubRegIndex->EnumValue);
@@ -1386,7 +1398,7 @@ Error GlobalISelEmitter::importNodeRenderer(RuleMatcher &M,
return importNamedNodeRenderer(M, MIBuilder, N);
if (N.isLeaf())
- return importLeafNodeRenderer(M, MIBuilder, N);
+ return importLeafNodeRenderer(M, MIBuilder, N, InsertPt);
if (N.getOperator()->isSubClassOf("SDNodeXForm"))
return importXFormNodeRenderer(M, MIBuilder, N);
@@ -1707,11 +1719,11 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
// This is a predicate or optional def operand which the pattern has not
// overridden, or which we aren't letting it override; emit the 'default
// ops' operands.
-
- const Record *OperandNode = DstI->Operands[InstOpNo].Rec;
- if (auto Error = importDefaultOperandRenderers(
- InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode)))
- return std::move(Error);
+ for (const TreePatternNode &OpNode :
+ make_pointee_range(CGP.getDefaultOperand(OperandNode).DefaultOps)) {
+ if (Error Err = importNodeRenderer(M, DstMIBuilder, OpNode, InsertPt))
+ return Err;
+ }
++NumDefaultOps;
continue;
@@ -1734,47 +1746,6 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers(
return InsertPt;
}
-Error GlobalISelEmitter::importDefaultOperandRenderers(
- action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder,
- const DAGDefaultOperand &DefaultOp) const {
- for (const auto &Op : DefaultOp.DefaultOps) {
- const auto &N = *Op;
- if (!N.isLeaf())
- return failedImport("Could not add default op");
-
- const auto *DefaultOp = N.getLeafValue();
-
- if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) {
- std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
- auto *Def = DefaultDefOp->getDef();
- if (Def->getName() == "undef_tied_input") {
- unsigned TempRegID = M.allocateTempRegID();
- M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone,
- TempRegID);
- InsertPt = M.insertAction<BuildMIAction>(
- InsertPt, M.allocateOutputInsnID(),
- &Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
- BuildMIAction &IDMIBuilder =
- *static_cast<BuildMIAction *>(InsertPt->get());
- IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
- DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID);
- } else {
- DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def);
- }
- continue;
- }
-
- if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) {
- DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue());
- continue;
- }
-
- return failedImport("Could not add default op");
- }
-
- return Error::success();
-}
-
Error GlobalISelEmitter::importImplicitDefRenderers(
BuildMIAction &DstMIBuilder, ArrayRef<const Record *> ImplicitDefs) const {
if (!ImplicitDefs.empty())
>From daa7154005a9ce0fa9cc3d505dd2aa5ec3abd04f Mon Sep 17 00:00:00 2001
From: Sergei Barannikov <barannikov88 at gmail.com>
Date: Sat, 4 Jan 2025 23:13:21 +0300
Subject: [PATCH 2/2] Check std::optional before dereferencing
---
.../GlobalISelEmitter/undef-tied-input.td | 17 ++++++++++++++---
llvm/utils/TableGen/GlobalISelEmitter.cpp | 5 +++++
2 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/llvm/test/TableGen/GlobalISelEmitter/undef-tied-input.td b/llvm/test/TableGen/GlobalISelEmitter/undef-tied-input.td
index a2ee3dc311772c..323aea9e396d16 100644
--- a/llvm/test/TableGen/GlobalISelEmitter/undef-tied-input.td
+++ b/llvm/test/TableGen/GlobalISelEmitter/undef-tied-input.td
@@ -1,14 +1,25 @@
-// RUN: llvm-tblgen -gen-global-isel -I %p/../../../include -I %p/../Common %s | FileCheck %s
+// RUN: llvm-tblgen -gen-global-isel -warn-on-skipped-patterns \
+// RUN: -I %p/../../../include -I %p/../Common %s 2> %t | FileCheck %s
+// RUN: FileCheck -check-prefix=ERR %s < %t
include "llvm/Target/Target.td"
include "GlobalISelEmitterCommon.td"
-def undef_tied : OperandWithDefaultOps<untyped, (ops (i32 undef_tied_input))> {
+def undef_tied_1 : OperandWithDefaultOps<untyped, (ops (i32 undef_tied_input))> {
let MIOperandInfo = (ops GPR32:$inactive);
}
+def undef_tied_2 : OperandWithDefaultOps<i32, (ops (untyped undef_tied_input))> {
+ let MIOperandInfo = (ops GPR32:$inactive);
+}
+
+let Constraints = "$opt.inactive = $rd" in
+def I1 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied_1:$opt),
+ [(set GPR32:$rd, (abs i32:$rs))]>;
+
+// ERR: [[#@LINE+2]]:5: warning: Skipped pattern: unsupported type
let Constraints = "$opt.inactive = $rd" in
-def I1 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied:$opt),
+def I2 : I<(outs GPR32:$rd), (ins GPR32:$rs, undef_tied_2:$opt),
[(set GPR32:$rd, (abs i32:$rs))]>;
// CHECK-LABEL: // (abs:{ *:[i32] } i32:{ *:[i32] }:$rs) => (I1:{ *:[i32] } i32:{ *:[i32] }:$rs)
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 9f244ca804a08c..9f6d3a506dceb7 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -1306,13 +1306,18 @@ Error GlobalISelEmitter::importLeafNodeRenderer(
if (R->getName() == "undef_tied_input") {
std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0));
+ if (!OpTyOrNone)
+ return failedImport("unsupported type");
+
unsigned TempRegID = M.allocateTempRegID();
M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, TempRegID);
+
auto I = M.insertAction<BuildMIAction>(
InsertPt, M.allocateOutputInsnID(),
&Target.getInstruction(RK.getDef("IMPLICIT_DEF")));
auto &ImpDefBuilder = static_cast<BuildMIAction &>(**I);
ImpDefBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true);
+
MIBuilder.addRenderer<TempRegRenderer>(TempRegID);
return Error::success();
}
More information about the llvm-commits
mailing list