//===- 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 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 addHash(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);

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

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