blob: 5855f0a3cbbc23892c00e8f68fc76130d2bd40b8 [file] [log] [blame]
Tanya Lattner642685a2004-05-26 06:27:36 +00001//===-- MSSchedule.cpp Schedule ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
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.
7//
8//===----------------------------------------------------------------------===//
9//
10//
11//
12//===----------------------------------------------------------------------===//
13#define DEBUG_TYPE "ModuloSched"
14
15#include "MSSchedule.h"
Reid Spencer7c16caa2004-09-01 22:55:40 +000016#include "llvm/Support/Debug.h"
Tanya Lattner642685a2004-05-26 06:27:36 +000017#include "llvm/Target/TargetSchedInfo.h"
Misha Brukman9da1134b2004-10-10 23:34:50 +000018#include "../SparcV9Internals.h"
Tanya Lattner642685a2004-05-26 06:27:36 +000019
20using namespace llvm;
21
Tanya Lattnera31ad512005-02-23 02:01:42 +000022//Returns a boolean indicating if the start cycle needs to be increased/decreased
Tanya Lattner642685a2004-05-26 06:27:36 +000023bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
24
25 //First, check if the cycle has a spot free to start
26 if(schedule.find(cycle) != schedule.end()) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000027 //Check if we have a free issue slot at this cycle
Tanya Lattner642685a2004-05-26 06:27:36 +000028 if (schedule[cycle].size() < numIssue) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000029 //Now check if all the resources in their respective cycles are available
Tanya Lattner642685a2004-05-26 06:27:36 +000030 if(resourcesFree(node, cycle)) {
Tanya Lattner341828e2004-11-28 23:36:15 +000031 //Insert to preserve dependencies
32 addToSchedule(cycle,node);
Tanya Lattner642685a2004-05-26 06:27:36 +000033 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
34 return false;
35 }
36 }
37 }
38 //Not in the map yet so put it in
39 else {
40 if(resourcesFree(node,cycle)) {
41 std::vector<MSchedGraphNode*> nodes;
42 nodes.push_back(node);
43 schedule[cycle] = nodes;
44 DEBUG(std::cerr << "Nothing in map yet so taking an issue slot\n");
45 return false;
46 }
47 }
48
49 DEBUG(std::cerr << "All issue slots taken\n");
50 return true;
Tanya Lattner13c71ca2004-11-24 01:49:10 +000051
Tanya Lattner642685a2004-05-26 06:27:36 +000052}
53
Tanya Lattner341828e2004-11-28 23:36:15 +000054void MSSchedule::addToSchedule(int cycle, MSchedGraphNode *node) {
55 std::vector<MSchedGraphNode*> nodesAtCycle = schedule[cycle];
56
57 std::map<unsigned, MSchedGraphNode*> indexMap;
58 for(unsigned i=0; i < nodesAtCycle.size(); ++i) {
59 indexMap[nodesAtCycle[i]->getIndex()] = nodesAtCycle[i];
60 }
61
62 indexMap[node->getIndex()] = node;
63
64 std::vector<MSchedGraphNode*> nodes;
65 for(std::map<unsigned, MSchedGraphNode*>::iterator I = indexMap.begin(), E = indexMap.end(); I != E; ++I)
66 nodes.push_back(I->second);
67
68 schedule[cycle] = nodes;
69}
70
71
Tanya Lattner642685a2004-05-26 06:27:36 +000072bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000073
Tanya Lattner642685a2004-05-26 06:27:36 +000074 //Get Resource usage for this instruction
Tanya Lattner081fbd12004-07-30 23:36:10 +000075 const TargetSchedInfo *msi = node->getParent()->getTarget()->getSchedInfo();
Tanya Lattner642685a2004-05-26 06:27:36 +000076 int currentCycle = cycle;
77 bool success = true;
Tanya Lattner13c71ca2004-11-24 01:49:10 +000078
79 //Get resource usage for this instruction
80 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
81 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
82
83 //Loop over resources in each cycle and increments their usage count
84 for(unsigned i=0; i < resources.size(); ++i) {
85 for(unsigned j=0; j < resources[i].size(); ++j) {
86
87 //Get Resource to check its availability
88 int resourceNum = resources[i][j];
89
90 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
91
Tanya Lattner642685a2004-05-26 06:27:36 +000092 //Check if this resource is available for this cycle
93 std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(currentCycle);
94
Tanya Lattner13c71ca2004-11-24 01:49:10 +000095 //First check if map exists for this cycle
Tanya Lattner642685a2004-05-26 06:27:36 +000096 if(resourcesForCycle != resourceNumPerCycle.end()) {
97 //A map exists for this cycle, so lets check for the resource
98 std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
99 if(resourceUse != resourcesForCycle->second.end()) {
100 //Check if there are enough of this resource and if so, increase count and move on
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000101 if(resourceUse->second < CPUResource::getCPUResource(resourceNum)->maxNumUsers)
Tanya Lattner642685a2004-05-26 06:27:36 +0000102 ++resourceUse->second;
Tanya Lattnerab9cf272004-11-22 20:41:24 +0000103
Tanya Lattner642685a2004-05-26 06:27:36 +0000104 else {
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000105 DEBUG(std::cerr << "No resource num " << resourceNum << " available for cycle " << currentCycle << "\n");
Tanya Lattner642685a2004-05-26 06:27:36 +0000106 success = false;
107 }
108 }
109 //Not in the map yet, so put it
110 else
111 resourcesForCycle->second[resourceNum] = 1;
112
113 }
114 else {
115 //Create a new map and put in our resource
116 std::map<int, int> resourceMap;
117 resourceMap[resourceNum] = 1;
Tanya Lattnerab9cf272004-11-22 20:41:24 +0000118 resourceNumPerCycle[currentCycle] = resourceMap;
Tanya Lattner642685a2004-05-26 06:27:36 +0000119 }
120 if(!success)
121 break;
122 }
123 if(!success)
124 break;
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000125
Tanya Lattner642685a2004-05-26 06:27:36 +0000126
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000127 //Increase cycle
128 currentCycle++;
129 }
130
131 if(!success) {
132 int oldCycle = cycle;
133 DEBUG(std::cerr << "Backtrack\n");
134 //Get resource usage for this instruction
135 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
136 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
137
138 //Loop over resources in each cycle and increments their usage count
139 for(unsigned i=0; i < resources.size(); ++i) {
140 if(oldCycle < currentCycle) {
141
142 //Check if this resource is available for this cycle
143 std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(oldCycle);
144 if(resourcesForCycle != resourceNumPerCycle.end()) {
145 for(unsigned j=0; j < resources[i].size(); ++j) {
146 int resourceNum = resources[i][j];
147 //remove from map
148 std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
149 //assert if not in the map.. since it should be!
150 //assert(resourceUse != resourcesForCycle.end() && "Resource should be in map!");
Tanya Lattnera31ad512005-02-23 02:01:42 +0000151 DEBUG(std::cerr << "Removing resource num " << resourceNum << " from cycle " << oldCycle << "\n");
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000152 --resourceUse->second;
Tanya Lattner642685a2004-05-26 06:27:36 +0000153 }
154 }
Tanya Lattner642685a2004-05-26 06:27:36 +0000155 }
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000156 else
157 break;
158 oldCycle++;
Tanya Lattner642685a2004-05-26 06:27:36 +0000159 }
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000160 return false;
161
162 }
Tanya Lattner642685a2004-05-26 06:27:36 +0000163
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000164 return true;
Tanya Lattner642685a2004-05-26 06:27:36 +0000165
166}
167
Tanya Lattner13417b52005-03-23 01:47:20 +0000168bool MSSchedule::constructKernel(int II, std::vector<MSchedGraphNode*> &branches, std::map<const MachineInstr*, unsigned> &indVar) {
Tanya Lattner201e9722004-12-02 07:22:15 +0000169
Tanya Lattner13417b52005-03-23 01:47:20 +0000170 //Our schedule is allowed to have negative numbers, so lets calculate this offset
171 int offset = schedule.begin()->first;
172 if(offset > 0)
173 offset = 0;
174
175 DEBUG(std::cerr << "Offset: " << offset << "\n");
176
177 //Not sure what happens in this case, but assert if offset is > II
178 //assert(offset > -II && "Offset can not be more then II");
179
180 std::vector<std::pair<MSchedGraphNode*, int> > tempKernel;
181
182
183 int stageNum = ((schedule.rbegin()->first-offset)+1)/ II;
184 int maxSN = 0;
185
Tanya Lattner642685a2004-05-26 06:27:36 +0000186 DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
187
Tanya Lattner13417b52005-03-23 01:47:20 +0000188 for(int index = offset; index < (II+offset); ++index) {
Tanya Lattner642685a2004-05-26 06:27:36 +0000189 int count = 0;
190 for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
191 if(schedule.count(i)) {
192 for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
193 E = schedule[i].end(); I != E; ++I) {
194 //Check if its a branch
195 if((*I)->isBranch()) {
Tanya Lattner642685a2004-05-26 06:27:36 +0000196 assert(count == 0 && "Branch can not be from a previous iteration");
Tanya Lattner13417b52005-03-23 01:47:20 +0000197 tempKernel.push_back(std::make_pair(*I, count));
Tanya Lattner642685a2004-05-26 06:27:36 +0000198 }
Tanya Lattner13417b52005-03-23 01:47:20 +0000199 else {
Tanya Lattner642685a2004-05-26 06:27:36 +0000200 //FIXME: Check if the instructions in the earlier stage conflict
Tanya Lattner13417b52005-03-23 01:47:20 +0000201 tempKernel.push_back(std::make_pair(*I, count));
202 maxSN = std::max(maxSN, count);
203 }
Tanya Lattner642685a2004-05-26 06:27:36 +0000204 }
205 }
206 ++count;
207 }
208 }
Tanya Lattner13417b52005-03-23 01:47:20 +0000209
210 //Add in induction var code
211 for(std::vector<std::pair<MSchedGraphNode*, int> >::iterator I = tempKernel.begin(), IE = tempKernel.end();
212 I != IE; ++I) {
213 //Add indVar instructions before this one for the current iteration
214 if(I->second == 0) {
215 std::map<unsigned, MachineInstr*> tmpMap;
216
217 //Loop over induction variable instructions in the map that come before this instr
218 for(std::map<const MachineInstr*, unsigned>::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
219
220
221 if(N->second < I->first->getIndex())
222 tmpMap[N->second] = (MachineInstr*) N->first;
223 }
224
225 //Add to kernel, and delete from indVar
226 for(std::map<unsigned, MachineInstr*>::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) {
227 kernel.push_back(std::make_pair(N->second, 0));
228 indVar.erase(N->second);
229 }
230 }
231
232 kernel.push_back(std::make_pair((MachineInstr*) I->first->getInst(), I->second));
233
Tanya Lattnera31ad512005-02-23 02:01:42 +0000234 }
235
Tanya Lattner13417b52005-03-23 01:47:20 +0000236 std::map<unsigned, MachineInstr*> tmpMap;
237
238 //Add remaining invar instructions
239 for(std::map<const MachineInstr*, unsigned>::iterator N = indVar.begin(), NE = indVar.end(); N != NE; ++N) {
240 tmpMap[N->second] = (MachineInstr*) N->first;
241 }
242
243 //Add to kernel, and delete from indVar
244 for(std::map<unsigned, MachineInstr*>::iterator N = tmpMap.begin(), NE = tmpMap.end(); N != NE; ++N) {
245 kernel.push_back(std::make_pair(N->second, 0));
246 indVar.erase(N->second);
247 }
248
249
250 maxStage = maxSN;
251
Tanya Lattnerdbac0cb2004-10-10 22:44:35 +0000252
Tanya Lattner642685a2004-05-26 06:27:36 +0000253 return true;
254}
255
256
257void MSSchedule::print(std::ostream &os) const {
258 os << "Schedule:\n";
259
260 for(schedule_const_iterator I = schedule.begin(), E = schedule.end(); I != E; ++I) {
261 os << "Cycle: " << I->first << "\n";
262 for(std::vector<MSchedGraphNode*>::const_iterator node = I->second.begin(), nodeEnd = I->second.end(); node != nodeEnd; ++node)
263 os << **node << "\n";
264 }
265
266 os << "Kernel:\n";
Tanya Lattner13417b52005-03-23 01:47:20 +0000267 for(std::vector<std::pair<MachineInstr*, int> >::const_iterator I = kernel.begin(),
Tanya Lattner642685a2004-05-26 06:27:36 +0000268 E = kernel.end(); I != E; ++I)
269 os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
270}
271