OpenASIP  2.0
BusBroker.cc
Go to the documentation of this file.
1 /*
2  Copyright (c) 2002-2011 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 BusBroker.cc
26  *
27  * Implementation of BusBroker class.
28  *
29  * @author Ari Mets�halme 2006 (ari.metsahalme-no.spam-tut.fi)
30  * @author Vladimir Guzma 2007 (vladimir.guzma-no.spam-tut.fi)
31  * @note rating: red
32  */
33 
34 #include "BusBroker.hh"
35 #include "BusResource.hh"
36 #include "OutputPSocketResource.hh"
38 #include "InputPSocketResource.hh"
39 #include "ResourceMapper.hh"
40 #include "Machine.hh"
41 #include "Segment.hh"
42 #include "Move.hh"
43 #include "MoveGuard.hh"
44 #include "Guard.hh"
45 #include "AssocTools.hh"
46 #include "MathTools.hh"
47 #include "MapTools.hh"
48 #include "MoveNode.hh"
50 #include "SequenceTools.hh"
51 #include "TemplateSlot.hh"
52 #include "TerminalImmediate.hh"
53 #include "UniversalMachine.hh"
54 #include "ControlUnit.hh"
55 #include "BasicBlockNode.hh"
56 #include "InstructionReference.hh"
57 #include "BasicBlock.hh"
58 #include "ControlFlowGraph.hh"
59 
60 using std::string;
61 using std::set;
62 using namespace TTAProgram;
63 using namespace TTAMachine;
64 
65 /**
66  * Constructor.
67  *
68  * @param name name for this broker.
69  * @param ipsb reference to InputPSocketBroker of this RM.
70  * @param opsb reference to OutputPSocketBroker of this RM.
71  * @param initiationInterval initiationinterval when doing loop scheduling.
72  */
74  std::string name,
75  ResourceBroker& ipBroker,
76  ResourceBroker& opBroker,
77  const TTAMachine::Machine& mach,
78  unsigned int initiationInterval) :
79  ResourceBroker(name, initiationInterval), inputPSocketBroker_(ipBroker),
80  outputPSocketBroker_(opBroker), hasLimm_(false), mach_(&mach) {
81 }
82 
83 /**
84  * Destructor.
85  */
88 }
89 
90 /**
91  * Return true if one of the resources managed by this broker is
92  * suitable for the request contained in the node and can be assigned
93  * to it in given cycle.
94  *
95  * @param cycle Cycle.
96  * @param node Node.
97  * @param bus if not null, bus that has to be used.
98  * @param srcFU if not null, srcFu that has to be used.
99  * @param dstFU if not null, dstFU that has to be used.
100  * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
101  * @return True if one of the resources managed by this broker is
102  * suitable for the request contained in the node and can be assigned
103  * to it in given cycle.
104  */
105 bool
107  const TTAMachine::Bus* bus,
108  const TTAMachine::FunctionUnit* srcFU,
109  const TTAMachine::FunctionUnit* dstFU,
110  int immWriteCycle,
111  const TTAMachine::ImmediateUnit* immu,
112  int immRegIndex) const {
113 
114  cycle = instructionIndex(cycle);
115  SchedulingResourceSet allAvailableBuses =
117  cycle, node, bus, srcFU, dstFU, immWriteCycle, immu, immRegIndex);
118  return allAvailableBuses.count() > 0;
119 }
120 
121 /**
122  * Return one (any) resource managed by this broker that can be
123  * assigned to the given node in the given cycle.
124  *
125  * If no change occurs to the state of the resources, the broker
126  * should always return the same object. If a resource of the type
127  * managed by this broker is already assigned to the node, it is
128  * returned.
129  *
130  * @param cycle Cycle.
131  * @param node Node.
132  * @param bus if not null, bus that has to be used.
133  * @param srcFU if not null, srcFu that has to be used.
134  * @param dstFU if not null, dstFU that has to be used.
135  * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
136  * @return One (any) resource managed by this broker that can be
137  * assigned to the given node in the given cycle.
138  * @exception InstanceNotFound If no available resource is found.
139  */
141 BusBroker::availableResource(int cycle, const MoveNode& node,
142  const TTAMachine::Bus* bus,
143  const TTAMachine::FunctionUnit* srcFU,
144  const TTAMachine::FunctionUnit* dstFU,
145  int immWriteCycle,
146  const TTAMachine::ImmediateUnit* immu,
147  int immRegIndex) const {
148 
149  cycle = instructionIndex(cycle);
150  SchedulingResourceSet allAvailableBuses =
151  allAvailableResources(cycle, node, bus, srcFU, dstFU, immWriteCycle,
152  immu, immRegIndex);
153  if (allAvailableBuses.count() == 0) {
154  string msg = "No available resource found.";
155  throw InstanceNotFound(__FILE__, __LINE__, __func__, msg);
156  } else {
157  if (bus != NULL) {
158  assert(allAvailableBuses.count() == 1);
159  }
160  return allAvailableBuses.resource(0);
161  }
162 }
163 
164 /**
165  * Return all resources managed by this broker that can be assigned to
166  * the given node in the given cycle.
167  *
168  * @param cycle Cycle.
169  * @param node Node.
170  * @param bus if not null, bus that has to be used.
171  * @param srcFU if not null, srcFu that has to be used.
172  * @param dstFU if not null, dstFU that has to be used.
173  * @param immWriteCycle if not -1 and src is imm, write cycle of limm.
174  * @return All resources managed by this broker that can be assigned to
175  * the given node in the given cycle.
176  */
179  int cycle,
180  const MoveNode& node,
181  const TTAMachine::Bus* bus,
183  const TTAMachine::FunctionUnit*, int,
184  const TTAMachine::ImmediateUnit*, int) const {
185 
186  cycle = instructionIndex(cycle);
187  SchedulingResourceSet candidates;
188 
189  Move& move = const_cast<MoveNode&>(node).move();
190  const Port* dstPort = &move.destination().port();
191  Socket* inputSocket = dstPort->inputSocket();
192 
193  // In case bus was already assigned previously, pick only relevant resource.
195  BusResource* preassignedBus = NULL;
196  if (&move.bus() != &um.universalBus()) {
197  preassignedBus = dynamic_cast<BusResource*>(resourceOf(move.bus()));
198  }
199  if (bus != NULL) {
200  preassignedBus = dynamic_cast<BusResource*>(resourceOf(*bus));
201  }
202 
203  if (inputSocket == NULL) {
204  string unit = dstPort->parentUnit()->name();
205  string port = dstPort->name();
206  string msg =
207  "Tried to find bus for a move to '" + unit + "." + port +
208  "' which has no connections to an input socket. "
209  "Check operation bindings!";
210  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
211  }
212 
213  InputPSocketResource* iPSocket = NULL;
214  try {
215  iPSocket =
216  static_cast<InputPSocketResource*>(
217  inputPSocketBroker_.resourceOf(*inputSocket));
218  } catch (const KeyNotFound& e) {
219  std::string msg = "BusBroker: finding ";
220  msg += " resource for Socket ";
221  msg += " failed with error: ";
222  msg += e.errorMessageStack();
223  throw KeyNotFound(
224  __FILE__, __LINE__, __func__, msg);
225  }
226 
227  OutputPSocketResource* oPSocket = NULL;
228 
229  if (move.source().isImmediate()) {
230 
231  // find a bus with appropriate immediate width that is connected to
232  // destination
233  ResourceMap::const_iterator resIter = resMap_.begin();
234  while (resIter != resMap_.end()) {
235  // look for bus resources with appropriate related shortimmsocket
236  // resources
237  BusResource* busRes =
238  static_cast<BusResource*>((*resIter).second);
239  if (busRes == NULL) {
240  throw InvalidData(
241  __FILE__, __LINE__, __func__,
242  "Bus broker has other then Bus Resource registered!");
243  }
244 
245  ShortImmPSocketResource& immRes = findImmResource(*busRes);
246  if (preassignedBus == NULL || busRes == preassignedBus) {
247  if (canTransportImmediate(node, immRes) &&
248  busRes->canAssign(cycle, node, immRes, *iPSocket)) {
249  candidates.insert(*busRes);
250  }
251  }
252  resIter++;
253  }
254 
255  } else {
256 
257  const Port* srcPort = &move.source().port();
258  Socket* outputSocket = srcPort->outputSocket();
259  if (outputSocket == NULL) {
260  string unit = srcPort->parentUnit()->name();
261  string port = srcPort->name();
262  string msg =
263  "Tried to find bus for a move from '" + unit + "." + port +
264  "' which has no connections to an output socket! Check "
265  "operation bindings!";
266  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
267  }
268 
269  oPSocket = NULL;
270  try {
271  oPSocket =
272  static_cast<OutputPSocketResource*>(
273  outputPSocketBroker_.resourceOf(*outputSocket));
274  } catch (const KeyNotFound& e) {
275  std::string msg = "BusBroker: finding ";
276  msg += " resource for Socket ";
277  msg += " failed with error: ";
278  msg += e.errorMessageStack();
279  throw KeyNotFound(
280  __FILE__, __LINE__, __func__, msg);
281  }
282 
283  ResourceMap::const_iterator resIter = resMap_.begin();
284  while (resIter != resMap_.end()) {
285  BusResource* busRes =
286  static_cast<BusResource*>((*resIter).second);
287  if (preassignedBus == NULL ||
288  busRes == preassignedBus) {
289  if (busRes->canAssign(cycle, node, *oPSocket, *iPSocket)) {
290  candidates.insert(*busRes);
291  }
292  }
293  resIter++;
294  }
295  }
296  if (!move.isUnconditional()) {
297 
298  const Guard& guard = move.guard().guard();
299  for (int i = 0; i < candidates.count(); i++) {
300  SchedulingResource& busResource = candidates.resource(i);
301  const Bus* aBus =
302  static_cast<const Bus*>(&machinePartOf(busResource));
303  if (aBus == NULL) {
304  throw InvalidData(
305  __FILE__, __LINE__, __func__,
306  "Bus Resource is missing bus in MOM!");
307  }
308 
309  bool guardFound = false;
310  for (int j = 0; j < aBus->guardCount(); j++) {
311  Guard* busGuard = aBus->guard(j);
312  if (busGuard->isEqual(guard)) {
313  guardFound = true;
314  break;
315  }
316  }
317 
318  if (!guardFound) {
319  candidates.remove(busResource);
320  i--;
321  }
322  }
323  }
324  return candidates;
325 }
326 
327 /**
328  * Tells whether the given resource is available for given node at
329  * given cycle.
330  */
331 bool
333  SchedulingResource& res, const MoveNode& node, int cycle,
334  const TTAMachine::Bus* bus,
337  int,
338  const TTAMachine::ImmediateUnit*, int) const {
339 
340  if (bus != NULL && resourceOf(*bus) != &res) {
341  return false;
342  }
343  cycle = instructionIndex(cycle);
344 
345  Move& move = const_cast<MoveNode&>(node).move();
346  const Port* dstPort = &move.destination().port();
347  Socket* inputSocket = dstPort->inputSocket();
348 
349  if (inputSocket == NULL) {
350  string unit = dstPort->parentUnit()->name();
351  string port = dstPort->name();
352  string msg =
353  "Tried to find bus for a move to '" + unit + "." + port +
354  "' which has no connections to an input socket. "
355  "Check operation bindings!";
356  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
357  }
358 
359  InputPSocketResource* iPSocket = NULL;
360  try {
361  iPSocket =
362  static_cast<InputPSocketResource*>(
363  inputPSocketBroker_.resourceOf(*inputSocket));
364  } catch (const KeyNotFound& e) {
365  std::string msg = "BusBroker: finding ";
366  msg += " resource for Socket ";
367  msg += " failed with error: ";
368  msg += e.errorMessageStack();
369  throw KeyNotFound(
370  __FILE__, __LINE__, __func__, msg);
371  }
372 
373  OutputPSocketResource* oPSocket = NULL;
374 
375  if (move.source().isImmediate()) {
376 
377  // look for bus resources with appropriate related shortimmsocket
378  // resources
379  BusResource* busRes =
380  dynamic_cast<BusResource*>(&res);
381  if (busRes == NULL) {
382  throw InvalidData(
383  __FILE__, __LINE__, __func__,
384  "Wrong type of resource for the broker given!");
385  }
386 
387  ShortImmPSocketResource& immRes = findImmResource(*busRes);
388  if (!canTransportImmediate(node, immRes) &&
389  busRes->canAssign(cycle, node, immRes, *iPSocket)) {
390  return false;
391  }
392  } else {
393  const Port* srcPort = &move.source().port();
394  Socket* outputSocket = srcPort->outputSocket();
395  if (outputSocket == NULL) {
396  string unit = srcPort->parentUnit()->name();
397  string port = srcPort->name();
398  string msg =
399  "Tried to find bus for a move from '" + unit + "." + port +
400  "' which has no connections to an output socket! Check "
401  "operation bindings!";
402  throw ModuleRunTimeError(__FILE__, __LINE__, __func__, msg);
403  }
404 
405  oPSocket = NULL;
406  try {
407  oPSocket =
408  static_cast<OutputPSocketResource*>(
409  outputPSocketBroker_.resourceOf(*outputSocket));
410  } catch (const KeyNotFound& e) {
411  std::string msg = "BusBroker: finding ";
412  msg += " resource for Socket ";
413  msg += " failed with error: ";
414  msg += e.errorMessageStack();
415  throw KeyNotFound(
416  __FILE__, __LINE__, __func__, msg);
417  }
418 
419  BusResource* busRes =
420  dynamic_cast<BusResource*>(&res);
421  if (busRes == NULL) {
422  throw InvalidData(
423  __FILE__, __LINE__, __func__,
424  "Wrong type of resource for the broker given!");
425  }
426 
427  if (!busRes->canAssign(cycle, node, *oPSocket, *iPSocket)) {
428  return false;
429  }
430  }
431  if (!move.isUnconditional()) {
432 
433  const Guard& guard = move.guard().guard();
434  const Bus* aBus =
435  dynamic_cast<const Bus*>(&machinePartOf(res));
436  if (aBus == NULL) {
437  throw InvalidData(
438  __FILE__, __LINE__, __func__,
439  "Bus Resource is missing bus in MOM!");
440  }
441 
442  bool guardFound = false;
443  for (int j = 0; j < aBus->guardCount(); j++) {
444  Guard* busGuard = aBus->guard(j);
445  if (busGuard->isEqual(guard)) {
446  guardFound = true;
447  break;
448  }
449  }
450 
451  if (!guardFound) {
452  return false;
453  }
454  }
455  return true;
456 }
457 
458 /**
459  * Mark given resource as in use for the given node, and assign the
460  * corresponding machine part (if applicable) to the node's move.
461  *
462  * If the node is already assigned to given resource, this method does
463  * nothing.
464  *
465  * @param cycle Cycle for which to assign bus
466  * @param node Node which will be transfered using a bus
467  * @param res ResourceObject referring to particular bus to assign
468  * @exception WrongSubclass If this broker does not recognise the given
469  * type of resource.
470  * @exception InvalidParameters If he given resource cannot be assigned to
471  * given node or no corresponding machine part is found.
472  */
473 void
475  int cycle, MoveNode& node, SchedulingResource& res, int, int) {
476 
477  cycle = instructionIndex(cycle);
478  BusResource& busRes = static_cast<BusResource&>(res);
479  Move& move = const_cast<MoveNode&>(node).move();
480  if (hasResource(res)) {
481  Bus& bus =
482  const_cast<Bus&>(static_cast<const Bus&>(machinePartOf(res)));
483 
485  if (&move.bus() != &um.universalBus()) {
486  busPreassigned_[&node] = true;
487  assert(&bus == &move.bus() &&
488  "preassigned bus which is different than selected bus?");
489  } else {
490  move.setBus(bus);
491  busPreassigned_[&node] = false;
492  }
493  if (!move.isUnconditional()) {
494  for (int j = 0; j < bus.guardCount(); j++) {
495  Guard* busGuard = bus.guard(j);
496  if (busGuard->isEqual(move.guard().guard())) {
497  move.setGuard(new MoveGuard(*busGuard));
498  break;
499  }
500  }
501  }
502  busRes.assign(cycle,node);
503  } else {
504  string msg = "Broker does not contain given resource.";
505  throw InvalidData(__FILE__, __LINE__, __func__, msg);
506  }
507  assignedResources_.insert(
508  std::pair<const MoveNode*, SchedulingResource*>(&node, &busRes));
509 }
510 
511 /**
512  * Free the resource type managed by this broker and unassign it from
513  * given node.
514  *
515  * If this broker is not applicable to the given node, or the node is
516  * not assigned a resource of the managed type, this method does
517  * nothing.
518  *
519  * @param node Node to unassign.
520  */
521 void
523 
525  Move& move = const_cast<MoveNode&>(node).move();
526  const Bus& bus = move.bus();
527  SchedulingResource* res = resourceOf(bus);
528  BusResource& busRes = static_cast<BusResource&>(*res);
529  busRes.unassign(node.cycle(),node);
530  assignedResources_.erase(&node);
531  if (!busPreassigned_[&node]) {
533  move.setBus(um.universalBus());
534  }
535  }
536 }
537 
538 /**
539  * Return the earliest cycle, starting from given cycle, where a
540  * resource of the type managed by this broker can be assigned to the
541  * given node.
542  *
543  * @param cycle Cycle.
544  * @param node Node.
545  * @return The earliest cycle, starting from given cycle, where a
546  * resource of the type managed by this broker can be assigned to the
547  * given node.
548  */
549 int
552  const TTAMachine::FunctionUnit*, int,
554  int) const {
555  abortWithError("Not implemented.");
556  return -1;
557 }
558 
559 /**
560  * Return the latest cycle, starting from given cycle, where a
561  * resource of the type managed by this broker can be assigned to the
562  * given node.
563  *
564  * @param cycle Cycle.
565  * @param node Node.
566  * @return The latest cycle, starting from given cycle, where a
567  * resource of the type managed by this broker can be assigned to the
568  * given node.
569  */
570 int
573  const TTAMachine::FunctionUnit*, int,
575  int) const {
576  abortWithError("Not implemented.");
577  return -1;
578 }
579 
580 /**
581  * Return true if the given node is already assigned a resource of the
582  * type managed by this broker, and the assignment appears valid (that
583  * is, the broker has marked that resource as in use in the given
584  * cycle).
585  *
586  * @param cycle Cycle.
587  * @param node Node.
588  * @return True if the given node is already assigned a resource of the
589  * type managed by this broker, and the assignment appears valid (that
590  * is, the broker has marked that resource as in use in the given
591  * cycle).
592  */
593 bool
595  int cycle, const MoveNode& node, const TTAMachine::Bus*) const {
597  return false;
598  }
599  return isInUse(instructionIndex(cycle),node);
600 }
601 
602 /**
603  * Return true if given node already uses a resource of the type
604  * managed by this broker and assignment appears to be valid.
605  *
606  * @param cycle Cycle to test
607  * @param node Node to test
608  * @return True if given node already uses a resource of the
609  * type managed by the broker.
610  */
611 bool
612 BusBroker::isInUse(int cycle, const MoveNode& node) const {
613  cycle = instructionIndex(cycle);
614  const Bus& bus = const_cast<MoveNode&>(node).move().bus();
615  if (!hasResourceOf(bus)) {
616  return false;
617  }
618 
619  SchedulingResource* res = resourceOf(bus);
620  BusResource& busRes = static_cast<BusResource&>(*res);
621  return busRes.isInUse(cycle);
622 }
623 /**
624  * Return true if the given node needs a resource of the type managed
625  * by this broker, false otherwise.
626  *
627  * @param node Node.
628  * @return True if the given node needs a resource of the type managed
629  * by this broker, false otherwise.
630  */
631 bool
633  return mn.isMove();
634 }
635 
636 /**
637  * Build all resource objects of the controlled type required to model
638  * scheduling resources of the given target processor.
639  *
640  * This method cannot set up the resource links (dependent and related
641  * resources) of the constructed resource objects.
642  *
643  * @param target Target machine.
644  */
645 void
647  hasLimm_ = target.immediateUnitNavigator().count() > 0;
648  Machine::BusNavigator navi = target.busNavigator();
651 
652  std::map<const Bus*,int> limmSlotCounts;
653  std::map<const Bus*,int> nopSlotCounts;
654 
655  // calculate count of limm slots and nop slots associated with each bus.
656  // used to priorize busses which do not get into way of limm writes.
657  for (int i = 0; i < itn.count(); i++) {
658  InstructionTemplate* it = itn.item(i);
659  for (int j = 0; j < it->slotCount(); j++) {
660  TemplateSlot* itSlot = it->slot(j);
661  if (itSlot->destination() != NULL) {
662  limmSlotCounts[itSlot->bus()]++;
663  }
664  }
665  }
666 
667  for (int i = 0; i < navi.count(); i++) {
668  Bus* bus = navi.item(i);
669  assert(bus->segmentCount() == 1);
670  int socketCount = bus->segment(0)->connectionCount();
671  BusResource* busResource = new BusResource(
672  bus->name(), bus->width(),limmSlotCounts[bus],
673  nopSlotCounts[bus], bus->guardCount(),
674  bus->immediateWidth(), socketCount, initiationInterval_);
675  ResourceBroker::addResource(*bus, busResource);
676  }
677 }
678 
679 /**
680  * Complete resource initialisation by creating the references to
681  * other resources due to a dependency or a relation. Use the given
682  * resource mapper to lookup dependent and related resources using
683  * machine parts as keys.
684  *
685  * @param mapper Resource mapper.
686  */
687 void
689 
690  setResourceMapper(mapper);
691 
692  for (ResourceMap::iterator resIter = resMap_.begin();
693  resIter != resMap_.end(); resIter++) {
694 
695  const Bus* bus = dynamic_cast<const Bus*>((*resIter).first);
696  if (bus == NULL) {
697  throw InvalidData(
698  __FILE__, __LINE__, __func__,
699  "Bus broker has other then Bus Resource registered!");
700  }
701 
702  SchedulingResource* busResource = (*resIter).second;
703 
704  int immWidth = bus->immediateWidth();
705 
706  ShortImmPSocketResource* immSocketResource =
708  bus->name() + "Imm", immWidth, bus->signExtends(),
710 
711  shortImmPSocketResources_.push_back(immSocketResource);
712  busResource->addToRelatedGroup(0, *immSocketResource);
713 
714  for (int i = 0; i < bus->segmentCount(); i++) {
715  Segment* seg = bus->segment(i);
716  for (int j = 0; j < seg->connectionCount(); j++) {
717  Socket* socket = seg->connection(j);
718  SchedulingResource* relRes =
720  if (relRes == NULL) {
721  relRes = outputPSocketBroker_.resourceOf(*socket);
722  }
723  if (relRes != NULL) {
724  busResource->addToRelatedGroup(0, *relRes);
725  } else {
726  std::string msg = "BusBroker: finding ";
727  msg += " resource for Socket ";
728  msg += " failed. ";
729  throw KeyNotFound(
730  __FILE__, __LINE__, __func__, msg);
731  }
732  }
733  }
734  }
735 }
736 
737 /**
738  * Return true always.
739  *
740  * @return True always.
741  */
742 bool
744  return true;
745 }
746 
747 /**
748  * Return true if immediate in given node can be transported by any bus
749  * in broker, with the guard which the move contains.
750  *
751  * @param node Node that contains immediate read.
752  * @return True if immediate in given node can be transported by any bus
753  * in broker.
754  */
755 bool
757  const MoveNode& node, const TTAMachine::Bus* preassignedBus) const {
758  ResourceMap::const_iterator resIter = resMap_.begin();
759  while (resIter != resMap_.end()) {
760  BusResource* busRes = static_cast<BusResource*>((*resIter).second);
761  ShortImmPSocketResource* immRes = &findImmResource(*busRes);
762  const Bus* aBus = static_cast<const Bus*>(resIter->first);
763  if (preassignedBus != NULL && aBus != preassignedBus) {
764  resIter++;
765  continue;
766  }
767  if (canTransportImmediate(node, *immRes)) {
768  bool guardOK = false;
769  if (node.move().isUnconditional()) {
770  guardOK = true;
771  } else {
772  // We need to check that the bus contains the guard
773  // which the move has. Only return true if the
774  // guard is found from the bus.
775  const Guard& guard = node.move().guard().guard();
776  for (int j = 0; j < aBus->guardCount(); j++) {
777  Guard* busGuard = aBus->guard(j);
778  if (busGuard->isEqual(guard)) {
779  guardOK = true;
780  break;
781  }
782  }
783  }
784  if (guardOK) {
785  if (!hasLimm_) {
786  return true;
787  } else {
789  *aBus, node)) {
790  return true;
791  }
792  }
793  }
794  }
795  resIter++;
796  }
797  return false;
798 }
799 
800 
802  const MoveNode&, ShortImmPSocketResource&) const {
803  return false; // WiP.
804 }
805 
806 /**
807  * Return true if immediate in given node can be transported by bus
808  * that is represented by given p-socket resource.
809  *
810  * @param node Node that contains immediate read.
811  * @param immRes P-socket resource representing write if immediate to related
812  * bus.
813  * @return True if immediate in given node can be transported by bus
814  * that is represented by given p-socket resource.
815  */
816 bool
818  const MoveNode& node,
819  ShortImmPSocketResource& immRes) const {
820 
821  Move& move = const_cast<MoveNode&>(node).move();
822 
823  if (move.isJump() && canPerformSIMMJump(node, immRes)) {
824  return true;
825  }
826 
828  immRes.signExtends(),
829  static_cast<const TTAProgram::TerminalImmediate&>(move.source()),
830  *mach_);
831 
832  if (bits <= immRes.immediateWidth()) {
833  return true;
834  } else {
835  return false;
836  }
837 }
838 
839 /**
840  * Return the short immediate p-socket resource related to given bus.
841  *
842  * @param busRes Bus resource.
843  * @return The short immediate p-socket resource related to given bus.
844  */
847  int i = 0;
848  SchedulingResource* socketRes = NULL;
849  ShortImmPSocketResource* immRes = NULL;
850  while (i < busRes.relatedResourceCount(0)) {
851  socketRes = &busRes.relatedResource(0, i);
852  if (socketRes->isShortImmPSocketResource()) {
853  return *(static_cast<ShortImmPSocketResource*>(socketRes));
854  }
855  i++;
856  }
857  return *immRes;
858 }
859 
860 /**
861  * Tests if any of a buses known to BusBroker supports a guard
862  * required by MoveNode.
863  *
864  * @param node MoveNode to test.
865  * @return true if some of the buses supports guard of node.
866  */
867 bool
868 BusBroker::hasGuard(const MoveNode& node) const {
869  Move& move = const_cast<MoveNode&>(node).move();
870  const Guard& guard = move.guard().guard();
871  ResourceMap::const_iterator resIter = resMap_.begin();
872  while (resIter != resMap_.end()) {
873  SchedulingResource& busResource = *(*resIter).second;
874  const Bus* aBus =
875  static_cast<const Bus*>(&machinePartOf(busResource));
876 
877  for (int j = 0; j < aBus->guardCount(); j++) {
878  Guard* busGuard = aBus->guard(j);
879  if (busGuard->isEqual(guard)) {
880  return true;
881  }
882  }
883  resIter++;
884  }
885  return false;
886 }
887 
888 void
891  for (std::list<SchedulingResource*>::iterator i =
892  shortImmPSocketResources_.begin();
893  i != shortImmPSocketResources_.end(); i++) {
894  (*i)->clear();
895  }
896  busPreassigned_.clear();
897 }
898 
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
BusResource::canAssign
virtual bool canAssign(const int cycle, const MoveNode &node) const override
Definition: BusResource.cc:164
TTAMachine::Guard
Definition: Guard.hh:55
TTAProgram
Definition: Estimator.hh:65
MachineConnectivityCheck::requiredImmediateWidth
static int requiredImmediateWidth(bool signExtension, const TTAProgram::TerminalImmediate &source, const TTAMachine::Machine &mach)
Definition: MachineConnectivityCheck.cc:1247
MachineConnectivityCheck::busConnectedToDestination
static bool busConnectedToDestination(const TTAMachine::Bus &bus, const MoveNode &moveNode)
Definition: MachineConnectivityCheck.cc:1433
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
OutputPSocketResource.hh
BusBroker::setupResourceLinks
virtual void setupResourceLinks(const ResourceMapper &mapper)
Definition: BusBroker.cc:688
BusBroker::isBusBroker
virtual bool isBusBroker() const
Definition: BusBroker.cc:743
ResourceBroker::initiationInterval_
unsigned int initiationInterval_
Definition: ResourceBroker.hh:158
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
BusBroker::BusBroker
BusBroker(std::string name, ResourceBroker &ipBroker, ResourceBroker &opBroker, const TTAMachine::Machine &mach, unsigned int initiationInterval=0)
Definition: BusBroker.cc:73
BusResource::assign
virtual void assign(const int cycle, MoveNode &node) override
Definition: BusResource.cc:124
MachineConnectivityCheck.hh
ResourceMapper.hh
ResourceBroker::resMap_
ResourceMap resMap_
Definition: ResourceBroker.hh:165
TTAMachine::Segment
Definition: Segment.hh:54
TTAMachine::Bus::width
int width() const
Definition: Bus.cc:149
UniversalMachine::universalBus
TTAMachine::Bus & universalBus() const
Definition: UniversalMachine.cc:306
BusBroker::clear
void clear() override
Definition: BusBroker.cc:889
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
MapTools.hh
TTAMachine::Guard::isEqual
virtual bool isEqual(const Guard &guard) const =0
TTAMachine::Bus
Definition: Bus.hh:53
BusBroker::shortImmPSocketResources_
std::list< SchedulingResource * > shortImmPSocketResources_
Definition: BusBroker.hh:146
SequenceTools.hh
BasicBlockNode.hh
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
BusBroker::hasLimm_
bool hasLimm_
Definition: BusBroker.hh:150
BusBroker::earliestCycle
virtual int earliestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:550
ResourceBroker
Definition: ResourceBroker.hh:61
BusBroker::findImmResource
virtual ShortImmPSocketResource & findImmResource(BusResource &busRes) const
Definition: BusBroker.cc:846
UniversalMachine::instance
static UniversalMachine & instance()
Definition: UniversalMachine.cc:73
ResourceBroker::hasResource
bool hasResource(const SchedulingResource &r) const
Definition: ResourceBroker.cc:214
TTAProgram::Move::bus
const TTAMachine::Bus & bus() const
Definition: Move.cc:373
TTAProgram::Move::setGuard
void setGuard(MoveGuard *guard)
Definition: Move.cc:360
MoveNode
Definition: MoveNode.hh:65
ResourceBroker::assignedResources_
MoveResMap assignedResources_
Definition: ResourceBroker.hh:167
TTAMachine::Machine::Navigator::count
int count() const
TTAMachine::Bus::segment
virtual Segment * segment(int index) const
Definition: Bus.cc:329
ResourceBroker::addResource
void addResource(const TTAMachine::MachinePart &mp, SchedulingResource *res)
Definition: ResourceBroker.cc:265
ResourceBroker::hasResourceOf
bool hasResourceOf(const TTAMachine::MachinePart &mp) const
Definition: ResourceBroker.cc:203
TTAMachine::InstructionTemplate::slotCount
virtual int slotCount() const
Definition: InstructionTemplate.cc:236
BusBroker::hasGuard
virtual bool hasGuard(const MoveNode &node) const
Definition: BusBroker.cc:868
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
BusBroker::busPreassigned_
std::map< const MoveNode *, bool > busPreassigned_
Definition: BusBroker.hh:147
TTAMachine::InstructionTemplate
Definition: InstructionTemplate.hh:49
SchedulingResourceSet
Definition: SchedulingResource.hh:161
assert
#define assert(condition)
Definition: Application.hh:86
BusBroker::isAnyResourceAvailable
virtual bool isAnyResourceAvailable(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:106
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TemplateSlot.hh
TTAMachine::Segment::connectionCount
int connectionCount() const
InputPSocketResource
Definition: InputPSocketResource.hh:47
UniversalMachine.hh
BusBroker::isAvailable
virtual bool isAvailable(SchedulingResource &des, const MoveNode &node, int cycle, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:332
ShortImmPSocketResource::signExtends
bool signExtends() const
Definition: ShortImmPSocketResource.cc:78
MoveNode::isMove
bool isMove() const
ResourceBroker::setResourceMapper
void setResourceMapper(const ResourceMapper &mapper)
Definition: ResourceBroker.cc:224
SequenceTools::deleteAllItems
static void deleteAllItems(SequenceType &aSequence)
Segment.hh
SchedulingResource::relatedResource
virtual SchedulingResource & relatedResource(const int group, const int index) const
Definition: SchedulingResource.cc:120
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
SchedulingResource::addToRelatedGroup
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
Definition: SchedulingResource.cc:82
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
ShortImmPSocketResource
Definition: ShortImmPSocketResource.hh:43
BusResource::isInUse
virtual bool isInUse(const int cycle) const override
Definition: BusResource.cc:75
InvalidData
Definition: Exception.hh:149
BusBroker::allAvailableResources
virtual SchedulingResourceSet allAvailableResources(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:178
ShortImmPSocketResource::immediateWidth
int immediateWidth() const
Definition: ShortImmPSocketResource.cc:68
ControlFlowGraph.hh
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
UniversalMachine
Definition: UniversalMachine.hh:56
BusBroker.hh
OutputPSocketResource
Definition: OutputPSocketResource.hh:52
SchedulingResource
Definition: SchedulingResource.hh:52
TTAMachine::Port
Definition: Port.hh:54
BusBroker::~BusBroker
virtual ~BusBroker()
Definition: BusBroker.cc:86
InputPSocketResource.hh
TTAMachine::TemplateSlot
Definition: TemplateSlot.hh:55
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
TTAMachine::TemplateSlot::destination
ImmediateUnit * destination() const
__func__
#define __func__
Definition: Application.hh:67
ResourceBroker::clear
virtual void clear()
Definition: ResourceBroker.cc:365
TTAMachine::Socket
Definition: Socket.hh:53
ShortImmPSocketResource.hh
Guard.hh
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
ResourceBroker::resourceOf
SchedulingResource * resourceOf(const TTAMachine::MachinePart &mp) const
BusBroker::outputPSocketBroker_
ResourceBroker & outputPSocketBroker_
Definition: BusBroker.hh:149
BusBroker::isApplicable
virtual bool isApplicable(const MoveNode &node, const TTAMachine::Bus *) const override
Definition: BusBroker.cc:632
TTAProgram::Move
Definition: Move.hh:55
Machine.hh
ModuleRunTimeError
Definition: Exception.hh:1043
BusBroker::mach_
const TTAMachine::Machine * mach_
Definition: BusBroker.hh:151
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Segment::connection
const Connection & connection(const Socket &socket) const
Definition: Segment.cc:250
BusResource
Definition: BusResource.hh:46
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
BusBroker::unassign
virtual void unassign(MoveNode &node)
Definition: BusBroker.cc:522
SchedulingResource::relatedResourceCount
int relatedResourceCount(const int group) const
TTAMachine::TemplateSlot::bus
const Bus * bus() const
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
MoveNode::move
TTAProgram::Move & move()
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
SchedulingResourceSet::remove
void remove(SchedulingResource &resource)
Definition: SchedulingResource.cc:279
SchedulingResourceSet::count
int count() const
Definition: SchedulingResource.cc:251
TerminalImmediate.hh
false
find Finds info of the inner loops in the false
Definition: InnerLoopFinder.cc:81
BusResource.hh
BusBroker::availableResource
virtual SchedulingResource & availableResource(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:141
AssocTools.hh
TTAMachine::Port::name
virtual std::string name() const
Definition: Port.cc:141
InstructionReference.hh
BusBroker::canTransportImmediate
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssigndBus) const
Definition: BusBroker.cc:756
BasicBlock.hh
ControlUnit.hh
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
ResourceBroker::instructionIndex
unsigned int instructionIndex(unsigned int) const
Definition: ResourceBroker.cc:249
ResourceMapper
Definition: ResourceMapper.hh:51
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
BusBroker::canPerformSIMMJump
bool canPerformSIMMJump(const MoveNode &mn, ShortImmPSocketResource &immRes) const
Definition: BusBroker.cc:801
BusBroker::latestCycle
virtual int latestCycle(int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
Definition: BusBroker.cc:571
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
BusBroker::assign
virtual void assign(int cycle, MoveNode &node, SchedulingResource &res, int immWriteCycle, int immRegIndex) override
Definition: BusBroker.cc:474
ResourceBroker::machinePartOf
virtual const TTAMachine::MachinePart & machinePartOf(const SchedulingResource &r) const
Definition: ResourceBroker.cc:181
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
KeyNotFound
Definition: Exception.hh:285
SchedulingResourceSet::resource
SchedulingResource & resource(int index) const
Definition: SchedulingResource.cc:263
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
MathTools.hh
TTAProgram::Move::isJump
bool isJump() const
Definition: Move.cc:164
BusResource::unassign
virtual void unassign(const int cycle, MoveNode &node) override
Definition: BusResource.cc:142
SchedulingResource::isShortImmPSocketResource
virtual bool isShortImmPSocketResource() const
Move.hh
TTAMachine
Definition: Assembler.hh:48
TTAProgram::Terminal::isImmediate
virtual bool isImmediate() const
Definition: Terminal.cc:63
MoveNode.hh
BusBroker::isInUse
virtual bool isInUse(int cycle, const MoveNode &node) const
Definition: BusBroker.cc:612
TTAProgram::MoveGuard
Definition: MoveGuard.hh:47
TTAMachine::Machine::instructionTemplateNavigator
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition: Machine.cc:428
BusBroker::isAlreadyAssigned
virtual bool isAlreadyAssigned(int cycle, const MoveNode &node, const TTAMachine::Bus *preassignedBus) const override
Definition: BusBroker.cc:594
SchedulingResourceSet::insert
void insert(SchedulingResource &resource)
Definition: SchedulingResource.cc:236
TTAProgram::Move::setBus
void setBus(const TTAMachine::Bus &bus)
Definition: Move.cc:383
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::Bus::segmentCount
virtual int segmentCount() const
Definition: Bus.cc:385
TTAMachine::InstructionTemplate::slot
virtual TemplateSlot * slot(int index) const
Definition: InstructionTemplate.cc:249
InstanceNotFound
Definition: Exception.hh:304
TTAMachine::Machine
Definition: Machine.hh:73
BusBroker::buildResources
virtual void buildResources(const TTAMachine::Machine &target)
Definition: BusBroker.cc:646
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50
BusBroker::inputPSocketBroker_
ResourceBroker & inputPSocketBroker_
Definition: BusBroker.hh:148