blob: db3a9a31e5fc886391a72921fabef3385d08259a [file] [log] [blame]
Misha Brukman8baa01c2003-04-09 21:51:34 +00001//===- ModuloSchedGraph.h - Modulo Scheduling Graph and Set -*- C++ -*-----===//
Guochun Shif1c154f2003-03-27 17:57:44 +00002//
3// This header defines the primative classes that make up a data structure
4// graph.
5//
6//===----------------------------------------------------------------------===//
7
8#ifndef LLVM_CODEGEN_MODULO_SCHED_GRAPH_H
9#define LLVM_CODEGEN_MODULO_SCHED_GRAPH_H
Misha Brukman8baa01c2003-04-09 21:51:34 +000010
Guochun Shif1c154f2003-03-27 17:57:44 +000011#include "llvm/Instruction.h"
12#include "llvm/Target/TargetMachine.h"
Guochun Shi6fbe5fb2003-04-06 23:56:19 +000013#include "llvm/Target/TargetInstrInfo.h"
Misha Brukman8baa01c2003-04-09 21:51:34 +000014#include "Support/HashExtras.h"
15#include "Support/GraphTraits.h"
Misha Brukman2c821cc2003-04-10 19:19:23 +000016#include "Support/hash_map"
Misha Brukman8baa01c2003-04-09 21:51:34 +000017#include "../InstrSched/SchedGraphCommon.h"
Guochun Shif1c154f2003-03-27 17:57:44 +000018#include <iostream>
Guochun Shif1c154f2003-03-27 17:57:44 +000019
Misha Brukman8baa01c2003-04-09 21:51:34 +000020//===----------------------------------------------------------------------===//
21// ModuloSchedGraphNode - Implement a data structure based on the
22// SchedGraphNodeCommon this class stores informtion needed later to order the
23// nodes in modulo scheduling
24//
25class ModuloSchedGraphNode:public SchedGraphNodeCommon {
Guochun Shif1c154f2003-03-27 17:57:44 +000026private:
Misha Brukman8baa01c2003-04-09 21:51:34 +000027 // the corresponding instruction
28 const Instruction *inst;
Guochun Shif1c154f2003-03-27 17:57:44 +000029
Misha Brukman8baa01c2003-04-09 21:51:34 +000030 // whether this node's property(ASAP,ALAP, ...) has been computed
Guochun Shif1c154f2003-03-27 17:57:44 +000031 bool propertyComputed;
32
Misha Brukman8baa01c2003-04-09 21:51:34 +000033 // ASAP: the earliest time the node could be scheduled
34 // ALAP: the latest time the node couldbe scheduled
35 // depth: the depth of the node
36 // height: the height of the node
37 // mov: the mobility function, computed as ALAP - ASAP
38 // scheTime: the scheduled time if this node has been scheduled
39 // earlyStart: the earliest time to be tried to schedule the node
40 // lateStart: the latest time to be tried to schedule the node
Guochun Shif1c154f2003-03-27 17:57:44 +000041 int ASAP, ALAP, depth, height, mov;
42 int schTime;
Misha Brukman8baa01c2003-04-09 21:51:34 +000043 int earlyStart, lateStart;
Guochun Shif1c154f2003-03-27 17:57:44 +000044
45public:
Misha Brukman8baa01c2003-04-09 21:51:34 +000046
Guochun Shif1c154f2003-03-27 17:57:44 +000047 //get the instruction
Misha Brukman8baa01c2003-04-09 21:51:34 +000048 const Instruction *getInst() const {
49 return inst;
50 }
Guochun Shif1c154f2003-03-27 17:57:44 +000051 //get the instruction op-code name
Misha Brukman8baa01c2003-04-09 21:51:34 +000052 const char *getInstOpcodeName() const {
53 return inst->getOpcodeName();
54 }
55 //get the instruction op-code
56 const unsigned getInstOpcode() const {
57 return inst->getOpcode();
58 }
Guochun Shi099b0642003-06-02 17:48:56 +000059
Guochun Shif1c154f2003-03-27 17:57:44 +000060 //return whether the node is NULL
Misha Brukman8baa01c2003-04-09 21:51:34 +000061 bool isNullNode() const {
62 return (inst == NULL);
63 }
Guochun Shif1c154f2003-03-27 17:57:44 +000064 //return whether the property of the node has been computed
Misha Brukman8baa01c2003-04-09 21:51:34 +000065 bool getPropertyComputed() {
66 return propertyComputed;
67 }
Guochun Shif1c154f2003-03-27 17:57:44 +000068 //set the propertyComputed
Misha Brukman8baa01c2003-04-09 21:51:34 +000069 void setPropertyComputed(bool _propertyComputed) {
70 propertyComputed = _propertyComputed;
71 }
72
Guochun Shif1c154f2003-03-27 17:57:44 +000073 //get the corresponding property
Misha Brukman8baa01c2003-04-09 21:51:34 +000074 int getASAP() {
75 return ASAP;
76 }
77 int getALAP() {
78 return ALAP;
79 }
80 int getMov() {
81 return mov;
82 }
83 int getDepth() {
84 return depth;
85 }
86 int getHeight() {
87 return height;
88 }
89 int getSchTime() {
90 return schTime;
91 }
92 int getEarlyStart() {
93 return earlyStart;
94 }
95 int getLateStart() {
96 return lateStart;
97 }
98 void setEarlyStart(int _earlyStart) {
99 earlyStart = _earlyStart;
100 }
101 void setLateStart(int _lateStart) {
102 lateStart = _lateStart;
103 }
104 void setSchTime(int _time) {
105 schTime = _time;
106 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000107
Misha Brukman8baa01c2003-04-09 21:51:34 +0000108private:
Guochun Shif1c154f2003-03-27 17:57:44 +0000109 friend class ModuloSchedGraph;
110 friend class SchedGraphNode;
111
112 //constructor:
113 //nodeId: the node id, unique within the each BasicBlock
114 //_bb: which BasicBlock the corresponding instruction belongs to
115 //_inst: the corresponding instruction
116 //indexInBB: the corresponding instruction's index in the BasicBlock
117 //target: the targetMachine
118 ModuloSchedGraphNode(unsigned int _nodeId,
Misha Brukman8baa01c2003-04-09 21:51:34 +0000119 const BasicBlock * _bb,
120 const Instruction * _inst,
121 int indexInBB, const TargetMachine &target);
122
123
124 friend std::ostream & operator<<(std::ostream & os,
125 const ModuloSchedGraphNode & edge);
126
Guochun Shif1c154f2003-03-27 17:57:44 +0000127};
128
Guochun Shif1c154f2003-03-27 17:57:44 +0000129//FIXME: these two value should not be used
130#define MAXNODE 100
131#define MAXCC 100
132
Guochun Shif1c154f2003-03-27 17:57:44 +0000133//===----------------------------------------------------------------------===//
134/// ModuloSchedGraph- the data structure to store dependence between nodes
135/// it catches data dependence and constrol dependence
136///
Misha Brukman8baa01c2003-04-09 21:51:34 +0000137class ModuloSchedGraph :
Guochun Shif1c154f2003-03-27 17:57:44 +0000138 public SchedGraphCommon,
Misha Brukman8baa01c2003-04-09 21:51:34 +0000139 protected hash_map<const Instruction*,ModuloSchedGraphNode*> {
140
141private:
Guochun Shi099b0642003-06-02 17:48:56 +0000142
143 BasicBlock* bb;
144
Guochun Shif1c154f2003-03-27 17:57:44 +0000145 //iteration Interval
146 int MII;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000147
Guochun Shif1c154f2003-03-27 17:57:44 +0000148 //target machine
Misha Brukman8baa01c2003-04-09 21:51:34 +0000149 const TargetMachine & target;
Guochun Shif1c154f2003-03-27 17:57:44 +0000150
151 //the circuits in the dependence graph
152 unsigned circuits[MAXCC][MAXNODE];
153
154 //the order nodes
155 std::vector<ModuloSchedGraphNode*> oNodes;
156
157 typedef std::vector<ModuloSchedGraphNode*> NodeVec;
158
159 //the function to compute properties
Guochun Shi099b0642003-06-02 17:48:56 +0000160 void computeNodeASAP(const BasicBlock * in_bb);
161 void computeNodeALAP(const BasicBlock * in_bb);
162 void computeNodeMov(const BasicBlock * in_bb);
163 void computeNodeDepth(const BasicBlock * in_bb);
164 void computeNodeHeight(const BasicBlock * in_bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000165
166 //the function to compute node property
Guochun Shi099b0642003-06-02 17:48:56 +0000167 void computeNodeProperty(const BasicBlock * in_bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000168
169 //the function to sort nodes
170 void orderNodes();
Misha Brukman8baa01c2003-04-09 21:51:34 +0000171
Guochun Shif1c154f2003-03-27 17:57:44 +0000172 //add the resource usage
Misha Brukman2c821cc2003-04-10 19:19:23 +0000173void addResourceUsage(std::vector<std::pair<int,int> > &, int);
Guochun Shif1c154f2003-03-27 17:57:44 +0000174
175 //debug functions:
176 //dump circuits
177 void dumpCircuits();
178 //dump the input set of nodes
179 void dumpSet(std::vector<ModuloSchedGraphNode*> set);
180 //dump the input resource usage table
Misha Brukman2c821cc2003-04-10 19:19:23 +0000181 void dumpResourceUsage(std::vector<std::pair<int,int> > &);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000182
183public:
Guochun Shif1c154f2003-03-27 17:57:44 +0000184 //help functions
Misha Brukman8baa01c2003-04-09 21:51:34 +0000185
Guochun Shif1c154f2003-03-27 17:57:44 +0000186 //get the maxium the delay between two nodes
Misha Brukman8baa01c2003-04-09 21:51:34 +0000187 SchedGraphEdge *getMaxDelayEdge(unsigned srcId, unsigned sinkId);
Guochun Shif1c154f2003-03-27 17:57:44 +0000188
189 //FIXME:
190 //get the predessor Set of the set
191 NodeVec predSet(NodeVec set, unsigned, unsigned);
192 NodeVec predSet(NodeVec set);
193
194 //get the predessor set of the node
Misha Brukman2c821cc2003-04-10 19:19:23 +0000195 NodeVec predSet(ModuloSchedGraphNode *node, unsigned, unsigned);
196 NodeVec predSet(ModuloSchedGraphNode *node);
Guochun Shif1c154f2003-03-27 17:57:44 +0000197
198 //get the successor set of the set
199 NodeVec succSet(NodeVec set, unsigned, unsigned);
200 NodeVec succSet(NodeVec set);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000201
Guochun Shif1c154f2003-03-27 17:57:44 +0000202 //get the succssor set of the node
Misha Brukman2c821cc2003-04-10 19:19:23 +0000203 NodeVec succSet(ModuloSchedGraphNode *node, unsigned, unsigned);
204 NodeVec succSet(ModuloSchedGraphNode *node);
Guochun Shif1c154f2003-03-27 17:57:44 +0000205
206 //return the uniton of the two vectors
Misha Brukman8baa01c2003-04-09 21:51:34 +0000207 NodeVec vectorUnion(NodeVec set1, NodeVec set2);
Guochun Shif1c154f2003-03-27 17:57:44 +0000208
209 //return the consjuction of the two vectors
Misha Brukman8baa01c2003-04-09 21:51:34 +0000210 NodeVec vectorConj(NodeVec set1, NodeVec set2);
211
Guochun Shif1c154f2003-03-27 17:57:44 +0000212 //return all nodes in set1 but not set2
213 NodeVec vectorSub(NodeVec set1, NodeVec set2);
214
Misha Brukman8baa01c2003-04-09 21:51:34 +0000215 typedef hash_map<const Instruction*,ModuloSchedGraphNode*> map_base;
216
Guochun Shif1c154f2003-03-27 17:57:44 +0000217public:
218 using map_base::iterator;
219 using map_base::const_iterator;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000220
Guochun Shif1c154f2003-03-27 17:57:44 +0000221public:
222
223 //get target machine
Misha Brukman8baa01c2003-04-09 21:51:34 +0000224 const TargetMachine & getTarget() {
225 return target;
226 }
Guochun Shi099b0642003-06-02 17:48:56 +0000227
228 //get the basic block
229 BasicBlock* getBasicBlock() const {
230 return bb;
231 }
232
233
Guochun Shif1c154f2003-03-27 17:57:44 +0000234 //get the iteration interval
Misha Brukman8baa01c2003-04-09 21:51:34 +0000235 const int getMII() {
236 return MII;
237 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000238
239 //get the ordered nodes
Misha Brukman8baa01c2003-04-09 21:51:34 +0000240 const NodeVec & getONodes() {
241 return oNodes;
242 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000243
244 //get the number of nodes (including the root and leaf)
245 //note: actually root and leaf is not used
Misha Brukman8baa01c2003-04-09 21:51:34 +0000246 const unsigned int getNumNodes() const {
247 return size() + 2;
248 }
Misha Brukman63e04f32003-04-22 23:00:08 +0000249
Guochun Shif1c154f2003-03-27 17:57:44 +0000250 //return wether the BasicBlock 'bb' contains a loop
Misha Brukman63e04f32003-04-22 23:00:08 +0000251 bool isLoop(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000252
Guochun Shif1c154f2003-03-27 17:57:44 +0000253 //return the node for the input instruction
Misha Brukman63e04f32003-04-22 23:00:08 +0000254 ModuloSchedGraphNode *getGraphNodeForInst(const Instruction *inst) const {
Guochun Shif1c154f2003-03-27 17:57:44 +0000255 const_iterator onePair = this->find(inst);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000256 return (onePair != this->end()) ? (*onePair).second : NULL;
Guochun Shif1c154f2003-03-27 17:57:44 +0000257 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000258
259 // Debugging support
260 //dump the graph
261 void dump() const;
262
263 // dump the basicBlock
Misha Brukman63e04f32003-04-22 23:00:08 +0000264 void dump(const BasicBlock *bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000265
Guochun Shif1c154f2003-03-27 17:57:44 +0000266 //dump the basicBlock into 'os' stream
Misha Brukman63e04f32003-04-22 23:00:08 +0000267 void dump(const BasicBlock *bb, std::ostream &os);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000268
Guochun Shif1c154f2003-03-27 17:57:44 +0000269 //dump the node property
Misha Brukman8baa01c2003-04-09 21:51:34 +0000270 void dumpNodeProperty() const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000271
Misha Brukman8baa01c2003-04-09 21:51:34 +0000272private:
273 friend class ModuloSchedGraphSet; //give access to ctor
274
275public:
Guochun Shi099b0642003-06-02 17:48:56 +0000276 ModuloSchedGraph(BasicBlock * in_bb,
277 const TargetMachine & in_target)
278 :SchedGraphCommon(), bb(in_bb),target(in_target)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000279 {
Guochun Shif1c154f2003-03-27 17:57:44 +0000280 buildGraph(target);
281 }
282
Misha Brukman8baa01c2003-04-09 21:51:34 +0000283 ~ModuloSchedGraph() {
284 for (const_iterator I = begin(); I != end(); ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +0000285 delete I->second;
286 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000287
Misha Brukman2c821cc2003-04-10 19:19:23 +0000288 // Unorder iterators
289 // return values are pair<const Instruction*, ModuloSchedGraphNode*>
Guochun Shif1c154f2003-03-27 17:57:44 +0000290 using map_base::begin;
291 using map_base::end;
292
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000293 void addHash(const Instruction *inst,
294 ModuloSchedGraphNode *node){
295
Misha Brukman8baa01c2003-04-09 21:51:34 +0000296 assert((*this)[inst] == NULL);
297 (*this)[inst] = node;
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000298
Misha Brukman8baa01c2003-04-09 21:51:34 +0000299 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000300
Misha Brukman63e04f32003-04-22 23:00:08 +0000301 // Graph builder
Misha Brukman8baa01c2003-04-09 21:51:34 +0000302 ModuloSchedGraphNode *getNode(const unsigned nodeId) const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000303
Misha Brukman63e04f32003-04-22 23:00:08 +0000304 // Build the graph from the basicBlock
305 void buildGraph(const TargetMachine &target);
Guochun Shif1c154f2003-03-27 17:57:44 +0000306
Misha Brukman63e04f32003-04-22 23:00:08 +0000307 // Build nodes for BasicBlock
Misha Brukman8baa01c2003-04-09 21:51:34 +0000308 void buildNodesforBB(const TargetMachine &target,
Guochun Shi8f1d4ab2003-06-08 23:16:07 +0000309 const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000310
311 //find definitiona and use information for all nodes
Misha Brukman8baa01c2003-04-09 21:51:34 +0000312 void findDefUseInfoAtInstr(const TargetMachine &target,
313 ModuloSchedGraphNode *node,
314 NodeVec &memNode,
315 RegToRefVecMap &regToRefVecMap,
316 ValueToDefVecMap &valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000317
318 //add def-use edge
Misha Brukman8baa01c2003-04-09 21:51:34 +0000319 void addDefUseEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000320
321 //add control dependence edges
Misha Brukman8baa01c2003-04-09 21:51:34 +0000322 void addCDEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000323
324 //add memory dependence dges
Misha Brukman8baa01c2003-04-09 21:51:34 +0000325 void addMemEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000326
Guochun Shif1c154f2003-03-27 17:57:44 +0000327 //computer source restrictoin II
Misha Brukman8baa01c2003-04-09 21:51:34 +0000328 int computeResII(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000329
330 //computer recurrence II
Misha Brukman8baa01c2003-04-09 21:51:34 +0000331 int computeRecII(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000332};
333
Misha Brukman8baa01c2003-04-09 21:51:34 +0000334//==================================-
335// Graph set
Guochun Shif1c154f2003-03-27 17:57:44 +0000336
Misha Brukman8baa01c2003-04-09 21:51:34 +0000337class ModuloSchedGraphSet : public std::vector<ModuloSchedGraph*> {
Guochun Shif1c154f2003-03-27 17:57:44 +0000338private:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000339 const Function *method;
340
Guochun Shif1c154f2003-03-27 17:57:44 +0000341public:
342 typedef std::vector<ModuloSchedGraph*> baseVector;
343 using baseVector::iterator;
344 using baseVector::const_iterator;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000345
Guochun Shif1c154f2003-03-27 17:57:44 +0000346public:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000347 ModuloSchedGraphSet(const Function *function, const TargetMachine &target);
348 ~ModuloSchedGraphSet();
349
350 // Iterators
Guochun Shif1c154f2003-03-27 17:57:44 +0000351 using baseVector::begin;
352 using baseVector::end;
353
Misha Brukman2c821cc2003-04-10 19:19:23 +0000354 // Debugging support
355 void dump() const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000356
Guochun Shif1c154f2003-03-27 17:57:44 +0000357private:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000358 void addGraph(ModuloSchedGraph *graph) {
359 assert(graph != NULL);
Guochun Shif1c154f2003-03-27 17:57:44 +0000360 this->push_back(graph);
361 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000362
Misha Brukman8baa01c2003-04-09 21:51:34 +0000363 // Graph builder
364 void buildGraphsForMethod(const Function *F,
365 const TargetMachine &target);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000366};
Misha Brukman8baa01c2003-04-09 21:51:34 +0000367
368#endif