//===- 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.
//
//===----------------------------------------------------------------------===//

#include "llvm/TableGen/Record.h"
#include "CodeGenTarget.h"
#include "DFAPacketizerEmitter.h"
#include <list>

using namespace llvm;

//
//
// 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].
//
//
namespace {
class State {
 public:
  static int currentStateNum;
  int stateNum;
  bool isInitial;
  std::set<unsigned> stateInfo;

  State();
  State(const State &S);

  //
  // canAddInsnClass - Returns true if an instruction of type InsnClass is a
  // valid transition from this state, i.e., can an instruction of type InsnClass
  // be added to the packet represented by this state.
  //
  // PossibleStates is the set of valid resource states that ensue from valid
  // transitions.
  //
  bool canAddInsnClass(unsigned InsnClass, std::set<unsigned> &PossibleStates);
};
} // End anonymous namespace.


namespace {
struct Transition {
 public:
  static int currentTransitionNum;
  int transitionNum;
  State *from;
  unsigned input;
  State *to;

  Transition(State *from_, unsigned input_, State *to_);
};
} // End anonymous namespace.


//
// Comparators to keep set of states sorted.
//
namespace {
struct ltState {
  bool operator()(const State *s1, const State *s2) 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.
  std::set<State*, ltState> states;

  // Map from a state to the list of transitions with that state as source.
  std::map<State*, SmallVector<Transition*, 16>, ltState> stateTransitions;
  State *currentState;

  // Highest valued Input seen.
  unsigned LargestInput;

  //
  // Modify the DFA.
  //
  void initialize();
  void addState(State *);
  void addTransition(Transition *);

  //
  // getTransition -  Return the state when a transition is made from
  // State From with Input I. If a transition is not found, return NULL.
  //
  State *getTransition(State *, unsigned);

  //
  // isValidTransition: Predicate that checks if there is a valid transition
  // from state From on input InsnClass.
  //
  bool isValidTransition(State *From, unsigned InsnClass);

  //
  // writeTable: Print out a table representing the DFA.
  //
  void writeTableAndAPI(raw_ostream &OS, const std::string &ClassName);
};
} // End anonymous namespace.


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


State::State(const State &S) :
  stateNum(currentStateNum++), isInitial(S.isInitial),
  stateInfo(S.stateInfo) {}


Transition::Transition(State *from_, unsigned input_, State *to_) :
  transitionNum(currentTransitionNum++), from(from_), input(input_),
  to(to_) {}


DFA::DFA() :
  LargestInput(0) {}


bool ltState::operator()(const State *s1, const State *s2) const {
    return (s1->stateNum < s2->stateNum);
}


//
// canAddInsnClass - Returns true if an instruction of type InsnClass is a
// valid transition from this state i.e., can an instruction of type InsnClass
// be added to the packet represented by this state.
//
// PossibleStates is the set of valid resource states that ensue from valid
// transitions.
//
bool State::canAddInsnClass(unsigned InsnClass,
                            std::set<unsigned> &PossibleStates) {
  //
  // Iterate over all resource states in currentState.
  //
  bool AddedState = false;

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

    //
    // Iterate over all possible resources used in InsnClass.
    // For ex: for InsnClass = 0x11, all resources = {0x01, 0x10}.
    //

    DenseSet<unsigned> VisitedResourceStates;
    for (unsigned int j = 0; j < sizeof(InsnClass) * 8; ++j) {
      if ((0x1 << j) & InsnClass) {
        //
        // For each possible resource used in InsnClass, generate the
        // resource state if that resource was used.
        //
        unsigned ResultingResourceState = thisState | (0x1 << j);
        //
        // Check if the resulting resource state can be accommodated in this
        // packet.
        // We compute ResultingResourceState OR thisState.
        // If the result of the OR is different than thisState, it implies
        // that there is at least one resource that can be used to schedule
        // InsnClass in the current packet.
        // Insert ResultingResourceState into PossibleStates only if we haven't
        // processed ResultingResourceState before.
        //
        if ((ResultingResourceState != thisState) &&
            (VisitedResourceStates.count(ResultingResourceState) == 0)) {
          VisitedResourceStates.insert(ResultingResourceState);
          PossibleStates.insert(ResultingResourceState);
          AddedState = true;
        }
      }
    }
  }

  return AddedState;
}


void DFA::initialize() {
  currentState->isInitial = true;
}


void DFA::addState(State *S) {
  assert(!states.count(S) && "State already exists");
  states.insert(S);
}


void DFA::addTransition(Transition *T) {
  // Update LargestInput.
  if (T->input > LargestInput)
    LargestInput = T->input;

  // Add the new transition.
  stateTransitions[T->from].push_back(T);
}


//
// getTransition - Return the state when a transition is made from
// State From with Input I. If a transition is not found, return NULL.
//
State *DFA::getTransition(State *From, unsigned I) {
  // Do we have a transition from state From?
  if (!stateTransitions.count(From))
    return NULL;

  // Do we have a transition from state From with Input I?
  for (SmallVector<Transition*, 16>::iterator VI =
         stateTransitions[From].begin();
         VI != stateTransitions[From].end(); ++VI)
    if ((*VI)->input == I)
      return (*VI)->to;

  return NULL;
}


