110aa09f0SMatt Davis //===--------------------- RetireControlUnitStatistics.cpp ------*- C++ -*-===//
210aa09f0SMatt Davis //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
610aa09f0SMatt Davis //
710aa09f0SMatt Davis //===----------------------------------------------------------------------===//
810aa09f0SMatt Davis /// \file
910aa09f0SMatt Davis ///
1010aa09f0SMatt Davis /// This file implements the RetireControlUnitStatistics interface.
1110aa09f0SMatt Davis ///
1210aa09f0SMatt Davis //===----------------------------------------------------------------------===//
1310aa09f0SMatt Davis
1410aa09f0SMatt Davis #include "Views/RetireControlUnitStatistics.h"
1510aa09f0SMatt Davis #include "llvm/Support/Format.h"
1610aa09f0SMatt Davis
175a8fd657SFangrui Song namespace llvm {
1810aa09f0SMatt Davis namespace mca {
1910aa09f0SMatt Davis
RetireControlUnitStatistics(const MCSchedModel & SM)2007a8255aSAndrea Di Biagio RetireControlUnitStatistics::RetireControlUnitStatistics(const MCSchedModel &SM)
2107a8255aSAndrea Di Biagio : NumRetired(0), NumCycles(0), EntriesInUse(0), MaxUsedEntries(0),
2207a8255aSAndrea Di Biagio SumOfUsedEntries(0) {
2307a8255aSAndrea Di Biagio TotalROBEntries = SM.MicroOpBufferSize;
2407a8255aSAndrea Di Biagio if (SM.hasExtraProcessorInfo()) {
2507a8255aSAndrea Di Biagio const MCExtraProcessorInfo &EPI = SM.getExtraProcessorInfo();
2607a8255aSAndrea Di Biagio if (EPI.ReorderBufferSize)
2707a8255aSAndrea Di Biagio TotalROBEntries = EPI.ReorderBufferSize;
2807a8255aSAndrea Di Biagio }
2907a8255aSAndrea Di Biagio }
3007a8255aSAndrea Di Biagio
onEvent(const HWInstructionEvent & Event)3110aa09f0SMatt Davis void RetireControlUnitStatistics::onEvent(const HWInstructionEvent &Event) {
3207a8255aSAndrea Di Biagio if (Event.Type == HWInstructionEvent::Dispatched) {
3307a8255aSAndrea Di Biagio unsigned NumEntries =
3407a8255aSAndrea Di Biagio static_cast<const HWInstructionDispatchedEvent &>(Event).MicroOpcodes;
3507a8255aSAndrea Di Biagio EntriesInUse += NumEntries;
3607a8255aSAndrea Di Biagio }
3707a8255aSAndrea Di Biagio
3807a8255aSAndrea Di Biagio if (Event.Type == HWInstructionEvent::Retired) {
3907a8255aSAndrea Di Biagio unsigned ReleasedEntries = Event.IR.getInstruction()->getDesc().NumMicroOps;
4007a8255aSAndrea Di Biagio assert(EntriesInUse >= ReleasedEntries && "Invalid internal state!");
4107a8255aSAndrea Di Biagio EntriesInUse -= ReleasedEntries;
4210aa09f0SMatt Davis ++NumRetired;
4310aa09f0SMatt Davis }
4407a8255aSAndrea Di Biagio }
4507a8255aSAndrea Di Biagio
onCycleEnd()4607a8255aSAndrea Di Biagio void RetireControlUnitStatistics::onCycleEnd() {
4707a8255aSAndrea Di Biagio // Update histogram
4807a8255aSAndrea Di Biagio RetiredPerCycle[NumRetired]++;
4907a8255aSAndrea Di Biagio NumRetired = 0;
5007a8255aSAndrea Di Biagio ++NumCycles;
5107a8255aSAndrea Di Biagio MaxUsedEntries = std::max(MaxUsedEntries, EntriesInUse);
5207a8255aSAndrea Di Biagio SumOfUsedEntries += EntriesInUse;
5307a8255aSAndrea Di Biagio }
5410aa09f0SMatt Davis
printView(raw_ostream & OS) const55db158be6SAndrea Di Biagio void RetireControlUnitStatistics::printView(raw_ostream &OS) const {
5610aa09f0SMatt Davis std::string Buffer;
5710aa09f0SMatt Davis raw_string_ostream TempStream(Buffer);
5810aa09f0SMatt Davis TempStream << "\n\nRetire Control Unit - "
5910aa09f0SMatt Davis << "number of cycles where we saw N instructions retired:\n";
6010aa09f0SMatt Davis TempStream << "[# retired], [# cycles]\n";
6110aa09f0SMatt Davis
62536c9a60SMark de Wever for (const std::pair<const unsigned, unsigned> &Entry : RetiredPerCycle) {
6310aa09f0SMatt Davis TempStream << " " << Entry.first;
6410aa09f0SMatt Davis if (Entry.first < 10)
6510aa09f0SMatt Davis TempStream << ", ";
6610aa09f0SMatt Davis else
6710aa09f0SMatt Davis TempStream << ", ";
6810aa09f0SMatt Davis TempStream << Entry.second << " ("
6910aa09f0SMatt Davis << format("%.1f", ((double)Entry.second / NumCycles) * 100.0)
7010aa09f0SMatt Davis << "%)\n";
7110aa09f0SMatt Davis }
7210aa09f0SMatt Davis
7307a8255aSAndrea Di Biagio unsigned AvgUsage = (double)SumOfUsedEntries / NumCycles;
74*14f77576SMarcos Horro double MaxUsagePercentage =
75*14f77576SMarcos Horro ((double)MaxUsedEntries / TotalROBEntries) * 100.0;
7607a8255aSAndrea Di Biagio double NormalizedMaxPercentage = floor((MaxUsagePercentage * 10) + 0.5) / 10;
7707a8255aSAndrea Di Biagio double AvgUsagePercentage = ((double)AvgUsage / TotalROBEntries) * 100.0;
7807a8255aSAndrea Di Biagio double NormalizedAvgPercentage = floor((AvgUsagePercentage * 10) + 0.5) / 10;
7907a8255aSAndrea Di Biagio
8007a8255aSAndrea Di Biagio TempStream << "\nTotal ROB Entries: " << TotalROBEntries
8107a8255aSAndrea Di Biagio << "\nMax Used ROB Entries: " << MaxUsedEntries
8207a8255aSAndrea Di Biagio << format(" ( %.1f%% )", NormalizedMaxPercentage)
8307a8255aSAndrea Di Biagio << "\nAverage Used ROB Entries per cy: " << AvgUsage
8407a8255aSAndrea Di Biagio << format(" ( %.1f%% )\n", NormalizedAvgPercentage);
8507a8255aSAndrea Di Biagio
8610aa09f0SMatt Davis TempStream.flush();
8710aa09f0SMatt Davis OS << Buffer;
8810aa09f0SMatt Davis }
8910aa09f0SMatt Davis
9010aa09f0SMatt Davis } // namespace mca
915a8fd657SFangrui Song } // namespace llvm
92