//===- DFAPacketizerEmitter.cpp - Packetization DFA for a VLIW machine ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "dfa-emitter"

#include "CodeGenTarget.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <map>
#include <set>
#include <string>
#include <vector>

using namespace llvm;

// --------------------------------------------------------------------
// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp

// DFA_MAX_RESTERMS * DFA_MAX_RESOURCES must fit within sizeof DFAInput.
// This is verified in DFAPacketizer.cpp:DFAPacketizer::DFAPacketizer.
//
// e.g. terms x resource bit combinations that fit in uint32_t:
//      4 terms x 8  bits = 32 bits
//      3 terms x 10 bits = 30 bits
//      2 terms x 16 bits = 32 bits
//
// e.g. terms x resource bit combinations that fit in uint64_t:
//      8 terms x 8  bits = 64 bits
//      7 terms x 9  bits = 63 bits
//      6 terms x 10 bits = 60 bits
//      5 terms x 12 bits = 60 bits
//      4 terms x 16 bits = 64 bits <--- current
//      3 terms x 21 bits = 63 bits
//      2 terms x 32 bits = 64 bits
//
#define DFA_MAX_RESTERMS        4   // The max # of AND'ed resource terms.
#define DFA_MAX_RESOURCES       16  // The max # of resource bits in one term.

typedef uint64_t                DFAInput;
typedef int64_t                 DFAStateInput;
#define DFA_TBLTYPE             "int64_t" // For generating DFAStateInputTable.

namespace {

  DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
    return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
  }

  /// Return the DFAInput for an instruction class input vector.
  /// This function is used in both DFAPacketizer.cpp and in
  /// DFAPacketizerEmitter.cpp.
  DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
    DFAInput InsnInput = 0;
    assert((InsnClass.size() <= DFA_MAX_RESTERMS) &&
           "Exceeded maximum number of DFA terms");
    for (auto U : InsnClass)
      InsnInput = addDFAFuncUnits(InsnInput, U);
    return InsnInput;
  }

} // end anonymous namespace

// --------------------------------------------------------------------

#ifndef NDEBUG
// To enable debugging, run llvm-tblgen with: "-debug-only dfa-emitter".
//
// dbgsInsnClass - When debugging, print instruction class stages.
//
void dbgsInsnClass(const std::vector<unsigned> &InsnClass);
//
// dbgsStateInfo - When debugging, print the set of state info.
//
void dbgsStateInfo(const std::set<unsigned> &stateInfo);
//
// dbgsIndent - When debugging, indent by the specified amount.
//
void dbgsIndent(unsigned indent);
#endif

//
// class DFAPacketizerEmitter: class that generates and prints out the DFA
// for resource tracking.
//
namespace {

class DFAPacketizerEmitter {
private:
  std::string TargetName;
  //
  // allInsnClasses is the set of all possible resources consumed by an
  // InstrStage.
  //
  std::vector<std::vector<unsigned>> allInsnClasses;
  RecordKeeper &Records;

public:
  DFAPacketizerEmitter(RecordKeeper &R);

  //
  // collectAllFuncUnits - Construct a map of function unit names to bits.
  //
  int collectAllFuncUnits(std::vector<Record*> &ProcItinList,
                           std::map<std::string, unsigned> &FUNameToBitsMap,
                           int &maxResources,
                           raw_ostream &OS);

  //
  // collectAllComboFuncs - Construct a map from a combo function unit bit to
  //                        the bits of all included functional units.
  //
  int collectAllComboFuncs(std::vector<Record*> &ComboFuncList,
                           std::map<std::string, unsigned> &FUNameToBitsMap,
                           std::map<unsigned, unsigned> &ComboBitToBitsMap,
                           raw_ostream &OS);

  //
  // collectOneInsnClass - Populate allInsnClasses with one instruction class.
  //
  int collectOneInsnClass(const std::string &ProcName,
                           std::vector<Record*> &ProcItinList,
                           std::map<std::string, unsigned> &FUNameToBitsMap,
                           Record *ItinData,
                           raw_ostream &OS);

  //
  // collectAllInsnClasses - Populate allInsnClasses which is a set of units
  // used in each stage.
  //
  int collectAllInsnClasses(const std::string &ProcName,
                           std::vector<Record*> &ProcItinList,
                           std::map<std::string, unsigned> &FUNameToBitsMap,
                           std::vector<Record*> &ItinDataList,
                           int &maxStages,
                           raw_ostream &OS);

