[llvm] [MVT][TableGen] Extend Machine Value Type to `uint16_t` (PR #99657)

Brandon Wu via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 08:05:25 PDT 2024


https://github.com/4vtomat created https://github.com/llvm/llvm-project/pull/99657

Currently 208 out of 256 MVTs are used, it will be run out soon, so
ultimately we need to extend the original `MVT::SimpleValueType` from
`uint8_t` to `uint16_t` to accomodate more types.
The `MatcherTable` uses `unsigned char` for encoding the matcher code,
so the extended MVTs are no longer fit into the table, thus we need to
use VBR to encode them as we do on others that are wider than 8 bits.

The statistics below shows the difference of the generated matcher table
file in terms of "number of characters":
Table                       Before     After     Change(%)
WebAssemblyGenDAGISel.inc   393561     379244    -3.64
NVPTXGenDAGISel.inc         2559591    2430267   -5.05
RISCVGenDAGISel.inc         34077228   33338013  -2.17
AVRGenDAGISel.inc           50151      47965     -4.36
PPCGenDAGISel.inc           2504435    2392041   -4.49
MipsGenDAGISel.inc          778353     751718    -3.42
SystemZGenDAGISel.inc       896893     863890    -3.68
AArch64GenDAGISel.inc       8107608    7841939   -3.28
MSP430GenDAGISel.inc        135129     130357    -3.53
LoongArchGenDAGISel.inc     1270101    1220317   -3.92
XCoreGenDAGISel.inc         61883      60740     -1.85
BPFGenDAGISel.inc           70406      69036     -1.95
VEGenDAGISel.inc            939901     909025    -3.29
LanaiGenDAGISel.inc         39537      38571     -2.44
X86GenDAGISel.inc           10144147   9789910   -3.49
ARMGenDAGISel.inc           2538230    2431278   -4.21
HexagonGenDAGISel.inc       2553975    2470275   -3.28
SparcGenDAGISel.inc         96671      93963     -2.80
AMDGPUGenDAGISel.inc        8546226    8391452   -1.81
R600GenDAGISel.inc          397075     390725    -1.60

The statistics below shows the runtime peak memory usage by compiling a
simple C program:
`/bin/time -v clang -target $TARGET -O3 -c test.c`
```
  int test(int a) {
    return a * 3;
  }
```
Target        Before(kbytes)    After(kbytes)    Change(%)
wasm64        109708            108748           -0.88
nvptx64       109892            108616           -1.16
riscv64       113492            112624           -0.76
avr           110440            109080           -1.23
ppc64         112384            111676           -0.63
mips64        113524            112568           -0.84
systemz       110864            109964           -0.81
aarch64       113736            112484           -1.10
msp430        110136            108956           -1.07
loongarch64   110784            109784           -0.90
xcore         108004            106776           -1.14
bpf           110612            109520           -0.99
ve            110976            109756           -1.10
lanai         109880            108620           -1.15
x86_64        113652            112540           -0.98
arm64         113576            112588           -0.87
hexagon       115264            113556           -1.48
sparc         110336            108792           -1.40
amdgcn        117248            116088           -0.99
r600          111060            109788           -1.15


>From 7db6e8c8e6ad06592f2700353e21d911769fc887 Mon Sep 17 00:00:00 2001
From: Brandon Wu <brandon.wu at sifive.com>
Date: Fri, 19 Jul 2024 05:23:55 -0700
Subject: [PATCH] [MVT][TableGen] Extend Machine Value Type to `uint16_t`

Currently 208 out of 256 MVTs are used, it will be run out soon, so
ultimately we need to extend the original `MVT::SimpleValueType` from
`uint8_t` to `uint16_t` to accomodate more types.
The `MatcherTable` uses `unsigned char` for encoding the matcher code,
so the extended MVTs are no longer fit into the table, thus we need to
use VBR to encode them as we do on others that are wider than 8 bits.

The statistics below shows the difference of the generated matcher table
file in terms of "number of characters":
Table                       Before     After     Change(%)
WebAssemblyGenDAGISel.inc   393561     379244    -3.64
NVPTXGenDAGISel.inc         2559591    2430267   -5.05
RISCVGenDAGISel.inc         34077228   33338013  -2.17
AVRGenDAGISel.inc           50151      47965     -4.36
PPCGenDAGISel.inc           2504435    2392041   -4.49
MipsGenDAGISel.inc          778353     751718    -3.42
SystemZGenDAGISel.inc       896893     863890    -3.68
AArch64GenDAGISel.inc       8107608    7841939   -3.28
MSP430GenDAGISel.inc        135129     130357    -3.53
LoongArchGenDAGISel.inc     1270101    1220317   -3.92
XCoreGenDAGISel.inc         61883      60740     -1.85
BPFGenDAGISel.inc           70406      69036     -1.95
VEGenDAGISel.inc            939901     909025    -3.29
LanaiGenDAGISel.inc         39537      38571     -2.44
X86GenDAGISel.inc           10144147   9789910   -3.49
ARMGenDAGISel.inc           2538230    2431278   -4.21
HexagonGenDAGISel.inc       2553975    2470275   -3.28
SparcGenDAGISel.inc         96671      93963     -2.80
AMDGPUGenDAGISel.inc        8546226    8391452   -1.81
R600GenDAGISel.inc          397075     390725    -1.60

The statistics below shows the runtime peak memory usage by compiling a
simple C program:
`/bin/time -v clang -target $TARGET -O3 -c test.c`
```
  int test(int a) {
    return a * 3;
  }
```
Target        Before(kbytes)    After(kbytes)    Change(%)
wasm64        109708            108748           -0.88
nvptx64       109892            108616           -1.16
riscv64       113492            112624           -0.76
avr           110440            109080           -1.23
ppc64         112384            111676           -0.63
mips64        113524            112568           -0.84
systemz       110864            109964           -0.81
aarch64       113736            112484           -1.10
msp430        110136            108956           -1.07
loongarch64   110784            109784           -0.90
xcore         108004            106776           -1.14
bpf           110612            109520           -0.99
ve            110976            109756           -1.10
lanai         109880            108620           -1.15
x86_64        113652            112540           -0.98
arm64         113576            112588           -0.87
hexagon       115264            113556           -1.48
sparc         110336            108792           -1.40
amdgcn        117248            116088           -0.99
r600          111060            109788           -1.15
---
 .../llvm/CodeGenTypes/MachineValueType.h      |  2 +-
 .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 69 ++++++++++++++-----
 .../TableGen/dag-isel-regclass-emit-enum.td   |  4 +-
 .../TableGen/Common/CodeGenDAGPatterns.h      |  8 +--
 llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 66 +++++++++++-------
 llvm/utils/TableGen/VTEmitter.cpp             |  4 +-
 6 files changed, 99 insertions(+), 54 deletions(-)

diff --git a/llvm/include/llvm/CodeGenTypes/MachineValueType.h b/llvm/include/llvm/CodeGenTypes/MachineValueType.h
index 7e7608c34fb70..556531c3147e5 100644
--- a/llvm/include/llvm/CodeGenTypes/MachineValueType.h
+++ b/llvm/include/llvm/CodeGenTypes/MachineValueType.h
@@ -33,7 +33,7 @@ namespace llvm {
   /// type can be represented by an MVT.
   class MVT {
   public:
-    enum SimpleValueType : uint8_t {
+    enum SimpleValueType : uint16_t {
       // Simple value types that aren't explicitly part of this enumeration
       // are considered extended value types.
       INVALID_SIMPLE_VALUE_TYPE = 0,
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index df3d207d85d35..63612ffdc9397 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -2896,8 +2896,10 @@ CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
 LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
 CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
                SDValue N, const TargetLowering *TLI, const DataLayout &DL) {
-  MVT::SimpleValueType VT =
-      static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+  unsigned SimpleVT = MatcherTable[MatcherIndex++];
+  if (SimpleVT & 128)
+    SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+  MVT::SimpleValueType VT = static_cast<MVT::SimpleValueType>(SimpleVT);
   if (cast<VTSDNode>(N)->getVT() == VT)
     return true;
 
@@ -3027,7 +3029,10 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
       VT = MVT::i64;
       break;
     default:
-      VT = static_cast<MVT::SimpleValueType>(Table[Index++]);
+      unsigned SimpleVT = Table[Index++];
+      if (SimpleVT & 128)
+        SimpleVT = GetVBR(SimpleVT, Table, Index);
+      VT = static_cast<MVT::SimpleValueType>(SimpleVT);
       break;
     }
     Result = !::CheckType(VT, N, SDISel.TLI, SDISel.CurDAG->getDataLayout());
@@ -3035,7 +3040,10 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
   }
   case SelectionDAGISel::OPC_CheckTypeRes: {
     unsigned Res = Table[Index++];
-    Result = !::CheckType(static_cast<MVT::SimpleValueType>(Table[Index++]),
+    unsigned SimpleVT = Table[Index++];
+    if (SimpleVT & 128)
+      SimpleVT = GetVBR(SimpleVT, Table, Index);
+    Result = !::CheckType(static_cast<MVT::SimpleValueType>(SimpleVT),
                           N.getValue(Res), SDISel.TLI,
                           SDISel.CurDAG->getDataLayout());
     return Index;
@@ -3075,7 +3083,10 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
       VT = MVT::i64;
       ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
     } else {
-      VT = static_cast<MVT::SimpleValueType>(Table[Index++]);
+      unsigned SimpleVT = Table[Index++];
+      if (SimpleVT & 128)
+        SimpleVT = GetVBR(SimpleVT, Table, Index);
+      VT = static_cast<MVT::SimpleValueType>(SimpleVT);
       ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
     }
     Result = !::CheckChildType(VT, N, SDISel.TLI,
@@ -3579,7 +3590,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
         VT = MVT::i64;
         break;
       default:
-        VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        unsigned SimpleVT = MatcherTable[MatcherIndex++];
+        if (SimpleVT & 128)
+          SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+        VT = static_cast<MVT::SimpleValueType>(SimpleVT);
         break;
       }
       if (!::CheckType(VT, N, TLI, CurDAG->getDataLayout()))
@@ -3588,9 +3602,11 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
 
     case OPC_CheckTypeRes: {
       unsigned Res = MatcherTable[MatcherIndex++];
-      if (!::CheckType(
-              static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]),
-              N.getValue(Res), TLI, CurDAG->getDataLayout()))
+      unsigned SimpleVT = MatcherTable[MatcherIndex++];
+      if (SimpleVT & 128)
+        SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+      if (!::CheckType(static_cast<MVT::SimpleValueType>(SimpleVT),
+                       N.getValue(Res), TLI, CurDAG->getDataLayout()))
         break;
       continue;
     }
@@ -3629,7 +3645,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
     case OPC_SwitchType: {
       MVT CurNodeVT = N.getSimpleValueType();
       unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
-      unsigned CaseSize;
+      unsigned CaseSize, CaseSimpleVT;
       while (true) {
         // Get the size of this case.
         CaseSize = MatcherTable[MatcherIndex++];
@@ -3637,8 +3653,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
           CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
         if (CaseSize == 0) break;
 
-        MVT CaseVT =
-            static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        CaseSimpleVT = MatcherTable[MatcherIndex++];
+        if (CaseSimpleVT & 128)
+          CaseSimpleVT = GetVBR(CaseSimpleVT, MatcherTable, MatcherIndex);
+        MVT CaseVT = static_cast<MVT::SimpleValueType>(CaseSimpleVT);
         if (CaseVT == MVT::iPTR)
           CaseVT = TLI->getPointerTy(CurDAG->getDataLayout());
 
@@ -3694,7 +3712,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
         VT = MVT::i64;
         ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
       } else {
-        VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        unsigned SimpleVT = MatcherTable[MatcherIndex++];
+        if (SimpleVT & 128)
+          SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+        VT = static_cast<MVT::SimpleValueType>(SimpleVT);
         ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
       }
       if (!::CheckChildType(VT, N, TLI, CurDAG->getDataLayout(), ChildNo))
@@ -3788,7 +3809,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
         VT = MVT::i64;
         break;
       default:
-        VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        unsigned SimpleVT = MatcherTable[MatcherIndex++];
+        if (SimpleVT & 128)
+          SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+        VT = static_cast<MVT::SimpleValueType>(SimpleVT);
         break;
       }
       int64_t Val = MatcherTable[MatcherIndex++];
@@ -3812,7 +3836,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
         VT = MVT::i64;
         break;
       default:
-        VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        unsigned SimpleVT = MatcherTable[MatcherIndex++];
+        if (SimpleVT & 128)
+          SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+        VT = static_cast<MVT::SimpleValueType>(SimpleVT);
         break;
       }
       unsigned RegNo = MatcherTable[MatcherIndex++];
@@ -3824,8 +3851,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
       // For targets w/ more than 256 register names, the register enum
       // values are stored in two bytes in the matcher table (just like
       // opcodes).
-      MVT::SimpleValueType VT =
-          static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+      unsigned SimpleVT = MatcherTable[MatcherIndex++];
+      if (SimpleVT & 128)
+        SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+      MVT::SimpleValueType VT = static_cast<MVT::SimpleValueType>(SimpleVT);
       unsigned RegNo = MatcherTable[MatcherIndex++];
       RegNo |= MatcherTable[MatcherIndex++] << 8;
       RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
@@ -4063,8 +4092,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
         NumVTs = MatcherTable[MatcherIndex++];
       SmallVector<EVT, 4> VTs;
       for (unsigned i = 0; i != NumVTs; ++i) {
-        MVT::SimpleValueType VT =
-            static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+        unsigned SimpleVT = MatcherTable[MatcherIndex++];
+        if (SimpleVT & 128)
+          SimpleVT = GetVBR(SimpleVT, MatcherTable, MatcherIndex);
+        MVT::SimpleValueType VT = static_cast<MVT::SimpleValueType>(SimpleVT);
         if (VT == MVT::iPTR)
           VT = TLI->getPointerTy(CurDAG->getDataLayout()).SimpleTy;
         VTs.push_back(VT);
diff --git a/llvm/test/TableGen/dag-isel-regclass-emit-enum.td b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
index ba60df2bbcf6e..0fd7fa02f064c 100644
--- a/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
+++ b/llvm/test/TableGen/dag-isel-regclass-emit-enum.td
@@ -27,13 +27,13 @@ def GPRAbove127 : RegisterClass<"TestTarget", [i32], 32,
 // CHECK-NEXT: OPC_CheckChild1Integer, 0,
 // CHECK-NEXT: OPC_EmitInteger32, 0|128,2/*256*/,
 // CHECK-NEXT: OPC_MorphNodeTo1None, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS),
-// CHECK-NEXT:     MVT::i32, 2/*#Ops*/, 1, 0,
+// CHECK-NEXT:     7, 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_EmitStringInteger32, TestNamespace::GPR127RegClassID,
 // CHECK-NEXT: OPC_MorphNodeTo1None, TARGET_VAL(TargetOpcode::COPY_TO_REGCLASS),
-// CHECK-NEXT:     MVT::i32, 2/*#Ops*/, 1, 0,
+// CHECK-NEXT:     7, 2/*#Ops*/, 1, 0,
 def : Pat<(i32 (add i32:$src, (i32 1))),
           (COPY_TO_REGCLASS GPR127, GPR0:$src)>;
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index 1f4d45d81fd33..bac213a356d84 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -48,15 +48,15 @@ class CodeGenDAGPatterns;
 using TreePatternNodePtr = IntrusiveRefCntPtr<TreePatternNode>;
 
 /// This represents a set of MVTs. Since the underlying type for the MVT
-/// is uint8_t, there are at most 256 values. To reduce the number of memory
+/// is uint16_t, there are at most 65536 values. To reduce the number of memory
 /// allocations and deallocations, represent the set as a sequence of bits.
 /// To reduce the allocations even further, make MachineValueTypeSet own
 /// the storage and use std::array as the bit container.
 struct MachineValueTypeSet {
   static_assert(std::is_same<std::underlying_type_t<MVT::SimpleValueType>,
-                             uint8_t>::value,
-                "Change uint8_t here to the SimpleValueType's type");
-  static unsigned constexpr Capacity = std::numeric_limits<uint8_t>::max() + 1;
+                             uint16_t>::value,
+                "Change uint16_t here to the SimpleValueType's type");
+  static unsigned constexpr Capacity = std::numeric_limits<uint16_t>::max() + 1;
   using WordType = uint64_t;
   static unsigned constexpr WordWidth = CHAR_BIT * sizeof(WordType);
   static unsigned constexpr NumWords = Capacity / WordWidth;
diff --git a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 229245ff40504..178ceb1443335 100644
--- a/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -339,7 +339,8 @@ unsigned MatcherTableEmitter::SizeMatcher(Matcher *N, raw_ostream &OS) {
         Size += 2; // Count the child's opcode.
       } else {
         Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
-        ++Size; // Count the child's type.
+        Size += GetVBRSize(cast<SwitchTypeMatcher>(N)->getCaseType(
+            i)); // Count the child's type.
       }
       const unsigned ChildSize = SizeMatcherList(Child, OS);
       assert(ChildSize != 0 && "Matcher cannot have child of size 0");
@@ -599,7 +600,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
         IdxSize = 2; // size of opcode in table is 2 bytes.
       } else {
         Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
-        IdxSize = 1; // size of type in table is 1 byte.
+        IdxSize = GetVBRSize(cast<SwitchTypeMatcher>(N)->getCaseType(
+            i)); // size of type in table is sizeof(MVT) byte.
       }
 
       if (i != 0) {
@@ -616,7 +618,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
       if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
         OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
       else
-        OS << getEnumName(cast<SwitchTypeMatcher>(N)->getCaseType(i)) << ',';
+        EmitVBRValue(cast<SwitchTypeMatcher>(N)->getCaseType(i),
+                     OS); // size of type in table is sizeof(MVT) byte.
       if (!OmitComments)
         OS << "// ->" << CurrentIdx + ChildSize;
       OS << '\n';
@@ -639,7 +642,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
     return CurrentIdx - StartIdx + 1;
   }
 
-  case Matcher::CheckType:
+  case Matcher::CheckType: {
     if (cast<CheckTypeMatcher>(N)->getResNo() == 0) {
       MVT::SimpleValueType VT = cast<CheckTypeMatcher>(N)->getType();
       switch (VT) {
@@ -648,13 +651,17 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
         OS << "OPC_CheckTypeI" << MVT(VT).getSizeInBits() << ",\n";
         return 1;
       default:
-        OS << "OPC_CheckType, " << getEnumName(VT) << ",\n";
-        return 2;
+        OS << "OPC_CheckType, ";
+        unsigned NumBytes = EmitVBRValue(VT, OS);
+        OS << "\n";
+        return NumBytes + 1;
       }
     }
-    OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() << ", "
-       << getEnumName(cast<CheckTypeMatcher>(N)->getType()) << ",\n";
-    return 3;
+    OS << "OPC_CheckTypeRes, " << cast<CheckTypeMatcher>(N)->getResNo() << ", ";
+    unsigned NumBytes = EmitVBRValue(cast<CheckTypeMatcher>(N)->getType(), OS);
+    OS << "\n";
+    return NumBytes + 2;
+  }
 
   case Matcher::CheckChildType: {
     MVT::SimpleValueType VT = cast<CheckChildTypeMatcher>(N)->getType();
@@ -666,8 +673,10 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
       return 1;
     default:
       OS << "OPC_CheckChild" << cast<CheckChildTypeMatcher>(N)->getChildNo()
-         << "Type, " << getEnumName(VT) << ",\n";
-      return 2;
+         << "Type, ";
+      unsigned NumBytes = EmitVBRValue(VT, OS);
+      OS << "\n";
+      return NumBytes + 1;
     }
   }
 
