[llvm] [SelectionDAG] Add instantiated OPC_EmitInteger and OPC_EmitStringInteger (PR #73241)
Wang Pengcheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 23 05:53:25 PST 2023
https://github.com/wangpc-pp created https://github.com/llvm/llvm-project/pull/73241
These two opcodes are used to be followed by a MVT operand, which is
always one of i8/i16/i32/i64.
We add instantiated `OPC_EmitInteger` and `OPC_EmitStringInteger` with
i8/i16/i32/i64 so that we can reduce one byte.
We reserve `OPC_EmitInteger` and `OPC_EmitStringInteger` in case that
we may need them someday, though I haven't found one usage after this
change.
Overall this reduces the llc binary size with all in-tree targets by
about 200K.
>From 957ca08756064f42914973a05eb93f4da72b63d5 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Thu, 23 Nov 2023 21:41:15 +0800
Subject: [PATCH] [SelectionDAG] Add instantiated OPC_EmitInteger and
OPC_EmitStringInteger
These two opcodes are used to be followed by a MVT operand, which is
always one of i8/i16/i32/i64.
We add instantiated `OPC_EmitInteger` and `OPC_EmitStringInteger` with
i8/i16/i32/i64 so that we can reduce one byte.
We reserve `OPC_EmitInteger` and `OPC_EmitStringInteger` in case that
we may need them someday, though I haven't found one usage after this
change.
Overall this reduces the llc binary size with all in-tree targets by
about 200K.
---
llvm/include/llvm/CodeGen/SelectionDAGISel.h | 6 +++
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 41 +++++++++++++++----
llvm/test/TableGen/DAGDefaultOps.td | 8 ++--
.../TableGen/dag-isel-regclass-emit-enum.td | 4 +-
llvm/test/TableGen/dag-isel-subregs.td | 4 +-
llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 40 ++++++++++++++----
6 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index ffeb4959ba7d076..654f5a2fc23e355 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -121,6 +121,7 @@ class SelectionDAGISel : public MachineFunctionPass {
static void EnforceNodeIdInvariant(SDNode *N);
// Opcodes used by the DAG state machine:
+ // clang-format off
enum BuiltinOpcodes {
OPC_Scope,
OPC_RecordNode,
@@ -159,7 +160,11 @@ class SelectionDAGISel : public MachineFunctionPass {
OPC_CheckFoldableChainNode,
OPC_EmitInteger,
+ // Space-optimized forms that implicitly encode integer VT.
+ OPC_EmitInteger8, OPC_EmitInteger16, OPC_EmitInteger32, OPC_EmitInteger64,
OPC_EmitStringInteger,
+ // Space-optimized forms that implicitly encode integer VT.
+ OPC_EmitStringInteger8, OPC_EmitStringInteger16, OPC_EmitStringInteger32, OPC_EmitStringInteger64,
OPC_EmitRegister,
OPC_EmitRegister2,
OPC_EmitConvertToTarget,
@@ -180,6 +185,7 @@ class SelectionDAGISel : public MachineFunctionPass {
// Contains offset in table for pattern being selected
OPC_Coverage
};
+ // clang-format on
enum {
OPFL_None = 0, // Node has no chain or glue input and isn't variadic.
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7d9bebdca127224..403cf32b2db079a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3452,17 +3452,44 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
}
case OPC_EmitInteger:
- case OPC_EmitStringInteger: {
- MVT::SimpleValueType VT =
- (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ case OPC_EmitInteger8:
+ case OPC_EmitInteger16:
+ case OPC_EmitInteger32:
+ case OPC_EmitInteger64:
+ case OPC_EmitStringInteger:
+ case OPC_EmitStringInteger8:
+ case OPC_EmitStringInteger16:
+ case OPC_EmitStringInteger32:
+ case OPC_EmitStringInteger64: {
+ MVT::SimpleValueType VT;
+ switch (Opcode) {
+ case OPC_EmitInteger8:
+ case OPC_EmitStringInteger8:
+ VT = MVT::i8;
+ break;
+ case OPC_EmitInteger16:
+ case OPC_EmitStringInteger16:
+ VT = MVT::i16;
+ break;
+ case OPC_EmitInteger32:
+ case OPC_EmitStringInteger32:
+ VT = MVT::i32;
+ break;
+ case OPC_EmitInteger64:
+ case OPC_EmitStringInteger64:
+ VT = MVT::i64;
+ break;
+ default:
+ VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ break;
+ }
int64_t Val = MatcherTable[MatcherIndex++];
if (Val & 128)
Val = GetVBR(Val, MatcherTable, MatcherIndex);
- if (Opcode == OPC_EmitInteger)
+ if (Opcode >= OPC_EmitInteger && Opcode <= OPC_EmitInteger64)
Val = decodeSignRotatedValue(Val);
- RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
- CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch),
- VT), nullptr));
+ RecordedNodes.push_back(std::pair<SDValue, SDNode *>(
+ CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch), VT), nullptr));
continue;
}
case OPC_EmitRegister: {
diff --git a/llvm/test/TableGen/DAGDefaultOps.td b/llvm/test/TableGen/DAGDefaultOps.td
index 88c3f6311feadd9..010ee205e6ff2f8 100644
--- a/llvm/test/TableGen/DAGDefaultOps.td
+++ b/llvm/test/TableGen/DAGDefaultOps.td
@@ -76,20 +76,20 @@ def MulIRRPat : Pat<(mul i32:$x, i32:$y), (MulIRR Reg:$x, Reg:$y)>;
// ADD: SwitchOpcode{{.*}}TARGET_VAL(ISD::ADD)
// ADD-NEXT: OPC_RecordChild0
// ADD-NEXT: OPC_RecordChild1
-// ADD-NEXT: OPC_EmitInteger, MVT::i32, 0
+// ADD-NEXT: OPC_EmitInteger32, 0
// ADD-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::AddRRI)
// ADDINT: SwitchOpcode{{.*}}TARGET_VAL(ISD::INTRINSIC_WO_CHAIN)
// ADDINT-NEXT: OPC_CheckChild0Integer
// ADDINT-NEXT: OPC_RecordChild1
// ADDINT-NEXT: OPC_RecordChild2
-// ADDINT-NEXT: OPC_EmitInteger, MVT::i32, 2
+// ADDINT-NEXT: OPC_EmitInteger32, 2
// ADDINT-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::AddRRI)
// SUB: SwitchOpcode{{.*}}TARGET_VAL(ISD::SUB)
// SUB-NEXT: OPC_RecordChild0
// SUB-NEXT: OPC_RecordChild1
-// SUB-NEXT: OPC_EmitInteger, MVT::i32, 0
+// SUB-NEXT: OPC_EmitInteger32, 0
// SUB-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::SubRRI)
// MULINT: SwitchOpcode{{.*}}TARGET_VAL(ISD::INTRINSIC_W_CHAIN)
@@ -102,7 +102,7 @@ def MulIRRPat : Pat<(mul i32:$x, i32:$y), (MulIRR Reg:$x, Reg:$y)>;
// MULINT-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::MulRRI)
// MUL: SwitchOpcode{{.*}}TARGET_VAL(ISD::MUL)
-// MUL-NEXT: OPC_EmitInteger, MVT::i32, 0
+// MUL-NEXT: OPC_EmitInteger32, 0
// MUL-NEXT: OPC_RecordChild0
// MUL-NEXT: OPC_RecordChild1
// MUL-NEXT: OPC_MorphNodeTo1, TARGET_VAL(::MulRRI)
diff --git a/llvm/test/TableGen/dag-isel-regclass-emit-enum.td b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
index b4a2db605b9aaee..89a38d0c7c304ec 100644
--- a/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
+++ b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
@@ -25,14 +25,14 @@ def GPRAbove127 : RegisterClass<"TestTarget", [i32], 32,
// CHECK-NEXT: OPC_RecordChild0, // #0 = $src
// CHECK-NEXT: OPC_Scope, 14, /*->20*/ // 2 children in Scope
// CHECK-NEXT: OPC_CheckChild1Integer, 0,
-// CHECK-NEXT: OPC_EmitInteger, MVT::i32, 0|128,2/*256*/,
+// CHECK-NEXT: OPC_EmitInteger32, 0|128,2/*256*/,
// CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS), 0,
// CHECK-NEXT: MVT::i32, 2/*#Ops*/, 1, 0,
def : Pat<(i32 (add i32:$src, (i32 0))),
(COPY_TO_REGCLASS GPRAbove127, GPR0:$src)>;
// CHECK: OPC_CheckChild1Integer, 2,
-// CHECK-NEXT: OPC_EmitStringInteger, MVT::i32, TestNamespace::GPR127RegClassID,
+// CHECK-NEXT: OPC_EmitStringInteger32, TestNamespace::GPR127RegClassID,
// CHECK-NEXT: OPC_MorphNodeTo1, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS), 0,
// CHECK-NEXT: MVT::i32, 2/*#Ops*/, 1, 0,
def : Pat<(i32 (add i32:$src, (i32 1))),
diff --git a/llvm/test/TableGen/dag-isel-subregs.td b/llvm/test/TableGen/dag-isel-subregs.td
index 0652637fe3c9c2d..52ac0377bd2c9f2 100644
--- a/llvm/test/TableGen/dag-isel-subregs.td
+++ b/llvm/test/TableGen/dag-isel-subregs.td
@@ -4,11 +4,11 @@ include "reg-with-subregs-common.td"
// CHECK-LABEL: OPC_CheckOpcode, TARGET_VAL(ISD::EXTRACT_SUBVECTOR),
// CHECK: OPC_CheckChild1Integer, 0,
-// CHECK: OPC_EmitStringInteger, MVT::i32, sub0_sub1,
+// CHECK: OPC_EmitStringInteger32, sub0_sub1,
def : Pat<(v2i32 (extract_subvector v32i32:$src, (i32 0))),
(EXTRACT_SUBREG GPR_1024:$src, sub0_sub1)>;
// CHECK: OPC_CheckChild1Integer, 30,
-// CHECK: OPC_EmitInteger, MVT::i32, 10|128,2/*266*/,
+// CHECK: OPC_EmitInteger32, 10|128,2/*266*/,
def : Pat<(v2i32 (extract_subvector v32i32:$src, (i32 15))),
(EXTRACT_SUBREG GPR_1024:$src, sub30_sub31)>;
diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 4a11991036efc11..17886787317e40d 100644
--- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -669,19 +669,45 @@ EmitMatcher(const Matcher *N, const unsigned Indent, unsigned CurrentIdx,
case Matcher::EmitInteger: {
int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
- OS << "OPC_EmitInteger, "
- << getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
- unsigned Bytes = 2 + EmitSignedVBRValue(Val, OS);
+ MVT::SimpleValueType VT = cast<EmitIntegerMatcher>(N)->getVT();
+ unsigned OpBytes;
+ switch (VT) {
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ case MVT::i64:
+ OpBytes = 1;
+ OS << "OPC_EmitInteger" << MVT(VT).getScalarSizeInBits() << ", ";
+ break;
+ default:
+ OpBytes = 2;
+ OS << "OPC_EmitInteger, " << getEnumName(VT) << ", ";
+ break;
+ }
+ unsigned Bytes = OpBytes + EmitSignedVBRValue(Val, OS);
OS << '\n';
return Bytes;
}
case Matcher::EmitStringInteger: {
const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
+ MVT::SimpleValueType VT = cast<EmitStringIntegerMatcher>(N)->getVT();
// These should always fit into 7 bits.
- OS << "OPC_EmitStringInteger, "
- << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", " << Val
- << ",\n";
- return 3;
+ unsigned OpBytes;
+ switch (VT) {
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ case MVT::i64:
+ OpBytes = 1;
+ OS << "OPC_EmitStringInteger" << MVT(VT).getScalarSizeInBits() << ", ";
+ break;
+ default:
+ OpBytes = 2;
+ OS << "OPC_EmitStringInteger, " << getEnumName(VT) << ", ";
+ break;
+ }
+ OS << Val << ",\n";
+ return OpBytes + 1;
}
case Matcher::EmitRegister: {
More information about the llvm-commits
mailing list