  void run(raw_ostream &OS);
};

//
// State represents the usage of machine resources if the packet contains
// a set of instruction classes.
//
// Specifically, currentState is a set of bit-masks.
// The nth bit in a bit-mask indicates whether the nth resource is being used
// by this state. The set of bit-masks in a state represent the different
// possible outcomes of transitioning to this state.
// For example: consider a two resource architecture: resource L and resource M
// with three instruction classes: L, M, and L_or_M.
// From the initial state (currentState = 0x00), if we add instruction class
// L_or_M we will transition to a state with currentState = [0x01, 0x10]. This
// represents the possible resource states that can result from adding a L_or_M
// instruction
//
// Another way of thinking about this transition is we are mapping a NDFA with
// two states [0x01] and [0x10] into a DFA with a single state [0x01, 0x10].
//
// A State instance also contains a collection of transitions from that state:
// a map from inputs to new states.
//
class State {
 public:
  static int currentStateNum;
  // stateNum is the only member used for equality/ordering, all other members
  // can be mutated even in const State objects.
  const int stateNum;
  mutable bool isInitial;
  mutable std::set<unsigned> stateInfo;
  typedef std::map<std::vector<unsigned>, const State *> TransitionMap;
  mutable TransitionMap Transitions;

  State();

  bool operator<(const State &s) const {
    return stateNum < s.stateNum;
  }

  //
  // canMaybeAddInsnClass - Quickly verifies if an instruction of type InsnClass
  // may be a valid transition from this state i.e., can an instruction of type
  // InsnClass be added to the packet represented by this state.
  //
  // Note that for multiple stages, this quick check does not take into account
  // any possible resource competition between the stages themselves.  That is
  // enforced in AddInsnClassStages which checks the cross product of all
  // stages for resource availability (which is a more involved check).
  //
  bool canMaybeAddInsnClass(std::vector<unsigned> &InsnClass,
                        std::map<unsigned, unsigned> &ComboBitToBitsMap) const;

  //
  // AddInsnClass - Return all combinations of resource reservation
  // which are possible from this state (PossibleStates).
  //
  // PossibleStates is the set of valid resource states that ensue from valid
  // transitions.
  //
  void AddInsnClass(std::vector<unsigned> &InsnClass,
                        std::map<unsigned, unsigned> &ComboBitToBitsMap,
                        std::set<unsigned> &PossibleStates) const;

  //
  // AddInsnClassStages - Return all combinations of resource reservation
  // resulting from the cross product of all stages for this InsnClass
  // which are possible from this state (PossibleStates).
  //
  void AddInsnClassStages(std::vector<unsigned> &InsnClass,
                        std::map<unsigned, unsigned> &ComboBitToBitsMap,
                        unsigned chkstage, unsigned numstages,
                        unsigned prevState, unsigned origState,
                        DenseSet<unsigned> &VisitedResourceStates,
                        std::set<unsigned> &PossibleStates) const;

  //
  // addTransition - Add a transition from this state given the input InsnClass
  //
  void addTransition(std::vector<unsigned> InsnClass, const State *To) const;

  //
  // hasTransition - Returns true if there is a transition from this state
  // given the input InsnClass
  //
  bool hasTransition(std::vector<unsigned> InsnClass) const;
};

//
// class DFA: deterministic finite automaton for processor resource tracking.
//
class DFA {
public:
  DFA() = default;

  // Set of states. Need to keep this sorted to emit the transition table.
  typedef std::set<State> StateSet;
  StateSet states;

  State *currentState = nullptr;

  //
  // Modify the DFA.
  //
  const State &newState();

  //
  // writeTable: Print out a table representing the DFA.
  //
  void writeTableAndAPI(raw_ostream &OS, const std::string &ClassName,
                 int numInsnClasses = 0,
                 int maxResources = 0, int numCombos = 0, int maxStages = 0);
};

} // end anonymous namespace

