//===- ExegesisEmitter.cpp - Generate exegesis target data ----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend emits llvm-exegesis information.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cstdint>
#include <map>
#include <string>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "exegesis-emitter"

namespace {

class ExegesisEmitter {
public:
  ExegesisEmitter(const RecordKeeper &RK);

  void run(raw_ostream &OS) const;

private:
  unsigned getPfmCounterId(llvm::StringRef Name) const {
    const auto It = PfmCounterNameTable.find(Name);
    if (It == PfmCounterNameTable.end())
      PrintFatalError("no pfm counter id for " + Name);
    return It->second;
  }

  // Collects all the ProcPfmCounters definitions available in this target.
  void emitPfmCounters(raw_ostream &OS) const;

  void emitPfmCountersInfo(const Record &Def,
                           unsigned &IssueCountersTableOffset,
                           raw_ostream &OS) const;

  void emitPfmCountersLookupTable(raw_ostream &OS) const;

  const RecordKeeper &Records;
  std::string Target;

  // Table of counter name -> counter index.
  const std::map<llvm::StringRef, unsigned> PfmCounterNameTable;
};

struct ValidationCounterInfo {
  int64_t EventNumber;
  StringRef EventName;
  unsigned PfmCounterID;
};

} // namespace

static std::map<llvm::StringRef, unsigned>
collectPfmCounters(const RecordKeeper &Records) {
  std::map<llvm::StringRef, unsigned> PfmCounterNameTable;
  const auto AddPfmCounterName = [&PfmCounterNameTable](
                                     const Record *PfmCounterDef) {
    const llvm::StringRef Counter = PfmCounterDef->getValueAsString("Counter");
    if (!Counter.empty())
      PfmCounterNameTable.emplace(Counter, 0);
  };
  for (const Record *Def :
       Records.getAllDerivedDefinitions("ProcPfmCounters")) {
    // Check that ResourceNames are unique.
    llvm::SmallSet<llvm::StringRef, 16> Seen;
    for (const Record *IssueCounter :
         Def->getValueAsListOfDefs("IssueCounters")) {
      const llvm::StringRef ResourceName =
          IssueCounter->getValueAsString("ResourceName");
      if (ResourceName.empty())
        PrintFatalError(IssueCounter->getLoc(), "invalid empty ResourceName");
      if (!Seen.insert(ResourceName).second)
        PrintFatalError(IssueCounter->getLoc(),
                        "duplicate ResourceName " + ResourceName);
      AddPfmCounterName(IssueCounter);
    }

    for (const Record *ValidationCounter :
         Def->getValueAsListOfDefs("ValidationCounters"))
      AddPfmCounterName(ValidationCounter);

    AddPfmCounterName(Def->getValueAsDef("CycleCounter"));
    AddPfmCounterName(Def->getValueAsDef("UopsCounter"));
  }
  unsigned Index = 0;
  for (auto &NameAndIndex : PfmCounterNameTable)
    NameAndIndex.second = Index++;
  return PfmCounterNameTable;
}

ExegesisEmitter::ExegesisEmitter(const RecordKeeper &RK)
    : Records(RK), PfmCounterNameTable(collectPfmCounters(RK)) {
  ArrayRef<const Record *> Targets = Records.getAllDerivedDefinitions("Target");
  if (Targets.size() == 0)
    PrintFatalError("No 'Target' subclasses defined!");
  if (Targets.size() != 1)
    PrintFatalError("Multiple subclasses of Target defined!");
  Target = Targets[0]->getName().str();
}

static bool EventNumberLess(const ValidationCounterInfo &LHS,
                            const ValidationCounterInfo &RHS) {
  return LHS.EventNumber < RHS.EventNumber;
}

