[AsmWriter] Factor out mnemonic generation to accessible getMnemonic.
authorFlorian Hahn <flo@fhahn.com>
Tue, 17 Nov 2020 09:38:17 +0000 (09:38 +0000)
committerFlorian Hahn <flo@fhahn.com>
Tue, 17 Nov 2020 09:47:38 +0000 (09:47 +0000)
This patch factors out the part of printInstruction that gets the
mnemonic string for a given MCInst. This is intended to be used
subsequently for the instruction-mix remarks to display the final
mnemonic (D90040).

Unfortunately making `getMnemonic` available to the AsmPrinter
seems to require making it virtual. Not sure if there's a way around
that with the current layering of the AsmPrinters.

Reviewed By: Paul-C-Anagnostopoulos

Differential Revision: https://reviews.llvm.org/D90039

21 files changed:
llvm/include/llvm/MC/MCInstPrinter.h
llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h
llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h
llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h
llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h
llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h
llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h
llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h
llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h
llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h
llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h
llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h
llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h
llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h
llvm/utils/TableGen/AsmWriterEmitter.cpp

index 751c2bd..8b9ef17 100644 (file)
@@ -88,6 +88,10 @@ public:
   /// Specify a stream to emit comments to.
   void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
 
+  /// Returns a pair containing the mnemonic for \p MI and the number of bits
+  /// left for further processing by printInstruction (generated by tablegen).
+  virtual std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) = 0;
+
   /// Print the specified MCInst to the specified raw_ostream.
   ///
   /// \p Address the address of current instruction on most targets, used to
index 6da5f0e..20c4e4c 100644 (file)
@@ -30,6 +30,7 @@ public:
   void printRegName(raw_ostream &OS, unsigned RegNo) const override;
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   virtual void printInstruction(const MCInst *MI, uint64_t Address,
                                 const MCSubtargetInfo &STI, raw_ostream &O);
   virtual bool printAliasInstr(const MCInst *MI, uint64_t Address,
@@ -203,6 +204,7 @@ public:
   void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
                  const MCSubtargetInfo &STI, raw_ostream &O) override;
 
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address,
                         const MCSubtargetInfo &STI, raw_ostream &O) override;
   bool printAliasInstr(const MCInst *MI, uint64_t Address,
index ed45c53..64ccb90 100644 (file)
@@ -24,6 +24,7 @@ public:
 
   //Autogenerated by tblgen
   void printRegName(raw_ostream &OS, unsigned RegNo) const override;
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address,
                         const MCSubtargetInfo &STI, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
@@ -253,6 +254,7 @@ public:
 
   void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
                  const MCSubtargetInfo &STI, raw_ostream &O) override;
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index 266f2de..bcb790c 100644 (file)
@@ -26,6 +26,7 @@ public:
       : MCInstPrinter(MAI, MII, MRI) {}
 
   // Autogenerated by tblgen.
+  std::pair<std::string, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index 37cb731..d975d79 100644 (file)
@@ -30,6 +30,7 @@ public:
   void printRegName(raw_ostream &OS, unsigned RegNo) const override;
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address,
                         const MCSubtargetInfo &STI, raw_ostream &O);
   virtual bool printAliasInstr(const MCInst *MI, uint64_t Address,
index 910fd34..8976ef2 100644 (file)
@@ -45,6 +45,7 @@ private:
   void printMemri(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 
   // Autogenerated by TableGen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O);
   void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
index 2181bb5..e76067e 100644 (file)
@@ -32,6 +32,7 @@ public:
   void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 };
index cd96a23..7665837 100644 (file)
@@ -34,6 +34,7 @@ public:
 
   static char const *getRegisterName(unsigned RegNo);
 
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   void printOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
   void printBrtarget(MCInst const *MI, unsigned OpNo, raw_ostream &O) const;
index ce6df29..f0d287c 100644 (file)
@@ -43,6 +43,7 @@ public:
   void printMemImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &OS);
   void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
index 6a6b07f..08c4663 100644 (file)
@@ -26,6 +26,7 @@ namespace llvm {
                    const MCSubtargetInfo &STI, raw_ostream &O) override;
 
     // Autogenerated by tblgen.
+    std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
     void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
     bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O);
     void printCustomAliasOperand(const MCInst *MI, uint64_t Address,
index 3f534a2..68b13bf 100644 (file)
@@ -79,6 +79,7 @@ public:
     : MCInstPrinter(MAI, MII, MRI) {}
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index cee0e7e..503f049 100644 (file)
@@ -29,6 +29,7 @@ public:
                  const MCSubtargetInfo &STI, raw_ostream &OS) override;
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
   // End
index 9763aec..2b54144 100644 (file)
@@ -36,6 +36,7 @@ public:
                  const MCSubtargetInfo &STI, raw_ostream &O) override;
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index fdaa00c..70ec0fe 100644 (file)
@@ -48,6 +48,7 @@ public:
                        const MCSubtargetInfo &STI, raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address,
                         const MCSubtargetInfo &STI, raw_ostream &O);
   bool printAliasInstr(const MCInst *MI, uint64_t Address,
index 11587f1..91b78bd 100644 (file)
@@ -31,6 +31,7 @@ public:
   bool isV9(const MCSubtargetInfo &STI) const;
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address,
                         const MCSubtargetInfo &STI, raw_ostream &O);
   bool printAliasInstr(const MCInst *MI, uint64_t Address,
index cfe1bd8..0db7279 100644 (file)
@@ -27,6 +27,7 @@ public:
     : MCInstPrinter(MAI, MII, MRI) {}
 
   // Automatically generated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index f40cef2..c46411b 100644 (file)
@@ -52,6 +52,7 @@ public:
                                        raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 };
