blob: 7cdfdd970e89db941ee4e4472b604670932e9fb0 [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
253 //return this basibBlock contains a loop
Misha Brukman8baa01c2003-04-09 21:51:34 +0000254 bool isLoop();
255
Guochun Shif1c154f2003-03-27 17:57:44 +0000256 //return the node for the input instruction
Misha Brukman63e04f32003-04-22 23:00:08 +0000257 ModuloSchedGraphNode *getGraphNodeForInst(const Instruction *inst) const {
Guochun Shif1c154f2003-03-27 17:57:44 +0000258 const_iterator onePair = this->find(inst);
Misha Brukman8baa01c2003-04-09 21:51:34 +0000259 return (onePair != this->end()) ? (*onePair).second : NULL;
Guochun Shif1c154f2003-03-27 17:57:44 +0000260 }
Misha Brukman2c821cc2003-04-10 19:19:23 +0000261
262 // Debugging support
263 //dump the graph
264 void dump() const;
265
266 // dump the basicBlock
Misha Brukman63e04f32003-04-22 23:00:08 +0000267 void dump(const BasicBlock *bb);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000268
Guochun Shif1c154f2003-03-27 17:57:44 +0000269 //dump the basicBlock into 'os' stream
Misha Brukman63e04f32003-04-22 23:00:08 +0000270 void dump(const BasicBlock *bb, std::ostream &os);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000271
Guochun Shif1c154f2003-03-27 17:57:44 +0000272 //dump the node property
Misha Brukman8baa01c2003-04-09 21:51:34 +0000273 void dumpNodeProperty() const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000274
Misha Brukman8baa01c2003-04-09 21:51:34 +0000275private:
276 friend class ModuloSchedGraphSet; //give access to ctor
277
278public:
Guochun Shi099b0642003-06-02 17:48:56 +0000279 ModuloSchedGraph(BasicBlock * in_bb,
280 const TargetMachine & in_target)
281 :SchedGraphCommon(), bb(in_bb),target(in_target)
Misha Brukman2c821cc2003-04-10 19:19:23 +0000282 {
Guochun Shif1c154f2003-03-27 17:57:44 +0000283 buildGraph(target);
284 }
285
Misha Brukman8baa01c2003-04-09 21:51:34 +0000286 ~ModuloSchedGraph() {
287 for (const_iterator I = begin(); I != end(); ++I)
Guochun Shif1c154f2003-03-27 17:57:44 +0000288 delete I->second;
289 }
Misha Brukman8baa01c2003-04-09 21:51:34 +0000290
Misha Brukman2c821cc2003-04-10 19:19:23 +0000291 // Unorder iterators
292 // return values are pair<const Instruction*, ModuloSchedGraphNode*>
Guochun Shif1c154f2003-03-27 17:57:44 +0000293 using map_base::begin;
294 using map_base::end;
295
Misha Brukman8baa01c2003-04-09 21:51:34 +0000296 void noteModuloSchedGraphNodeForInst(const Instruction *inst,
297 ModuloSchedGraphNode *node)
298 {
299 assert((*this)[inst] == NULL);
300 (*this)[inst] = node;
301 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000302
Misha Brukman63e04f32003-04-22 23:00:08 +0000303 // Graph builder
Misha Brukman8baa01c2003-04-09 21:51:34 +0000304 ModuloSchedGraphNode *getNode(const unsigned nodeId) const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000305
Misha Brukman63e04f32003-04-22 23:00:08 +0000306 // Build the graph from the basicBlock
307 void buildGraph(const TargetMachine &target);
Guochun Shif1c154f2003-03-27 17:57:44 +0000308
Misha Brukman63e04f32003-04-22 23:00:08 +0000309 // Build nodes for BasicBlock
Misha Brukman8baa01c2003-04-09 21:51:34 +0000310 void buildNodesforBB(const TargetMachine &target,
311 const BasicBlock *bb,
312 NodeVec &memNode,
313 RegToRefVecMap &regToRefVecMap,
314 ValueToDefVecMap &valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000315
316 //find definitiona and use information for all nodes
Misha Brukman8baa01c2003-04-09 21:51:34 +0000317 void findDefUseInfoAtInstr(const TargetMachine &target,
318 ModuloSchedGraphNode *node,
319 NodeVec &memNode,
320 RegToRefVecMap &regToRefVecMap,
321 ValueToDefVecMap &valueToDefVecMap);
Guochun Shif1c154f2003-03-27 17:57:44 +0000322
323 //add def-use edge
Misha Brukman8baa01c2003-04-09 21:51:34 +0000324 void addDefUseEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000325
326 //add control dependence edges
Misha Brukman8baa01c2003-04-09 21:51:34 +0000327 void addCDEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000328
329 //add memory dependence dges
Misha Brukman8baa01c2003-04-09 21:51:34 +0000330 void addMemEdges(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000331
332 //add dummy edges
333 void addDummyEdges();
334
335 //computer source restrictoin II
Misha Brukman8baa01c2003-04-09 21:51:34 +0000336 int computeResII(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000337
338 //computer recurrence II
Misha Brukman8baa01c2003-04-09 21:51:34 +0000339 int computeRecII(const BasicBlock *bb);
Guochun Shif1c154f2003-03-27 17:57:44 +0000340};
341
Misha Brukman8baa01c2003-04-09 21:51:34 +0000342//==================================-
343// Graph set
Guochun Shif1c154f2003-03-27 17:57:44 +0000344
Misha Brukman8baa01c2003-04-09 21:51:34 +0000345class ModuloSchedGraphSet : public std::vector<ModuloSchedGraph*> {
Guochun Shif1c154f2003-03-27 17:57:44 +0000346private:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000347 const Function *method;
348
Guochun Shif1c154f2003-03-27 17:57:44 +0000349public:
350 typedef std::vector<ModuloSchedGraph*> baseVector;
351 using baseVector::iterator;
352 using baseVector::const_iterator;
Misha Brukman8baa01c2003-04-09 21:51:34 +0000353
Guochun Shif1c154f2003-03-27 17:57:44 +0000354public:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000355 ModuloSchedGraphSet(const Function *function, const TargetMachine &target);
356 ~ModuloSchedGraphSet();
357
358 // Iterators
Guochun Shif1c154f2003-03-27 17:57:44 +0000359 using baseVector::begin;
360 using baseVector::end;
361
Misha Brukman2c821cc2003-04-10 19:19:23 +0000362 // Debugging support
363 void dump() const;
Guochun Shif1c154f2003-03-27 17:57:44 +0000364
Guochun Shif1c154f2003-03-27 17:57:44 +0000365private:
Misha Brukman8baa01c2003-04-09 21:51:34 +0000366 void addGraph(ModuloSchedGraph *graph) {
367 assert(graph != NULL);
Guochun Shif1c154f2003-03-27 17:57:44 +0000368 this->push_back(graph);
369 }
Guochun Shif1c154f2003-03-27 17:57:44 +0000370
Misha Brukman8baa01c2003-04-09 21:51:34 +0000371 // Graph builder
372 void buildGraphsForMethod(const Function *F,
373 const TargetMachine &target);
Misha Brukman2c821cc2003-04-10 19:19:23 +0000374};
Misha Brukman8baa01c2003-04-09 21:51:34 +0000375
376#endif