[llvm-mca][View] Improved Retire Control Unit Statistics.

RetireControlUnitStatistics now reports extra information about the ROB and the
avg/maximum number of entries consumed over the entire simulation.

Example:
  Retire Control Unit - number of cycles where we saw N instructions retired:
  [# retired], [# cycles]
   0,           109  (17.9%)
   1,           102  (16.7%)
   2,           399  (65.4%)

  Total ROB Entries:                64
  Max Used ROB Entries:             35  ( 54.7% )
  Average Used ROB Entries per cy:  32  ( 50.0% )

Documentation in llvm/docs/CommandGuide/llvmn-mca.rst has been updated to
reflect this change.

llvm-svn: 347493
diff --git a/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.cpp b/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.cpp
index 7e2fd31..54eb28f 100644
--- a/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.cpp
+++ b/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.cpp
@@ -18,9 +18,39 @@
 namespace llvm {
 namespace mca {
 
+RetireControlUnitStatistics::RetireControlUnitStatistics(const MCSchedModel &SM)
+    : NumRetired(0), NumCycles(0), EntriesInUse(0), MaxUsedEntries(0),
+      SumOfUsedEntries(0) {
+  TotalROBEntries = SM.MicroOpBufferSize;
+  if (SM.hasExtraProcessorInfo()) {
+    const MCExtraProcessorInfo &EPI = SM.getExtraProcessorInfo();
+    if (EPI.ReorderBufferSize)
+      TotalROBEntries = EPI.ReorderBufferSize;
+  }
+}
+
 void RetireControlUnitStatistics::onEvent(const HWInstructionEvent &Event) {
-  if (Event.Type == HWInstructionEvent::Retired)
+  if (Event.Type == HWInstructionEvent::Dispatched) {
+    unsigned NumEntries =
+        static_cast<const HWInstructionDispatchedEvent &>(Event).MicroOpcodes;
+    EntriesInUse += NumEntries;
+  }
+
+  if (Event.Type == HWInstructionEvent::Retired) {
+    unsigned ReleasedEntries = Event.IR.getInstruction()->getDesc().NumMicroOps;
+    assert(EntriesInUse >= ReleasedEntries && "Invalid internal state!");
+    EntriesInUse -= ReleasedEntries;
     ++NumRetired;
+  }
+}
+
+void RetireControlUnitStatistics::onCycleEnd() {
+  // Update histogram
+  RetiredPerCycle[NumRetired]++;
+  NumRetired = 0;
+  ++NumCycles;
+  MaxUsedEntries = std::max(MaxUsedEntries, EntriesInUse);
+  SumOfUsedEntries += EntriesInUse;
 }
 
 void RetireControlUnitStatistics::printView(raw_ostream &OS) const {
@@ -41,6 +71,18 @@
                << "%)\n";
   }
 
+  unsigned AvgUsage = (double)SumOfUsedEntries / NumCycles;
+  double MaxUsagePercentage = ((double)MaxUsedEntries / TotalROBEntries) * 100.0;
+  double NormalizedMaxPercentage = floor((MaxUsagePercentage * 10) + 0.5) / 10;
+  double AvgUsagePercentage = ((double)AvgUsage / TotalROBEntries) * 100.0;
+  double NormalizedAvgPercentage = floor((AvgUsagePercentage * 10) + 0.5) / 10;
+
+  TempStream << "\nTotal ROB Entries:                " << TotalROBEntries
+             << "\nMax Used ROB Entries:             " << MaxUsedEntries
+             << format("  ( %.1f%% )", NormalizedMaxPercentage)
+             << "\nAverage Used ROB Entries per cy:  " << AvgUsage
+             << format("  ( %.1f%% )\n", NormalizedAvgPercentage);
+
   TempStream.flush();
   OS << Buffer;
 }