index 51ddae6..f7a8505 100644 (file)
@@ -36,6 +36,7 @@ public:
                                raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &OS);
   static const char *getRegisterName(unsigned RegNo);
 
index 82baf61..aa4d054 100644 (file)
@@ -37,6 +37,7 @@ public:
                                raw_ostream &O);
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index c7868bf..0ea4710 100644 (file)
@@ -27,6 +27,7 @@ public:
     : MCInstPrinter(MAI, MII, MRI) {}
 
   // Autogenerated by tblgen.
+  std::pair<const char *, uint64_t> getMnemonic(const MCInst *MI) override;
   void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O);
   static const char *getRegisterName(unsigned RegNo);
 
index dfbe871..f903be1 100644 (file)
@@ -64,9 +64,15 @@ public:
   AsmWriterEmitter(RecordKeeper &R);
 
   void run(raw_ostream &o);
-
 private:
-  void EmitPrintInstruction(raw_ostream &o);
+  void EmitGetMnemonic(
+      raw_ostream &o,
+      std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+      unsigned &BitsLeft, unsigned &AsmStrBits);
+  void EmitPrintInstruction(
+      raw_ostream &o,
+      std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+      unsigned &BitsLeft, unsigned &AsmStrBits);
   void EmitGetRegisterName(raw_ostream &o);
   void EmitPrintAliasInstruction(raw_ostream &O);
 
@@ -288,22 +294,19 @@ static void UnescapeAliasString(std::string &Str) {
   }
 }
 
-/// EmitPrintInstruction - Generate the code for the "printInstruction" method
-/// implementation. Destroys all instances of AsmWriterInst information, by
-/// clearing the Instructions vector.
-void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
+void AsmWriterEmitter::EmitGetMnemonic(
+    raw_ostream &O,
+    std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+    unsigned &BitsLeft, unsigned &AsmStrBits) {
   Record *AsmWriter = Target.getAsmWriter();
   StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
   bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
 
-  O << "/// printInstruction - This method is automatically generated by "
+  O << "/// getMnemonic - This method is automatically generated by "
        "tablegen\n"
        "/// from the instruction set description.\n"
-       "void "
-    << Target.getName() << ClassName
-    << "::printInstruction(const MCInst *MI, uint64_t Address, "
-    << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
-    << "raw_ostream &O) {\n";
+       "std::pair<const char *, uint64_t> "
+    << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n";
 
   // Build an aggregate string, and build a table of offsets into it.
   SequenceToOffsetTable<std::string> StringTable;
@@ -349,13 +352,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   }
 
   // Figure out how many bits we used for the string index.
-  unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2);
+  AsmStrBits = Log2_32_Ceil(MaxStringIdx + 2);
 
   // To reduce code size, we compactify common instructions into a few bits
   // in the opcode-indexed table.
-  unsigned BitsLeft = OpcodeInfoBits-AsmStrBits;
-
-  std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
+  BitsLeft = OpcodeInfoBits - AsmStrBits;
 
   while (true) {
     std::vector<std::string> UniqueOperandCommands;
@@ -435,15 +436,47 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
     ++Table;
   }
 
-  // Emit the initial tab character.
-  O << "  O << \"\\t\";\n\n";
-
   O << "  // Emit the opcode for the instruction.\n";
   O << BitsString;
 
+  // Return mnemonic string and bits.
+  O << "  return {AsmStrs+(Bits & " << (1 << AsmStrBits) - 1
+    << ")-1, Bits};\n\n";
+
+  O << "}\n";
+}
+
+/// EmitPrintInstruction - Generate the code for the "printInstruction" method
+/// implementation. Destroys all instances of AsmWriterInst information, by
+/// clearing the Instructions vector.
+void AsmWriterEmitter::EmitPrintInstruction(
+    raw_ostream &O,
+    std::vector<std::vector<std::string>> &TableDrivenOperandPrinters,
+    unsigned &BitsLeft, unsigned &AsmStrBits) {
+  const unsigned OpcodeInfoBits = 64;
+  Record *AsmWriter = Target.getAsmWriter();
+  StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+  bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
+
+  O << "/// printInstruction - This method is automatically generated by "
+       "tablegen\n"
+       "/// from the instruction set description.\n"
+       "void "
+    << Target.getName() << ClassName
+    << "::printInstruction(const MCInst *MI, uint64_t Address, "
+    << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+    << "raw_ostream &O) {\n";
+
+  // Emit the initial tab character.
+  O << "  O << \"\\t\";\n\n";
+
   // Emit the starting string.
-  O << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n"
-    << "  O << AsmStrs + (Bits & " << (1 << AsmStrBits)-1 << ") - 1;\n\n";
+  O << "  auto MnemonicInfo = getMnemonic(MI);\n\n";
+  O << "  O << MnemonicInfo.first;\n\n";
+
+  O << "  uint" << ((BitsLeft < (OpcodeInfoBits - 32)) ? 64 : 32)
+    << "_t Bits = MnemonicInfo.second;\n"
+    << "  assert(Bits != 0 && \"Cannot print this instruction.\");\n";
 
   // Output the table driven operand information.
   BitsLeft = OpcodeInfoBits-AsmStrBits;
@@ -1262,7 +1295,11 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
 }
 
 void AsmWriterEmitter::run(raw_ostream &O) {
-  EmitPrintInstruction(O);
+  std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
+  unsigned BitsLeft = 0;
+  unsigned AsmStrBits = 0;
+  EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
+  EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits);
   EmitGetRegisterName(O);
   EmitPrintAliasInstruction(O);
 }