@@ -696,10 +705,13 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
        << cast<CheckChild2CondCodeMatcher>(N)->getCondCodeName() << ",\n";
     return 2;
 
-  case Matcher::CheckValueType:
-    OS << "OPC_CheckValueType, "
-       << getEnumName(cast<CheckValueTypeMatcher>(N)->getVT()) << ",\n";
-    return 2;
+  case Matcher::CheckValueType: {
+    OS << "OPC_CheckValueType, ";
+    unsigned NumBytes =
+        EmitVBRValue(cast<CheckValueTypeMatcher>(N)->getVT(), OS);
+    OS << "\n";
+    return NumBytes + 1;
+  }
 
   case Matcher::CheckComplexPat: {
     const CheckComplexPatMatcher *CCPM = cast<CheckComplexPatMatcher>(N);
@@ -766,8 +778,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
       OS << "OPC_EmitInteger" << MVT(VT).getSizeInBits() << ", ";
       break;
     default:
-      OpBytes = 2;
-      OS << "OPC_EmitInteger, " << getEnumName(VT) << ", ";
+      OS << "OPC_EmitInteger, ";
+      OpBytes = EmitVBRValue(VT, OS) + 1;
       break;
     }
     unsigned Bytes = OpBytes + EmitSignedVBRValue(Val, OS);
