[llvm] bf11ed2 - [X86][tablgen] Add class RecognizableInstrBase to simplify X86 code, NFCI

Shengchen Kan via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 25 22:03:35 PDT 2022


Author: Shengchen Kan
Date: 2022-03-26T13:03:06+08:00
New Revision: bf11ed293abf4dcb2bcd37be3a027a786132e695

URL: https://github.com/llvm/llvm-project/commit/bf11ed293abf4dcb2bcd37be3a027a786132e695
DIFF: https://github.com/llvm/llvm-project/commit/bf11ed293abf4dcb2bcd37be3a027a786132e695.diff

LOG: [X86][tablgen] Add class RecognizableInstrBase to simplify X86 code, NFCI

Added: 
    

Modified: 
    llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
    llvm/utils/TableGen/X86FoldTablesEmitter.cpp
    llvm/utils/TableGen/X86MnemonicTables.cpp
    llvm/utils/TableGen/X86RecognizableInstr.cpp
    llvm/utils/TableGen/X86RecognizableInstr.h

Removed: 
    


################################################################################
diff  --git a/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp b/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
index 740bd63f2aa90..6f82dfea8d5ce 100644
--- a/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
@@ -13,6 +13,7 @@
 
 #include "CodeGenInstruction.h"
 #include "CodeGenTarget.h"
+#include "X86RecognizableInstr.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/TableGenBackend.h"
 
