//===- DFAPacketizerEmitter.cpp - Packetization DFA for a VLIW machine ----===//
//
// 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 class parses the Schedule.td file and produces an API that can be used
// to reason about whether an instruction can be added to a packet on a VLIW
// architecture. The class internally generates a deterministic finite
// automaton (DFA) that models all possible mappings of machine instructions
// to functional units as instructions are added to a packet.
//
//===----------------------------------------------------------------------===//

#include "Common/CodeGenSchedule.h"
#include "Common/CodeGenTarget.h"
#include "DFAEmitter.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cstdint>
#include <deque>
#include <map>
#include <set>
#include <string>
#include <vector>

#define DEBUG_TYPE "dfa-emitter"

using namespace llvm;

// We use a uint64_t to represent a resource bitmask.
#define DFA_MAX_RESOURCES 64

namespace {
using ResourceVector = SmallVector<uint64_t, 4>;

struct ScheduleClass {
  /// The parent itinerary index (processor model ID).
  unsigned ItineraryID;

  /// Index within this itinerary of the schedule class.
  unsigned Idx;

  /// The index within the uniqued set of required resources of Resources.
  unsigned ResourcesIdx;

  /// Conjunctive list of resource requirements:
  ///   {a|b, b|c} => (a OR b) AND (b or c).
  /// Resources are unique across all itineraries.
  ResourceVector Resources;
};

// Generates and prints out the DFA for resource tracking.
class DFAPacketizerEmitter {
private:
  std::string TargetName;
  const RecordKeeper &Records;

  UniqueVector<ResourceVector> UniqueResources;
  std::vector<ScheduleClass> ScheduleClasses;
  std::map<std::string, uint64_t> FUNameToBitsMap;
  std::map<unsigned, uint64_t> ComboBitToBitsMap;

public:
  DFAPacketizerEmitter(const RecordKeeper &R);

  // Construct a map of function unit names to bits.
  int collectAllFuncUnits(ArrayRef<const CodeGenProcModel *> ProcModels);

  // Construct a map from a combo function unit bit to the bits of all included
  // functional units.
  int collectAllComboFuncs(ArrayRef<const Record *> ComboFuncList);

  ResourceVector getResourcesForItinerary(const Record *Itinerary);
  void createScheduleClasses(unsigned ItineraryIdx,
                             ArrayRef<const Record *> Itineraries);

  // Emit code for a subset of itineraries.
  void emitForItineraries(raw_ostream &OS,
                          std::vector<const CodeGenProcModel *> &ProcItinList,
                          std::string DFAName);

  void run(raw_ostream &OS);
};
} // end anonymous namespace

DFAPacketizerEmitter::DFAPacketizerEmitter(const RecordKeeper &R)
    : TargetName(CodeGenTarget(R).getName().str()), Records(R) {}

int DFAPacketizerEmitter::collectAllFuncUnits(
    ArrayRef<const CodeGenProcModel *> ProcModels) {
  LLVM_DEBUG(dbgs() << "-------------------------------------------------------"
                       "----------------------\n");
  LLVM_DEBUG(dbgs() << "collectAllFuncUnits");
  LLVM_DEBUG(dbgs() << " (" << ProcModels.size() << " itineraries)\n");

  // Use the LessRecord comparator to make the traversal deterministic with the
  // same input
  std::set<const Record *, LessRecord> ProcItinList;
  for (const CodeGenProcModel *Model : ProcModels)
    ProcItinList.insert(Model->ItinsDef);

  int TotalFUs = 0;
  // Parse functional units for all the itineraries.
  for (const Record *Proc : ProcItinList) {
    std::vector<const Record *> FUs = Proc->getValueAsListOfDefs("FU");

    LLVM_DEBUG(dbgs() << "    FU:"
                      << " (" << FUs.size() << " FUs) " << Proc->getName());

    // Convert macros to bits for each stage.
    unsigned numFUs = FUs.size();
    for (unsigned j = 0; j < numFUs; ++j) {
      assert((j < DFA_MAX_RESOURCES) &&
             "Exceeded maximum number of representable resources");
      uint64_t FuncResources = 1ULL << j;
      FUNameToBitsMap[FUs[j]->getName().str()] = FuncResources;
      LLVM_DEBUG(dbgs() << " " << FUs[j]->getName() << ":0x"
                        << Twine::utohexstr(FuncResources));
    }
    TotalFUs += numFUs;
    LLVM_DEBUG(dbgs() << "\n");
  }
  return TotalFUs;
}