#ifndef NDEBUG
// To enable debugging, run llvm-tblgen with: "-debug-only dfa-emitter".
//
// dbgsInsnClass - When debugging, print instruction class stages.
//
void dbgsInsnClass(const std::vector<unsigned> &InsnClass) {
  DEBUG(dbgs() << "InsnClass: ");
  for (unsigned i = 0; i < InsnClass.size(); ++i) {
    if (i > 0) {
      DEBUG(dbgs() << ", ");
    }
    DEBUG(dbgs() << "0x" << utohexstr(InsnClass[i]));
  }
  DFAInput InsnInput = getDFAInsnInput(InsnClass);
  DEBUG(dbgs() << " (input: 0x" << utohexstr(InsnInput) << ")");
}

//
// dbgsStateInfo - When debugging, print the set of state info.
//
void dbgsStateInfo(const std::set<unsigned> &stateInfo) {
  DEBUG(dbgs() << "StateInfo: ");
  unsigned i = 0;
  for (std::set<unsigned>::iterator SI = stateInfo.begin();
       SI != stateInfo.end(); ++SI, ++i) {
    unsigned thisState = *SI;
    if (i > 0) {
      DEBUG(dbgs() << ", ");
    }
    DEBUG(dbgs() << "0x" << utohexstr(thisState));
  }
}

//
// dbgsIndent - When debugging, indent by the specified amount.
//
void dbgsIndent(unsigned indent) {
  for (unsigned i = 0; i < indent; ++i) {
    DEBUG(dbgs() << " ");
  }
}
#endif // NDEBUG

//
// Constructors and destructors for State and DFA
//
State::State() :
  stateNum(currentStateNum++), isInitial(false) {}

//
// addTransition - Add a transition from this state given the input InsnClass
//
void State::addTransition(std::vector<unsigned> InsnClass, const State *To)
      const {
  assert(!Transitions.count(InsnClass) &&
      "Cannot have multiple transitions for the same input");
  Transitions[InsnClass] = To;
}

//
// hasTransition - Returns true if there is a transition from this state
// given the input InsnClass
//
bool State::hasTransition(std::vector<unsigned> InsnClass) const {
  return Transitions.count(InsnClass) > 0;
}

//
// AddInsnClass - Return all combinations of resource reservation
// which are possible from this state (PossibleStates).
//
// PossibleStates is the set of valid resource states that ensue from valid
// transitions.
//
void State::AddInsnClass(std::vector<unsigned> &InsnClass,
                        std::map<unsigned, unsigned> &ComboBitToBitsMap,
                        std::set<unsigned> &PossibleStates) const {
  //
  // Iterate over all resource states in currentState.
  //
  unsigned numstages = InsnClass.size();
  assert((numstages > 0) && "InsnClass has no stages");

  for (std::set<unsigned>::iterator SI = stateInfo.begin();
       SI != stateInfo.end(); ++SI) {
    unsigned thisState = *SI;

    DenseSet<unsigned> VisitedResourceStates;

    DEBUG(dbgs() << "  thisState: 0x" << utohexstr(thisState) << "\n");
    AddInsnClassStages(InsnClass, ComboBitToBitsMap,
                                numstages - 1, numstages,
                                thisState, thisState,
                                VisitedResourceStates, PossibleStates);
  }
}

