[llvm] r191859 - [llvm-c][Disassembler] Add an option to print latency information in

Quentin Colombet qcolombet at apple.com
Wed Oct 2 15:07:57 PDT 2013


Author: qcolombet
Date: Wed Oct  2 17:07:57 2013
New Revision: 191859

URL: http://llvm.org/viewvc/llvm-project?rev=191859&view=rev
Log:
[llvm-c][Disassembler] Add an option to print latency information in
disassembled output alongside the instructions.
E.g., on a vector shuffle operation with a memory operand, disassembled
outputs are:
* Without the option:
    vpshufd $-0x79, (%rsp), %xmm0
    
* With the option:
    vpshufd $-0x79, (%rsp), %xmm0   ## Latency: 5

The printed latency is extracted from the schedule model available in the
disassembler context. Thus, this option has no effect if there is not a
scheduling model for the target.
This boils down to one may need to specify the CPU string, so that this
option could have an effect.

Note: Latency < 2 are not printed.

This part of <rdar://problem/14687488>.

Modified:
    llvm/trunk/include/llvm-c/Disassembler.h
    llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp
    llvm/trunk/lib/MC/MCDisassembler/Disassembler.h

Modified: llvm/trunk/include/llvm-c/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Disassembler.h?rev=191859&r1=191858&r2=191859&view=diff
==============================================================================
--- llvm/trunk/include/llvm-c/Disassembler.h (original)
+++ llvm/trunk/include/llvm-c/Disassembler.h Wed Oct  2 17:07:57 2013
@@ -172,6 +172,8 @@ int LLVMSetDisasmOptions(LLVMDisasmConte
 #define LLVMDisassembler_Option_AsmPrinterVariant 4
 /* The option to set comment on instructions */
 #define LLVMDisassembler_Option_SetInstrComments 8
+  /* The option to print latency information alongside instructions */
+#define LLVMDisassembler_Option_PrintLatency 16
 
 /**
  * Dispose of a disassembler context.

Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=191859&r1=191858&r2=191859&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original)
+++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Wed Oct  2 17:07:57 2013
@@ -174,6 +174,52 @@ static void emitComments(LLVMDisasmConte
   DC->CommentStream.resync();
 }
 
+/// \brief Gets latency information for \p Inst, based on \p DC information.
+/// \return The maximum expected latency over all the definitions or -1
+/// if no information are available.
+static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
+  // Try to compute scheduling information.
+  const MCSubtargetInfo *STI = DC->getSubtargetInfo();
+  const MCSchedModel *SCModel = STI->getSchedModel();
+  const int NoInformationAvailable = -1;
+
+  // Check if we have a scheduling model for instructions.
+  if (!SCModel || !SCModel->hasInstrSchedModel())
+    return NoInformationAvailable;
+
+  // Get the scheduling class of the requested instruction.
+  const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode());
+  unsigned SCClass = Desc.getSchedClass();
+  const MCSchedClassDesc *SCDesc = SCModel->getSchedClassDesc(SCClass);
+  if (!SCDesc || !SCDesc->isValid())
+    return NoInformationAvailable;
+
+  // Compute output latency.
+  int Latency = 0;
+  for (unsigned DefIdx = 0, DefEnd = SCDesc->NumWriteLatencyEntries;
+       DefIdx != DefEnd; ++DefIdx) {
+    // Lookup the definition's write latency in SubtargetInfo.
+    const MCWriteLatencyEntry *WLEntry = STI->getWriteLatencyEntry(SCDesc,
+                                                                   DefIdx);
+    Latency = std::max(Latency, WLEntry->Cycles);
+  }
+
+  return Latency;
+}
+
+
+/// \brief Emits latency information in DC->CommentStream for \p Inst, based
+/// on the information available in \p DC.
+static void emitLatency(LLVMDisasmContext *DC, const MCInst &Inst) {
+  int Latency = getLatency(DC, Inst);
+
+  // Report only interesting latency.
+  if (Latency < 2)
+    return;
+
+  DC->CommentStream << "Latency: " << Latency << '\n';
+}
+
 //
 // LLVMDisasmInstruction() disassembles a single instruction using the
 // disassembler context specified in the parameter DC.  The bytes of the
@@ -217,6 +263,9 @@ size_t LLVMDisasmInstruction(LLVMDisasmC
     formatted_raw_ostream FormattedOS(OS);
     IP->printInst(&Inst, FormattedOS, AnnotationsStr);
 
+    if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency)
+      emitLatency(DC, Inst);
+
     emitComments(DC, FormattedOS);
 
     assert(OutStringSize != 0 && "Output buffer cannot be zero size");
@@ -239,12 +288,14 @@ int LLVMSetDisasmOptions(LLVMDisasmConte
       LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
       MCInstPrinter *IP = DC->getIP();
       IP->setUseMarkup(1);
+      DC->addOptions(LLVMDisassembler_Option_UseMarkup);
       Options &= ~LLVMDisassembler_Option_UseMarkup;
   }
   if (Options & LLVMDisassembler_Option_PrintImmHex){
       LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
       MCInstPrinter *IP = DC->getIP();
       IP->setPrintImmHex(1);
+      DC->addOptions(LLVMDisassembler_Option_PrintImmHex);
       Options &= ~LLVMDisassembler_Option_PrintImmHex;
   }
   if (Options & LLVMDisassembler_Option_AsmPrinterVariant){
@@ -260,6 +311,7 @@ int LLVMSetDisasmOptions(LLVMDisasmConte
           AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
       if (IP) {
         DC->setIP(IP);
+        DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant);
         Options &= ~LLVMDisassembler_Option_AsmPrinterVariant;
       }
   }
@@ -267,7 +319,13 @@ int LLVMSetDisasmOptions(LLVMDisasmConte
     LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
     MCInstPrinter *IP = DC->getIP();
     IP->setCommentStream(DC->CommentStream);
+    DC->addOptions(LLVMDisassembler_Option_SetInstrComments);
     Options &= ~LLVMDisassembler_Option_SetInstrComments;
   }
+  if (Options & LLVMDisassembler_Option_PrintLatency) {
+    LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR;
+    DC->addOptions(LLVMDisassembler_Option_PrintLatency);
+    Options &= ~LLVMDisassembler_Option_PrintLatency;
+  }
   return (Options == 0);
 }

Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.h?rev=191859&r1=191858&r2=191859&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDisassembler/Disassembler.h (original)
+++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.h Wed Oct  2 17:07:57 2013
@@ -73,6 +73,8 @@ private:
   llvm::OwningPtr<const llvm::MCDisassembler> DisAsm;
   // The instruction printer for the target architecture.
   llvm::OwningPtr<llvm::MCInstPrinter> IP;
+  // The options used to set up the disassembler.
+  uint64_t Options;
 
 public:
   // Comment stream and backing vector.
@@ -90,6 +92,7 @@ public:
                     MCInstPrinter *iP) : TripleName(tripleName),
                     DisInfo(disInfo), TagType(tagType), GetOpInfo(getOpInfo),
                     SymbolLookUp(symbolLookUp), TheTarget(theTarget),
+                    Options(0),
                     CommentStream(CommentsToEmit) {
     MAI.reset(mAI);
     MRI.reset(mRI);
@@ -114,6 +117,8 @@ public:
   const MCSubtargetInfo *getSubtargetInfo() const { return MSI.get(); }
   MCInstPrinter *getIP() { return IP.get(); }
   void setIP(MCInstPrinter *NewIP) { IP.reset(NewIP); }
+  uint64_t getOptions() const { return Options; }
+  void addOptions(uint64_t Options) { this->Options |= Options; }
 };
 
 } // namespace llvm





More information about the llvm-commits mailing list