blob: 29aba158c30d31f2cde358c16aa3f730323e0351 [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
22bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
23
24 //First, check if the cycle has a spot free to start
25 if(schedule.find(cycle) != schedule.end()) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000026 //Check if we have a free issue slot at this cycle
Tanya Lattner642685a2004-05-26 06:27:36 +000027 if (schedule[cycle].size() < numIssue) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000028 //Now check if all the resources in their respective cycles are available
Tanya Lattner642685a2004-05-26 06:27:36 +000029 if(resourcesFree(node, cycle)) {
Tanya Lattner341828e2004-11-28 23:36:15 +000030 //Insert to preserve dependencies
31 addToSchedule(cycle,node);
Tanya Lattner642685a2004-05-26 06:27:36 +000032 DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
33 return false;
34 }
35 }
36 }
37 //Not in the map yet so put it in
38 else {
39 if(resourcesFree(node,cycle)) {
40 std::vector<MSchedGraphNode*> nodes;
41 nodes.push_back(node);
42 schedule[cycle] = nodes;
43 DEBUG(std::cerr << "Nothing in map yet so taking an issue slot\n");
44 return false;
45 }
46 }
47
48 DEBUG(std::cerr << "All issue slots taken\n");
49 return true;
Tanya Lattner13c71ca2004-11-24 01:49:10 +000050
Tanya Lattner642685a2004-05-26 06:27:36 +000051}
52
Tanya Lattner341828e2004-11-28 23:36:15 +000053void MSSchedule::addToSchedule(int cycle, MSchedGraphNode *node) {
54 std::vector<MSchedGraphNode*> nodesAtCycle = schedule[cycle];
55
56 std::map<unsigned, MSchedGraphNode*> indexMap;
57 for(unsigned i=0; i < nodesAtCycle.size(); ++i) {
58 indexMap[nodesAtCycle[i]->getIndex()] = nodesAtCycle[i];
59 }
60
61 indexMap[node->getIndex()] = node;
62
63 std::vector<MSchedGraphNode*> nodes;
64 for(std::map<unsigned, MSchedGraphNode*>::iterator I = indexMap.begin(), E = indexMap.end(); I != E; ++I)
65 nodes.push_back(I->second);
66
67 schedule[cycle] = nodes;
68}
69
70
Tanya Lattner642685a2004-05-26 06:27:36 +000071bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
Tanya Lattner13c71ca2004-11-24 01:49:10 +000072
Tanya Lattner642685a2004-05-26 06:27:36 +000073 //Get Resource usage for this instruction
Tanya Lattner081fbd12004-07-30 23:36:10 +000074 const TargetSchedInfo *msi = node->getParent()->getTarget()->getSchedInfo();
Tanya Lattner642685a2004-05-26 06:27:36 +000075 int currentCycle = cycle;
76 bool success = true;
Tanya Lattner13c71ca2004-11-24 01:49:10 +000077
78 //Get resource usage for this instruction
79 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
80 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
81
82 //Loop over resources in each cycle and increments their usage count
83 for(unsigned i=0; i < resources.size(); ++i) {
84 for(unsigned j=0; j < resources[i].size(); ++j) {
85
86 //Get Resource to check its availability
87 int resourceNum = resources[i][j];
88
89 DEBUG(std::cerr << "Attempting to schedule Resource Num: " << resourceNum << " in cycle: " << currentCycle << "\n");
90
Tanya Lattner642685a2004-05-26 06:27:36 +000091 //Check if this resource is available for this cycle
92 std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(currentCycle);
93
Tanya Lattner13c71ca2004-11-24 01:49:10 +000094 //First check if map exists for this cycle
Tanya Lattner642685a2004-05-26 06:27:36 +000095 if(resourcesForCycle != resourceNumPerCycle.end()) {
96 //A map exists for this cycle, so lets check for the resource
97 std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
98 if(resourceUse != resourcesForCycle->second.end()) {
99 //Check if there are enough of this resource and if so, increase count and move on
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000100 if(resourceUse->second < CPUResource::getCPUResource(resourceNum)->maxNumUsers)
Tanya Lattner642685a2004-05-26 06:27:36 +0000101 ++resourceUse->second;
Tanya Lattnerab9cf272004-11-22 20:41:24 +0000102
Tanya Lattner642685a2004-05-26 06:27:36 +0000103 else {
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000104 DEBUG(std::cerr << "No resource num " << resourceNum << " available for cycle " << currentCycle << "\n");
Tanya Lattner642685a2004-05-26 06:27:36 +0000105 success = false;
106 }
107 }
108 //Not in the map yet, so put it
109 else
110 resourcesForCycle->second[resourceNum] = 1;
111
112 }
113 else {
114 //Create a new map and put in our resource
115 std::map<int, int> resourceMap;
116 resourceMap[resourceNum] = 1;
Tanya Lattnerab9cf272004-11-22 20:41:24 +0000117 resourceNumPerCycle[currentCycle] = resourceMap;
Tanya Lattner642685a2004-05-26 06:27:36 +0000118 }
119 if(!success)
120 break;
121 }
122 if(!success)
123 break;
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000124
Tanya Lattner642685a2004-05-26 06:27:36 +0000125
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000126 //Increase cycle
127 currentCycle++;
128 }
129
130 if(!success) {
131 int oldCycle = cycle;
132 DEBUG(std::cerr << "Backtrack\n");
133 //Get resource usage for this instruction
134 InstrRUsage rUsage = msi->getInstrRUsage(node->getInst()->getOpcode());
135 std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
136
137 //Loop over resources in each cycle and increments their usage count
138 for(unsigned i=0; i < resources.size(); ++i) {
139 if(oldCycle < currentCycle) {
140
141 //Check if this resource is available for this cycle
142 std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(oldCycle);
143 if(resourcesForCycle != resourceNumPerCycle.end()) {
144 for(unsigned j=0; j < resources[i].size(); ++j) {
145 int resourceNum = resources[i][j];
146 //remove from map
147 std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
148 //assert if not in the map.. since it should be!
149 //assert(resourceUse != resourcesForCycle.end() && "Resource should be in map!");
150 --resourceUse->second;
Tanya Lattner642685a2004-05-26 06:27:36 +0000151 }
152 }
Tanya Lattner642685a2004-05-26 06:27:36 +0000153 }
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000154 else
155 break;
156 oldCycle++;
Tanya Lattner642685a2004-05-26 06:27:36 +0000157 }
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000158 return false;
159
160 }
Tanya Lattner642685a2004-05-26 06:27:36 +0000161
Tanya Lattner13c71ca2004-11-24 01:49:10 +0000162 return true;
Tanya Lattner642685a2004-05-26 06:27:36 +0000163
164}
165
166bool MSSchedule::constructKernel(int II) {
Reid Spencer2bce8002004-08-07 15:19:31 +0000167 MSchedGraphNode *branchNode = 0;
Tanya Lattnerdbac0cb2004-10-10 22:44:35 +0000168 MSchedGraphNode *branchANode = 0;
Tanya Lattner642685a2004-05-26 06:27:36 +0000169
170 int stageNum = (schedule.rbegin()->first)/ II;
171 DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
172
173 for(int index = 0; index < II; ++index) {
174 int count = 0;
175 for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
176 if(schedule.count(i)) {
177 for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
178 E = schedule[i].end(); I != E; ++I) {
179 //Check if its a branch
180 if((*I)->isBranch()) {
Tanya Lattnerdbac0cb2004-10-10 22:44:35 +0000181 if((*I)->getInst()->getOpcode() == V9::BA)
182 branchANode = *I;
183 else
184 branchNode = *I;
Tanya Lattner642685a2004-05-26 06:27:36 +0000185 assert(count == 0 && "Branch can not be from a previous iteration");
186 }
187 else
188 //FIXME: Check if the instructions in the earlier stage conflict
189 kernel.push_back(std::make_pair(*I, count));
190 }
191 }
192 ++count;
193 }
194 }
195
196 //Add Branch to the end
197 kernel.push_back(std::make_pair(branchNode, 0));
Tanya Lattnerdbac0cb2004-10-10 22:44:35 +0000198
199 //Add Branch Always to the end
200 kernel.push_back(std::make_pair(branchANode, 0));
201
202
203 if(stageNum > 0)
204 maxStage = stageNum;
205 else
206 maxStage = 0;
207
Tanya Lattner642685a2004-05-26 06:27:36 +0000208 return true;
209}
210
211
212void MSSchedule::print(std::ostream &os) const {
213 os << "Schedule:\n";
214
215 for(schedule_const_iterator I = schedule.begin(), E = schedule.end(); I != E; ++I) {
216 os << "Cycle: " << I->first << "\n";
217 for(std::vector<MSchedGraphNode*>::const_iterator node = I->second.begin(), nodeEnd = I->second.end(); node != nodeEnd; ++node)
218 os << **node << "\n";
219 }
220
221 os << "Kernel:\n";
222 for(std::vector<std::pair<MSchedGraphNode*, int> >::const_iterator I = kernel.begin(),
223 E = kernel.end(); I != E; ++I)
224 os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
225}
226