void State::AddInsnClassStages(std::vector<unsigned> &InsnClass,
                        std::map<unsigned, unsigned> &ComboBitToBitsMap,
                        unsigned chkstage, unsigned numstages,
                        unsigned prevState, unsigned origState,
                        DenseSet<unsigned> &VisitedResourceStates,
                        std::set<unsigned> &PossibleStates) const {
  assert((chkstage < numstages) && "AddInsnClassStages: stage out of range");
  unsigned thisStage = InsnClass[chkstage];

  DEBUG({
    dbgsIndent((1 + numstages - chkstage) << 1);
    dbgs() << "AddInsnClassStages " << chkstage << " (0x"
           << utohexstr(thisStage) << ") from ";
    dbgsInsnClass(InsnClass);
    dbgs() << "\n";
  });

  //
  // Iterate over all possible resources used in thisStage.
  // For ex: for thisStage = 0x11, all resources = {0x01, 0x10}.
  //
  for (unsigned int j = 0; j < DFA_MAX_RESOURCES; ++j) {
    unsigned resourceMask = (0x1 << j);
    if (resourceMask & thisStage) {
      unsigned combo = ComboBitToBitsMap[resourceMask];
      if (combo && ((~prevState & combo) != combo)) {
        DEBUG(dbgs() << "\tSkipped Add 0x" << utohexstr(prevState)
                     << " - combo op 0x" << utohexstr(resourceMask)
                     << " (0x" << utohexstr(combo) <<") cannot be scheduled\n");
        continue;
      }
      //
      // For each possible resource used in thisStage, generate the
      // resource state if that resource was used.
      //
      unsigned ResultingResourceState = prevState | resourceMask | combo;
      DEBUG({
        dbgsIndent((2 + numstages - chkstage) << 1);
        dbgs() << "0x" << utohexstr(prevState)
               << " | 0x" << utohexstr(resourceMask);
        if (combo)
          dbgs() << " | 0x" << utohexstr(combo);
        dbgs() << " = 0x" << utohexstr(ResultingResourceState) << " ";
      });

      //
      // If this is the final stage for this class
      //
      if (chkstage == 0) {
        //
        // Check if the resulting resource state can be accommodated in this
        // packet.
        // We compute resource OR prevState (originally started as origState).
        // If the result of the OR is different than origState, it implies
        // that there is at least one resource that can be used to schedule
        // thisStage in the current packet.
        // Insert ResultingResourceState into PossibleStates only if we haven't
        // processed ResultingResourceState before.
        //
        if (ResultingResourceState != prevState) {
          if (VisitedResourceStates.count(ResultingResourceState) == 0) {
            VisitedResourceStates.insert(ResultingResourceState);
            PossibleStates.insert(ResultingResourceState);
            DEBUG(dbgs() << "\tResultingResourceState: 0x"
                         << utohexstr(ResultingResourceState) << "\n");
          } else {
            DEBUG(dbgs() << "\tSkipped Add - state already seen\n");
          }
        } else {
          DEBUG(dbgs() << "\tSkipped Add - no final resources available\n");
        }
      } else {
        //
        // If the current resource can be accommodated, check the next
        // stage in InsnClass for available resources.
        //
        if (ResultingResourceState != prevState) {
          DEBUG(dbgs() << "\n");
          AddInsnClassStages(InsnClass, ComboBitToBitsMap,
                                chkstage - 1, numstages,
                                ResultingResourceState, origState,
                                VisitedResourceStates, PossibleStates);
        } else {
          DEBUG(dbgs() << "\tSkipped Add - no resources available\n");
        }
      }
    }
  }
}

//
// canMaybeAddInsnClass - Quickly verifies if an instruction of type InsnClass
// may be a valid transition from this state i.e., can an instruction of type
// InsnClass be added to the packet represented by this state.
//
// Note that this routine is performing conservative checks that can be
// quickly executed acting as a filter before calling AddInsnClassStages.
// Any cases allowed through here will be caught later in AddInsnClassStages
// which performs the more expensive exact check.
//
bool State::canMaybeAddInsnClass(std::vector<unsigned> &InsnClass,
                    std::map<unsigned, unsigned> &ComboBitToBitsMap) const {
  for (std::set<unsigned>::const_iterator SI = stateInfo.begin();
       SI != stateInfo.end(); ++SI) {
    // Check to see if all required resources are available.
    bool available = true;

    // Inspect each stage independently.
    // note: This is a conservative check as we aren't checking for
    //       possible resource competition between the stages themselves
    //       The full cross product is examined later in AddInsnClass.
    for (unsigned i = 0; i < InsnClass.size(); ++i) {
      unsigned resources = *SI;
      if ((~resources & InsnClass[i]) == 0) {
        available = false;
        break;
      }
      // Make sure _all_ resources for a combo function are available.
      // note: This is a quick conservative check as it won't catch an
      //       unscheduleable combo if this stage is an OR expression
      //       containing a combo.
      //       These cases are caught later in AddInsnClass.
      unsigned combo = ComboBitToBitsMap[InsnClass[i]];
      if (combo && ((~resources & combo) != combo)) {
        DEBUG(dbgs() << "\tSkipped canMaybeAdd 0x" << utohexstr(resources)
                     << " - combo op 0x" << utohexstr(InsnClass[i])
                     << " (0x" << utohexstr(combo) <<") cannot be scheduled\n");
        available = false;
        break;
      }
    }

    if (available) {
      return true;
    }
  }
  return false;
}

