1 //===-- SchedGraph.h - Scheduling Graph -------------------------*- C++ -*-===//
3 // This is a scheduling graph based on SSA graph plus extra dependence edges
4 // capturing dependences due to machine resources (machine registers, CC
5 // registers, and any others).
7 // This graph tries to leverage the SSA graph as much as possible, but captures
8 // the extra dependences through a common interface.
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_CODEGEN_SCHEDGRAPH_H
13 #define LLVM_CODEGEN_SCHEDGRAPH_H
15 #include "llvm/CodeGen/SchedGraphCommon.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/Transforms/Scalar.h"
18 #include "Support/hash_map"
19 #include "Support/GraphTraits.h"
22 class ValueToDefVecMap;
25 class SchedGraphNode : public SchedGraphNodeCommon {
27 MachineBasicBlock *MBB;
28 const MachineInstr *MI;
31 SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
32 const TargetMachine& Target);
35 friend class SchedGraph; // give access for ctor and dtor
36 friend class SchedGraphEdge; // give access for adding edges
41 const MachineInstr* getMachineInstr() const { return MI; }
42 const MachineOpCode getOpCode() const { return MI->getOpCode(); }
43 bool isDummyNode() const { return (MI == NULL); }
44 MachineBasicBlock &getMachineBasicBlock() const { return *MBB; }
46 void print(std::ostream &os) const;
49 class SchedGraph : public SchedGraphCommon {
50 MachineBasicBlock &MBB;
51 hash_map<const MachineInstr*, SchedGraphNode*> GraphMap;
54 typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator iterator;
55 typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator const_iterator;
57 MachineBasicBlock& getBasicBlock() const{return MBB;}
58 const unsigned int getNumNodes() const { return GraphMap.size()+2; }
59 SchedGraphNode* getGraphNodeForInstr(const MachineInstr* MI) const {
60 const_iterator onePair = find(MI);
61 return (onePair != end())? onePair->second : NULL;
68 SchedGraph(MachineBasicBlock& mbb, const TargetMachine& TM);
71 // Unordered iterators.
72 // Return values is pair<const MachineIntr*,SchedGraphNode*>.
74 hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator begin() const {
75 return GraphMap.begin();
77 hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator end() const {
78 return GraphMap.end();
81 unsigned size() { return GraphMap.size(); }
82 iterator find(const MachineInstr *MI) const { return GraphMap.find(MI); }
84 SchedGraphNode *&operator[](const MachineInstr *MI) {
89 friend class SchedGraphSet; // give access to ctor
91 inline void noteGraphNodeForInstr (const MachineInstr* minstr,
92 SchedGraphNode* node) {
93 assert((*this)[minstr] == NULL);
94 (*this)[minstr] = node;
100 void buildGraph(const TargetMachine& target);
102 void buildNodesForBB(const TargetMachine& target,MachineBasicBlock &MBB,
103 std::vector<SchedGraphNode*>& memNV,
104 std::vector<SchedGraphNode*>& callNV,
105 RegToRefVecMap& regToRefVecMap,
106 ValueToDefVecMap& valueToDefVecMap);
109 void findDefUseInfoAtInstr(const TargetMachine& target, SchedGraphNode* node,
110 std::vector<SchedGraphNode*>& memNV,
111 std::vector<SchedGraphNode*>& callNV,
112 RegToRefVecMap& regToRefVecMap,
113 ValueToDefVecMap& valueToDefVecMap);
115 void addEdgesForInstruction(const MachineInstr& minstr,
116 const ValueToDefVecMap& valueToDefVecMap,
117 const TargetMachine& target);
119 void addCDEdges(const TerminatorInst* term, const TargetMachine& target);
121 void addMemEdges(const std::vector<SchedGraphNode*>& memNod,
122 const TargetMachine& target);
124 void addCallCCEdges(const std::vector<SchedGraphNode*>& memNod,
125 MachineBasicBlock& bbMvec,
126 const TargetMachine& target);
128 void addCallDepEdges(const std::vector<SchedGraphNode*>& callNV,
129 const TargetMachine& target);
131 void addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
132 const TargetMachine& target);
134 void addEdgesForValue(SchedGraphNode* refNode, const RefVec& defVec,
135 const Value* defValue, bool refNodeIsDef,
136 bool refNodeIsDefAndUse,
137 const TargetMachine& target);
139 void addDummyEdges();
145 class SchedGraphSet {
146 const Function* function;
147 std::vector<SchedGraph*> Graphs;
150 void buildGraphsForMethod(const Function *F, const TargetMachine& target);
152 inline void addGraph(SchedGraph* graph) {
153 assert(graph != NULL);
154 Graphs.push_back(graph);
158 SchedGraphSet(const Function *function, const TargetMachine& target);
162 typedef std::vector<SchedGraph*>::const_iterator iterator;
163 typedef std::vector<SchedGraph*>::const_iterator const_iterator;
165 std::vector<SchedGraph*>::const_iterator begin() const { return Graphs.begin(); }
166 std::vector<SchedGraph*>::const_iterator end() const { return Graphs.end(); }
174 //********************** Sched Graph Iterators *****************************/
176 // Ok to make it a template because it shd get instantiated at most twice:
177 // for <SchedGraphNode, SchedGraphNode::iterator> and
178 // for <const SchedGraphNode, SchedGraphNode::const_iterator>.
180 template <class _NodeType, class _EdgeType, class _EdgeIter>
181 class SGPredIterator: public bidirectional_iterator<_NodeType, ptrdiff_t> {
185 typedef SGPredIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
187 inline SGPredIterator(_EdgeIter startEdge) : oi(startEdge) {}
189 inline bool operator==(const _Self& x) const { return oi == x.oi; }
190 inline bool operator!=(const _Self& x) const { return !operator==(x); }
192 // operator*() differs for pred or succ iterator
193 inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSrc(); }
194 inline _NodeType* operator->() const { return operator*(); }
196 inline _EdgeType* getEdge() const { return *(oi); }
198 inline _Self &operator++() { ++oi; return *this; } // Preincrement
199 inline _Self operator++(int) { // Postincrement
200 _Self tmp(*this); ++*this; return tmp;
203 inline _Self &operator--() { --oi; return *this; } // Predecrement
204 inline _Self operator--(int) { // Postdecrement
205 _Self tmp = *this; --*this; return tmp;
209 template <class _NodeType, class _EdgeType, class _EdgeIter>
210 class SGSuccIterator : public bidirectional_iterator<_NodeType, ptrdiff_t> {
214 typedef SGSuccIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
216 inline SGSuccIterator(_EdgeIter startEdge) : oi(startEdge) {}
218 inline bool operator==(const _Self& x) const { return oi == x.oi; }
219 inline bool operator!=(const _Self& x) const { return !operator==(x); }
221 inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSink(); }
222 inline _NodeType* operator->() const { return operator*(); }
224 inline _EdgeType* getEdge() const { return *(oi); }
226 inline _Self &operator++() { ++oi; return *this; } // Preincrement
227 inline _Self operator++(int) { // Postincrement
228 _Self tmp(*this); ++*this; return tmp;
231 inline _Self &operator--() { --oi; return *this; } // Predecrement
232 inline _Self operator--(int) { // Postdecrement
233 _Self tmp = *this; --*this; return tmp;
239 // sg_pred_const_iterator
241 typedef SGPredIterator<SchedGraphNode, SchedGraphEdge, SchedGraphNode::iterator>
243 typedef SGPredIterator<const SchedGraphNode, const SchedGraphEdge,SchedGraphNode::const_iterator>
244 sg_pred_const_iterator;
246 inline sg_pred_iterator pred_begin(SchedGraphNode *N) {
247 return sg_pred_iterator(N->beginInEdges());
249 inline sg_pred_iterator pred_end(SchedGraphNode *N) {
250 return sg_pred_iterator(N->endInEdges());
252 inline sg_pred_const_iterator pred_begin(const SchedGraphNode *N) {
253 return sg_pred_const_iterator(N->beginInEdges());
255 inline sg_pred_const_iterator pred_end(const SchedGraphNode *N) {
256 return sg_pred_const_iterator(N->endInEdges());
262 // sg_succ_const_iterator
264 typedef SGSuccIterator<SchedGraphNode, SchedGraphEdge, SchedGraphNode::iterator>
266 typedef SGSuccIterator<const SchedGraphNode, const SchedGraphEdge,SchedGraphNode::const_iterator>
267 sg_succ_const_iterator;
269 inline sg_succ_iterator succ_begin(SchedGraphNode *N) {
270 return sg_succ_iterator(N->beginOutEdges());
272 inline sg_succ_iterator succ_end(SchedGraphNode *N) {
273 return sg_succ_iterator(N->endOutEdges());
275 inline sg_succ_const_iterator succ_begin(const SchedGraphNode *N) {
276 return sg_succ_const_iterator(N->beginOutEdges());
278 inline sg_succ_const_iterator succ_end(const SchedGraphNode *N) {
279 return sg_succ_const_iterator(N->endOutEdges());
282 // Provide specializations of GraphTraits to be able to use graph iterators on
283 // the scheduling graph!
285 template <> struct GraphTraits<SchedGraph*> {
286 typedef SchedGraphNode NodeType;
287 typedef sg_succ_iterator ChildIteratorType;
289 static inline NodeType *getEntryNode(SchedGraph *SG) { return (NodeType*)SG->getRoot(); }
290 static inline ChildIteratorType child_begin(NodeType *N) {
291 return succ_begin(N);
293 static inline ChildIteratorType child_end(NodeType *N) {
298 template <> struct GraphTraits<const SchedGraph*> {
299 typedef const SchedGraphNode NodeType;
300 typedef sg_succ_const_iterator ChildIteratorType;
302 static inline NodeType *getEntryNode(const SchedGraph *SG) {
303 return (NodeType*)SG->getRoot();
305 static inline ChildIteratorType child_begin(NodeType *N) {
306 return succ_begin(N);
308 static inline ChildIteratorType child_end(NodeType *N) {