[llvm] 1e8ce74 - [X86][Disassembler] Optimize argument passing and immediate reading

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 11 15:58:13 PST 2020


Author: Fangrui Song
Date: 2020-01-11T15:43:26-08:00
New Revision: 1e8ce7492e91aa6db269334d12187c7ae854dccb

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

LOG: [X86][Disassembler] Optimize argument passing and immediate reading

Added: 
    

Modified: 
    llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
    llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
    llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index be03dd777457..4e929d586d82 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -177,33 +177,35 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
     raw_ostream &CStream) const {
   CommentStream = &CStream;
 
-  InternalInstruction InternalInstr;
+  InternalInstruction Insn;
+  memset(&Insn, 0, sizeof(InternalInstruction));
+  Insn.bytes = Bytes;
+  Insn.startLocation = Address;
+  Insn.readerCursor = Address;
+  Insn.mode = fMode;
 
-  std::pair<ArrayRef<uint8_t>, uint64_t> R(Bytes, Address);
-
-  int Ret = decodeInstruction(&InternalInstr, &R, (const void *)MII.get(),
-                              Address, fMode);
+  int Ret = decodeInstruction(&Insn, MII.get());
 
   if (Ret) {
-    Size = InternalInstr.readerCursor - Address;
+    Size = Insn.readerCursor - Address;
     return Fail;
   } else {
-    Size = InternalInstr.length;
-    bool Ret = translateInstruction(Instr, InternalInstr, this);
+    Size = Insn.length;
+    bool Ret = translateInstruction(Instr, Insn, this);
     if (!Ret) {
       unsigned Flags = X86::IP_NO_PREFIX;
-      if (InternalInstr.hasAdSize)
+      if (Insn.hasAdSize)
         Flags |= X86::IP_HAS_AD_SIZE;
-      if (!InternalInstr.mandatoryPrefix) {
-        if (InternalInstr.hasOpSize)
+      if (!Insn.mandatoryPrefix) {
+        if (Insn.hasOpSize)
           Flags |= X86::IP_HAS_OP_SIZE;
-        if (InternalInstr.repeatPrefix == 0xf2)
+        if (Insn.repeatPrefix == 0xf2)
           Flags |= X86::IP_HAS_REPEAT_NE;
-        else if (InternalInstr.repeatPrefix == 0xf3 &&
+        else if (Insn.repeatPrefix == 0xf3 &&
                  // It should not be 'pause' f3 90
-                 InternalInstr.opcode != 0x90)
+                 Insn.opcode != 0x90)
           Flags |= X86::IP_HAS_REPEAT;
-        if (InternalInstr.hasLockPrefix)
+        if (Insn.hasLockPrefix)
           Flags |= X86::IP_HAS_LOCK;
       }
       Instr.setFlags(Flags);

diff  --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
index cf0f474eea04..7ab9e8f60f78 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
@@ -18,11 +18,13 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <cassert>
 #include <cstdarg> /* for va_*()       */
 #include <cstdio>  /* for vsnprintf()  */
 #include <cstdlib> /* for exit()       */
 #include <cstring> /* for memset()     */
 
+using namespace llvm;
 using namespace llvm::X86Disassembler;
 
 #define DEBUG_TYPE "x86-disassembler"
@@ -196,12 +198,11 @@ static const struct InstructionSpecifier *specifierForUID(InstrUID uid) {
 }
 
 static bool peek(struct InternalInstruction *insn, uint8_t &byte) {
-  auto *r = static_cast<const std::pair<llvm::ArrayRef<uint8_t>, uint64_t> *>(
-      insn->readerArg);
-  uint64_t offset = insn->readerCursor - r->second;
-  if (offset >= r->first.size())
+  auto r = insn->bytes;
+  uint64_t offset = insn->readerCursor - insn->startLocation;
+  if (offset >= r.size())
     return true;
-  byte = r->first[offset];
+  byte = r[offset];
   return false;
 }
 
@@ -211,14 +212,13 @@ static void unconsumeByte(struct InternalInstruction* insn) {
 
 template <typename T>
 static bool consume(InternalInstruction *insn, T &ptr) {
-  auto *r = static_cast<const std::pair<llvm::ArrayRef<uint8_t>, uint64_t> *>(
-      insn->readerArg);
-  uint64_t offset = insn->readerCursor - r->second;
-  if (offset + sizeof(T) > r->first.size())
+  auto r = insn->bytes;
+  uint64_t offset = insn->readerCursor - insn->startLocation;
+  if (offset + sizeof(T) > r.size())
     return true;
   T ret = 0;
   for (unsigned i = 0; i < sizeof(T); ++i)
-    ret |= (uint64_t)r->first[offset + i] << (i * 8);
+    ret |= (uint64_t)r[offset + i] << (i * 8);
   ptr = ret;
   insn->readerCursor += sizeof(T);
   return false;
@@ -774,7 +774,7 @@ static bool is64Bit(const char *name) {
  * @return      - 0 if the ModR/M could be read when needed or was not needed;
  *                nonzero otherwise.
  */
-static int getID(struct InternalInstruction* insn, const void *miiArg) {
+static int getID(struct InternalInstruction* insn, const MCInstrInfo *miiArg) {
   uint16_t attrMask;
   uint16_t instructionID;
 
@@ -1553,15 +1553,9 @@ static int readImmediate(struct InternalInstruction* insn, uint8_t size) {
 
   dbgprintf(insn, "readImmediate()");
 
-  if (insn->numImmediatesConsumed == 2) {
-    debug("Already consumed two immediates");
-    return -1;
-  }
+  assert(insn->numImmediatesConsumed < 2 && "Already consumed two immediates");
 
-  if (size == 0)
-    size = insn->immediateSize;
-  else
-    insn->immediateSize = size;
+  insn->immediateSize = size;
   insn->immediateOffset = insn->readerCursor - insn->startLocation;
 
   switch (size) {
@@ -1585,6 +1579,8 @@ static int readImmediate(struct InternalInstruction* insn, uint8_t size) {
       return -1;
     insn->immediates[insn->numImmediatesConsumed] = imm64;
     break;
+  default:
+    llvm_unreachable("invalid size");
   }
 
   insn->numImmediatesConsumed++;
@@ -1811,36 +1807,13 @@ static int readOperands(struct InternalInstruction* insn) {
  * decodeInstruction - Reads and interprets a full instruction provided by the
  *   user.
  *
- * @param insn      - A pointer to the instruction to be populated.  Must be
- *                    pre-allocated.
- * @param reader    - The function to be used to read the instruction's bytes.
- * @param readerArg - A generic argument to be passed to the reader to store
- *                    any internal state.
- * @param startLoc  - The address (in the reader's address space) of the first
- *                    byte in the instruction.
- * @param mode      - The mode (real mode, IA-32e, or IA-32e in 64-bit mode) to
- *                    decode the instruction in.
  * @return          - 0 if the instruction's memory could be read; nonzero if
  *                    not.
  */
 int llvm::X86Disassembler::decodeInstruction(struct InternalInstruction *insn,
-                                             const void *readerArg,
-                                             const void *miiArg,
-                                             uint64_t startLoc,
-                                             DisassemblerMode mode) {
-  memset(insn, 0, sizeof(struct InternalInstruction));
-
-  insn->readerArg = readerArg;
-  insn->startLocation = startLoc;
-  insn->readerCursor = startLoc;
-  insn->mode = mode;
-  insn->numImmediatesConsumed = 0;
-
-  if (readPrefixes(insn)       ||
-      readOpcode(insn)         ||
-      getID(insn, miiArg)      ||
-      insn->instructionID == 0 ||
-      readOperands(insn))
+                                             const MCInstrInfo *mii) {
+  if (readPrefixes(insn) || readOpcode(insn) || getID(insn, mii) ||
+      insn->instructionID == 0 || readOperands(insn))
     return -1;
 
   insn->operands = x86OperandSets[insn->spec->operands];
@@ -1848,7 +1821,7 @@ int llvm::X86Disassembler::decodeInstruction(struct InternalInstruction *insn,
   insn->length = insn->readerCursor - insn->startLocation;
 
   dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu",
-            startLoc, insn->readerCursor, insn->length);
+            insn->startLocation, insn->readerCursor, insn->length);
 
   if (insn->length > 15)
     dbgprintf(insn, "Instruction exceeds 15-byte limit");

diff  --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index a1e036ca7ba1..df4085edb818 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -19,6 +19,9 @@
 #include "llvm/Support/X86DisassemblerDecoderCommon.h"
 
 namespace llvm {
+
+class MCInstrInfo;
+
 namespace X86Disassembler {
 
 // Accessor functions for various fields of an Intel instruction
@@ -530,7 +533,7 @@ struct InstructionSpecifier {
 /// The x86 internal instruction, which is produced by the decoder.
 struct InternalInstruction {
   // Opaque value passed to the reader
-  const void* readerArg;
+  llvm::ArrayRef<uint8_t> bytes;
   // The address of the next byte to read via the reader
   uint64_t readerCursor;
 
@@ -652,19 +655,8 @@ struct InternalInstruction {
 
 /// Decode one instruction and store the decoding results in
 /// a buffer provided by the consumer.
-/// \param insn      The buffer to store the instruction in.  Allocated by the
-///                  consumer.
-/// \param readerArg An argument to pass to the reader for storing context
-///                  specific to the consumer.  May be NULL.
-/// \param startLoc  The address (in the reader's address space) of the first
-///                  byte in the instruction.
-/// \param mode      The mode (16-bit, 32-bit, 64-bit) to decode in.
 /// \return          Nonzero if there was an error during decode, 0 otherwise.
-int decodeInstruction(InternalInstruction *insn,
-                      const void *readerArg,
-                      const void *miiArg,
-                      uint64_t startLoc,
-                      DisassemblerMode mode);
+int decodeInstruction(InternalInstruction *insn, const MCInstrInfo *mii);
 
 /// Print a message to debugs()
 /// \param file The name of the file printing the debug message.


        


More information about the llvm-commits mailing list