//===--------------------- RegisterFileStatistics.cpp -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file implements the RegisterFileStatistics interface.
///
//===----------------------------------------------------------------------===//

#include "Views/RegisterFileStatistics.h"
#include "llvm/Support/Format.h"

namespace llvm {
namespace mca {

RegisterFileStatistics::RegisterFileStatistics(const MCSubtargetInfo &sti)
    : STI(sti) {
  const MCSchedModel &SM = STI.getSchedModel();
  RegisterFileUsage RFUEmpty = {0, 0, 0};
  MoveEliminationInfo MEIEmpty = {0, 0, 0, 0, 0};
  if (!SM.hasExtraProcessorInfo()) {
    // Assume a single register file.
    PRFUsage.emplace_back(RFUEmpty);
    MoveElimInfo.emplace_back(MEIEmpty);
    return;
  }

  // Initialize a RegisterFileUsage for every user defined register file, plus
  // the default register file which is always at index #0.
  const MCExtraProcessorInfo &PI = SM.getExtraProcessorInfo();
  // There is always an "InvalidRegisterFile" entry in tablegen. That entry can
  // be skipped. If there are no user defined register files, then reserve a
  // single entry for the default register file at index #0.
  unsigned NumRegFiles = std::max(PI.NumRegisterFiles, 1U);

  PRFUsage.resize(NumRegFiles);
  std::fill(PRFUsage.begin(), PRFUsage.end(), RFUEmpty);

  MoveElimInfo.resize(NumRegFiles);
  std::fill(MoveElimInfo.begin(), MoveElimInfo.end(), MEIEmpty);
}

void RegisterFileStatistics::updateRegisterFileUsage(
    ArrayRef<unsigned> UsedPhysRegs) {
  for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I) {
    RegisterFileUsage &RFU = PRFUsage[I];
    unsigned NumUsedPhysRegs = UsedPhysRegs[I];
    RFU.CurrentlyUsedMappings += NumUsedPhysRegs;
    RFU.TotalMappings += NumUsedPhysRegs;
    RFU.MaxUsedMappings =
        std::max(RFU.MaxUsedMappings, RFU.CurrentlyUsedMappings);
  }
}

void RegisterFileStatistics::updateMoveElimInfo(const Instruction &Inst) {
  if (!Inst.isOptimizableMove())
    return;

  if (Inst.getDefs().size() != Inst.getUses().size())
    return;

  for (size_t I = 0, E = Inst.getDefs().size(); I < E; ++I) {
    const WriteState &WS = Inst.getDefs()[I];
    const ReadState &RS = Inst.getUses()[E - (I + 1)];

    MoveEliminationInfo &Info =
        MoveElimInfo[Inst.getDefs()[0].getRegisterFileID()];
    Info.TotalMoveEliminationCandidates++;
    if (WS.isEliminated())
      Info.CurrentMovesEliminated++;
    if (WS.isWriteZero() && RS.isReadZero())
      Info.TotalMovesThatPropagateZero++;
  }
}

void RegisterFileStatistics::onEvent(const HWInstructionEvent &Event) {
  switch (Event.Type) {
  default:
    break;
  case HWInstructionEvent::Retired: {
    const auto &RE = static_cast<const HWInstructionRetiredEvent &>(Event);
    for (unsigned I = 0, E = PRFUsage.size(); I < E; ++I)
      PRFUsage[I].CurrentlyUsedMappings -= RE.FreedPhysRegs[I];
    break;
  }
  case HWInstructionEvent::Dispatched: {
    const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event);
    updateRegisterFileUsage(DE.UsedPhysRegs);
    updateMoveElimInfo(*DE.IR.getInstruction());
  }
  }
}

void RegisterFileStatistics::onCycleEnd() {
  for (MoveEliminationInfo &MEI : MoveElimInfo) {
    unsigned &CurrentMax = MEI.MaxMovesEliminatedPerCycle;
    CurrentMax = std::max(CurrentMax, MEI.CurrentMovesEliminated);
    MEI.TotalMovesEliminated += MEI.CurrentMovesEliminated;
    MEI.CurrentMovesEliminated = 0;
  }
}

void RegisterFileStatistics::printView(raw_ostream &OS) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);

  TempStream << "\n\nRegister File statistics:";
  const RegisterFileUsage &GlobalUsage = PRFUsage[0];
  TempStream << "\nTotal number of mappings created:    "
             << GlobalUsage.TotalMappings;
  TempStream << "\nMax number of mappings used:         "
             << GlobalUsage.MaxUsedMappings << '\n';

  for (unsigned I = 1, E = PRFUsage.size(); I < E; ++I) {
    const RegisterFileUsage &RFU = PRFUsage[I];
    // Obtain the register file descriptor from the scheduling model.
    assert(STI.getSchedModel().hasExtraProcessorInfo() &&
           "Unable to find register file info!");
    const MCExtraProcessorInfo &PI =
        STI.getSchedModel().getExtraProcessorInfo();
    assert(I <= PI.NumRegisterFiles && "Unexpected register file index!");
    const MCRegisterFileDesc &RFDesc = PI.RegisterFiles[I];
    // Skip invalid register files.
    if (!RFDesc.NumPhysRegs)
      continue;

    TempStream << "\n*  Register File #" << I;
    TempStream << " -- " << StringRef(RFDesc.Name) << ':';
    TempStream << "\n   Number of physical registers:     ";
    if (!RFDesc.NumPhysRegs)
      TempStream << "unbounded";
    else
      TempStream << RFDesc.NumPhysRegs;
    TempStream << "\n   Total number of mappings created: "
               << RFU.TotalMappings;
    TempStream << "\n   Max number of mappings used:      "
               << RFU.MaxUsedMappings << '\n';
    const MoveEliminationInfo &MEI = MoveElimInfo[I];

    if (MEI.TotalMoveEliminationCandidates) {
      TempStream << "   Number of optimizable moves:      "
                 << MEI.TotalMoveEliminationCandidates;
      double EliminatedMovProportion = (double)MEI.TotalMovesEliminated /
                                       MEI.TotalMoveEliminationCandidates *
                                       100.0;
      double ZeroMovProportion = (double)MEI.TotalMovesThatPropagateZero /
                                 MEI.TotalMoveEliminationCandidates * 100.0;
      TempStream << "\n   Number of moves eliminated:       "
                 << MEI.TotalMovesEliminated << "  "
                 << format("(%.1f%%)",
                           floor((EliminatedMovProportion * 10) + 0.5) / 10);
      TempStream << "\n   Number of zero moves:             "
                 << MEI.TotalMovesThatPropagateZero << "  "
                 << format("(%.1f%%)",
                           floor((ZeroMovProportion * 10) + 0.5) / 10);
      TempStream << "\n   Max moves eliminated per cycle:   "
                 << MEI.MaxMovesEliminatedPerCycle << '\n';
    }
  }

  TempStream.flush();
  OS << Buffer;
}

} // namespace mca
} // namespace llvm
