OpenASIP  2.0
RegisterQuantityCheck.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2009 Tampere University.
3 
4  This file is part of TTA-Based Codesign Environment (TCE).
5 
6  Permission is hereby granted, free of charge, to any person obtaining a
7  copy of this software and associated documentation files (the "Software"),
8  to deal in the Software without restriction, including without limitation
9  the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  and/or sell copies of the Software, and to permit persons to whom the
11  Software is furnished to do so, subject to the following conditions:
12 
13  The above copyright notice and this permission notice shall be included in
14  all copies or substantial portions of the Software.
15 
16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  DEALINGS IN THE SOFTWARE.
23  */
24 /**
25  * @file RegisterQuantityCheck.cc
26  *
27  * Implementation of RegisterQuantityCheck class.
28  *
29  * Checks that given machine has enough registers.
30  *
31  * @author Heikki Kultala (hkultala-no.spam-cs.tut.fi)
32  * @author Esa Määttä 2008 (esa.maatta-no.spam-tut.fi)
33  * @note rating: red
34  */
35 
36 #include "RegisterFile.hh"
37 #include "Machine.hh"
38 #include "Guard.hh"
39 #include "AssocTools.hh"
40 
41 #include "Conversion.hh"
42 
43 #include "RegisterQuantityCheck.hh"
44 #include "FullyConnectedCheck.hh"
45 #include "MachineCheckResults.hh"
46 
48  MachineCheck("Checks that machine has enough registers") {}
49 
51 
52 
53 /**
54  * Checks register quantities, just returns false if problems where found.
55  *
56  * @param mach Machine to be checked for registers resources.
57  * @param results MachineCheckResults where possible errors are added.
58  * @return True if no problems were found during testing, false otherwise.
59  */
60 bool
62  std::set<Register> guardRegs;
63  const std::set<std::string> ignoreRFs; //empty, no ignore
64 
65  // find all registers that can be used for guards
66  findGuardRegisters(mach, guardRegs, ignoreRFs);
67 
68  // check if enough predicate registers
69  if (!checkPredRegs(guardRegs.size(), NULL)) {
70  return false;
71  }
72 
73  // count all integer registers
74  unsigned int intRegs = countIntRegisters(mach, guardRegs, ignoreRFs);
75 
76  // check if enough integer registers
77  if (missingIntRegs(intRegs, NULL, fullyConCheck_.check(mach))) {
78  return false;
79  }
80 
81  return true;
82 }
83 
84 
85 /**
86  * Checks register quantities.
87  *
88  * Stores errors during checking to a MachineCheckResults object given as a
89  * parameter.
90  *
91  * @param mach Machine to be checked for registers resources.
92  * @param results MachineCheckResults where possible errors are added.
93  * @return True if no problems were found during testing, false otherwise.
94  */
95 bool
97  const TTAMachine::Machine& mach,
98  MachineCheckResults& results) const {
99 
100  const std::set<std::string> empty;
101  return RegisterQuantityCheck::checkWithIgnore(mach, results, empty);
102 }
103 
104 
105 /**
106  * Checks register quantities with an option to ignore some RFs.
107  *
108  * Can be passed a list of RFs names that are ignored regarding the test.
109  *
110  * @param mach Machine to be checked for registers resources.
111  * @param ignoreRFs A sorted list of RFs to be ignored while checking the
112  * needed registers.
113  * @return True if no problems were found during testing, false otherwise.
114  */
115 bool
117  const TTAMachine::Machine& mach,
118  const std::set<std::string>& ignoreRFs) const {
119 
120  std::set<Register> guardRegs;
121 
122  // find all registers that can be used for guards
123  findGuardRegisters(mach, guardRegs, ignoreRFs);
124 
125  // check if enough predicate registers
126  if (!checkPredRegs(guardRegs.size(), NULL)) {
127  return false;
128  }
129 
130  // count all integer registers
131  unsigned int intRegs = countIntRegisters(mach, guardRegs, ignoreRFs);
132 
133  // check if enough integer registers
134  if (missingIntRegs(intRegs, NULL, fullyConCheck_.check(mach))) {
135  return false;
136  }
137 
138  return true;
139 }
140 
141 
142 /**
143  * Checks register quantities with an option to ignore some RFs.
144  *
145  * Can be passed a list of RFs names that are ignored regarding the test.
146  * Stores errors during checking to a MachineCheckResults object given as a
147  * parameter.
148  *
149  * @param mach Machine to be checked for registers resources.
150  * @param results MachineCheckResults where possible errors are added.
151  * @param ignoreRFs A sorted list of RFs to be ignored while checking the
152  * needed registers.
153  * @return True if no problems were found during testing, false otherwise.
154  */
155 bool
157  const TTAMachine::Machine& mach,
158  MachineCheckResults& results,
159  const std::set<std::string>& ignoreRFs) const {
160 
161  std::set<Register> guardRegs;
162 
163  // find all registers that can be used for guards
164  findGuardRegisters(mach, guardRegs, ignoreRFs);
165 
166  // check if enough predicate registers
167  checkPredRegs(guardRegs.size(), &results);
168 
169  // count all integer registers
170  unsigned int intRegs = countIntRegisters(mach, guardRegs, ignoreRFs);
171 
172  // check if enough integer registers
173  missingIntRegs(intRegs, &results, fullyConCheck_.check(mach));
174 
175  return results.errorCount() == 0;
176 }
177 
178 
179 /**
180  * Check only if enough integer registers.
181  *
182  * @param mach Machine to be checked for int registers.
183  * @return True if enough integer registers found.
184  */
185 bool
187  // find all registers that can be used for guards
188  std::set<Register> guardRegs;
189  const std::set<std::string> ignoreRFs; //empty, no ignore
190  findGuardRegisters(mach, guardRegs, ignoreRFs);
191 
192  // count all integer registers
193  unsigned int intRegs = countIntRegisters(mach, guardRegs, ignoreRFs);
194 
195  // check if enough integer registers
196  if (missingIntRegs(intRegs, NULL, fullyConCheck_.check(mach))) {
197  return false;
198  }
199  return true;
200 }
201 
202 
203 /**
204  * Checks register quantities with an option to ignore some RFs.
205  *
206  * Can be passed a list of RFs names that are ignored regarding the test.
207  *
208  * @param mach Machine to be checked for registers resources.
209  * @param guardRegs Counts registers that can be used as guards in the
210  * given machine.
211  * @param ignoreRFs A sorted list of RFs to be ignored while checking the
212  * needed registers.
213  * @return True if no problems were found during testing, false otherwise.
214  */
215 void
217  const TTAMachine::Machine& mach,
218  std::set<Register>& guardRegs,
219  const std::set<std::string>& ignoreRFs) const {
220 
221  // find all registers that can be used for guards
223  for (int i = 0; i < busNav.count(); i++) {
224  TTAMachine::Bus* bus = busNav.item(i);
225  for (int j = 0; j < bus->guardCount(); j++) {
226  const TTAMachine::RegisterGuard* regGuard =
227  dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(j));
228  if (regGuard != NULL) {
229  if(ignoreRFs.find(regGuard->registerFile()->name()) ==
230  ignoreRFs.end()) {
231  guardRegs.insert(
232  Register(
233  regGuard->registerFile(), regGuard->registerIndex()));
234  }
235  }
236  }
237  }
238 }
239 
240 
241 /**
242  * Counts integer registers int the given machine.
243  *
244  * Doesn't count guard registers given as sorted list of pairs.
245  * Can be passed a list of RFs names that are ignored regarding the test.
246  *
247  * @param mach Machine where integer registers are counted.
248  * @param guardRegs A sorted list of register file, index pairs.
249  * @param ignoreRFs A sorted list of RFs to be ignored while counting the
250  * registers.
251  * @return The number of counted integer registers in them machine.
252  */
253 unsigned int
255  const TTAMachine::Machine& mach,
256  const std::set<Register>& guardRegs,
257  const std::set<std::string>& ignoreRFs) const {
258 
260  mach.registerFileNavigator();
261 
262  unsigned int intRegs = 0;
263  for (int i = 0; i < regNav.count(); i++) {
264  const TTAMachine::RegisterFile* rf = regNav.item(i);
265  if (rf->width() == 32 &&
266  ignoreRFs.find(rf->name()) == ignoreRFs.end()) {
267  for (int j = 0; j < rf->size(); j++) {
268  if (!AssocTools::containsKey(guardRegs, Register(rf,j))) {
269  intRegs++;
270  }
271  }
272  }
273  }
274  return intRegs;
275 }
276 
277 
278 /**
279  * Checks that there are enough predicate registers.
280  *
281  * Outputs errors in MachineCheckResults object if given as a pointer.
282  *
283  * @param regCount The number of predicate registers.
284  * @param results MachineCheckResults where possible errors are added.
285  * @return True if the number of predicate registers given was high enough.
286  */
287 bool
289  const unsigned int& regCount,
290  MachineCheckResults* results) const {
291 
292  if (regCount < 2) {
293  if (results != NULL) {
294  std::string msg = "too few predicate registers, 2 needed, ";
295  msg += Conversion::toString(regCount);
296  msg += " found";
297  results->addError(*this, msg);
298  }
299  return false;
300  }
301  return true;
302 }
303 
304 
305 /**
306  * Checks that there are enough integer registers.
307  *
308  * Outputs errors in MachineCheckResults object if given as a pointer.
309  *
310  * @param regCount The number of integer registers.
311  * @param results MachineCheckResults where possible errors are added.
312  * @return number of missing registers, 0 if none missing.
313  */
314 unsigned int
316  const unsigned int& regCount,
317  MachineCheckResults* results,
318  bool isFullyConnected) const {
319 
320  unsigned int neededIntRegs = isFullyConnected ? 5 : 6;
321  unsigned int missingRegisters = 0;
322 
323  if (regCount < neededIntRegs) {
324  missingRegisters = neededIntRegs - regCount;
325  if (results != NULL) {
326  results->addError(*this, "too few integer registers");
327  }
328  }
329  return missingRegisters;
330 }
331 
332 
333 /**
334  * Adds integer registers to an int rf so that requirements are met.
335  *
336  * @param machine Machine where integer registers are to be added if needed.
337  * @return True if something was done to the machine, false otherwise.
338  */
339 bool
341  // find all guard registers, which are ignored
342  std::set<Register> guardRegs;
343  const std::set<std::string> ignoreRFs; //empty, no ignore
344  findGuardRegisters(mach, guardRegs, ignoreRFs);
345 
346  // count all integer registers
347  unsigned int intRegs = countIntRegisters(mach, guardRegs, ignoreRFs);
348 
349  unsigned int missingRegs =
350  missingIntRegs(intRegs, NULL, fullyConCheck_.check(mach));
351 
352  if (!missingRegs) {
353  return true;
354  }
355 
357  mach.registerFileNavigator();
358 
359  // find an int rf to add registers
360  for (int i = 0; i < regNav.count(); i++) {
361  TTAMachine::RegisterFile* rf = regNav.item(i);
362  if (rf->width() == 32) {
363  rf->setNumberOfRegisters(rf->size() + missingRegs);
364  return true;
365  }
366  }
367 
368  // no int rf found
369  return false;
370 }
371 
372 
373 /**
374  * Returns true if an int register file found, meaning int registers can be
375  * added.
376  *
377  * @return True, if int rf found.
378  */
379 bool
382  mach.registerFileNavigator();
383 
384  // return true if an int register file was found
385  for (int i = 0; i < regNav.count(); i++) {
386  TTAMachine::RegisterFile* rf = regNav.item(i);
387  if (rf->width() == 32) {
388  return true;
389  }
390  }
391  return false;
392 }
RegisterQuantityCheck::checkWithIgnore
bool checkWithIgnore(const TTAMachine::Machine &mach, const std::set< std::string > &ignoreRFs) const
Definition: RegisterQuantityCheck.cc:116
RegisterQuantityCheck::missingIntRegs
unsigned int missingIntRegs(const unsigned int &regCount, MachineCheckResults *results, bool isFullyConnected) const
Definition: RegisterQuantityCheck.cc:315
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
RegisterQuantityCheck::Register
std::pair< const TTAMachine::RegisterFile *, int > Register
Definition: RegisterQuantityCheck.hh:71
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
TTAMachine::Bus
Definition: Bus.hh:53
RegisterQuantityCheck.hh
MachineCheckResults::addError
void addError(const MachineCheck &check, const std::string &errorMsg)
Definition: MachineCheckResults.cc:85
RegisterQuantityCheck::countIntRegisters
unsigned int countIntRegisters(const TTAMachine::Machine &mach, const std::set< Register > &guardRegs, const std::set< std::string > &ignoreRFs) const
Definition: RegisterQuantityCheck.cc:254
TTAMachine::Machine::Navigator::count
int count() const
Conversion::toString
static std::string toString(const T &source)
FullyConnectedCheck.hh
MachineCheckResults::errorCount
int errorCount() const
Definition: MachineCheckResults.cc:56
RegisterQuantityCheck::checkPredRegs
bool checkPredRegs(const unsigned int &regCount, MachineCheckResults *results) const
Definition: RegisterQuantityCheck.cc:288
Conversion.hh
TTAMachine::RegisterGuard
Definition: Guard.hh:137
RegisterQuantityCheck::findGuardRegisters
void findGuardRegisters(const TTAMachine::Machine &mach, std::set< Register > &registers, const std::set< std::string > &ignoreRFs) const
Definition: RegisterQuantityCheck.cc:216
Guard.hh
RegisterQuantityCheck::~RegisterQuantityCheck
virtual ~RegisterQuantityCheck()
Definition: RegisterQuantityCheck.cc:50
MachineCheckResults
Definition: MachineCheckResults.hh:46
Machine.hh
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
RegisterQuantityCheck::fixIntRegs
bool fixIntRegs(TTAMachine::Machine &mach) const
Definition: RegisterQuantityCheck.cc:340
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
FullyConnectedCheck::check
virtual bool check(const TTAMachine::Machine &mach) const
Definition: FullyConnectedCheck.cc:99
MachineCheckResults.hh
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
RegisterFile.hh
AssocTools.hh
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
MachineCheck
Definition: MachineCheck.hh:50
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
RegisterQuantityCheck::checkIntRegs
bool checkIntRegs(const TTAMachine::Machine &mach) const
Definition: RegisterQuantityCheck.cc:186
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
RegisterQuantityCheck::check
virtual bool check(const TTAMachine::Machine &mach) const
Definition: RegisterQuantityCheck.cc:61
TTAMachine::BaseRegisterFile::size
virtual int size() const
TTAMachine::BaseRegisterFile::width
virtual int width() const
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
RegisterQuantityCheck::RegisterQuantityCheck
RegisterQuantityCheck()
Definition: RegisterQuantityCheck.cc:47
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::RegisterFile::setNumberOfRegisters
virtual void setNumberOfRegisters(int registers)
Definition: RegisterFile.cc:320
RegisterQuantityCheck::fullyConCheck_
FullyConnectedCheck fullyConCheck_
Definition: RegisterQuantityCheck.hh:88
RegisterQuantityCheck::canFixIntRegs
bool canFixIntRegs(const TTAMachine::Machine &mach) const
Definition: RegisterQuantityCheck.cc:380
TTAMachine::Machine
Definition: Machine.hh:73