const State &DFA::newState() {
  auto IterPair = states.insert(State());
  assert(IterPair.second && "State already exists");
  return *IterPair.first;
}

int State::currentStateNum = 0;

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

//
// writeTableAndAPI - Print out a table representing the DFA and the
// associated API to create a DFA packetizer.
//
// Format:
// DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
//                           transitions.
// DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable for
//                         the ith state.
//
//
void DFA::writeTableAndAPI(raw_ostream &OS, const std::string &TargetName,
                           int numInsnClasses,
                           int maxResources, int numCombos, int maxStages) {
  unsigned numStates = states.size();

  DEBUG(dbgs() << "-----------------------------------------------------------------------------\n");
  DEBUG(dbgs() << "writeTableAndAPI\n");
  DEBUG(dbgs() << "Total states: " << numStates << "\n");

  OS << "namespace llvm {\n";

  OS << "\n// Input format:\n";
  OS << "#define DFA_MAX_RESTERMS        " << DFA_MAX_RESTERMS
     << "\t// maximum AND'ed resource terms\n";
  OS << "#define DFA_MAX_RESOURCES       " << DFA_MAX_RESOURCES
     << "\t// maximum resource bits in one term\n";

  OS << "\n// " << TargetName << "DFAStateInputTable[][2] = "
     << "pairs of <Input, NextState> for all valid\n";
  OS << "//                           transitions.\n";
  OS << "// " << numStates << "\tstates\n";
  OS << "// " << numInsnClasses << "\tinstruction classes\n";
  OS << "// " << maxResources << "\tresources max\n";
  OS << "// " << numCombos << "\tcombo resources\n";
  OS << "// " << maxStages << "\tstages max\n";
  OS << "const " << DFA_TBLTYPE << " "
     << TargetName << "DFAStateInputTable[][2] = {\n";

  // This table provides a map to the beginning of the transitions for State s
  // in DFAStateInputTable.
  std::vector<int> StateEntry(numStates+1);
  static const std::string SentinelEntry = "{-1, -1}";

  // Tracks the total valid transitions encountered so far. It is used
  // to construct the StateEntry table.
  int ValidTransitions = 0;
  DFA::StateSet::iterator SI = states.begin();
  for (unsigned i = 0; i < numStates; ++i, ++SI) {
    assert ((SI->stateNum == (int) i) && "Mismatch in state numbers");
    StateEntry[i] = ValidTransitions;
    for (State::TransitionMap::iterator
        II = SI->Transitions.begin(), IE = SI->Transitions.end();
        II != IE; ++II) {
      OS << "{0x" << utohexstr(getDFAInsnInput(II->first)) << ", "
         << II->second->stateNum
         << "},\t";
    }
    ValidTransitions += SI->Transitions.size();

    // If there are no valid transitions from this stage, we need a sentinel
    // transition.
    if (ValidTransitions == StateEntry[i]) {
      OS << SentinelEntry << ",\t";
      ++ValidTransitions;
    }

    OS << " // state " << i << ": " << StateEntry[i];
    if (StateEntry[i] != (ValidTransitions-1)) {   // More than one transition.
       OS << "-" << (ValidTransitions-1);
    }
    OS << "\n";
  }

  // Print out a sentinel entry at the end of the StateInputTable. This is
  // needed to iterate over StateInputTable in DFAPacketizer::ReadTable()
  OS << SentinelEntry << "\t";
  OS << " // state " << numStates << ": " << ValidTransitions;
  OS << "\n";

  OS << "};\n\n";
  OS << "// " << TargetName << "DFAStateEntryTable[i] = "
     << "Index of the first entry in DFAStateInputTable for\n";
  OS << "//                         "
     << "the ith state.\n";
  OS << "// " << numStates << " states\n";
  OS << "const unsigned int " << TargetName << "DFAStateEntryTable[] = {\n";

  // Multiply i by 2 since each entry in DFAStateInputTable is a set of
  // two numbers.
  unsigned lastState = 0;
  for (unsigned i = 0; i < numStates; ++i) {
    if (i && ((i % 10) == 0)) {
        lastState = i-1;
        OS << "   // states " << (i-10) << ":" << lastState << "\n";
    }
    OS << StateEntry[i] << ", ";
  }

  // Print out the index to the sentinel entry in StateInputTable
  OS << ValidTransitions << ", ";
  OS << "   // states " << (lastState+1) << ":" << numStates << "\n";

  OS << "};\n";
  OS << "} // namespace\n";

  //
  // Emit DFA Packetizer tables if the target is a VLIW machine.
  //
  std::string SubTargetClassName = TargetName + "GenSubtargetInfo";
  OS << "\n" << "#include \"llvm/CodeGen/DFAPacketizer.h\"\n";
  OS << "namespace llvm {\n";
  OS << "DFAPacketizer *" << SubTargetClassName << "::"
     << "createDFAPacketizer(const InstrItineraryData *IID) const {\n"
     << "   return new DFAPacketizer(IID, " << TargetName
     << "DFAStateInputTable, " << TargetName << "DFAStateEntryTable);\n}\n\n";
  OS << "} // End llvm namespace \n";
}

