//===- 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("ERROR: No 'Target' subclasses defined!");
  if (Targets.size() != 1)
    PrintFatalError("ERROR: 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
