//===- 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/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <map>
#include <string>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "exegesis-emitter"

namespace {

class ExegesisEmitter {
public:
  ExegesisEmitter(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;

  RecordKeeper &Records;
  std::string Target;

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

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

ExegesisEmitter::ExegesisEmitter(RecordKeeper &RK)
    : Records(RK), PfmCounterNameTable(collectPfmCounters(RK)) {
  std::vector<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 = std::string(Targets[0]->getName());
}

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

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

  // Cycle Counter.
  if (CycleCounter.empty())
    OS << "  nullptr,  // No cycle counter.\n";
  else
    OS << "  " << Target << "PfmCounterNames[" << getPfmCounterId(CycleCounter)
       << "],  // Cycle counter\n";

  // Uops Counter.
  if (UopsCounter.empty())
    OS << "  nullptr,  // No uops counter.\n";
  else
    OS << "  " << Target << "PfmCounterNames[" << getPfmCounterId(UopsCounter)
       << "],  // Uops counter\n";

  // Issue Counters
  if (NumIssueCounters == 0)
    OS << "  nullptr,  // No issue counters.\n  0\n";
  else
    OS << "  " << Target << "PfmIssueCounters + " << IssueCountersTableOffset
       << ", " << NumIssueCounters << " // Issue 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";
} // namespace

void ExegesisEmitter::emitPfmCountersLookupTable(raw_ostream &OS) const {
  std::vector<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 (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);
}

} // end anonymous namespace

namespace llvm {

void EmitExegesis(RecordKeeper &RK, raw_ostream &OS) {
  ExegesisEmitter(RK).run(OS);
}

} // end namespace llvm
