//===--------------------- ResourcePressureView.cpp -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file implements methods in the ResourcePressureView interface.
///
//===----------------------------------------------------------------------===//

#include "ResourcePressureView.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/raw_ostream.h"

namespace mca {

using namespace llvm;

void ResourcePressureView::initialize() {
  // Populate the map of resource descriptors.
  unsigned R2VIndex = 0;
  const MCSchedModel &SM = STI.getSchedModel();
  for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
    unsigned NumUnits = ProcResource.NumUnits;
    // Skip groups and invalid resources with zero units.
    if (ProcResource.SubUnitsIdxBegin || !NumUnits)
      continue;

    Resource2VecIndex.insert(std::pair<unsigned, unsigned>(I, R2VIndex));
    R2VIndex += ProcResource.NumUnits;
  }

  NumResourceUnits = R2VIndex;
  ResourceUsage.resize(NumResourceUnits * (Source.size() + 1));
  std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0.0);
}

void ResourcePressureView::onEvent(const HWInstructionEvent &Event) {
  // We're only interested in Issue events.
  if (Event.Type != HWInstructionEvent::Issued)
    return;
  const auto &IssueEvent = static_cast<const HWInstructionIssuedEvent &>(Event);
  const unsigned SourceIdx = Event.IR.getSourceIndex() % Source.size();
  for (const std::pair<ResourceRef, double> &Use : IssueEvent.UsedResources) {
    const ResourceRef &RR = Use.first;
    assert(Resource2VecIndex.find(RR.first) != Resource2VecIndex.end());
    unsigned R2VIndex = Resource2VecIndex[RR.first];
    R2VIndex += countTrailingZeros(RR.second);
    ResourceUsage[R2VIndex + NumResourceUnits * SourceIdx] += Use.second;
    ResourceUsage[R2VIndex + NumResourceUnits * Source.size()] += Use.second;
  }
}

static void printColumnNames(formatted_raw_ostream &OS,
                             const MCSchedModel &SM) {
  unsigned Column = OS.getColumn();
  for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
       I < E; ++I) {
    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
    unsigned NumUnits = ProcResource.NumUnits;
    // Skip groups and invalid resources with zero units.
    if (ProcResource.SubUnitsIdxBegin || !NumUnits)
      continue;

    for (unsigned J = 0; J < NumUnits; ++J) {
      Column += 7;
      OS << "[" << ResourceIndex;
      if (NumUnits > 1)
        OS << '.' << J;
      OS << ']';
      OS.PadToColumn(Column);
    }

    ResourceIndex++;
  }
}

static void printResourcePressure(formatted_raw_ostream &OS, double Pressure,
                                  unsigned Col) {
  if (!Pressure || Pressure < 0.005) {
    OS << " - ";
  } else {
    // Round to the value to the nearest hundredth and then print it.
    OS << format("%.2f", floor((Pressure * 100) + 0.5) / 100);
  }
  OS.PadToColumn(Col);
}

void ResourcePressureView::printResourcePressurePerIteration(
    raw_ostream &OS, unsigned Executions) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  formatted_raw_ostream FOS(TempStream);

  FOS << "\n\nResources:\n";
  const MCSchedModel &SM = STI.getSchedModel();
  for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
       I < E; ++I) {
    const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
    unsigned NumUnits = ProcResource.NumUnits;
    // Skip groups and invalid resources with zero units.
    if (ProcResource.SubUnitsIdxBegin || !NumUnits)
      continue;

    for (unsigned J = 0; J < NumUnits; ++J) {
      FOS << '[' << ResourceIndex;
      if (NumUnits > 1)
        FOS << '.' << J;
      FOS << ']';
      FOS.PadToColumn(6);
      FOS << "- " << ProcResource.Name << '\n';
    }

    ResourceIndex++;
  }

  FOS << "\n\nResource pressure per iteration:\n";
  FOS.flush();
  printColumnNames(FOS, SM);
  FOS << '\n';
  FOS.flush();

  for (unsigned I = 0, E = NumResourceUnits; I < E; ++I) {
    double Usage = ResourceUsage[I + Source.size() * E];
    printResourcePressure(FOS, Usage / Executions, (I + 1) * 7);
  }

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

void ResourcePressureView::printResourcePressurePerInstruction(
    raw_ostream &OS, unsigned Executions) const {
  std::string Buffer;
  raw_string_ostream TempStream(Buffer);
  formatted_raw_ostream FOS(TempStream);

  FOS << "\n\nResource pressure by instruction:\n";
  printColumnNames(FOS, STI.getSchedModel());
  FOS << "Instructions:\n";

  std::string Instruction;
  raw_string_ostream InstrStream(Instruction);

  for (unsigned I = 0, E = Source.size(); I < E; ++I) {
    for (unsigned J = 0; J < NumResourceUnits; ++J) {
      double Usage = ResourceUsage[J + I * NumResourceUnits];
      printResourcePressure(FOS, Usage / Executions, (J + 1) * 7);
    }

    MCIP.printInst(&Source.getMCInstFromIndex(I), InstrStream, "", STI);
    InstrStream.flush();
    StringRef Str(Instruction);

    // Remove any tabs or spaces at the beginning of the instruction.
    Str = Str.ltrim();

    FOS << Str << '\n';
    Instruction = "";

    FOS.flush();
    OS << Buffer;
    Buffer = "";
  }
}
} // namespace mca