bool DFA::isValidTransition(State *From, unsigned InsnClass) {
  return (getTransition(From, InsnClass) != NULL);
}


int State::currentStateNum = 0;
int Transition::currentTransitionNum = 0;

DFAGen::DFAGen(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) {
  std::set<State*, ltState>::iterator SI = states.begin();
  // This table provides a map to the beginning of the transitions for State s
  // in DFAStateInputTable.
  std::vector<int> StateEntry(states.size());

  OS << "namespace llvm {\n\n";
  OS << "const int " << TargetName << "DFAStateInputTable[][2] = {\n";

  // Tracks the total valid transitions encountered so far. It is used
  // to construct the StateEntry table.
  int ValidTransitions = 0;
  for (unsigned i = 0; i < states.size(); ++i, ++SI) {
    StateEntry[i] = ValidTransitions;
    for (unsigned j = 0; j <= LargestInput; ++j) {
      assert (((*SI)->stateNum == (int) i) && "Mismatch in state numbers");
      if (!isValidTransition(*SI, j))
        continue;

      OS << "{" << j << ", "
         << getTransition(*SI, j)->stateNum
         << "},    ";
      ++ValidTransitions;
    }

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

    OS << "\n";
  }
  OS << "};\n\n";
  OS << "const unsigned int " << TargetName << "DFAStateEntryTable[] = {\n";

  // Multiply i by 2 since each entry in DFAStateInputTable is a set of
  // two numbers.
  for (unsigned i = 0; i < states.size(); ++i)
    OS << StateEntry[i] << ", ";

  OS << "\n};\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";
}


//
// collectAllInsnClasses - Populate allInsnClasses which is a set of units
// used in each stage.
//
void DFAGen::collectAllInsnClasses(const std::string &Name,
                                  Record *ItinData,
                                  unsigned &NStages,
                                  raw_ostream &OS) {
  // Collect processor itineraries.
  std::vector<Record*> ProcItinList =
    Records.getAllDerivedDefinitions("ProcessorItineraries");

  // If just no itinerary then don't bother.
  if (ProcItinList.size() < 2)
    return;
  std::map<std::string, unsigned> NameToBitsMap;

  // 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");

    // Convert macros to bits for each stage.
    for (unsigned i = 0, N = FUs.size(); i < N; ++i)
      NameToBitsMap[FUs[i]->getName()] = (unsigned) (1U << i);
  }

  const std::vector<Record*> &StageList =
    ItinData->getValueAsListOfDefs("Stages");

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

  // For each unit.
  unsigned UnitBitValue = 0;

  // 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");

    for (unsigned j = 0, M = UnitList.size(); j < M; ++j) {
      // Conduct bitwise or.
      std::string UnitName = UnitList[j]->getName();
      assert(NameToBitsMap.count(UnitName));
      UnitBitValue |= NameToBitsMap[UnitName];
    }

    if (UnitBitValue != 0)
      allInsnClasses.insert(UnitBitValue);
  }
}


//
// Run the worklist algorithm to generate the DFA.
//
void DFAGen::run(raw_ostream &OS) {
  EmitSourceFileHeader("Target DFA Packetizer Tables", OS);

  // Collect processor iteraries.
  std::vector<Record*> ProcItinList =
    Records.getAllDerivedDefinitions("ProcessorItineraries");

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

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

    // Skip default.
    if (Name == "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 instruction classes for all itinerary data.
    for (unsigned j = 0, M = ItinDataList.size(); j < M; j++) {
      Record *ItinData = ItinDataList[j];
      unsigned NStages;
      collectAllInsnClasses(Name, ItinData, NStages, OS);
    }
  }


  //
  // Run a worklist algorithm to generate the DFA.
  //
  DFA D;
  State *Initial = new State;
  Initial->isInitial = true;
  Initial->stateInfo.insert(0x0);
  D.addState(Initial);
  SmallVector<State*, 32> WorkList;
  std::map<std::set<unsigned>, 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()) {
    State *current = WorkList.pop_back_val();
    for (DenseSet<unsigned>::iterator CI = allInsnClasses.begin(),
           CE = allInsnClasses.end(); CI != CE; ++CI) {
      unsigned InsnClass = *CI;

      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 (!D.getTransition(current, InsnClass) &&
          current->canAddInsnClass(InsnClass, NewStateResources)) {
        State *NewState = NULL;

        //
        // If we have seen this state before, then do not create a new state.
        //
        //
        std::map<std::set<unsigned>, State*>::iterator VI;
        if ((VI = Visited.find(NewStateResources)) != Visited.end())
          NewState = VI->second;
        else {
          NewState = new State;
          NewState->stateInfo = NewStateResources;
          D.addState(NewState);
          Visited[NewStateResources] = NewState;
          WorkList.push_back(NewState);
        }

        Transition *NewTransition = new Transition(current, InsnClass,
                                                   NewState);
        D.addTransition(NewTransition);
      }
    }
  }

  // Print out the table.
  D.writeTableAndAPI(OS, TargetName);
}