int DFAPacketizerEmitter::collectAllComboFuncs(
    ArrayRef<const Record *> ComboFuncList) {
  LLVM_DEBUG(dbgs() << "-------------------------------------------------------"
                       "----------------------\n");
  LLVM_DEBUG(dbgs() << "collectAllComboFuncs");
  LLVM_DEBUG(dbgs() << " (" << ComboFuncList.size() << " sets)\n");

  int NumCombos = 0;
  for (unsigned I = 0, N = ComboFuncList.size(); I < N; ++I) {
    const Record *Func = ComboFuncList[I];
    std::vector<const Record *> FUs = Func->getValueAsListOfDefs("CFD");

    LLVM_DEBUG(dbgs() << "    CFD:" << I << " (" << FUs.size() << " combo FUs) "
                      << Func->getName() << "\n");

    // Convert macros to bits for each stage.
    for (unsigned J = 0, N = FUs.size(); J < N; ++J) {
      assert((J < DFA_MAX_RESOURCES) &&
             "Exceeded maximum number of DFA resources");
      const Record *FuncData = FUs[J];
      const Record *ComboFunc = FuncData->getValueAsDef("TheComboFunc");
      const std::vector<const Record *> FuncList =
          FuncData->getValueAsListOfDefs("FuncList");
      const std::string &ComboFuncName = ComboFunc->getName().str();
      uint64_t ComboBit = FUNameToBitsMap[ComboFuncName];
      uint64_t ComboResources = ComboBit;
      LLVM_DEBUG(dbgs() << "      combo: " << ComboFuncName << ":0x"
                        << Twine::utohexstr(ComboResources) << "\n");
      for (const Record *K : FuncList) {
        std::string FuncName = K->getName().str();
        uint64_t FuncResources = FUNameToBitsMap[FuncName];
        LLVM_DEBUG(dbgs() << "        " << FuncName << ":0x"
                          << Twine::utohexstr(FuncResources) << "\n");
        ComboResources |= FuncResources;
      }
      ComboBitToBitsMap[ComboBit] = ComboResources;
      NumCombos++;
      LLVM_DEBUG(dbgs() << "          => combo bits: " << ComboFuncName << ":0x"
                        << Twine::utohexstr(ComboBit) << " = 0x"
                        << Twine::utohexstr(ComboResources) << "\n");
    }
  }
  return NumCombos;
}

ResourceVector
DFAPacketizerEmitter::getResourcesForItinerary(const Record *Itinerary) {
  ResourceVector Resources;
  assert(Itinerary);
  for (const Record *StageDef : Itinerary->getValueAsListOfDefs("Stages")) {
    uint64_t StageResources = 0;
    for (const Record *Unit : StageDef->getValueAsListOfDefs("Units")) {
      StageResources |= FUNameToBitsMap[Unit->getName().str()];
    }
    if (StageResources != 0)
      Resources.push_back(StageResources);
  }
  return Resources;
}

void DFAPacketizerEmitter::createScheduleClasses(
    unsigned ItineraryIdx, ArrayRef<const Record *> Itineraries) {
  unsigned Idx = 0;
  for (const Record *Itinerary : Itineraries) {
    if (!Itinerary) {
      ScheduleClasses.push_back({ItineraryIdx, Idx++, 0, ResourceVector{}});
      continue;
    }
    ResourceVector Resources = getResourcesForItinerary(Itinerary);
    ScheduleClasses.push_back(
        {ItineraryIdx, Idx++, UniqueResources.insert(Resources), Resources});
  }
}