@@ -785,8 +797,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
       OS << "OPC_EmitStringInteger" << MVT(VT).getSizeInBits() << ", ";
       break;
     default:
-      OpBytes = 2;
-      OS << "OPC_EmitStringInteger, " << getEnumName(VT) << ", ";
+      OS << "OPC_EmitStringInteger, ";
+      OpBytes = EmitVBRValue(VT, OS) + 1;
       break;
     }
     OS << Val << ",\n";
@@ -797,14 +809,15 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
     const EmitRegisterMatcher *Matcher = cast<EmitRegisterMatcher>(N);
     const CodeGenRegister *Reg = Matcher->getReg();
     MVT::SimpleValueType VT = Matcher->getVT();
+    unsigned OpBytes;
     // If the enum value of the register is larger than one byte can handle,
     // use EmitRegister2.
     if (Reg && Reg->EnumValue > 255) {
-      OS << "OPC_EmitRegister2, " << getEnumName(VT) << ", ";
+      OS << "OPC_EmitRegister2, ";
+      OpBytes = EmitVBRValue(VT, OS);
       OS << "TARGET_VAL(" << getQualifiedName(Reg->TheDef) << "),\n";
-      return 4;
+      return OpBytes + 3;
     }
-    unsigned OpBytes;
     switch (VT) {
     case MVT::i32:
     case MVT::i64:
@@ -812,8 +825,8 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
       OS << "OPC_EmitRegisterI" << MVT(VT).getSizeInBits() << ", ";
       break;
     default:
-      OpBytes = 2;
-      OS << "OPC_EmitRegister, " << getEnumName(VT) << ", ";
+      OS << "OPC_EmitRegister, ";
+      OpBytes = EmitVBRValue(VT, OS) + 1;
       break;
     }
     if (Reg) {
@@ -958,8 +971,9 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
         OS << "/*#VTs*/";
       OS << ", ";
     }
