92 lines · cpp
1//===--------------------- RetireControlUnitStatistics.cpp ------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file implements the RetireControlUnitStatistics interface.11///12//===----------------------------------------------------------------------===//13 14#include "Views/RetireControlUnitStatistics.h"15#include "llvm/Support/Format.h"16 17namespace llvm {18namespace mca {19 20RetireControlUnitStatistics::RetireControlUnitStatistics(const MCSchedModel &SM)21 : NumRetired(0), NumCycles(0), EntriesInUse(0), MaxUsedEntries(0),22 SumOfUsedEntries(0) {23 TotalROBEntries = SM.MicroOpBufferSize;24 if (SM.hasExtraProcessorInfo()) {25 const MCExtraProcessorInfo &EPI = SM.getExtraProcessorInfo();26 if (EPI.ReorderBufferSize)27 TotalROBEntries = EPI.ReorderBufferSize;28 }29}30 31void RetireControlUnitStatistics::onEvent(const HWInstructionEvent &Event) {32 if (Event.Type == HWInstructionEvent::Dispatched) {33 unsigned NumEntries =34 static_cast<const HWInstructionDispatchedEvent &>(Event).MicroOpcodes;35 EntriesInUse += NumEntries;36 }37 38 if (Event.Type == HWInstructionEvent::Retired) {39 unsigned ReleasedEntries = Event.IR.getInstruction()->getDesc().NumMicroOps;40 assert(EntriesInUse >= ReleasedEntries && "Invalid internal state!");41 EntriesInUse -= ReleasedEntries;42 ++NumRetired;43 }44}45 46void RetireControlUnitStatistics::onCycleEnd() {47 // Update histogram48 RetiredPerCycle[NumRetired]++;49 NumRetired = 0;50 ++NumCycles;51 MaxUsedEntries = std::max(MaxUsedEntries, EntriesInUse);52 SumOfUsedEntries += EntriesInUse;53}54 55void RetireControlUnitStatistics::printView(raw_ostream &OS) const {56 std::string Buffer;57 raw_string_ostream TempStream(Buffer);58 TempStream << "\n\nRetire Control Unit - "59 << "number of cycles where we saw N instructions retired:\n";60 TempStream << "[# retired], [# cycles]\n";61 62 for (const std::pair<const unsigned, unsigned> &Entry : RetiredPerCycle) {63 TempStream << " " << Entry.first;64 if (Entry.first < 10)65 TempStream << ", ";66 else67 TempStream << ", ";68 TempStream << Entry.second << " ("69 << format("%.1f", ((double)Entry.second / NumCycles) * 100.0)70 << "%)\n";71 }72 73 unsigned AvgUsage = (double)SumOfUsedEntries / NumCycles;74 double MaxUsagePercentage =75 ((double)MaxUsedEntries / TotalROBEntries) * 100.0;76 double NormalizedMaxPercentage = floor((MaxUsagePercentage * 10) + 0.5) / 10;77 double AvgUsagePercentage = ((double)AvgUsage / TotalROBEntries) * 100.0;78 double NormalizedAvgPercentage = floor((AvgUsagePercentage * 10) + 0.5) / 10;79 80 TempStream << "\nTotal ROB Entries: " << TotalROBEntries81 << "\nMax Used ROB Entries: " << MaxUsedEntries82 << format(" ( %.1f%% )", NormalizedMaxPercentage)83 << "\nAverage Used ROB Entries per cy: " << AvgUsage84 << format(" ( %.1f%% )\n", NormalizedAvgPercentage);85 86 TempStream.flush();87 OS << Buffer;88}89 90} // namespace mca91} // namespace llvm92