//
// collectAllFuncUnits - Construct a map of function unit names to bits.
//
int DFAPacketizerEmitter::collectAllFuncUnits(
                            std::vector<Record*> &ProcItinList,
                            std::map<std::string, unsigned> &FUNameToBitsMap,
                            int &maxFUs,
                            raw_ostream &OS) {
  DEBUG(dbgs() << "-----------------------------------------------------------------------------\n");
  DEBUG(dbgs() << "collectAllFuncUnits");
  DEBUG(dbgs() << " (" << ProcItinList.size() << " itineraries)\n");

  int totalFUs = 0;
  // Parse functional units for all the itineraries.
  for (unsigned i = 0, N = ProcItinList.size(); i < N; ++i) {
    Record *Proc = ProcItinList[i];
    std::vector<Record*> FUs = Proc->getValueAsListOfDefs("FU");

    DEBUG(dbgs() << "    FU:" << i
                 << " (" << 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");
      unsigned FuncResources = (unsigned) (1U << j);
      FUNameToBitsMap[FUs[j]->getName()] = FuncResources;
      DEBUG(dbgs() << " " << FUs[j]->getName()
                   << ":0x" << utohexstr(FuncResources));
    }
    if (((int) numFUs) > maxFUs) {
      maxFUs = numFUs;
    }
    totalFUs += numFUs;
    DEBUG(dbgs() << "\n");
  }
  return totalFUs;
}

//
// collectAllComboFuncs - Construct a map from a combo function unit bit to
//                        the bits of all included functional units.
//
int DFAPacketizerEmitter::collectAllComboFuncs(
                            std::vector<Record*> &ComboFuncList,
                            std::map<std::string, unsigned> &FUNameToBitsMap,
                            std::map<unsigned, unsigned> &ComboBitToBitsMap,
                            raw_ostream &OS) {
  DEBUG(dbgs() << "-----------------------------------------------------------------------------\n");
  DEBUG(dbgs() << "collectAllComboFuncs");
  DEBUG(dbgs() << " (" << ComboFuncList.size() << " sets)\n");

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

    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");
      Record *FuncData = FUs[j];
      Record *ComboFunc = FuncData->getValueAsDef("TheComboFunc");
      const std::vector<Record*> &FuncList =
                                   FuncData->getValueAsListOfDefs("FuncList");
      const std::string &ComboFuncName = ComboFunc->getName();
      unsigned ComboBit = FUNameToBitsMap[ComboFuncName];
      unsigned ComboResources = ComboBit;
      DEBUG(dbgs() << "      combo: " << ComboFuncName
                   << ":0x" << utohexstr(ComboResources) << "\n");
      for (unsigned k = 0, M = FuncList.size(); k < M; ++k) {
        std::string FuncName = FuncList[k]->getName();
        unsigned FuncResources = FUNameToBitsMap[FuncName];
        DEBUG(dbgs() << "        " << FuncName
                     << ":0x" << utohexstr(FuncResources) << "\n");
        ComboResources |= FuncResources;
      }
      ComboBitToBitsMap[ComboBit] = ComboResources;
      numCombos++;
      DEBUG(dbgs() << "          => combo bits: " << ComboFuncName << ":0x"
                   << utohexstr(ComboBit) << " = 0x"
                   << utohexstr(ComboResources) << "\n");
    }
  }
  return numCombos;
}

