OpenASIP 2.2
Loading...
Searching...
No Matches
MachineResourceModifier.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 MachineResourceModifier.cc
26 *
27 * Implementation of the MachineResourceModifier class.
28 *
29 * @author Jari Mäntyneva 2007 (jari.mantyneva-no.spam-tut.fi)
30 * @note rating: red
31 */
32
33#include <cmath>
34
37#include "Conversion.hh"
38#include "AssocTools.hh"
39#include "Guard.hh"
40#include "TemplateSlot.hh"
41#include "ObjectState.hh"
42
43using namespace TTAMachine;
44
45/**
46 * The constructor.
47 */
50
51/**
52 * The destructor.
53 */
56
57/**
58 * Adds given number of buses to the given architecture.
59 *
60 * Determines the bus parameters in basis of the original architecture and
61 * the most common bus types are added first.
62 *
63 * @param busesToAdd Number of buses to add.
64 * @mach Architecture where the buses are added.
65 */
66void
68 int busesToAdd, TTAMachine::Machine& mach) {
69
70 BusMap busMap;
71 analyzeBuses(mach, busMap);
72
73 int addedBuses = 0;
74 std::multimap<double, TTAMachine::Bus*>::const_iterator iter = busMap.end();
75 while (iter != busMap.begin()) {
76 iter--;
77 if (addedBuses == busesToAdd) {
78 break;
79 }
80 double numberToAdd = ceil((*iter).first * busesToAdd);
81
82 while (numberToAdd > 0) {
83 if (addedBuses < busesToAdd) {
84 TTAMachine::Bus& original = *(*iter).second;
85 TTAMachine::Bus* newBus = original.copy();
86
87 int busNum = 0;
88 std::string busBaseName = original.name();
90 mach.busNavigator();
91 while (busNavigator.hasItem(
92 busBaseName + Conversion::toString(busNum))) {
93 busNum++;
94 }
95
96 newBus->setName(busBaseName + Conversion::toString(busNum));
97 mach.addBus(*newBus);
98
99 original.copyGuardsTo(*newBus);
100 // Fully connect the machine.
102 check.fix(mach);
103 addedBuses++;
104 }
105 numberToAdd--;
106 }
107 }
108}
109
110/**
111 * Reduces the amount of buses with a given number using some strange
112 * algorithm.
113 *
114 * Won't remove buses that are immediate template slots. Remove slots first.
115 * Slots may cause that given number of buses cannot be removed.
116 * (I, maattae, have really no idea why this function does what it does. And
117 * what it does isn't actually very clear.)
118 *
119 * @param busesToRemove Number of buses to remove.
120 * @param mach Machine where the buses are removed.
121 * @param removedBusName Names of the removed buses are added at the end
122 * of this list.
123 */
124void
126 const int& busesToRemove, TTAMachine::Machine& mach,
127 std::list<std::string>& removedBusNames) {
128
129 BusMap busMap;
130 analyzeBuses(mach, busMap);
131
132 int removedBuses = 0;
133 std::multimap<double, TTAMachine::Bus*>::const_iterator iter =
134 busMap.begin();
135
136 while (iter != busMap.end() && removedBuses != busesToRemove) {
137
138 double numberToRemove = ceil(iter->first * busesToRemove);
139
141
142 for (int i = 0; numberToRemove > 0 && i < navigator.count(); i++) {
143 if (removedBuses < busesToRemove) {
144 if ((*iter).second->isArchitectureEqual(
145 *navigator.item(i))) {
148 if (hasSlot(mach, navigator.item(i)->name())) {
149 // buses that contains template slot are not removed
150 continue;
151 }
152 // remove the bus
153 removedBusNames.push_back(
154 (*iter).second->name());
155 mach.removeBus(*(navigator.item(i)));
156 removedBuses++;
157 numberToRemove--;
158 }
159 } else {
160 // continue with next bus type
161 break;
162 }
163 }
164 iter++;
165 }
166}
167
168
169/**
170 * Removes busses from machine.
171 *
172 * Doens't remove buses that have template slots.
173 *
174 * @param countToRemove Number of buses to remove in optimal case.
175 * @param mach Machine where buses are going to be removed.
176 * @param removedBusName Names of the removed buses are added at the end
177 * of this list.
178 * @return True if the number of buses to be removed were actually removed,
179 * false otherwise.
180 */
181bool
183 const int& countToRemove, TTAMachine::Machine& mach,
184 std::list<std::string>& removedBusNames) {
185
189
190 // TODO: make test that the last guard bus isn't removed either.
191 for (int busesRemoved = 0, i = 0; 0 < navigator.count(); ++i) {
192 if ( countToRemove == busesRemoved ) {
193 return true;
194 }
195 // buses that contains template slot are not removed
196 if (hasSlot(mach, navigator.item(i)->name())) {
197 continue;
198 }
199 removedBusNames.push_back(navigator.item(i)->name());
200 // remove the bus
201 mach.removeBus(*(navigator.item(i)));
202 ++busesRemoved;
203 --i;
204 }
205 return false;
206}
207
208
209/**
210 * Returns true if the machine contains an Instruction template slot for given
211 * bus name.
212 *
213 * @param mach Machine where the slot is searched.
214 * @param busName Name of the slot that is searched.
215 * @return True if the machine contains template slot for the given bus name.
216 */
217bool
219 const Machine& mach, const std::string& slotName) {
220
223 for (int i = 0; i < itNav.count(); i++) {
224 for (int slot = 0;
225 slot < itNav.item(i)->slotCount();
226 slot++) {
227
228 if (itNav.item(i)->slot(slot)->slot() == slotName) {
229 return true;
230 }
231 }
232 }
233 return false;
234}
235
236/**
237 * Removes not sockets that have no connection to any port from the machine.
238 *
239 * @param mach Machine where the sockets are removed.
240 * @param removedSocketNames Names of the removed sockets are inserted at the
241 * end of this list.
242 */
243void
245 TTAMachine::Machine& mach, std::list<std::string>& removedSocketNames) {
246
247 std::list<std::string> socketsToRemove;
248
250 for (int i = 0; i < navigator.count(); i++) {
251 if (navigator.item(i)->portCount() == 0 ||
252 navigator.item(i)->segmentCount() == 0) {
253 socketsToRemove.push_back(navigator.item(i)->name());
254 }
255 }
256
257 std::list<std::string>::const_iterator iter = socketsToRemove.begin();
258 while (iter != socketsToRemove.end()) {
259 mach.removeSocket(*navigator.item(*iter));
260 removedSocketNames.push_back(*iter);
261 iter++;
262 }
263}
264
265/**
266 * Analyzes the bus types of the architecture.
267 *
268 * @param mach Machine to be analyzed.
269 * @param busMap Map where bus counts are stored.
270 */
271void
273 const TTAMachine::Machine& mach, BusMap& busMap) const {
274
276
277 std::set<int> checkedBuses;
278 for (int i = 0; i < busNavigator.count(); i++) {
279
280 // go trough only the buses that are not already counted
281 if (checkedBuses.find(i) != checkedBuses.end()) {
282 continue;
283 }
284
285 TTAMachine::Bus* bus = busNavigator.item(i);
286 int counter = 1;
287 for (int j = i + 1; j < busNavigator.count(); j++) {
288 if (bus->isArchitectureEqual(*busNavigator.item(j))) {
289 checkedBuses.insert(j);
290 counter++;
291 }
292 }
293 busMap.insert(
294 std::pair<double, TTAMachine::Bus*>(
295 Conversion::toDouble(counter) /
296 Conversion::toDouble(busNavigator.count()), bus));
297 checkedBuses.insert(i);
298 }
299
300 assert(Conversion::toInt(checkedBuses.size()) == busNavigator.count());
301}
302
303
304/**
305 * Increase all different register files by given amount.
306 *
307 * @param registersToAdd Number of every register type will be added.
308 * @param mach Machine which registers are added.
309 */
310void
312 int registersToAdd, TTAMachine::Machine& mach) {
313
314 RegisterMap rfMap;
315 analyzeRegisters(mach, rfMap);
316
317 std::multimap<double, TTAMachine::RegisterFile*>::const_iterator iter =
318 rfMap.end();
319 while (iter != rfMap.begin()) {
320 iter--;
321 if (!(*iter).second->isUsedAsGuard()) {
322 int addedRegisters = 0;
323 while (addedRegisters < registersToAdd) {
324 ObjectState* newRFState = (*iter).second->saveState();
326 new TTAMachine::RegisterFile(newRFState);
327 delete newRFState;
328 newRFState = NULL;
329
330 int rfNum = 1;
331 std::string rfBaseName = "rf";
334 while (rfNavigator.hasItem(
335 rfBaseName + Conversion::toString(rfNum))) {
336 rfNum++;
337 }
338 newRF->setName(rfBaseName + Conversion::toString(rfNum));
339 mach.addRegisterFile(*newRF);
340 // Fully connect the machine.
342 check.fix(mach);
343 addedRegisters++;
344 }
345 }
346 }
347}
348
349/**
350 * Increase all different register files by percentage value.
351 *
352 * Fully connects the machine after adding the units.
353 *
354 * @param percentualRegisterIncrease How much will the register files be
355 * increased in percents.
356 * @param mach Machine which registers are increased.
357 */
358void
360 double percentsOfRegistersToAdd, TTAMachine::Machine& mach) {
361
362 if (percentsOfRegistersToAdd < 0.0) {
363 // nothing to add
364 return;
365 }
366
367 RegisterMap rfMap;
368 analyzeRegisters(mach, rfMap);
371
372 std::multimap<double, TTAMachine::RegisterFile*>::const_iterator iter =
373 rfMap.end();
374 while (iter != rfMap.begin()) {
375 iter--;
376 if (!(*iter).second->isUsedAsGuard()) {
377 int addedRegisters = 0;
378 int registersToAdd =
380 ceil((*iter).first * percentsOfRegistersToAdd));
381 while (addedRegisters < registersToAdd) {
383 new TTAMachine::RegisterFile((*iter).second->saveState());
384 int rfNum = 1;
385 std::string rfBaseName = "rf";
388 while (rfNavigator.hasItem(
389 rfBaseName + Conversion::toString(rfNum))) {
390 rfNum++;
391 }
392 newRF->setName(rfBaseName + Conversion::toString(rfNum));
393 mach.addRegisterFile(*newRF);
394 // Fully connect the machine.
396 check.fix(mach);
397 addedRegisters++;
398 }
399 }
400 }
401}
402
403/**
404 * Analyzes the register types of the architecture.
405 *
406 * @param mach Machine which registers are analyzed.
407 * @param registerMap Map where register counts are stored.
408 */
409void
411 const TTAMachine::Machine& mach, RegisterMap& registerMap) const {
412
415
416 std::set<int> checkedRegisters;
417 for (int i = 0; i < registerNavigator.count(); i++) {
418 // go trough only the registers that are not already counted
419 if (checkedRegisters.find(i) != checkedRegisters.end()) {
420 continue;
421 }
422 // @todo boolean registers are propably not needed to multiply
423 TTAMachine::RegisterFile* rf = registerNavigator.item(i);
424 int counter = 1;
425 for (int j = i + 1; j < registerNavigator.count(); j++) {
426 if (rf->isArchitectureEqual(*registerNavigator.item(j))) {
427 checkedRegisters.insert(j);
428 counter++;
429 }
430 }
431
432 registerMap.insert(
433 std::pair<double, TTAMachine::RegisterFile*>(
434 Conversion::toDouble(counter) /
435 Conversion::toDouble(registerNavigator.count()), rf));
436
437 checkedRegisters.insert(i);
438 }
439
440 assert(Conversion::toInt(checkedRegisters.size())
441 == registerNavigator.count());
442}
443
444/**
445 * Increase all different funtion units by given amount.
446 *
447 * @param unitsToAdd How many function units are added for each fu type.
448 * @param mach Machine where the function units are added.
449 */
450void
452 int unitsToAdd, TTAMachine::Machine& mach) {
453
454 FunctionUnitMap fuMap;
455 analyzeFunctionUnits(mach, fuMap);
456
457 std::multimap<double, TTAMachine::FunctionUnit*>::const_iterator iter =
458 fuMap.end();
459 while (iter != fuMap.begin()) {
460 iter--;
461 int addedUnits = 0;
462 while (addedUnits < unitsToAdd) {
463 ObjectState* newFuState = (*iter).second->saveState();
465 new TTAMachine::FunctionUnit(newFuState);
466 delete newFuState;
467
468 newFuState = NULL;
469 int fuNum = 1;
470 std::string fuBaseName = "fu";
473 while (fuNavigator.hasItem(
474 fuBaseName + Conversion::toString(fuNum))) {
475 fuNum++;
476 }
477 newFU->setName(fuBaseName + Conversion::toString(fuNum));
478 mach.addFunctionUnit(*newFU);
479
480 // set the same address space to the new unit.
481 newFU->setAddressSpace((*iter).second->addressSpace());
482
483 // Fully connect the machine (adds new sockets).
485 check.fix(mach);
486 addedUnits++;
487 }
488 }
489}
490
491/**
492 * Increase all different function units by percentage value.
493 *
494 * Fully connects the machine after adding the units.
495 *
496 * @param percentualFUIncrease How much will the function units be
497 * increased in percents.
498 * @param mach Machine which function units are increased.
499 */
500void
502 double percentualFUIncrease, TTAMachine::Machine& mach) {
503
504 if (percentualFUIncrease < 0.0) {
505 // nothing to add
506 return;
507 }
508
509 FunctionUnitMap fuMap;
510 analyzeFunctionUnits(mach, fuMap);
513
514 std::multimap<double, TTAMachine::FunctionUnit*>::const_iterator iter =
515 fuMap.end();
516 while (iter != fuMap.begin()) {
517 iter--;
518 int addedUnits = 0;
519 int unitsToAdd =
520 Conversion::toInt(ceil((*iter).first * percentualFUIncrease));
521 while (addedUnits < unitsToAdd) {
523 new TTAMachine::FunctionUnit((*iter).second->saveState());
524 int fuNum = 1;
525 std::string fuBaseName = "fu";
528 while (fuNavigator.hasItem(
529 fuBaseName + Conversion::toString(fuNum))) {
530 fuNum++;
531 }
532 newFU->setName(fuBaseName + Conversion::toString(fuNum));
533 mach.addFunctionUnit(*newFU);
534
535 // set the same address space to the new unit.
536 newFU->setAddressSpace((*iter).second->addressSpace());
537
538 // Fully connect the machine.
540 check.fix(mach);
541 addedUnits++;
542 }
543 }
544}
545
546/**
547 * Analyzes the unit types of the architecture.
548 *
549 * @param mach Machine which function units are analyzed.
550 * @param unitMap Map where unit counts are stored. FU pointers in the map
551 * are pointers to the machine units.
552 */
553void
555 const TTAMachine::Machine& mach, FunctionUnitMap& unitMap) const {
556
559
560 std::set<int> checkedUnits;
561 for (int i = 0; i < unitNavigator.count(); i++) {
562 // go trough only the units that are not already counted
563 if (checkedUnits.find(i) != checkedUnits.end()) {
564 continue;
565 }
566
567 TTAMachine::FunctionUnit* fu = unitNavigator.item(i);
568 int counter = 1;
569 for (int j = i + 1; j < unitNavigator.count(); j++) {
570 if (fu->isArchitectureEqual(unitNavigator.item(j))) {
571 checkedUnits.insert(j);
572 counter++;
573 }
574 }
575
576 unitMap.insert(
577 std::pair<double, TTAMachine::FunctionUnit*>(
578 Conversion::toDouble(counter) /
579 Conversion::toDouble(unitNavigator.count()), fu));
580 checkedUnits.insert(i);
581 }
582
583 assert(Conversion::toInt(checkedUnits.size())
584 == unitNavigator.count());
585}
#define assert(condition)
static double toDouble(const T &source)
static std::string toString(const T &source)
static int toInt(const T &source)
virtual std::string fix(TTAMachine::Machine &mach) const
bool hasSlot(const TTAMachine::Machine &mach, const std::string &slotName)
std::multimap< double, TTAMachine::RegisterFile * > RegisterMap
Map of register amounts in percents.
void reduceBuses(const int &busesToRemove, TTAMachine::Machine &mach, std::list< std::string > &removedBusNames)
bool removeBuses(const int &countToRemove, TTAMachine::Machine &mach, std::list< std::string > &removedBusNames)
void increaseAllFUsThatDiffersByAmount(int moreFUs, TTAMachine::Machine &mach)
void percentualFUIncrease(double percentualFUIncrease, TTAMachine::Machine &mach)
void addBusesByAmount(int busesToAdd, TTAMachine::Machine &mach)
std::multimap< double, TTAMachine::Bus * > BusMap
Map of bus amounts in percents.
std::multimap< double, TTAMachine::FunctionUnit * > FunctionUnitMap
Map of function unit amounts in percents.
void increaseAllRFsThatDiffersByAmount(int registersToAdd, TTAMachine::Machine &mach)
void percentualRegisterIncrease(double percentsOfRegistersToAdd, TTAMachine::Machine &mach)
void analyzeBuses(const TTAMachine::Machine &mach, BusMap &busMap) const
void analyzeRegisters(const TTAMachine::Machine &mach, RegisterMap &registerMap) const
void analyzeFunctionUnits(const TTAMachine::Machine &mach, FunctionUnitMap &unitMap) const
void removeNotConnectedSockets(TTAMachine::Machine &mach, std::list< std::string > &removedSocketNames)
virtual void setName(const std::string &name)
Definition Bus.cc:196
virtual Bus * copy() const
Definition Bus.cc:1145
virtual bool isArchitectureEqual(const Bus &bus) const
Definition Bus.cc:1111
virtual void copyGuardsTo(Bus &other) const
Definition Bus.cc:1155
virtual TCEString name() const
virtual void setAddressSpace(AddressSpace *as)
virtual void setName(const std::string &name)
virtual bool isArchitectureEqual(const FunctionUnit *fu, const bool checkPortWidths=true) const
const_iterator begin() const noexcept
const_iterator end() const noexcept
ComponentType * item(int index) const
bool hasItem(const std::string &name) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428
virtual SocketNavigator socketNavigator() const
Definition Machine.cc:368
virtual void removeBus(Bus &bus)
Definition Machine.cc:477
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
virtual void addFunctionUnit(FunctionUnit &unit)
Definition Machine.cc:202
virtual void addBus(Bus &bus)
Definition Machine.cc:139
virtual void addRegisterFile(RegisterFile &unit)
Definition Machine.cc:236
virtual void removeSocket(Socket &socket)
Definition Machine.cc:490
virtual bool isArchitectureEqual(const RegisterFile &rf) const
virtual void setName(const std::string &name)