void ExegesisEmitter::emitPfmCountersInfo(const Record &Def,
                                          unsigned &IssueCountersTableOffset,
                                          raw_ostream &OS) const {
  const Record *CycleCounterDef = Def.getValueAsDef("CycleCounter");
  const auto CycleCounter = CycleCounterDef->getValueAsString("Counter");
  const Record *UopsCounterDef = Def.getValueAsDef("UopsCounter");
  const auto UopsCounter = UopsCounterDef->getValueAsString("Counter");
  const size_t NumIssueCounters =
      Def.getValueAsListOfDefs("IssueCounters").size();
  const size_t NumValidationCounters =
      Def.getValueAsListOfDefs("ValidationCounters").size();

  // Emit Validation Counters Array
  if (NumValidationCounters != 0) {
    std::vector<ValidationCounterInfo> ValidationCounters;
    ValidationCounters.reserve(NumValidationCounters);
    for (const Record *ValidationCounter :
         Def.getValueAsListOfDefs("ValidationCounters")) {
      ValidationCounters.push_back(
          {ValidationCounter->getValueAsDef("EventType")
               ->getValueAsInt("EventNumber"),
           ValidationCounter->getValueAsDef("EventType")->getName(),
           getPfmCounterId(ValidationCounter->getValueAsString("Counter"))});
    }
    std::sort(ValidationCounters.begin(), ValidationCounters.end(),
              EventNumberLess);
    OS << "\nstatic const std::pair<ValidationEvent, const char*> " << Target
       << Def.getName() << "ValidationCounters[] = {\n";
    for (const ValidationCounterInfo &VCI : ValidationCounters) {
      OS << "  { " << VCI.EventName << ", " << Target << "PfmCounterNames["
         << VCI.PfmCounterID << "]},\n";
    }
    OS << "};\n";
  }

  OS << "\nstatic const PfmCountersInfo " << Target << Def.getName()
     << " = {\n";

  // Cycle Counter.
  if (CycleCounterDef->getValueAsInt("EventSelect") != -1) {
    const int64_t EventSelect = CycleCounterDef->getValueAsInt("EventSelect");
    if (!isInt<16>(EventSelect))
      PrintFatalError(CycleCounterDef->getLoc(),
                      "EventSelect must fit in 16 bits");
    const int64_t UMask = CycleCounterDef->getValueAsInt("UMask");
    if (!isInt<8>(UMask))
      PrintFatalError(CycleCounterDef->getLoc(), "UMask must fit in 8 bits");
    OS << "  nullptr,  // Cycle counter uses raw encoding below.\n";
    OS << "  0x" << format_hex_no_prefix(EventSelect, 4) << ", 0x"
       << format_hex_no_prefix(UMask, 2) << ", // Raw cycle counter\n";
  } else if (CycleCounter.empty()) {
    OS << "  nullptr,  // No cycle counter.\n";
    OS << "  -1, 0, // No raw cycle counter\n";
  } else {
    OS << "  " << Target << "PfmCounterNames[" << getPfmCounterId(CycleCounter)
       << "],  // Cycle counter\n";
    OS << "  -1, 0, // No raw cycle counter\n";
  }

  // Uops Counter.
  if (UopsCounterDef->getValueAsInt("EventSelect") != -1) {
    const int64_t EventSelect = UopsCounterDef->getValueAsInt("EventSelect");
    if (!isInt<16>(EventSelect))
      PrintFatalError(UopsCounterDef->getLoc(),
                      "EventSelect must fit in 16 bits");
    const int64_t UMask = UopsCounterDef->getValueAsInt("UMask");
    if (!isInt<8>(UMask))
      PrintFatalError(UopsCounterDef->getLoc(), "UMask must fit in 8 bits");
    OS << "  nullptr,  // Uops counter uses raw encoding below.\n";
    OS << "  0x" << format_hex_no_prefix(EventSelect, 4) << ", 0x"
       << format_hex_no_prefix(UMask, 2) << ", // Raw uops counter\n";
  } else if (UopsCounter.empty()) {
    OS << "  nullptr,  // No uops counter.\n";
    OS << "  -1, 0, // No raw uops counter\n";
  } else {
    OS << "  " << Target << "PfmCounterNames[" << getPfmCounterId(UopsCounter)
       << "],  // Uops counter\n";
    OS << "  -1, 0, // No raw uops counter\n";
  }

  // Issue Counters
  if (NumIssueCounters == 0)
    OS << "  nullptr, 0, // No issue counters\n";
  else
    OS << "  " << Target << "PfmIssueCounters + " << IssueCountersTableOffset
       << ", " << NumIssueCounters << ", // Issue counters.\n";

  // Validation Counters
  if (NumValidationCounters == 0)
    OS << "  nullptr, 0 // No validation counters.\n";
  else
    OS << "  " << Target << Def.getName() << "ValidationCounters, "
       << NumValidationCounters << " // Validation counters.\n";

  OS << "};\n";
  IssueCountersTableOffset += NumIssueCounters;
}

