[llvm] [MC][NFC] Generate ComplexDeprecationInfos as function (PR #207496)

Alexis Engelke via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 4 01:10:44 PDT 2026


https://github.com/aengelke created https://github.com/llvm/llvm-project/pull/207496

The only user of ComplexDeprecationInfos is ARM, where 19 instructions
are deprecated. Instead of emitting a ~36kiB function pointer table,
emit a single 201B (x86-64) function switching over the opcodes.


>From 02d1677e465e2442f95966e983a2e6fd005bf887 Mon Sep 17 00:00:00 2001
From: Alexis Engelke <engelke at in.tum.de>
Date: Sat, 4 Jul 2026 08:10:06 +0000
Subject: [PATCH] [spr] initial version

Created using spr 1.3.8-wip
---
 llvm/include/llvm/MC/MCInstrInfo.h       |  9 ++++----
 llvm/lib/MC/MCInstrInfo.cpp              |  5 +++--
 llvm/utils/TableGen/InstrInfoEmitter.cpp | 28 ++++++++++--------------
 3 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/llvm/include/llvm/MC/MCInstrInfo.h b/llvm/include/llvm/MC/MCInstrInfo.h
index 97d5e7a52d1a8..77625fef40fda 100644
--- a/llvm/include/llvm/MC/MCInstrInfo.h
+++ b/llvm/include/llvm/MC/MCInstrInfo.h
@@ -40,7 +40,7 @@ class MCInstrInfo {
   const uint8_t *DeprecatedFeatures;
   // A complex method to determine if a certain instruction is deprecated or
   // not, and return the reason for deprecation.
-  const ComplexDeprecationPredicate *ComplexDeprecationInfos;
+  ComplexDeprecationPredicate ComplexDeprecationInfo;
   unsigned NumOpcodes;              // Number of entries in the desc array
 
 protected:
@@ -52,15 +52,14 @@ class MCInstrInfo {
   /// Initialize MCInstrInfo, called by TableGen auto-generated routines.
   /// *DO NOT USE*.
   void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
-                       const uint8_t *DF,
-                       const ComplexDeprecationPredicate *CDI, unsigned NO,
-                       const int16_t *RCHWTables = nullptr,
+                       const uint8_t *DF, ComplexDeprecationPredicate CDI,
+                       unsigned NO, const int16_t *RCHWTables = nullptr,
                        int16_t NumRegClassByHwMode = 0) {
     LastDesc = D + NO - 1;
     InstrNameIndices = NI;
     InstrNameData = ND;
     DeprecatedFeatures = DF;
-    ComplexDeprecationInfos = CDI;
+    ComplexDeprecationInfo = CDI;
     NumOpcodes = NO;
     RegClassByHwModeTables = RCHWTables;
     NumRegClassByHwModes = NumRegClassByHwMode;
diff --git a/llvm/lib/MC/MCInstrInfo.cpp b/llvm/lib/MC/MCInstrInfo.cpp
index ab63db0405324..ffb0b8d3e72ec 100644
--- a/llvm/lib/MC/MCInstrInfo.cpp
+++ b/llvm/lib/MC/MCInstrInfo.cpp
@@ -14,9 +14,10 @@ using namespace llvm;
 
 bool MCInstrInfo::getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
                                     std::string &Info) const {
+  if (ComplexDeprecationInfo)
+    if (ComplexDeprecationInfo(MI, STI, Info))
+      return true;
   unsigned Opcode = MI.getOpcode();
-  if (ComplexDeprecationInfos && ComplexDeprecationInfos[Opcode])
-    return ComplexDeprecationInfos[Opcode](MI, STI, Info);
   if (DeprecatedFeatures && DeprecatedFeatures[Opcode] != uint8_t(-1U) &&
       STI.getFeatureBits()[DeprecatedFeatures[Opcode]]) {
     // FIXME: it would be nice to include the subtarget feature here.
diff --git a/llvm/utils/TableGen/InstrInfoEmitter.cpp b/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 08526cc2a72bf..272912aa90f63 100644
--- a/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -1079,20 +1079,16 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
     }
 
     if (HasComplexDeprecationInfos) {
-      OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
-         << TargetName << "InstrComplexDeprecationInfos[] = {";
-      Num = 0;
+      OS << "bool " << TargetName << "InstrComplexDeprecationInfo("
+         << "MCInst &Inst, const MCSubtargetInfo &STI, std::string &Info) {\n"
+         << "  switch (Inst.getOpcode()) {\n";
       for (const CodeGenInstruction *Inst : NumberedInstructions) {
-        if (Num % 8 == 0)
-          OS << "\n    ";
-        if (Inst->HasComplexDeprecationPredicate)
-          // Emit a function pointer to the complex predicate method.
-          OS << "&get" << Inst->DeprecatedReason << "DeprecationInfo, ";
-        else
-          OS << "nullptr, ";
-        ++Num;
+        if (!Inst->HasComplexDeprecationPredicate)
+          continue;
+        OS << "  case " << getQualifiedName(Inst->TheDef) << ": return get"
+           << Inst->DeprecatedReason << "DeprecationInfo(Inst, STI, Info);\n";
       }
-      OS << "\n};\n\n";
+      OS << "  }\n  return false;\n}\n\n";
     }
 
     // MCInstrInfo initialization routine.
@@ -1141,7 +1137,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
     else
       OS << "nullptr, ";
     if (HasComplexDeprecationInfos)
-      OS << TargetName << "InstrComplexDeprecationInfos, ";
+      OS << TargetName << "InstrComplexDeprecationInfo, ";
     else
       OS << "nullptr, ";
     OS << NumberedInstructions.size() << ", ";
@@ -1216,8 +1212,8 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
       OS << "extern const uint8_t " << TargetName
          << "InstrDeprecationFeatures[];\n";
     if (HasComplexDeprecationInfos)
-      OS << "extern const MCInstrInfo::ComplexDeprecationPredicate "
-         << TargetName << "InstrComplexDeprecationInfos[];\n";
+      OS << "bool " << TargetName << "InstrComplexDeprecationInfo("
+         << "MCInst &Inst, const MCSubtargetInfo &STI, std::string &Info);\n";
     Twine ClassName = TargetName + "GenInstrInfo";
     OS << ClassName << "::" << ClassName
        << "(const TargetSubtargetInfo &STI, const TargetRegisterInfo &TRI, "
@@ -1239,7 +1235,7 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
     else
       OS << "nullptr, ";
     if (HasComplexDeprecationInfos)
-      OS << TargetName << "InstrComplexDeprecationInfos, ";
+      OS << TargetName << "InstrComplexDeprecationInfo, ";
     else
       OS << "nullptr, ";
     OS << NumberedInstructions.size();



More information about the llvm-commits mailing list