//
// collectOneInsnClass - Populate allInsnClasses with one instruction class
//
int DFAPacketizerEmitter::collectOneInsnClass(const std::string &ProcName,
                        std::vector<Record*> &ProcItinList,
                        std::map<std::string, unsigned> &FUNameToBitsMap,
                        Record *ItinData,
                        raw_ostream &OS) {
  const std::vector<Record*> &StageList =
    ItinData->getValueAsListOfDefs("Stages");

  // The number of stages.
  unsigned NStages = StageList.size();

  DEBUG(dbgs() << "    " << ItinData->getValueAsDef("TheClass")->getName()
               << "\n");

  std::vector<unsigned> UnitBits;

  // Compute the bitwise or of each unit used in this stage.
  for (unsigned i = 0; i < NStages; ++i) {
    const Record *Stage = StageList[i];

    // Get unit list.
    const std::vector<Record*> &UnitList =
      Stage->getValueAsListOfDefs("Units");

    DEBUG(dbgs() << "        stage:" << i
                 << " [" << UnitList.size() << " units]:");
    unsigned dbglen = 26;  // cursor after stage dbgs

    // Compute the bitwise or of each unit used in this stage.
    unsigned UnitBitValue = 0;
    for (unsigned j = 0, M = UnitList.size(); j < M; ++j) {
      // Conduct bitwise or.
      std::string UnitName = UnitList[j]->getName();
      DEBUG(dbgs() << " " << j << ":" << UnitName);
      dbglen += 3 + UnitName.length();
      assert(FUNameToBitsMap.count(UnitName));
      UnitBitValue |= FUNameToBitsMap[UnitName];
    }

    if (UnitBitValue != 0)
      UnitBits.push_back(UnitBitValue);

    while (dbglen <= 64) {   // line up bits dbgs
        dbglen += 8;
        DEBUG(dbgs() << "\t");
    }
    DEBUG(dbgs() << " (bits: 0x" << utohexstr(UnitBitValue) << ")\n");
  }

  if (!UnitBits.empty())
    allInsnClasses.push_back(UnitBits);

  DEBUG({
    dbgs() << "        ";
    dbgsInsnClass(UnitBits);
    dbgs() << "\n";
  });

  return NStages;
}

//
// collectAllInsnClasses - Populate allInsnClasses which is a set of units
// used in each stage.
//
int DFAPacketizerEmitter::collectAllInsnClasses(const std::string &ProcName,
                            std::vector<Record*> &ProcItinList,
                            std::map<std::string, unsigned> &FUNameToBitsMap,
                            std::vector<Record*> &ItinDataList,
                            int &maxStages,
                            raw_ostream &OS) {
  // Collect all instruction classes.
  unsigned M = ItinDataList.size();

  int numInsnClasses = 0;
  DEBUG(dbgs() << "-----------------------------------------------------------------------------\n"
               << "collectAllInsnClasses "
               << ProcName
               << " (" << M << " classes)\n");

  // Collect stages for each instruction class for all itinerary data
  for (unsigned j = 0; j < M; j++) {
    Record *ItinData = ItinDataList[j];
    int NStages = collectOneInsnClass(ProcName, ProcItinList,
                                      FUNameToBitsMap, ItinData, OS);
    if (NStages > maxStages) {
      maxStages = NStages;
    }
    numInsnClasses++;
  }
  return numInsnClasses;
}

