2003-03-27 18:57:44 +01:00
|
|
|
//===- ModuloSchedGraph.h - Represent a collection of data structures ----*- 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 "Support/HashExtras.h"
|
|
|
|
#include "Support/GraphTraits.h"
|
|
|
|
#include "../InstrSched/SchedGraphCommon.h"
|
|
|
|
#include "llvm/Instruction.h"
|
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2003-04-07 01:56:19 +02:00
|
|
|
#include "llvm/Target/TargetInstrInfo.h"
|
2003-03-27 18:57:44 +01:00
|
|
|
#include <iostream>
|
|
|
|
using std::pair;
|
|
|
|
|
|
|
|
//for debug information selecton
|
|
|
|
enum ModuloSchedDebugLevel_t{
|
|
|
|
ModuloSched_NoDebugInfo,
|
|
|
|
ModuloSched_Disable,
|
|
|
|
ModuloSched_PrintSchedule,
|
|
|
|
ModuloSched_PrintScheduleProcess,
|
|
|
|
};
|
|
|
|
|
|
|
|
//===============------------------------------------------------------------------------
|
|
|
|
///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:
|
|
|
|
//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* bb);
|
|
|
|
void computeNodeALAP(const BasicBlock* bb);
|
|
|
|
void computeNodeMov(const BasicBlock* bb);
|
|
|
|
void computeNodeDepth(const BasicBlock* bb);
|
|
|
|
void computeNodeHeight(const BasicBlock* bb);
|
|
|
|
|
|
|
|
//the function to compute node property
|
|
|
|
void computeNodeProperty(const BasicBlock* bb);
|
|
|
|
|
|
|
|
//the function to sort nodes
|
|
|
|
void orderNodes();
|
|
|
|
|
|
|
|
//add the resource usage
|
|
|
|
void addResourceUsage(std::vector<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<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 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:
|
|
|
|
/*ctr*/
|
|
|
|
ModuloSchedGraph(const BasicBlock* bb, const TargetMachine& _target)
|
|
|
|
:SchedGraphCommon(bb), target(_target){
|
|
|
|
buildGraph(target);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*dtr*/
|
|
|
|
~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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline 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);
|
|
|
|
};
|
|
|
|
|
|
|
|
///==================================-
|
|
|
|
//gragh 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:
|
|
|
|
/*ctor*/ ModuloSchedGraphSet (const Function* function, const TargetMachine& target);
|
|
|
|
|
|
|
|
/*dtor*/ ~ModuloSchedGraphSet ();
|
|
|
|
|
|
|
|
//iterators
|
|
|
|
using baseVector::begin;
|
|
|
|
using baseVector::end;
|
|
|
|
|
|
|
|
|
|
|
|
//Debugging support
|
|
|
|
void dump() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
inline void addGraph(ModuloSchedGraph* graph){
|
|
|
|
assert(graph !=NULL);
|
|
|
|
this->push_back(graph);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Graph builder
|
|
|
|
void buildGraphsForMethod (const Function *F, const TargetMachine& target);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|