blob: 4513b28a36c1a2c532f08dc203a1bfac479cfcdb [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"
Chris Lattnerd0f166a2002-12-29 03:13:05 +000018#include "llvm/Target/TargetSchedInfo.h"
Chris Lattner4a63b722002-10-28 02:11:53 +000019#include "Support/hash_set"
Chris Lattner3ff43872001-09-28 22:56:31 +000020#include <list>
Chris Lattner179cdfb2002-08-09 20:08:03 +000021
Chris Lattnere7506a32002-03-23 22:51:58 +000022class Function;
Vikram S. Adve37866b32001-08-28 23:06:49 +000023class MachineInstr;
24class SchedulingManager;
Chris Lattner483e14e2002-04-27 07:27:19 +000025class FunctionLiveVarInfo;
Vikram S. Adve37866b32001-08-28 23:06:49 +000026
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000027//---------------------------------------------------------------------------
Chris Lattner77f66c12002-02-04 02:44:20 +000028// Debug option levels for instruction scheduling
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000029
Chris Lattner77f66c12002-02-04 02:44:20 +000030enum SchedDebugLevel_t {
31 Sched_NoDebugInfo,
Vikram S. Adve7c7e46a2002-03-24 03:45:35 +000032 Sched_Disable,
Chris Lattner77f66c12002-02-04 02:44:20 +000033 Sched_PrintMachineCode,
34 Sched_PrintSchedTrace,
35 Sched_PrintSchedGraphs,
36};
37
Chris Lattner70e60cb2002-05-22 17:08:27 +000038extern SchedDebugLevel_t SchedDebugLevel;
Vikram S. Adve37866b32001-08-28 23:06:49 +000039
Chris Lattnerb99bd2b2002-02-04 05:55:42 +000040//---------------------------------------------------------------------------
41// Function: instrIsFeasible
42//
43// Purpose:
44// Used by the priority analysis to filter out instructions
45// that are not feasible to issue in the current cycle.
46// Should only be used during schedule construction..
47//---------------------------------------------------------------------------
48
49bool instrIsFeasible(const SchedulingManager &S, MachineOpCode opCode);
50
51
52
Vikram S. Adve37866b32001-08-28 23:06:49 +000053struct NodeDelayPair {
54 const SchedGraphNode* node;
55 cycles_t delay;
56 NodeDelayPair(const SchedGraphNode* n, cycles_t d) : node(n), delay(d) {}
Chris Lattner697954c2002-01-20 22:54:45 +000057 inline bool operator<(const NodeDelayPair& np) { return delay < np.delay; }
Vikram S. Adve37866b32001-08-28 23:06:49 +000058};
59
60inline bool
61NDPLessThan(const NodeDelayPair* np1, const NodeDelayPair* np2)
62{
Chris Lattner697954c2002-01-20 22:54:45 +000063 return np1->delay < np2->delay;
Vikram S. Adve37866b32001-08-28 23:06:49 +000064}
65
Chris Lattner9efc4d62003-06-02 22:45:07 +000066class NodeHeap : public std::list<NodeDelayPair*> {
67 NodeHeap(const NodeHeap&); // DO NOT IMPLEMENT
68 void operator=(const NodeHeap&); // DO NOT IMPLEMENT
Vikram S. Adve37866b32001-08-28 23:06:49 +000069public:
Chris Lattner697954c2002-01-20 22:54:45 +000070 typedef std::list<NodeDelayPair*>::iterator iterator;
71 typedef std::list<NodeDelayPair*>::const_iterator const_iterator;
Vikram S. Adve37866b32001-08-28 23:06:49 +000072
73public:
Chris Lattnerf35f2fb2002-02-04 16:35:45 +000074 NodeHeap() : _size(0) {}
Vikram S. Adve37866b32001-08-28 23:06:49 +000075
Chris Lattnerf35f2fb2002-02-04 16:35:45 +000076 inline unsigned size() const { return _size; }
Vikram S. Adve37866b32001-08-28 23:06:49 +000077
78 const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
79 cycles_t getDelay(const_iterator i) const { return (*i)->delay;}
80
81 inline void makeHeap() {
82 // make_heap(begin(), end(), NDPLessThan);
83 }
84
85 inline iterator findNode(const SchedGraphNode* node) {
86 for (iterator I=begin(); I != end(); ++I)
87 if (getNode(I) == node)
88 return I;
89 return end();
90 }
91
92 inline void removeNode (const SchedGraphNode* node) {
93 iterator ndpPtr = findNode(node);
94 if (ndpPtr != end())
95 {
96 delete *ndpPtr;
97 erase(ndpPtr);
98 --_size;
99 }
100 };
101
102 void insert(const SchedGraphNode* node, cycles_t delay) {
103 NodeDelayPair* ndp = new NodeDelayPair(node, delay);
104 if (_size == 0 || front()->delay < delay)
105 push_front(ndp);
106 else
107 {
108 iterator I=begin();
109 for ( ; I != end() && getDelay(I) >= delay; ++I)
110 ;
Chris Lattner697954c2002-01-20 22:54:45 +0000111 std::list<NodeDelayPair*>::insert(I, ndp);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000112 }
113 _size++;
114 }
115private:
116 unsigned int _size;
117};
118
119
Chris Lattner9efc4d62003-06-02 22:45:07 +0000120class SchedPriorities {
121 SchedPriorities(const SchedPriorities&); // DO NOT IMPLEMENT
122 void operator=(const SchedPriorities &); // DO NOT IMPLEMENT
Vikram S. Adve37866b32001-08-28 23:06:49 +0000123public:
Chris Lattnere7506a32002-03-23 22:51:58 +0000124 SchedPriorities(const Function *F, const SchedGraph *G,
Chris Lattner483e14e2002-04-27 07:27:19 +0000125 FunctionLiveVarInfo &LVI);
Chris Lattner9adb7ad2002-02-04 20:02:16 +0000126
Vikram S. Adve37866b32001-08-28 23:06:49 +0000127
128 // This must be called before scheduling begins.
129 void initialize ();
130
131 cycles_t getTime () const { return curTime; }
132 cycles_t getEarliestReadyTime () const { return earliestReadyTime; }
133 unsigned getNumReady () const { return candsAsHeap.size(); }
134 bool nodeIsReady (const SchedGraphNode* node) const {
135 return (candsAsSet.find(node) != candsAsSet.end());
136 }
137
138 void issuedReadyNodeAt (cycles_t curTime,
139 const SchedGraphNode* node);
140
141 void insertReady (const SchedGraphNode* node);
142
143 void updateTime (cycles_t /*unused*/);
144
145 const SchedGraphNode* getNextHighest (const SchedulingManager& S,
146 cycles_t curTime);
147 // choose next highest priority instr
148
149private:
150 typedef NodeHeap::iterator candIndex;
151
152private:
153 cycles_t curTime;
154 const SchedGraph* graph;
Chris Lattner483e14e2002-04-27 07:27:19 +0000155 FunctionLiveVarInfo &methodLiveVarInfo;
Chris Lattnercb6289a2002-07-24 21:21:33 +0000156 hash_map<const MachineInstr*, bool> lastUseMap;
Chris Lattner697954c2002-01-20 22:54:45 +0000157 std::vector<cycles_t> nodeDelayVec;
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000158 std::vector<cycles_t> nodeEarliestUseVec;
159 std::vector<cycles_t> earliestReadyTimeForNode;
Vikram S. Adve37866b32001-08-28 23:06:49 +0000160 cycles_t earliestReadyTime;
161 NodeHeap candsAsHeap; // candidate nodes, ready to go
Chris Lattnercb6289a2002-07-24 21:21:33 +0000162 hash_set<const SchedGraphNode*> candsAsSet; //same entries as candsAsHeap,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000163 // but as set for fast lookup
Chris Lattner697954c2002-01-20 22:54:45 +0000164 std::vector<candIndex> mcands; // holds pointers into cands
Vikram S. Adve37866b32001-08-28 23:06:49 +0000165 candIndex nextToTry; // next cand after the last
166 // one tried in this cycle
167
Chris Lattner697954c2002-01-20 22:54:45 +0000168 int chooseByRule1 (std::vector<candIndex>& mcands);
169 int chooseByRule2 (std::vector<candIndex>& mcands);
170 int chooseByRule3 (std::vector<candIndex>& mcands);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000171
Chris Lattner697954c2002-01-20 22:54:45 +0000172 void findSetWithMaxDelay (std::vector<candIndex>& mcands,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000173 const SchedulingManager& S);
174
175 void computeDelays (const SchedGraph* graph);
176
177 void initializeReadyHeap (const SchedGraph* graph);
178
Chris Lattner483e14e2002-04-27 07:27:19 +0000179 bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
Vikram S. Adve37866b32001-08-28 23:06:49 +0000180 const SchedGraphNode* graphNode);
181
182 // NOTE: The next two return references to the actual vector entries.
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000183 // Use the following two if you don't need to modify the value.
Vikram S. Adve37866b32001-08-28 23:06:49 +0000184 cycles_t& getNodeDelayRef (const SchedGraphNode* node) {
185 assert(node->getNodeId() < nodeDelayVec.size());
186 return nodeDelayVec[node->getNodeId()];
187 }
Vikram S. Adve0baf1c02002-07-08 22:59:23 +0000188 cycles_t& getEarliestReadyTimeForNodeRef (const SchedGraphNode* node) {
189 assert(node->getNodeId() < earliestReadyTimeForNode.size());
190 return earliestReadyTimeForNode[node->getNodeId()];
191 }
192
193 cycles_t getNodeDelay (const SchedGraphNode* node) const {
194 return ((SchedPriorities*) this)->getNodeDelayRef(node);
195 }
196 cycles_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
197 return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000198 }
199};
200
201
Chris Lattnerdcd2fb52001-09-07 21:18:16 +0000202inline void SchedPriorities::updateTime(cycles_t c) {
Vikram S. Adve37866b32001-08-28 23:06:49 +0000203 curTime = c;
204 nextToTry = candsAsHeap.begin();
205 mcands.clear();
206}
207
Chris Lattner5da2e6a2002-11-02 22:07:51 +0000208std::ostream &operator<<(std::ostream &os, const NodeDelayPair* nd);
Vikram S. Adve37866b32001-08-28 23:06:49 +0000209
Vikram S. Adve37866b32001-08-28 23:06:49 +0000210#endif