//
// Run the worklist algorithm to generate the DFA.
//
void DFAPacketizerEmitter::run(raw_ostream &OS) {
  emitSourceFileHeader("Target DFA Packetizer Tables", OS);
  OS << "\n"
     << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n";
  OS << "namespace llvm {\n";

  CodeGenTarget CGT(Records);
  CodeGenSchedModels CGS(Records, CGT);

  StringMap<std::vector<const CodeGenProcModel *>> ItinsByNamespace;
  for (const CodeGenProcModel &ProcModel : CGS.procModels()) {
    if (ProcModel.hasItineraries()) {
      auto NS = ProcModel.ItinsDef->getValueAsString("PacketizerNamespace");
      ItinsByNamespace[NS].push_back(&ProcModel);
    }
  }

  for (auto &KV : ItinsByNamespace)
    emitForItineraries(OS, KV.second, KV.first().str());
  OS << "} // end namespace llvm\n";
}

void DFAPacketizerEmitter::emitForItineraries(
    raw_ostream &OS, std::vector<const CodeGenProcModel *> &ProcModels,
    std::string DFAName) {
  OS << "} // end namespace llvm\n\n";
  OS << "namespace {\n";
  collectAllFuncUnits(ProcModels);
  collectAllComboFuncs(Records.getAllDerivedDefinitions("ComboFuncUnits"));

  // Collect the itineraries.
  DenseMap<const CodeGenProcModel *, unsigned> ProcModelStartIdx;
  for (const CodeGenProcModel *Model : ProcModels) {
    assert(Model->hasItineraries());
    ProcModelStartIdx[Model] = ScheduleClasses.size();
    createScheduleClasses(Model->Index, Model->ItinDefList);
  }

  // Output the mapping from ScheduleClass to ResourcesIdx.
  unsigned Idx = 0;
  OS << "constexpr unsigned " << TargetName << DFAName
     << "ResourceIndices[] = {";
  for (const ScheduleClass &SC : ScheduleClasses) {
    if (Idx++ % 32 == 0)
      OS << "\n  ";
    OS << SC.ResourcesIdx << ", ";
  }
  OS << "\n};\n\n";

  // And the mapping from Itinerary index into the previous table.
  OS << "constexpr unsigned " << TargetName << DFAName
     << "ProcResourceIndexStart[] = {\n";
  OS << "  0, // NoSchedModel\n";
  for (const CodeGenProcModel *Model : ProcModels) {
    OS << "  " << ProcModelStartIdx[Model] << ", // " << Model->ModelName
       << "\n";
  }
  OS << "  " << ScheduleClasses.size() << "\n};\n\n";

  // Output the mapping from proc ID to ResourceIndexStart
  Idx = 1;
  OS << "int " << TargetName << DFAName
     << "GetResourceIndex(unsigned ProcID) { \n"
     << "  static const unsigned " << TargetName << DFAName
     << "ProcIdToProcResourceIdxTable[][2] = {\n";
  for (const CodeGenProcModel *Model : ProcModels) {
    OS << "    { " << Model->Index << ",  " << Idx++ << " }, // "
       << Model->ModelName << "\n";
  }
  OS << "  };\n"
     << "  auto It = llvm::lower_bound(" << TargetName << DFAName
     << "ProcIdToProcResourceIdxTable, ProcID,\n"
     << "      [](const unsigned LHS[], unsigned Val) { return LHS[0] < Val; "
        "});\n"
     << "  assert(*It[0] == ProcID);\n"
     << "  return (*It)[1];\n"
     << "}\n\n";

  // The type of a state in the nondeterministic automaton we're defining.
  using NfaStateTy = uint64_t;

  // Given a resource state, return all resource states by applying
  // InsnClass.
  auto ApplyInsnClass = [&](const ResourceVector &InsnClass,
                            NfaStateTy State) -> std::deque<NfaStateTy> {
    std::deque<NfaStateTy> V(1, State);
    // Apply every stage in the class individually.
    for (NfaStateTy Stage : InsnClass) {
      // Apply this stage to every existing member of V in turn.
      size_t Sz = V.size();
      for (unsigned I = 0; I < Sz; ++I) {
        NfaStateTy S = V.front();
        V.pop_front();

        // For this stage, state combination, try all possible resources.
        for (unsigned J = 0; J < DFA_MAX_RESOURCES; ++J) {
          NfaStateTy ResourceMask = 1ULL << J;
          if ((ResourceMask & Stage) == 0)
            // This resource isn't required by this stage.
            continue;
          NfaStateTy Combo = ComboBitToBitsMap[ResourceMask];
          if (Combo && ((~S & Combo) != Combo))
            // This combo units bits are not available.
            continue;
          NfaStateTy ResultingResourceState = S | ResourceMask | Combo;
          if (ResultingResourceState == S)
            continue;
          V.push_back(ResultingResourceState);
        }
      }
    }
    return V;
  };

  // Given a resource state, return a quick (conservative) guess as to whether
  // InsnClass can be applied. This is a filter for the more heavyweight
  // ApplyInsnClass.
  auto canApplyInsnClass = [](const ResourceVector &InsnClass,
                              NfaStateTy State) -> bool {
    for (NfaStateTy Resources : InsnClass) {
      if ((State | Resources) == State)
        return false;
    }
    return true;
  };

  DfaEmitter Emitter;
  std::deque<NfaStateTy> Worklist(1, 0);
  std::set<NfaStateTy> SeenStates;
  SeenStates.insert(Worklist.front());
  while (!Worklist.empty()) {
    NfaStateTy State = Worklist.front();
    Worklist.pop_front();
    for (const ResourceVector &Resources : UniqueResources) {
      if (!canApplyInsnClass(Resources, State))
        continue;
      unsigned ResourcesID = UniqueResources.idFor(Resources);
      for (uint64_t NewState : ApplyInsnClass(Resources, State)) {
        if (SeenStates.emplace(NewState).second)
          Worklist.emplace_back(NewState);
        Emitter.addTransition(State, NewState, ResourcesID);
      }
    }
  }

  std::string TargetAndDFAName = TargetName + DFAName;
  Emitter.emit(TargetAndDFAName, OS);
  OS << "} // end anonymous namespace\n\n";

  std::string SubTargetClassName = TargetName + "GenSubtargetInfo";
  OS << "namespace llvm {\n";
  OS << "DFAPacketizer *" << SubTargetClassName << "::" << "create" << DFAName
     << "DFAPacketizer(const InstrItineraryData *IID) const {\n"
     << "  static Automaton<uint64_t> A(ArrayRef<" << TargetAndDFAName
     << "Transition>(" << TargetAndDFAName << "Transitions), "
     << TargetAndDFAName << "TransitionInfo);\n"
     << "  unsigned Index = " << TargetName << DFAName
     << "GetResourceIndex(IID->SchedModel.ProcID);\n"
     << "  unsigned ProcResIdxStart = " << TargetAndDFAName
     << "ProcResourceIndexStart[Index];\n"
     << "  unsigned ProcResIdxNum = " << TargetAndDFAName
     << "ProcResourceIndexStart[Index + 1] - "
        "ProcResIdxStart;\n"
     << "  return new DFAPacketizer(IID, A, {&" << TargetAndDFAName
     << "ResourceIndices[ProcResIdxStart], ProcResIdxNum});\n"
     << "\n}\n\n";
}

static TableGen::Emitter::OptClass<DFAPacketizerEmitter>
    X("gen-dfa-packetizer", "Generate DFA Packetizer for VLIW targets");