void ExegesisEmitter::emitPfmCounters(raw_ostream &OS) const {
  // Emit the counter name table.
  OS << "\nstatic const char *" << Target << "PfmCounterNames[] = {\n";
  for (const auto &NameAndIndex : PfmCounterNameTable)
    OS << "  \"" << NameAndIndex.first << "\", // " << NameAndIndex.second
       << "\n";
  OS << "};\n\n";

  // Emit the IssueCounters table.
  const auto PfmCounterDefs =
      Records.getAllDerivedDefinitions("ProcPfmCounters");
  // Only emit if non-empty.
  const bool HasAtLeastOnePfmIssueCounter =
      llvm::any_of(PfmCounterDefs, [](const Record *Def) {
        return !Def->getValueAsListOfDefs("IssueCounters").empty();
      });
  if (HasAtLeastOnePfmIssueCounter) {
    OS << "static const PfmCountersInfo::IssueCounter " << Target
       << "PfmIssueCounters[] = {\n";
    for (const Record *Def : PfmCounterDefs) {
      for (const Record *ICDef : Def->getValueAsListOfDefs("IssueCounters"))
        OS << "  { " << Target << "PfmCounterNames["
           << getPfmCounterId(ICDef->getValueAsString("Counter")) << "], \""
           << ICDef->getValueAsString("ResourceName") << "\"},\n";
    }
    OS << "};\n";
  }

  // Now generate the PfmCountersInfo.
  unsigned IssueCountersTableOffset = 0;
  for (const Record *Def : PfmCounterDefs)
    emitPfmCountersInfo(*Def, IssueCountersTableOffset, OS);

  OS << "\n";
}

void ExegesisEmitter::emitPfmCountersLookupTable(raw_ostream &OS) const {
  std::vector<const Record *> Bindings =
      Records.getAllDerivedDefinitions("PfmCountersBinding");
  assert(!Bindings.empty() && "there must be at least one binding");
  llvm::sort(Bindings, [](const Record *L, const Record *R) {
    return L->getValueAsString("CpuName") < R->getValueAsString("CpuName");
  });

  OS << "// Sorted (by CpuName) array of pfm counters.\n"
     << "static const CpuAndPfmCounters " << Target << "CpuPfmCounters[] = {\n";
  for (const Record *Binding : Bindings) {
    // Emit as { "cpu", procinit },
    OS << "  { \""                                                        //
       << Binding->getValueAsString("CpuName") << "\","                   //
       << " &" << Target << Binding->getValueAsDef("Counters")->getName() //
       << " },\n";
  }
  OS << "};\n\n";
}

void ExegesisEmitter::run(raw_ostream &OS) const {
  emitSourceFileHeader("Exegesis Tables", OS);
  emitPfmCounters(OS);
  emitPfmCountersLookupTable(OS);
}

static TableGen::Emitter::OptClass<ExegesisEmitter>
    X("gen-exegesis", "Generate llvm-exegesis tables");