+    unsigned NumTypeBytes = 0;
     for (unsigned i = 0, e = EN->getNumVTs(); i != e; ++i)
-      OS << getEnumName(EN->getVT(i)) << ", ";
+      NumTypeBytes += EmitVBRValue(EN->getVT(i), OS);
 
     OS << EN->getNumOperands();
     if (!OmitComments)
@@ -992,7 +1006,7 @@ unsigned MatcherTableEmitter::EmitMatcher(const Matcher *N,
     } else
       OS << '\n';
 
-    return 4 + !CompressVTs + !CompressNodeInfo + EN->getNumVTs() +
+    return 4 + !CompressVTs + !CompressNodeInfo + NumTypeBytes +
            NumOperandBytes + NumCoveredBytes;
   }
   case Matcher::CompleteMatch: {
diff --git a/llvm/utils/TableGen/VTEmitter.cpp b/llvm/utils/TableGen/VTEmitter.cpp
index 851a525cf48c0..77d3514b4c22c 100644
--- a/llvm/utils/TableGen/VTEmitter.cpp
+++ b/llvm/utils/TableGen/VTEmitter.cpp
@@ -79,12 +79,12 @@ static void VTtoGetLLVMTyString(raw_ostream &OS, const Record *VT) {
 void VTEmitter::run(raw_ostream &OS) {
   emitSourceFileHeader("ValueTypes Source Fragment", OS, Records);
 
-  std::array<const Record *, 256> VTsByNumber = {};
+  std::array<const Record *, 65536> VTsByNumber = {};
   auto ValueTypes = Records.getAllDerivedDefinitions("ValueType");
   for (auto *VT : ValueTypes) {
     auto Number = VT->getValueAsInt("Value");
     assert(0 <= Number && Number < (int)VTsByNumber.size() &&
-           "ValueType should be uint8_t");
+           "ValueType should be uint16_t");
     assert(!VTsByNumber[Number] && "Duplicate ValueType");
     VTsByNumber[Number] = VT;
   }



More information about the llvm-commits mailing list