@@ -109,28 +110,25 @@ class IsMatch {
   IsMatch(const CodeGenInstruction *EVEXInst) : EVEXInst(EVEXInst) {}
 
   bool operator()(const CodeGenInstruction *VEXInst) {
-    Record *RecE = EVEXInst->TheDef;
-    Record *RecV = VEXInst->TheDef;
-    bool EVEX_W = RecE->getValueAsBit("HasVEX_W");
-    bool VEX_W  = RecV->getValueAsBit("HasVEX_W");
-    bool VEX_WIG  = RecV->getValueAsBit("IgnoresVEX_W");
-    bool EVEX_WIG = RecE->getValueAsBit("IgnoresVEX_W");
-    bool EVEX_W1_VEX_W0 = RecE->getValueAsBit("EVEX_W1_VEX_W0");
-
-    if (RecV->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
-        RecV->getValueAsBit("isCodeGenOnly") != RecE->getValueAsBit("isCodeGenOnly") ||
+    X86Disassembler::RecognizableInstrBase VEXRI(*VEXInst);
+    X86Disassembler::RecognizableInstrBase EVEXRI(*EVEXInst);
+    bool VEX_W = VEXRI.HasVEX_W;
+    bool EVEX_W = EVEXRI.HasVEX_W;
+    bool VEX_WIG  = VEXRI.IgnoresVEX_W;
+    bool EVEX_WIG  = EVEXRI.IgnoresVEX_W;
+    bool EVEX_W1_VEX_W0 = EVEXRI.Rec->getValueAsBit("EVEX_W1_VEX_W0");
+
+    if (VEXRI.IsCodeGenOnly != EVEXRI.IsCodeGenOnly ||
         // VEX/EVEX fields
-        RecV->getValueAsDef("OpPrefix") != RecE->getValueAsDef("OpPrefix") ||
-        RecV->getValueAsDef("OpMap") != RecE->getValueAsDef("OpMap") ||
-        RecV->getValueAsBit("hasVEX_4V") != RecE->getValueAsBit("hasVEX_4V") ||
-        RecV->getValueAsBit("hasEVEX_L2") != RecE->getValueAsBit("hasEVEX_L2") ||
-        RecV->getValueAsBit("hasVEX_L") != RecE->getValueAsBit("hasVEX_L") ||
+        VEXRI.OpPrefix != EVEXRI.OpPrefix || VEXRI.OpMap != EVEXRI.OpMap ||
+        VEXRI.HasVEX_4V != EVEXRI.HasVEX_4V ||
+        VEXRI.HasVEX_LPrefix != EVEXRI.HasVEX_LPrefix ||
         // Match is allowed if either is VEX_WIG, or they match, or EVEX
         // is VEX_W1X and VEX is VEX_W0.
         (!(VEX_WIG || (!EVEX_WIG && EVEX_W == VEX_W) ||
            (EVEX_W1_VEX_W0 && EVEX_W && !VEX_W))) ||
         // Instruction's format
-        RecV->getValueAsDef("Form") != RecE->getValueAsDef("Form"))
+        VEXRI.Form != EVEXRI.Form)
       return false;
 
     // This is needed for instructions with intrinsic version (_Int).
@@ -207,23 +205,19 @@ void X86EVEX2VEXTablesEmitter::run(raw_ostream &OS) {
       Target.getInstructionsByEnumValue();
 
   for (const CodeGenInstruction *Inst : NumberedInstructions) {
+    X86Disassembler::RecognizableInstrBase RI(*Inst);
+    const Record *Def = RI.Rec;
     // Filter non-X86 instructions.
-    if (!Inst->TheDef->isSubClassOf("X86Inst"))
+    if (!Def->isSubClassOf("X86Inst"))
       continue;
 
     // Add VEX encoded instructions to one of VEXInsts vectors according to
     // it's opcode.
-    if (Inst->TheDef->getValueAsDef("OpEnc")->getName() == "EncVEX") {
-      uint64_t Opcode = getValueFromBitsInit(Inst->TheDef->
-                                             getValueAsBitsInit("Opcode"));
-      VEXInsts[Opcode].push_back(Inst);
-    }
+    if (RI.Encoding == X86Local::VEX)
+      VEXInsts[RI.Opcode].push_back(Inst);
     // Add relevant EVEX encoded instructions to EVEXInsts
-    else if (Inst->TheDef->getValueAsDef("OpEnc")->getName() == "EncEVEX" &&
-             !Inst->TheDef->getValueAsBit("hasEVEX_K") &&
-             !Inst->TheDef->getValueAsBit("hasEVEX_B") &&
-             !Inst->TheDef->getValueAsBit("hasEVEX_L2") &&
-             !Inst->TheDef->getValueAsBit("notEVEX2VEXConvertible"))
+    else if (RI.Encoding == X86Local::EVEX && !RI.HasEVEX_K && !RI.HasEVEX_B &&
+             !RI.HasEVEX_L2Prefix && !Def->getValueAsBit("notEVEX2VEXConvertible"))
       EVEXInsts.push_back(Inst);
   }
 

diff  --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
index 6b3b8ae84ba65..c5f5ed8e084dc 100644
--- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
+++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp
@@ -212,20 +212,6 @@ static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
   return Value;
 }
 
-// Returns true if the two given BitsInits represent the same integer value
-static inline bool equalBitsInits(const BitsInit *B1, const BitsInit *B2) {
-  if (B1->getNumBits() != B2->getNumBits())
-    PrintFatalError("Comparing two BitsInits with 
diff erent sizes!");
-
-  for (unsigned i = 0, e = B1->getNumBits(); i != e; ++i) {
-    BitInit *Bit1 = cast<BitInit>(B1->getBit(i));
-    BitInit *Bit2 = cast<BitInit>(B2->getBit(i));
-    if (Bit1->getValue() != Bit2->getValue())
-      return false;
-  }
-  return true;
-}
-
 // Return the size of the register operand
 static inline unsigned int getRegOperandSize(const Record *RegRec) {
   if (RegRec->isSubClassOf("RegisterOperand"))
@@ -323,53 +309,42 @@ class IsMatch {
       : MemInst(Inst) {}
 
   bool operator()(const CodeGenInstruction *RegInst) {
-    Record *MemRec = MemInst->TheDef;
-    Record *RegRec = RegInst->TheDef;
+    X86Disassembler::RecognizableInstrBase RegRI(*RegInst);
+    X86Disassembler::RecognizableInstrBase MemRI(*MemInst);
+    const Record *RegRec = RegRI.Rec;
+    const Record *MemRec = MemRI.Rec;
+
+    // EVEX_B means 
diff erent things for memory and register forms.
+    if (RegRI.HasEVEX_B != 0 || MemRI.HasEVEX_B != 0)
+      return false;
+
+    // Instruction's format - The register form's "Form" field should be
+    // the opposite of the memory form's "Form" field.
+    if (!areOppositeForms(RegRI.Form, MemRI.Form))
+      return false;
 
     // Return false if one (at least) of the encoding fields of both
     // instructions do not match.
-    if (RegRec->getValueAsDef("OpEnc") != MemRec->getValueAsDef("OpEnc") ||
-        !equalBitsInits(RegRec->getValueAsBitsInit("Opcode"),
-                        MemRec->getValueAsBitsInit("Opcode")) ||
-        // VEX/EVEX fields
-        RegRec->getValueAsDef("OpPrefix") !=
-            MemRec->getValueAsDef("OpPrefix") ||
-        RegRec->getValueAsDef("OpMap") != MemRec->getValueAsDef("OpMap") ||
-        RegRec->getValueAsDef("OpSize") != MemRec->getValueAsDef("OpSize") ||
-        RegRec->getValueAsDef("AdSize") != MemRec->getValueAsDef("AdSize") ||
-        RegRec->getValueAsBit("hasVEX_4V") !=
-            MemRec->getValueAsBit("hasVEX_4V") ||
-        RegRec->getValueAsBit("hasEVEX_K") !=
-            MemRec->getValueAsBit("hasEVEX_K") ||
-        RegRec->getValueAsBit("hasEVEX_Z") !=
-            MemRec->getValueAsBit("hasEVEX_Z") ||
-        // EVEX_B means 
diff erent things for memory and register forms.
-        RegRec->getValueAsBit("hasEVEX_B") != 0 ||
-        MemRec->getValueAsBit("hasEVEX_B") != 0 ||
+    if (RegRI.Encoding != MemRI.Encoding || RegRI.Opcode != MemRI.Opcode ||
+        RegRI.OpPrefix != MemRI.OpPrefix || RegRI.OpMap != MemRI.OpMap ||
+        RegRI.OpSize != MemRI.OpSize || RegRI.AdSize != MemRI.AdSize ||
+        RegRI.HasREX_WPrefix != MemRI.HasREX_WPrefix ||
+        RegRI.HasVEX_4V != MemRI.HasVEX_4V ||
+        RegRI.HasVEX_LPrefix != MemRI.HasVEX_LPrefix ||
+        RegRI.HasVEX_W != MemRI.HasVEX_W ||
+        RegRI.IgnoresVEX_L != MemRI.IgnoresVEX_L ||
+        RegRI.IgnoresVEX_W != MemRI.IgnoresVEX_W ||
+        RegRI.HasEVEX_K != MemRI.HasEVEX_K ||
+        RegRI.HasEVEX_KZ != MemRI.HasEVEX_KZ ||
+        RegRI.HasEVEX_L2Prefix != MemRI.HasEVEX_L2Prefix ||
         RegRec->getValueAsBit("hasEVEX_RC") !=
             MemRec->getValueAsBit("hasEVEX_RC") ||
-        RegRec->getValueAsBit("hasREX_WPrefix") !=
-            MemRec->getValueAsBit("hasREX_WPrefix") ||
         RegRec->getValueAsBit("hasLockPrefix") !=
             MemRec->getValueAsBit("hasLockPrefix") ||
         RegRec->getValueAsBit("hasNoTrackPrefix") !=
             MemRec->getValueAsBit("hasNoTrackPrefix") ||
-        RegRec->getValueAsBit("hasVEX_L") !=
-            MemRec->getValueAsBit("hasVEX_L") ||
-        RegRec->getValueAsBit("hasEVEX_L2") !=
-            MemRec->getValueAsBit("hasEVEX_L2") ||
-        RegRec->getValueAsBit("ignoresVEX_L") !=
-            MemRec->getValueAsBit("ignoresVEX_L") ||
-        RegRec->getValueAsBit("HasVEX_W") !=
-            MemRec->getValueAsBit("HasVEX_W") ||
-        RegRec->getValueAsBit("IgnoresVEX_W") !=
-            MemRec->getValueAsBit("IgnoresVEX_W") ||
         RegRec->getValueAsBit("EVEX_W1_VEX_W0") !=
             MemRec->getValueAsBit("EVEX_W1_VEX_W0") ||
-        // Instruction's format - The register form's "Form" field should be
-        // the opposite of the memory form's "Form" field.
-        !areOppositeForms(RegRec->getValueAsBitsInit("FormBits"),
-                          MemRec->getValueAsBitsInit("FormBits")) ||
         RegRec->getValueAsBit("isAsmParserOnly") !=
             MemRec->getValueAsBit("isAsmParserOnly"))
       return false;
@@ -424,31 +399,24 @@ class IsMatch {
 
 private:
   // Return true of the 2 given forms are the opposite of each other.
-  bool areOppositeForms(const BitsInit *RegFormBits,
-                        const BitsInit *MemFormBits) {
-    uint64_t MemFormNum = getValueFromBitsInit(MemFormBits);
-    uint64_t RegFormNum = getValueFromBitsInit(RegFormBits);
-
-    if ((MemFormNum == X86Local::MRM0m && RegFormNum == X86Local::MRM0r) ||
-        (MemFormNum == X86Local::MRM1m && RegFormNum == X86Local::MRM1r) ||
-        (MemFormNum == X86Local::MRM2m && RegFormNum == X86Local::MRM2r) ||
-        (MemFormNum == X86Local::MRM3m && RegFormNum == X86Local::MRM3r) ||
-        (MemFormNum == X86Local::MRM4m && RegFormNum == X86Local::MRM4r) ||
-        (MemFormNum == X86Local::MRM5m && RegFormNum == X86Local::MRM5r) ||
-        (MemFormNum == X86Local::MRM6m && RegFormNum == X86Local::MRM6r) ||
-        (MemFormNum == X86Local::MRM7m && RegFormNum == X86Local::MRM7r) ||
-        (MemFormNum == X86Local::MRMXm && RegFormNum == X86Local::MRMXr) ||
-        (MemFormNum == X86Local::MRMXmCC && RegFormNum == X86Local::MRMXrCC) ||
-        (MemFormNum == X86Local::MRMDestMem &&
-         RegFormNum == X86Local::MRMDestReg) ||
-        (MemFormNum == X86Local::MRMSrcMem &&
-         RegFormNum == X86Local::MRMSrcReg) ||
-        (MemFormNum == X86Local::MRMSrcMem4VOp3 &&
-         RegFormNum == X86Local::MRMSrcReg4VOp3) ||
-        (MemFormNum == X86Local::MRMSrcMemOp4 &&
-         RegFormNum == X86Local::MRMSrcRegOp4) ||
-        (MemFormNum == X86Local::MRMSrcMemCC &&
-         RegFormNum == X86Local::MRMSrcRegCC))
+  bool areOppositeForms(unsigned RegForm, unsigned MemForm) {
+    if ((MemForm == X86Local::MRM0m && RegForm == X86Local::MRM0r) ||
+        (MemForm == X86Local::MRM1m && RegForm == X86Local::MRM1r) ||
+        (MemForm == X86Local::MRM2m && RegForm == X86Local::MRM2r) ||
+        (MemForm == X86Local::MRM3m && RegForm == X86Local::MRM3r) ||
+        (MemForm == X86Local::MRM4m && RegForm == X86Local::MRM4r) ||
+        (MemForm == X86Local::MRM5m && RegForm == X86Local::MRM5r) ||
+        (MemForm == X86Local::MRM6m && RegForm == X86Local::MRM6r) ||
+        (MemForm == X86Local::MRM7m && RegForm == X86Local::MRM7r) ||
+        (MemForm == X86Local::MRMXm && RegForm == X86Local::MRMXr) ||
+        (MemForm == X86Local::MRMXmCC && RegForm == X86Local::MRMXrCC) ||
+        (MemForm == X86Local::MRMDestMem && RegForm == X86Local::MRMDestReg) ||
+        (MemForm == X86Local::MRMSrcMem && RegForm == X86Local::MRMSrcReg) ||
+        (MemForm == X86Local::MRMSrcMem4VOp3 &&
+         RegForm == X86Local::MRMSrcReg4VOp3) ||
+        (MemForm == X86Local::MRMSrcMemOp4 &&
+         RegForm == X86Local::MRMSrcRegOp4) ||
+        (MemForm == X86Local::MRMSrcMemCC && RegForm == X86Local::MRMSrcRegCC))
       return true;
 
     return false;

diff  --git a/llvm/utils/TableGen/X86MnemonicTables.cpp b/llvm/utils/TableGen/X86MnemonicTables.cpp
index 8c899a3e57c13..9faa3664739f4 100644
--- a/llvm/utils/TableGen/X86MnemonicTables.cpp
+++ b/llvm/utils/TableGen/X86MnemonicTables.cpp
@@ -13,7 +13,6 @@
 
 #include "CodeGenInstruction.h"
 #include "CodeGenTarget.h"
-#include "X86DisassemblerTables.h"
 #include "X86RecognizableInstr.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/TableGenBackend.h"
@@ -41,23 +40,17 @@ void X86MnemonicTablesEmitter::run(raw_ostream &OS) {
   // Hold all instructions grouped by mnemonic
   StringMap<SmallVector<const CodeGenInstruction *, 0>> MnemonicToCGInstrMap;
 
-  // Unused
-  X86Disassembler::DisassemblerTables Tables;
   ArrayRef<const CodeGenInstruction *> NumberedInstructions =
       Target.getInstructionsByEnumValue();
-  for (unsigned II = 0, IE = NumberedInstructions.size(); II != IE; ++II) {
-    const CodeGenInstruction *I = NumberedInstructions[II];
-    X86Disassembler::RecognizableInstr RI(Tables, *I, II);
-    Record *Def = I->TheDef;
-    if ( // Filter non-X86 instructions
-        !Def->isSubClassOf("X86Inst") ||
-        // Skip pseudo instructions as they may contain non-alnum characters in
-        // mnemonic
-        (RI.IsCodeGenOnly && !RI.ForceDisassemble) ||
-        // Non-parsable instruction defs contain prefix as part of AsmString
+  for (const CodeGenInstruction *I : NumberedInstructions) {
+    X86Disassembler::RecognizableInstrBase RI(*I);
+    const Record *Def = RI.Rec;
+    if (!RI.ShouldBeEmitted)
+      continue;
+    if ( // Non-parsable instruction defs contain prefix as part of AsmString
         Def->getValueAsString("AsmVariantName") == "NonParsable" ||
-        // Skip CodeGenInstructions that are not real standalone instructions
-        RI.Form == X86Local::PrefixByte || RI.Form == X86Local::Pseudo)
+        // Skip prefix byte
+        RI.Form == X86Local::PrefixByte)
       continue;
     std::string Mnemonic = X86Disassembler::getMnemonic(I, Variant);
     MnemonicToCGInstrMap[Mnemonic].push_back(I);

diff  --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp
index e9a9f8faf4233..6d857f6883763 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -75,14 +75,9 @@ static uint8_t byteFromRec(const Record* rec, StringRef name) {
   return byteFromBitsInit(*bits);
 }
 
-RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
-                                     const CodeGenInstruction &insn,
-                                     InstrUID uid) {
-  UID = uid;
-
+RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) {
   Rec = insn.TheDef;
   Name = std::string(Rec->getName());
-  Spec = &tables.specForUID(UID);
 
   if (!Rec->isSubClassOf("X86Inst")) {
     ShouldBeEmitted = false;
@@ -144,6 +139,14 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
   ShouldBeEmitted = true;
 }
 
+RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
+                                     const CodeGenInstruction &insn,
+                                     InstrUID uid)
+    : RecognizableInstrBase(insn) {
+  UID = uid;
+  Spec = &tables.specForUID(UID);
+}
+
 void RecognizableInstr::processInstr(DisassemblerTables &tables,
                                      const CodeGenInstruction &insn,
                                      InstrUID uid)

diff  --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h
index 1c151511f4b5c..bef4024d1d358 100644
--- a/llvm/utils/TableGen/X86RecognizableInstr.h
+++ b/llvm/utils/TableGen/X86RecognizableInstr.h
@@ -158,14 +158,8 @@ namespace X86Disassembler {
 
 class DisassemblerTables;
 
-/// RecognizableInstr - Encapsulates all information required to decode a single
-///   instruction, as extracted from the LLVM instruction tables.  Has methods
-///   to interpret the information available in the LLVM tables, and to emit the
-///   instruction into DisassemblerTables.
-class RecognizableInstr {
-public:
-  /// The opcode of the instruction, as used in an MCInst
-  InstrUID UID;
+/// Extract common fields of a single X86 instruction from a CodeGenInstruction
+struct RecognizableInstrBase {
   /// The record from the .td files corresponding to this instruction
   const Record* Rec;
   /// The OpPrefix field from the record
@@ -228,6 +222,18 @@ class RecognizableInstr {
   /// memory operands expand to 5 operands in the MCInst
   const std::vector<CGIOperandList::OperandInfo>* Operands;
 
+  /// \param insn The CodeGenInstruction to extract information from.
+  RecognizableInstrBase(const CodeGenInstruction &insn);
+};
+
+/// RecognizableInstr - Encapsulates all information required to decode a single
+///   instruction, as extracted from the LLVM instruction tables.  Has methods
+///   to interpret the information available in the LLVM tables, and to emit the
+///   instruction into DisassemblerTables.
+class RecognizableInstr : public RecognizableInstrBase {
+public:
+  /// The opcode of the instruction, as used in an MCInst
+  InstrUID UID;
   /// The description of the instruction that is emitted into the instruction
   /// info table
   InstructionSpecifier* Spec;


        


More information about the llvm-commits mailing list