1 //===-- MSchedGraph.h - Scheduling Graph ------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // A graph class for dependencies. This graph only contains true, anti, and
11 // output data dependencies for a given MachineBasicBlock. Dependencies
12 // across iterations are also computed. Unless data dependence analysis
13 // is provided, a conservative approach of adding dependencies between all
14 // loads and stores is taken.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_MSCHEDGRAPH_H
18 #define LLVM_MSCHEDGRAPH_H
19 #include "DependenceAnalyzer.h"
20 #include "llvm/Analysis/AliasAnalysis.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Target/TargetData.h"
24 #include "llvm/ADT/GraphTraits.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/iterator"
32 class MSchedGraphNode;
33 template<class IteratorType, class NodeType>
34 class MSchedGraphNodeIterator;
36 //MSchedGraphEdge encapsulates the data dependence between nodes. It
37 //identifies the dependence type, on what, and the iteration
39 struct MSchedGraphEdge {
40 enum DataDepOrderType {
41 TrueDep, AntiDep, OutputDep, NonDataDep
44 enum MSchedGraphEdgeType {
45 MemoryDep, ValueDep, MachineRegister, BranchDep
48 //Get or set edge data
49 MSchedGraphNode *getDest() const { return dest; }
50 unsigned getIteDiff() { return iteDiff; }
51 unsigned getDepOrderType() { return depOrderType; }
52 void setDest(MSchedGraphNode *newDest) { dest = newDest; }
55 friend class MSchedGraphNode;
56 MSchedGraphEdge(MSchedGraphNode *destination, MSchedGraphEdgeType type,
57 unsigned deptype, unsigned diff)
58 : dest(destination), depType(type), depOrderType(deptype), iteDiff(diff) {}
60 MSchedGraphNode *dest;
61 MSchedGraphEdgeType depType;
62 unsigned depOrderType;
66 //MSchedGraphNode represents a machine instruction and its
67 //corresponding latency. Each node also contains a list of its
68 //predecessors and sucessors.
69 class MSchedGraphNode {
71 const MachineInstr* Inst; //Machine Instruction
72 MSchedGraph* Parent; //Graph this node belongs to
73 unsigned index; //Index in BB
74 unsigned latency; //Latency of Instruction
75 bool isBranchInstr; //Is this node the branch instr or not
77 std::vector<MSchedGraphNode*> Predecessors; //Predecessor Nodes
78 std::vector<MSchedGraphEdge> Successors; //Successor edges
81 MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph,
82 unsigned index, unsigned late=0, bool isBranch=false);
84 MSchedGraphNode(const MSchedGraphNode &N);
86 //Iterators - Predecessor and Succussor
87 typedef std::vector<MSchedGraphNode*>::iterator pred_iterator;
88 pred_iterator pred_begin() { return Predecessors.begin(); }
89 pred_iterator pred_end() { return Predecessors.end(); }
90 unsigned pred_size() { return Predecessors.size(); }
92 typedef std::vector<MSchedGraphNode*>::const_iterator pred_const_iterator;
93 pred_const_iterator pred_begin() const { return Predecessors.begin(); }
94 pred_const_iterator pred_end() const { return Predecessors.end(); }
96 typedef MSchedGraphNodeIterator<std::vector<MSchedGraphEdge>::const_iterator,
97 const MSchedGraphNode> succ_const_iterator;
98 succ_const_iterator succ_begin() const;
99 succ_const_iterator succ_end() const;
101 typedef MSchedGraphNodeIterator<std::vector<MSchedGraphEdge>::iterator,
102 MSchedGraphNode> succ_iterator;
103 succ_iterator succ_begin();
104 succ_iterator succ_end();
105 unsigned succ_size() { return Successors.size(); }
107 //Get or set predecessor nodes, or successor edges
108 void setPredecessor(unsigned index, MSchedGraphNode *dest) {
109 Predecessors[index] = dest;
112 MSchedGraphNode* getPredecessor(unsigned index) {
113 return Predecessors[index];
116 MSchedGraphEdge* getSuccessor(unsigned index) {
117 return &Successors[index];
120 void deleteSuccessor(MSchedGraphNode *node) {
121 for (unsigned i = 0; i != Successors.size(); ++i)
122 if (Successors[i].getDest() == node) {
123 Successors.erase(Successors.begin()+i);
124 node->Predecessors.erase(std::find(node->Predecessors.begin(),
125 node->Predecessors.end(), this));
126 --i; //Decrease index var since we deleted a node
130 void addOutEdge(MSchedGraphNode *destination,
131 MSchedGraphEdge::MSchedGraphEdgeType type,
132 unsigned deptype, unsigned diff=0) {
133 Successors.push_back(MSchedGraphEdge(destination, type, deptype,diff));
134 destination->Predecessors.push_back(this);
137 //General methods to get and set data for the node
138 const MachineInstr* getInst() { return Inst; }
139 MSchedGraph* getParent() { return Parent; }
140 bool hasPredecessors() { return (Predecessors.size() > 0); }
141 bool hasSuccessors() { return (Successors.size() > 0); }
142 unsigned getLatency() { return latency; }
143 unsigned getLatency() const { return latency; }
144 unsigned getIndex() { return index; }
145 unsigned getIteDiff(MSchedGraphNode *succ);
146 MSchedGraphEdge getInEdge(MSchedGraphNode *pred);
147 unsigned getInEdgeNum(MSchedGraphNode *pred);
148 bool isSuccessor(MSchedGraphNode *);
149 bool isPredecessor(MSchedGraphNode *);
150 bool isBranch() { return isBranchInstr; }
153 void print(std::ostream &os) const;
154 void setParent(MSchedGraph *p) { Parent = p; }
157 //Node iterator for graph generation
158 template<class IteratorType, class NodeType>
159 class MSchedGraphNodeIterator : public forward_iterator<NodeType*, ptrdiff_t> {
160 IteratorType I; // std::vector<MSchedGraphEdge>::iterator or const_iterator
162 MSchedGraphNodeIterator(IteratorType i) : I(i) {}
164 bool operator==(const MSchedGraphNodeIterator RHS) const { return I == RHS.I; }
165 bool operator!=(const MSchedGraphNodeIterator RHS) const { return I != RHS.I; }
167 const MSchedGraphNodeIterator &operator=(const MSchedGraphNodeIterator &RHS) {
172 NodeType* operator*() const {
175 NodeType* operator->() const { return operator*(); }
177 MSchedGraphNodeIterator& operator++() { // Preincrement
181 MSchedGraphNodeIterator operator++(int) { // Postincrement
182 MSchedGraphNodeIterator tmp = *this; ++*this; return tmp;
185 MSchedGraphEdge &getEdge() {
188 const MSchedGraphEdge &getEdge() const {
193 inline MSchedGraphNode::succ_const_iterator MSchedGraphNode::succ_begin() const {
194 return succ_const_iterator(Successors.begin());
196 inline MSchedGraphNode::succ_const_iterator MSchedGraphNode::succ_end() const {
197 return succ_const_iterator(Successors.end());
199 inline MSchedGraphNode::succ_iterator MSchedGraphNode::succ_begin() {
200 return succ_iterator(Successors.begin());
202 inline MSchedGraphNode::succ_iterator MSchedGraphNode::succ_end() {
203 return succ_iterator(Successors.end());
206 // ostream << operator for MSGraphNode class
207 inline std::ostream &operator<<(std::ostream &os,
208 const MSchedGraphNode &node) {
214 // Provide specializations of GraphTraits to be able to use graph
215 // iterators on the scheduling graph!
217 template <> struct GraphTraits<MSchedGraphNode*> {
218 typedef MSchedGraphNode NodeType;
219 typedef MSchedGraphNode::succ_iterator ChildIteratorType;
221 static inline ChildIteratorType child_begin(NodeType *N) {
222 return N->succ_begin();
224 static inline ChildIteratorType child_end(NodeType *N) {
225 return N->succ_end();
228 static NodeType *getEntryNode(NodeType* N) { return N; }
233 //Graph class to represent dependence graph
236 std::vector<const MachineBasicBlock *> BBs; //Machine basic block
237 const TargetMachine &Target; //Target Machine
240 std::map<const MachineInstr*, MSchedGraphNode*> GraphMap;
242 //Add Nodes and Edges to this graph for our BB
243 typedef std::pair<int, MSchedGraphNode*> OpIndexNodePair;
244 void buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs, DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
245 void addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
246 MSchedGraphNode *node,
247 bool nodeIsUse, bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff=0);
248 void addMachRegEdges(std::map<int,
249 std::vector<OpIndexNodePair> >& regNumtoNodeMap);
250 void addMemEdges(const std::vector<MSchedGraphNode*>& memInst,
251 DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
252 void addBranchEdges();
255 MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ,
256 std::map<const MachineInstr*, unsigned> &ignoreInstrs,
257 DependenceAnalyzer &DA, std::map<MachineInstr*, Instruction*> &machineTollvm);
259 //Copy constructor with maps to link old nodes to new nodes
260 MSchedGraph(const MSchedGraph &G, std::map<MSchedGraphNode*, MSchedGraphNode*> &newNodes);
262 MSchedGraph(std::vector<const MachineBasicBlock*> &bbs,
263 const TargetMachine &targ,
264 std::map<const MachineInstr*, unsigned> &ignoreInstrs,
265 DependenceAnalyzer &DA,
266 std::map<MachineInstr*, Instruction*> &machineTollvm);
269 void print(std::ostream &os) const;
274 //Add or delete nodes from the Graph
275 void addNode(const MachineInstr* MI, MSchedGraphNode *node);
276 void deleteNode(MSchedGraphNode *node);
280 typedef std::map<const MachineInstr*, MSchedGraphNode*>::iterator iterator;
281 typedef std::map<const MachineInstr*, MSchedGraphNode*>::const_iterator const_iterator;
282 typedef std::map<const MachineInstr*, MSchedGraphNode*>::reverse_iterator reverse_iterator;
283 iterator find(const MachineInstr* I) { return GraphMap.find(I); }
284 iterator end() { return GraphMap.end(); }
285 iterator begin() { return GraphMap.begin(); }
286 unsigned size() { return GraphMap.size(); }
287 reverse_iterator rbegin() { return GraphMap.rbegin(); }
288 reverse_iterator rend() { return GraphMap.rend(); }
290 //Get Target or original machine basic block
291 const TargetMachine* getTarget() { return &Target; }
292 std::vector<const MachineBasicBlock*> getBBs() { return BBs; }
299 // Provide specializations of GraphTraits to be able to use graph
300 // iterators on the scheduling graph
301 static MSchedGraphNode& getSecond(std::pair<const MachineInstr* const,
302 MSchedGraphNode*> &Pair) {
306 template <> struct GraphTraits<MSchedGraph*> {
307 typedef MSchedGraphNode NodeType;
308 typedef MSchedGraphNode::succ_iterator ChildIteratorType;
310 static inline ChildIteratorType child_begin(NodeType *N) {
311 return N->succ_begin();
313 static inline ChildIteratorType child_end(NodeType *N) {
314 return N->succ_end();
317 typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
318 MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
320 typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
321 static nodes_iterator nodes_begin(MSchedGraph *G) {
322 return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
324 static nodes_iterator nodes_end(MSchedGraph *G) {
325 return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
330 template <> struct GraphTraits<const MSchedGraph*> {
331 typedef const MSchedGraphNode NodeType;
332 typedef MSchedGraphNode::succ_const_iterator ChildIteratorType;
334 static inline ChildIteratorType child_begin(NodeType *N) {
335 return N->succ_begin();
337 static inline ChildIteratorType child_end(NodeType *N) {
338 return N->succ_end();
340 typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
341 MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
343 typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
344 static nodes_iterator nodes_begin(MSchedGraph *G) {
345 return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
347 static nodes_iterator nodes_end(MSchedGraph *G) {
348 return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
352 template <> struct GraphTraits<Inverse<MSchedGraph*> > {
353 typedef MSchedGraphNode NodeType;
354 typedef MSchedGraphNode::pred_iterator ChildIteratorType;
356 static inline ChildIteratorType child_begin(NodeType *N) {
357 return N->pred_begin();
359 static inline ChildIteratorType child_end(NodeType *N) {
360 return N->pred_end();
362 typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
363 MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
365 typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
366 static nodes_iterator nodes_begin(MSchedGraph *G) {
367 return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
369 static nodes_iterator nodes_end(MSchedGraph *G) {
370 return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
374 template <> struct GraphTraits<Inverse<const MSchedGraph*> > {
375 typedef const MSchedGraphNode NodeType;
376 typedef MSchedGraphNode::pred_const_iterator ChildIteratorType;
378 static inline ChildIteratorType child_begin(NodeType *N) {
379 return N->pred_begin();
381 static inline ChildIteratorType child_end(NodeType *N) {
382 return N->pred_end();
385 typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
386 MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
388 typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
389 static nodes_iterator nodes_begin(MSchedGraph *G) {
390 return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
392 static nodes_iterator nodes_end(MSchedGraph *G) {
393 return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));