//===- 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/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"
#include "llvm/Support/Debug.h"
#include <map>
#include <string>
#include <queue>

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);
};
} // end anonymous namespace

//
//
// 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.
//
namespace {
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;
};
} // end anonymous namespace

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

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

  State *currentState;

  //
  // 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) {}

DFA::DFA(): currentState(nullptr) {}

//
// 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()),
  allInsnClasses(), 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.size() > 0)
    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::queue<State*> 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.size() == 0) {
          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 namespaec llvm
