//===- ModuloSchedGraph.h - Modulo Scheduling Graph and Set -*- C++ -*-----===//
//
// This header defines the primative classes that make up a data structure
// graph.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MODULO_SCHED_GRAPH_H
#define LLVM_CODEGEN_MODULO_SCHED_GRAPH_H

#include "llvm/Instruction.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "Support/HashExtras.h"
#include "Support/GraphTraits.h"
#include "Support/hash_map"
#include "../InstrSched/SchedGraphCommon.h"
#include <iostream>

//===----------------------------------------------------------------------===//
// ModuloSchedGraphNode - Implement a data structure based on the
// SchedGraphNodeCommon this class stores informtion needed later to order the
// nodes in modulo scheduling
//
class ModuloSchedGraphNode:public SchedGraphNodeCommon {
private:
  // the corresponding instruction 
  const Instruction *inst;

  // whether this node's property(ASAP,ALAP, ...) has been computed
  bool propertyComputed;

  // ASAP: the earliest time the node could be scheduled
  // ALAP: the latest time the node couldbe scheduled
  // depth: the depth of the node
  // height: the height of the node
  // mov: the mobility function, computed as ALAP - ASAP
  // scheTime: the scheduled time if this node has been scheduled 
  // earlyStart: the earliest time to be tried to schedule the node
  // lateStart: the latest time to be tried to schedule the node
  int ASAP, ALAP, depth, height, mov;
  int schTime;
  int earlyStart, lateStart;

public:

  //get the instruction
  const Instruction *getInst() const {
    return inst;
  }
  //get the instruction op-code name
  const char *getInstOpcodeName() const {
    return inst->getOpcodeName();
  }
  //get the instruction op-code
  const unsigned getInstOpcode() const {
    return inst->getOpcode();
  }

  //return whether the node is NULL
  bool isNullNode() const {
    return (inst == NULL);
  }
  //return whether the property of the node has been computed
  bool getPropertyComputed() {
    return propertyComputed;
  }
  //set the propertyComputed
  void setPropertyComputed(bool _propertyComputed) {
    propertyComputed = _propertyComputed;
  }
  
  //get the corresponding property
  int getASAP() {
    return ASAP;
  }
  int getALAP() {
    return ALAP;
  }
  int getMov() {
    return mov;
  }
  int getDepth() {
    return depth;
  }
  int getHeight() {
    return height;
  }
  int getSchTime() {
    return schTime;
  }
  int getEarlyStart() {
    return earlyStart;
  }
  int getLateStart() {
    return lateStart;
  }
  void setEarlyStart(int _earlyStart) {
    earlyStart = _earlyStart;
  }
  void setLateStart(int _lateStart) {
    lateStart = _lateStart;
  }
  void setSchTime(int _time) {
    schTime = _time;
  }

private:
  friend class ModuloSchedGraph;
  friend class SchedGraphNode;

  //constructor:
  //nodeId: the node id, unique within the each BasicBlock
  //_bb: which BasicBlock the corresponding instruction belongs to 
  //_inst: the corresponding instruction
  //indexInBB: the corresponding instruction's index in the BasicBlock
  //target: the targetMachine
  ModuloSchedGraphNode(unsigned int _nodeId,
                       const BasicBlock * _bb,
                       const Instruction * _inst,
                       int indexInBB, const TargetMachine &target);


  friend std::ostream & operator<<(std::ostream & os,
                                   const ModuloSchedGraphNode & edge);

};

//FIXME: these two value should not be used
#define MAXNODE 100
#define MAXCC   100