//
// Run the worklist algorithm to generate the DFA.
//
void DFAPacketizerEmitter::run(raw_ostream &OS) {
  // Collect processor iteraries.
  std::vector<Record*> ProcItinList =
    Records.getAllDerivedDefinitions("ProcessorItineraries");

  //
  // Collect the Functional units.
  //
  std::map<std::string, unsigned> FUNameToBitsMap;
  int maxResources = 0;
  collectAllFuncUnits(ProcItinList,
                              FUNameToBitsMap, maxResources, OS);

  //
  // Collect the Combo Functional units.
  //
  std::map<unsigned, unsigned> ComboBitToBitsMap;
  std::vector<Record*> ComboFuncList =
    Records.getAllDerivedDefinitions("ComboFuncUnits");
  int numCombos = collectAllComboFuncs(ComboFuncList,
                              FUNameToBitsMap, ComboBitToBitsMap, OS);

  //
  // Collect the itineraries.
  //
  int maxStages = 0;
  int numInsnClasses = 0;
  for (unsigned i = 0, N = ProcItinList.size(); i < N; i++) {
    Record *Proc = ProcItinList[i];

    // Get processor itinerary name.
    const std::string &ProcName = Proc->getName();

    // Skip default.
    if (ProcName == "NoItineraries")
      continue;

    // Sanity check for at least one instruction itinerary class.
    unsigned NItinClasses =
      Records.getAllDerivedDefinitions("InstrItinClass").size();
    if (NItinClasses == 0)
      return;

    // Get itinerary data list.
    std::vector<Record*> ItinDataList = Proc->getValueAsListOfDefs("IID");

    // Collect all instruction classes
    numInsnClasses += collectAllInsnClasses(ProcName, ProcItinList,
                          FUNameToBitsMap, ItinDataList, maxStages, OS);
  }

  //
  // Run a worklist algorithm to generate the DFA.
  //
  DFA D;
  const State *Initial = &D.newState();
  Initial->isInitial = true;
  Initial->stateInfo.insert(0x0);
  SmallVector<const State*, 32> WorkList;
  std::map<std::set<unsigned>, const State*> Visited;

  WorkList.push_back(Initial);

  //
  // Worklist algorithm to create a DFA for processor resource tracking.
  // C = {set of InsnClasses}
  // Begin with initial node in worklist. Initial node does not have
  // any consumed resources,
  //     ResourceState = 0x0
  // Visited = {}
  // While worklist != empty
  //    S = first element of worklist
  //    For every instruction class C
  //      if we can accommodate C in S:
  //          S' = state with resource states = {S Union C}
  //          Add a new transition: S x C -> S'
  //          If S' is not in Visited:
  //             Add S' to worklist
  //             Add S' to Visited
  //
  while (!WorkList.empty()) {
    const State *current = WorkList.pop_back_val();
    DEBUG({
      dbgs() << "---------------------\n";
      dbgs() << "Processing state: " << current->stateNum << " - ";
      dbgsStateInfo(current->stateInfo);
      dbgs() << "\n";
    });
    for (unsigned i = 0; i < allInsnClasses.size(); i++) {
      std::vector<unsigned> InsnClass = allInsnClasses[i];
      DEBUG({
        dbgs() << i << " ";
        dbgsInsnClass(InsnClass);
        dbgs() << "\n";
      });

      std::set<unsigned> NewStateResources;
      //
      // If we haven't already created a transition for this input
      // and the state can accommodate this InsnClass, create a transition.
      //
      if (!current->hasTransition(InsnClass) &&
          current->canMaybeAddInsnClass(InsnClass, ComboBitToBitsMap)) {
        const State *NewState = nullptr;
        current->AddInsnClass(InsnClass, ComboBitToBitsMap, NewStateResources);
        if (NewStateResources.empty()) {
          DEBUG(dbgs() << "  Skipped - no new states generated\n");
          continue;
        }

        DEBUG({
          dbgs() << "\t";
          dbgsStateInfo(NewStateResources);
          dbgs() << "\n";
        });

        //
        // If we have seen this state before, then do not create a new state.
        //
        auto VI = Visited.find(NewStateResources);
        if (VI != Visited.end()) {
          NewState = VI->second;
          DEBUG({
            dbgs() << "\tFound existing state: " << NewState->stateNum
                   << " - ";
            dbgsStateInfo(NewState->stateInfo);
            dbgs() << "\n";
          });
        } else {
          NewState = &D.newState();
          NewState->stateInfo = NewStateResources;
          Visited[NewStateResources] = NewState;
          WorkList.push_back(NewState);
          DEBUG({
            dbgs() << "\tAccepted new state: " << NewState->stateNum << " - ";
            dbgsStateInfo(NewState->stateInfo);
            dbgs() << "\n";
          });
        }

        current->addTransition(InsnClass, NewState);
      }
    }
  }

  // Print out the table.
  D.writeTableAndAPI(OS, TargetName,
               numInsnClasses, maxResources, numCombos, maxStages);
}

namespace llvm {

void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS) {
  emitSourceFileHeader("Target DFA Packetizer Tables", OS);
  DFAPacketizerEmitter(RK).run(OS);
}

} // end namespace llvm
