summaryrefslogtreecommitdiff
path: root/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h
blob: 2abd448fcdc1f109663d0fe60579ef361e80bad0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
//===- 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/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