//===----------------------------------------------------------------------===//
/// ModuloSchedGraph- the data structure to store dependence between nodes
/// it catches data dependence and constrol dependence
/// 
class ModuloSchedGraph :
  public SchedGraphCommon,
  protected hash_map<const Instruction*,ModuloSchedGraphNode*> {

private:

  BasicBlock* bb;
  
  //iteration Interval
  int MII;

  //target machine
  const TargetMachine & target;

  //the circuits in the dependence graph
  unsigned circuits[MAXCC][MAXNODE];

  //the order nodes
  std::vector<ModuloSchedGraphNode*> oNodes;

  typedef std::vector<ModuloSchedGraphNode*> NodeVec;

  //the function to compute properties
  void computeNodeASAP(const BasicBlock * in_bb);
  void computeNodeALAP(const BasicBlock * in_bb);
  void computeNodeMov(const BasicBlock *  in_bb);
  void computeNodeDepth(const BasicBlock * in_bb);
  void computeNodeHeight(const BasicBlock * in_bb);

  //the function to compute node property
  void computeNodeProperty(const BasicBlock * in_bb);

  //the function to sort nodes
  void orderNodes();

  //add the resource usage 
void addResourceUsage(std::vector<std::pair<int,int> > &, int);

  //debug functions:
  //dump circuits
  void dumpCircuits();
  //dump the input set of nodes
  void dumpSet(std::vector<ModuloSchedGraphNode*> set);
  //dump the input resource usage table  
  void dumpResourceUsage(std::vector<std::pair<int,int> > &);

public:
  //help functions

  //get the maxium the delay between two nodes
  SchedGraphEdge *getMaxDelayEdge(unsigned srcId, unsigned sinkId);

  //FIXME:
  //get the predessor Set of the set
  NodeVec predSet(NodeVec set, unsigned, unsigned);
  NodeVec predSet(NodeVec set);

  //get the predessor set of the node
  NodeVec predSet(ModuloSchedGraphNode *node, unsigned, unsigned);
  NodeVec predSet(ModuloSchedGraphNode *node);

  //get the successor set of the set
  NodeVec succSet(NodeVec set, unsigned, unsigned);
  NodeVec succSet(NodeVec set);

  //get the succssor set of the node
  NodeVec succSet(ModuloSchedGraphNode *node, unsigned, unsigned);
  NodeVec succSet(ModuloSchedGraphNode *node);

  //return the uniton of the two vectors
  NodeVec vectorUnion(NodeVec set1, NodeVec set2);
  
  //return the consjuction of the two vectors
  NodeVec vectorConj(NodeVec set1, NodeVec set2);

  //return all nodes in  set1 but not  set2
  NodeVec vectorSub(NodeVec set1, NodeVec set2);

  typedef hash_map<const Instruction*,ModuloSchedGraphNode*> map_base;

public:
  using map_base::iterator;
  using map_base::const_iterator;

public:

  //get target machine
  const TargetMachine & getTarget() {
    return target;
  }

  //get the basic block
  BasicBlock* getBasicBlock() const {
    return bb;
  }


  //get the iteration interval
  const int getMII() {
    return MII;
  }

  //get the ordered nodes
  const NodeVec & getONodes() {
    return oNodes;
  }

  //get the number of nodes (including the root and leaf)
  //note: actually root and leaf is not used
  const unsigned int getNumNodes() const {
    return size() + 2;
  }

  //return wether the BasicBlock 'bb' contains a loop
  bool isLoop(const BasicBlock *bb);

  //return this basibBlock contains a loop
  bool isLoop();

  //return the node for the input instruction
  ModuloSchedGraphNode *getGraphNodeForInst(const Instruction *inst) const {
    const_iterator onePair = this->find(inst);
    return (onePair != this->end()) ? (*onePair).second : NULL;
  }

  // Debugging support
  //dump the graph
  void dump() const;

  // dump the basicBlock
  void dump(const BasicBlock *bb);

  //dump the basicBlock into 'os' stream
  void dump(const BasicBlock *bb, std::ostream &os);

  //dump the node property
  void dumpNodeProperty() const;
  
private:
  friend class ModuloSchedGraphSet;     //give access to ctor

public:
  ModuloSchedGraph(BasicBlock * in_bb, 
		   const TargetMachine & in_target)
    :SchedGraphCommon(), bb(in_bb),target(in_target)
  {
    buildGraph(target);
  }

  ~ModuloSchedGraph() {
    for (const_iterator I = begin(); I != end(); ++I)
      delete I->second;
  }

  // Unorder iterators
  // return values are pair<const Instruction*, ModuloSchedGraphNode*>
  using map_base::begin;
  using map_base::end;

  void noteModuloSchedGraphNodeForInst(const Instruction *inst,
                                       ModuloSchedGraphNode *node)
  {
    assert((*this)[inst] == NULL);
    (*this)[inst] = node;
  }

  // Graph builder
  ModuloSchedGraphNode *getNode(const unsigned nodeId) const;

  // Build the graph from the basicBlock
  void buildGraph(const TargetMachine &target);

  // Build nodes for BasicBlock
  void buildNodesforBB(const TargetMachine &target,
                       const BasicBlock *bb,
                       NodeVec &memNode,
                       RegToRefVecMap &regToRefVecMap,
                       ValueToDefVecMap &valueToDefVecMap);

  //find definitiona and use information for all nodes
  void findDefUseInfoAtInstr(const TargetMachine &target,
                             ModuloSchedGraphNode *node,
                             NodeVec &memNode,
                             RegToRefVecMap &regToRefVecMap,
                             ValueToDefVecMap &valueToDefVecMap);

  //add def-use edge
  void addDefUseEdges(const BasicBlock *bb);

  //add control dependence edges
  void addCDEdges(const BasicBlock *bb);

  //add memory dependence dges
  void addMemEdges(const BasicBlock *bb);

  //add dummy edges
  void addDummyEdges();

  //computer source restrictoin II
  int computeResII(const BasicBlock *bb);

  //computer recurrence II
  int computeRecII(const BasicBlock *bb);
};

//==================================-
// Graph set

class ModuloSchedGraphSet : public std::vector<ModuloSchedGraph*> {
private:
  const Function *method;

public:
  typedef std::vector<ModuloSchedGraph*> baseVector;
  using baseVector::iterator;
  using baseVector::const_iterator;

public:
  ModuloSchedGraphSet(const Function *function, const TargetMachine &target);
  ~ModuloSchedGraphSet();

  // Iterators
  using baseVector::begin;
  using baseVector::end;

  // Debugging support
  void dump() const;

private:
  void addGraph(ModuloSchedGraph *graph) {
    assert(graph != NULL);
    this->push_back(graph);
  }

  // Graph builder
  void buildGraphsForMethod(const Function *F,
                            const TargetMachine &target);
};

#endif
