blob: 7cfcb038399d847f273994e410d396cf8c870681 [file] [log] [blame]
Chris Lattner179cdfb2002-08-09 20:08:03 +00001//===-- SchedPriorities.h - Encapsulate scheduling heuristics --*- C++ -*--===//
Vikram S. Adve851d44c2001-09-18 12:49:39 +00002//
3// Strategy:
4// Priority ordering rules:
5// (1) Max delay, which is the order of the heap S.candsAsHeap.
6// (2) Instruction that frees up a register.
7// (3) Instruction that has the maximum number of dependent instructions.
8// Note that rules 2 and 3 are only used if issue conflicts prevent
9// choosing a higher priority instruction by rule 1.
Chris Lattner179cdfb2002-08-09 20:08:03 +000010//
11//===----------------------------------------------------------------------===//
Vikram S. Adve37866b32001-08-28 23:06:49 +000012
13#ifndef LLVM_CODEGEN_SCHEDPRIORITIES_H
14#define LLVM_CODEGEN_SCHEDPRIORITIES_H
15
Chris Lattner46cbff62001-09-14 16:56:32 +000016#include "SchedGraph.h"
Chris Lattnerdcd2fb52001-09-07 21:18:16 +000017#include "llvm/CodeGen/InstrScheduling.h"
Vikram S. Adve851d44c2001-09-18 12:49:39 +000018#include "llvm/Target/MachineSchedInfo.h"
Chris Lattner4a63b722002-10-28 02:11:53 +000019#include "Support/hash_set"
Chris Lattner3ff43872001-09-28 22:56:31 +000020#include <list>
Chris Lattnerec3e2f42002-11-01 16:46:05 +000021#include <iosfwd>
Chris Lattner179cdfb2002-08-09 20:08:03 +000022
Chris Lattnere7506a32002-03-23 22:51:58 +000023class Function;
Vikram S. Adve37866b32001-08-28 23:06:49 +000024class MachineInstr;
25class SchedulingManager;
Chris Lattner483e14e2002-04-27 07:27:19 +000026class FunctionLiveVarInfo;
Vikram S. Adve37866b32001-08-28 23:06:49 +000027
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000028//---------------------------------------------------------------------------
Chris Lattner77f66c12002-02-04 02:44:20 +000029// Debug option levels for instruction scheduling
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000030
Chris Lattner77f66c12002-02-04 02:44:20 +000031enum SchedDebugLevel_t {
32 Sched_NoDebugInfo,
Vikram S. Adve7c7e46a2002-03-24 03:45:35 +000033 Sched_Disable,
Chris Lattner77f66c12002-02-04 02:44:20 +000034 Sched_PrintMachineCode,
35 Sched_PrintSchedTrace,
36 Sched_PrintSchedGraphs,
37};
38
Chris Lattner70e60cb2002-05-22 17:08:27 +000039extern SchedDebugLevel_t SchedDebugLevel;
Vikram S. Adve37866b32001-08-28 23:06:49 +000040
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000041//---------------------------------------------------------------------------
42// Function: instrIsFeasible
43//
44// Purpose:
45// Used by the priority analysis to filter out instructions
46// that are not feasible to issue in the current cycle.
47// Should only be used during schedule construction..
48//---------------------------------------------------------------------------
49
50bool instrIsFeasible(const SchedulingManager &S, MachineOpCode opCode);
51
52
53
Vikram S. Adve37866b32001-08-28 23:06:49 +000054struct NodeDelayPair {
55 const SchedGraphNode* node;
56 cycles_t delay;
57 NodeDelayPair(const SchedGraphNode* n, cycles_t d) : node(n), delay(d) {}
Chris Lattner697954c2002-01-20 22:54:45 +000058 inline bool operator<(const NodeDelayPair& np) { return delay < np.delay; }
Vikram S. Adve37866b32001-08-28 23:06:49 +000059};
60
61inline bool
62NDPLessThan(const NodeDelayPair* np1, const NodeDelayPair* np2)
63{
Chris Lattner697954c2002-01-20 22:54:45 +000064 return np1->delay < np2->delay;
Vikram S. Adve37866b32001-08-28 23:06:49 +000065}
66
Chris Lattner697954c2002-01-20 22:54:45 +000067class NodeHeap: public std::list<NodeDelayPair*>, public NonCopyable {
Vikram S. Adve37866b32001-08-28 23:06:49 +000068public:
Chris Lattner697954c2002-01-20 22:54:45 +000069 typedef std::list<NodeDelayPair*>::iterator iterator;
70 typedef std::list<NodeDelayPair*>::const_iterator const_iterator;
Vikram S. Adve37866b32001-08-28 23:06:49 +000071
72public:
Chris Lattnerf35f2fb2002-02-04 16:35:45 +000073 NodeHeap() : _size(0) {}
Vikram S. Adve37866b32001-08-28 23:06:49 +000074
Chris Lattnerf35f2fb2002-02-04 16:35:45 +000075 inline unsigned size() const { return _size; }
Vikram S. Adve37866b32001-08-28 23:06:49 +000076
77 const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
78 cycles_t getDelay(const_iterator i) const { return (*i)->delay;}
79
80 inline void makeHeap() {
81 // make_heap(begin(), end(), NDPLessThan);
82 }
83
84 inline iterator findNode(const SchedGraphNode* node) {
85 for (iterator I=begin(); I != end(); ++I)
86 if (getNode(I) == node)
87 return I;
88 return end();
89 }
90
91 inline void removeNode (const SchedGraphNode* node) {
92 iterator ndpPtr = findNode(node);
93 if (ndpPtr != end())
94 {
95 delete *ndpPtr;
96 erase(ndpPtr);
97 --_size;
98 }
99 };
100
101 void insert(const SchedGraphNode* node, cycles_t delay) {
102 NodeDelayPair* ndp = new NodeDelayPair(node, delay);
103 if (_size == 0 || front()->delay < delay)
104 push_front(ndp);
105 else
106 {
107 iterator I=begin();
108 for ( ; I != end() && getDelay(I) >= delay; ++I)
109 ;
Chris Lattner697954c2002-01-20 22:54:45 +0000110 std::list<NodeDelayPair*>::insert(I, ndp);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000111 }
112 _size++;
113 }
114private:
115 unsigned int _size;
116};
117
118
119class SchedPriorities: public NonCopyable {
120public:
Chris Lattnere7506a32002-03-23 22:51:58 +0000121 SchedPriorities(const Function *F, const SchedGraph *G,
Chris Lattner483e14e2002-04-27 07:27:19 +0000122 FunctionLiveVarInfo &LVI);
Chris Lattner9adb7ad2002-02-04 20:02:16 +0000123
Vikram S. Adve37866b32001-08-28 23:06:49 +0000124
125 // This must be called before scheduling begins.
126 void initialize ();
127
128 cycles_t getTime () const { return curTime; }
129 cycles_t getEarliestReadyTime () const { return earliestReadyTime; }
130 unsigned getNumReady () const { return candsAsHeap.size(); }
131 bool nodeIsReady (const SchedGraphNode* node) const {
132 return (candsAsSet.find(node) != candsAsSet.end());
133 }
134
135 void issuedReadyNodeAt (cycles_t curTime,
136 const SchedGraphNode* node);
137
138 void insertReady (const SchedGraphNode* node);
139
140 void updateTime (cycles_t /*unused*/);
141
142 const SchedGraphNode* getNextHighest (const SchedulingManager& S,
143 cycles_t curTime);
144 // choose next highest priority instr
145
146private:
147 typedef NodeHeap::iterator candIndex;
148
149private:
150 cycles_t curTime;
151 const SchedGraph* graph;
Chris Lattner483e14e2002-04-27 07:27:19 +0000152 FunctionLiveVarInfo &methodLiveVarInfo;
Chris Lattnercb6289a2002-07-24 21:21:33 +0000153 hash_map<const MachineInstr*, bool> lastUseMap;
Chris Lattner697954c2002-01-20 22:54:45 +0000154 std::vector<cycles_t> nodeDelayVec;
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000155 std::vector<cycles_t> nodeEarliestUseVec;
156 std::vector<cycles_t> earliestReadyTimeForNode;
Vikram S. Adve37866b32001-08-28 23:06:49 +0000157 cycles_t earliestReadyTime;
158 NodeHeap candsAsHeap; // candidate nodes, ready to go
Chris Lattnercb6289a2002-07-24 21:21:33 +0000159 hash_set<const SchedGraphNode*> candsAsSet; //same entries as candsAsHeap,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000160 // but as set for fast lookup
Chris Lattner697954c2002-01-20 22:54:45 +0000161 std::vector<candIndex> mcands; // holds pointers into cands
Vikram S. Adve37866b32001-08-28 23:06:49 +0000162 candIndex nextToTry; // next cand after the last
163 // one tried in this cycle
164
Chris Lattner697954c2002-01-20 22:54:45 +0000165 int chooseByRule1 (std::vector<candIndex>& mcands);
166 int chooseByRule2 (std::vector<candIndex>& mcands);
167 int chooseByRule3 (std::vector<candIndex>& mcands);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000168
Chris Lattner697954c2002-01-20 22:54:45 +0000169 void findSetWithMaxDelay (std::vector<candIndex>& mcands,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000170 const SchedulingManager& S);
171
172 void computeDelays (const SchedGraph* graph);
173
174 void initializeReadyHeap (const SchedGraph* graph);
175
Chris Lattner483e14e2002-04-27 07:27:19 +0000176 bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000177 const SchedGraphNode* graphNode);
178
179 // NOTE: The next two return references to the actual vector entries.
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000180 // Use the following two if you don't need to modify the value.
Vikram S. Adve37866b32001-08-28 23:06:49 +0000181 cycles_t& getNodeDelayRef (const SchedGraphNode* node) {
182 assert(node->getNodeId() < nodeDelayVec.size());
183 return nodeDelayVec[node->getNodeId()];
184 }
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000185 cycles_t& getEarliestReadyTimeForNodeRef (const SchedGraphNode* node) {
186 assert(node->getNodeId() < earliestReadyTimeForNode.size());
187 return earliestReadyTimeForNode[node->getNodeId()];
188 }
189
190 cycles_t getNodeDelay (const SchedGraphNode* node) const {
191 return ((SchedPriorities*) this)->getNodeDelayRef(node);
192 }
193 cycles_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
194 return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000195 }
196};
197
198
Chris Lattnerdcd2fb52001-09-07 21:18:16 +0000199inline void SchedPriorities::updateTime(cycles_t c) {
Vikram S. Adve37866b32001-08-28 23:06:49 +0000200 curTime = c;
201 nextToTry = candsAsHeap.begin();
202 mcands.clear();
203}
204
Chris Lattner697954c2002-01-20 22:54:45 +0000205inline std::ostream &operator<<(std::ostream &os, const NodeDelayPair* nd) {
Chris Lattnerdcd2fb52001-09-07 21:18:16 +0000206 return os << "Delay for node " << nd->node->getNodeId()
Chris Lattner697954c2002-01-20 22:54:45 +0000207 << " = " << (long)nd->delay << "\n";
Vikram S. Adve37866b32001-08-28 23:06:49 +0000208}
209
Vikram S. Adve37866b32001-08-28 23:06:49 +0000210#endif