OpenASIP  2.0
MachineConnectivityCheck.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 MachineConnectivityCheck.cc
26  *
27  * Implementation of MachineConnectivityCheck class.
28  *
29  * @author Pekka Jääskeläinen 2007 (pjaaskel-no.spam-cs.tut.fi)
30  * @author Heikki Kultala 2008 (hkultala-no.spam-cs.tut.fi)
31  * @note rating: red
32  */
33 
34 #include <set>
35 
37 #include "MachineInfo.hh"
38 #include "Application.hh"
39 #include "Bus.hh"
40 #include "Segment.hh"
41 #include "SetTools.hh"
42 #include "RegisterFile.hh"
43 #include "ControlUnit.hh"
44 #include "SpecialRegisterPort.hh"
45 #include "MathTools.hh"
46 #include "TerminalImmediate.hh"
47 #include "Move.hh"
48 #include "TerminalFUPort.hh"
49 #include "HWOperation.hh"
50 #include "TCEString.hh"
51 #include "Operation.hh"
52 #include "FUPort.hh"
53 #include "ProgramOperation.hh"
54 #include "AssocTools.hh"
55 #include "StringTools.hh"
56 #include "MoveNode.hh"
57 #include "MoveGuard.hh"
58 #include "TemplateSlot.hh"
59 #include "Guard.hh"
60 #include "OperationPool.hh"
61 #include "Operand.hh"
62 
63 using namespace TTAMachine;
64 /**
65  * Constructor for using this generic class directly.
66  */
68  MachineCheck("Common helper functionality for connectivity checks.") {
69 }
70 
71 /**
72  * Destructor.
73  */
75 }
76 
77 /**
78  * Constructor for deriving.
79  *
80  * @param shortDesc The short description of the check.
81  */
83  const std::string& shortDesc_) : MachineCheck(shortDesc_) {
84 }
85 
86 
87 bool
89  PortSet sourcePorts,
90  PortSet destinationPorts,
91  const Guard* guard) {
92  for (PortSet::iterator i =
93  sourcePorts.begin();
94  i != sourcePorts.end(); i++) {
95  const TTAMachine::Port& sport = **i;
96  for (PortSet::iterator j =
97  destinationPorts.begin();
98  j != destinationPorts.end(); j++) {
99  if (isConnected(sport, **j, guard)) {
100  return true;
101  }
102  }
103  }
104  return false;
105 }
106 
107 /**
108  * Dummy implementation for the pure virtual method MachineCheck::check().
109  *
110  * The implementation is needed for generation of Python bindings, as
111  * Boost.Python cannot create instances of abstract base classes.
112  */
113 
114 bool
116  MachineCheckResults&) const {
117  assert(0);
118 }
119 
120 /**
121  * Checks whether there is a connection between two ports.
122  *
123  * @param sourcePort The source (rf/fu) port.
124  * @param destinationPort The destination (rf/fu) port.
125  * @return True if there is at least one path between the given ports.
126  */
127 bool
129  const TTAMachine::Port& sourcePort,
130  const TTAMachine::Port& destinationPort,
131  const Guard* guard) {
132 
133  // TODO: replace this cache's second value(bool) with set of buses.
134  PortPortBoolMap::const_iterator
135  i = portPortCache_.find(PortPortPair(&sourcePort, &destinationPort));
136  if (i != portPortCache_.end()) {
137  if (i->second == false || guard == NULL) {
138  return i->second;
139  }
140  }
141  std::set<const TTAMachine::Bus*> sourceBuses;
143  sourcePort, sourceBuses);
144 
145  std::set<const TTAMachine::Bus*> destinationBuses;
147  destinationPort, destinationBuses);
148 
149  std::set<const TTAMachine::Bus*> sharedBuses;
150  SetTools::intersection(sourceBuses, destinationBuses, sharedBuses);
151  if (sharedBuses.size() > 0) {
152  portPortCache_[PortPortPair(&sourcePort,&destinationPort)] = true;
153 
154  if (guard == NULL) {
155  return true;
156  }
157 
158  for (std::set<const TTAMachine::Bus*>::iterator i = sharedBuses.begin();
159  i != sharedBuses.end(); i++) {
160  if ((*i)->hasGuard(*guard)) {
161  return true;
162  }
163  }
164 
165  return false; // bus found but lacks the guards
166  } else {
167  portPortCache_[PortPortPair(&sourcePort,&destinationPort)] = false;
168  return false;
169  }
170 }
171 
172 /**
173  * Checks whether an immediate with given width can be transported to the
174  * destination register file.
175  *
176  * @param destRF The destination RF.
177  * @param immediate The immediate to transport.
178  * @return True if there is at least one path between the given ports.
179  */
180 bool
182  const TTAProgram::TerminalImmediate& immediate,
183  const TTAMachine::BaseRegisterFile& destRF,
184  const Guard* guard) {
185 
186  std::set<const TTAMachine::Bus*> buses;
188 
189  for (auto bus : buses) {
190  int requiredBits =
192  bus->signExtends(), immediate, *destRF.machine());
193  if (bus->immediateWidth() < requiredBits) {
194  continue;
195  }
196 
197  if (guard == NULL) {
198  return true;
199  } else {
200  if (bus->hasGuard(*guard)) {
201  return true;
202  }
203  }
204  }
205  return false;
206 }
207 
208 /**
209  * Checks whether an immediate with given width can be transported to the
210  * destination port.
211  *
212  * @param immediate The immediate to transport.
213  * @param destinationPort The destination port.
214  * @return True if there is at least one path between the given ports.
215  */
216 bool
218  const TTAProgram::TerminalImmediate& immediate,
219  const TTAMachine::Port& destinationPort,
220  const Guard* guard) {
221 
222  std::set<const TTAMachine::Bus*> buses;
224  destinationPort, buses);
225 
226  for (auto i = buses.begin(); i != buses.end(); ++i) {
227  const TTAMachine::Bus& bus = **i;
228 
229  if (!canTransportImmediate(immediate, bus)) {
230  continue;
231  }
232  if (guard == NULL) {
233  return true;
234  } else {
235  if (bus.hasGuard(*guard)) {
236  return true;
237  }
238  }
239  }
240  return false;
241 }
242 
243 bool
245  const TTAProgram::TerminalImmediate& immediate,
246  PortSet destinationPorts,
247  const Guard* guard) {
248 
249  for (PortSet::iterator i =
250  destinationPorts.begin();
251  i != destinationPorts.end(); i++) {
252  if (canTransportImmediate(immediate, **i, guard)) {
253  return true;
254  }
255  }
256  return false;
257 }
258 
259 /**
260  * Checks whether an immediate with given width can be transported on the
261  * bus.
262  *
263  * @param immediate The immediate to transport.
264  * @param bus The bus.
265  * @return True if the bus can transport the immediate as inline.
266  */
267 bool
269  const TTAProgram::TerminalImmediate& immediate,
270  const TTAMachine::Bus& bus) {
271 
272  int requiredBits =
274  bus.signExtends(), immediate, *bus.machine());
275  if (bus.immediateWidth() >= requiredBits) {
276  return true;
277  } else {
278  return false;
279  }
280 }
281 
282 /**
283  * Checks whether there is a connection from some outport port of a
284  * register file or immediate unit into the specified port.
285  *
286  * @param sourceRF Source RF/Immediate unit.
287  * @param destPort The destination port.
288  * @return True if there is at least one connection from any of the output
289  * ports of the source RF/Imm unit into the destination port.
290  */
291 bool
293  const TTAMachine::BaseRegisterFile& sourceRF,
294  const TTAMachine::Port& destPort) {
295 
296  RfPortBoolMap::const_iterator
297  i = rfPortCache_.find(RfPortPair(&sourceRF, &destPort));
298  if (i != rfPortCache_.end()) {
299  return i->second;
300  }
301  std::set<const TTAMachine::Bus*> destBuses = connectedSourceBuses(destPort);
302  std::set<const TTAMachine::Bus*> srcBuses;
303 
304  for (int i = 0; i < sourceRF.portCount(); i++) {
305  const TTAMachine::Port& port = *sourceRF.port(i);
306  if (port.outputSocket() != NULL) {
307  appendConnectedDestinationBuses(port, srcBuses);
308  }
309  }
310 
311  std::set<const TTAMachine::Bus*> sharedBuses;
313  srcBuses, destBuses, sharedBuses);
314  if (sharedBuses.size() > 0) {
315  rfPortCache_[RfPortPair(&sourceRF,&destPort)] = true;
316  return true;
317  } else {
318  rfPortCache_[RfPortPair(&sourceRF,&destPort)] = false;
319  return false;
320  }
321 }
322 
323 /**
324  * Checks whether there is a connection from some outport port of a
325  * register file or immediate unit into some input port of the given
326  * target register file or immediate unit.
327  *
328  * @param sourceRF Source RF/Immediate unit.
329  * @param destRF Source RF/Immediate unit.
330  * @return True if there is at least one connection from any of the output
331  * ports of the source RF/Imm unit into the destination RF.
332  */
333 bool
335  const TTAMachine::BaseRegisterFile& sourceRF,
336  const TTAMachine::BaseRegisterFile& destRF,
337  const TTAMachine::Guard* guard) {
338 
339  RfRfBoolMap::const_iterator
340  i = rfRfCache_.find(RfRfPair(&sourceRF, &destRF));
341  if (i != rfRfCache_.end()) {
342  if (i->second == false || guard == NULL) {
343  return i->second;
344  }
345  }
346  std::set<const TTAMachine::Bus*> srcBuses;
347  appendConnectedDestinationBuses(sourceRF, srcBuses);
348 
349  std::set<const TTAMachine::Bus*> dstBuses;
350  appendConnectedSourceBuses(destRF, dstBuses);
351 
352  std::set<const TTAMachine::Bus*> sharedBuses;
353  SetTools::intersection(srcBuses, dstBuses, sharedBuses);
354  if (sharedBuses.size() > 0) {
355  rfRfCache_[RfRfPair(&sourceRF,&destRF)] = true;
356  if (guard == NULL) {
357  return true;
358  }
359 
360  for (std::set<const TTAMachine::Bus*>::iterator i = sharedBuses.begin();
361  i != sharedBuses.end(); i++) {
362  if ((*i)->hasGuard(*guard)) {
363  return true;
364  }
365  }
366  return false; // bus found but lacks the guards
367  } else {
368  rfRfCache_[RfRfPair(&sourceRF,&destRF)] = false;
369  return false;
370  }
371 }
372 
373 /**
374  * Checks whether there is a connection from some outport port of a
375  * register file or immediate unit into some input port of the given
376  * target function unit.
377  *
378  * @param sourceRF Source RF/Immediate unit.
379  * @param destFU Destination FU.
380  * @return True if there is at least one connection from any of the output
381  * ports of the source RF/Imm unit into the destination FU.
382  */
383 bool
385  const TTAMachine::BaseRegisterFile& sourceRF,
386  const TTAMachine::FunctionUnit& destFU) {
387 
388  std::set<const TTAMachine::Bus*> srcBuses;
389  appendConnectedDestinationBuses(sourceRF, srcBuses);
390 
391  std::set<const TTAMachine::Bus*> dstBuses;
392  appendConnectedSourceBuses(destFU, dstBuses);
393 
394  std::set<const TTAMachine::Bus*> sharedBuses;
395  SetTools::intersection(srcBuses, dstBuses, sharedBuses);
396  return (sharedBuses.size() > 0);
397 }
398 
399 
400 /**
401  * Checks whether there is a connection from specified port into some
402  * input port of a register file.
403  *
404  * @param sourcePort The source port.
405  * @param destRF Destination register file.
406  * @return True if there exists at least one connection from source to
407  * any input port of destination register file.
408  */
409 bool
411  const TTAMachine::Port& sourcePort,
412  const TTAMachine::RegisterFile& destRF) {
413 
414  PortRfBoolMap::const_iterator
415  i = portRfCache_.find(PortRfPair(&sourcePort, &destRF));
416  if (i != portRfCache_.end()) {
417  return i->second;
418  }
419 
420  std::set<const TTAMachine::Bus*> sourceBuses =
421  connectedDestinationBuses(sourcePort);
422  std::set<const TTAMachine::Bus*> destBuses;
423 
424  for (int i = 0; i < destRF.portCount(); i++) {
425  const TTAMachine::Port& port = *destRF.port(i);
426  if (port.inputSocket() != NULL) {
427  appendConnectedSourceBuses(port, destBuses);
428  }
429  }
430 
431  std::set<const TTAMachine::Bus*> sharedBuses;
432  SetTools::intersection(sourceBuses, destBuses, sharedBuses);
433 
434  if (sharedBuses.size() > 0) {
435  portRfCache_[PortRfPair(&sourcePort,&destRF)] = true;
436  return true;
437  } else {
438  portRfCache_[PortRfPair(&sourcePort,&destRF)] = false;
439  return false;
440  }
441 }
442 
443 /**
444  * Checks whether the two RFs are connected to the exact same buses.
445  */
446 bool
448  const TTAMachine::BaseRegisterFile& RF1,
449  const TTAMachine::BaseRegisterFile& RF2) {
450 
451  std::set<const TTAMachine::Bus*> dstBuses1, dstBuses2;
452  appendConnectedDestinationBuses(RF1, dstBuses1);
453  appendConnectedDestinationBuses(RF2, dstBuses2);
454 
455  std::set<const TTAMachine::Bus*> srcBuses1, srcBuses2;
456  appendConnectedSourceBuses(RF1, srcBuses1);
457  appendConnectedSourceBuses(RF2, srcBuses2);
458 
459  return dstBuses1 == dstBuses2 && srcBuses1 == srcBuses2;
460 }
461 
462 bool
464  const TTAMachine::Port& port, std::set<int> widths) {
465  auto fup = dynamic_cast<const FUPort*>(&port);
466  if (fup == nullptr) {
467  return false;
468  }
469  auto fu = dynamic_cast<const FunctionUnit*>(port.parentUnit());
470  if (fu == nullptr) {
471  return false;
472  }
473 
474  OperationPool opPool;
475 
476  for (int i = 0; i < fu->operationCount(); i++) {
477  auto hwop = fu->operation(i);
478  if (!hwop->isBound(*fup))
479  continue;
480 
481  int opIndex = hwop->io(*fup);
482  int oprWidth = operandWidth(*hwop, opIndex);
483  if (AssocTools::containsKey(widths, oprWidth)) {
484  return true;
485  }
486  }
487  return false;
488 }
489 
490 /**
491  * Checks whether there is a connection from the given Register file
492  * or Immediate unit to all FU's and control unit of the machine.
493  *
494  * It both this and toRfConnected() returns true,
495  * then this FU can be used as the only register file
496  * to be used for reduced connectivity-register copying.
497  *
498  * @param brf Register file or immediate unit being checked.
499  * @return true if this RF can write to all ports af all FU's.
500  */
501 bool
503  const TTAMachine::BaseRegisterFile& brf) {
504 
505  int width = brf.width();
506  bool isVectorRegs = width > 32;
507  TTAMachine::Machine& mach = *brf.machine();
509  mach.functionUnitNavigator();
510 
511 
512  std::set<const TTAMachine::Bus*> rfBuses;
513 
514  for (int i = 0; i < brf.portCount(); i++) {
515  const TTAMachine::Port& port = *brf.port(i);
516  if (port.outputSocket() != NULL) {
517  appendConnectedDestinationBuses(port, rfBuses);
518  }
519  }
520 
521  std::set<int> widths;
522  widths.insert(brf.width());
523 
524  auto widthsExt = widths;
525  if (width == 32) {
526  widthsExt.insert(1);
527  widthsExt.insert(8);
528  widthsExt.insert(16);
529  }
530  if (width == 1) {
531  widthsExt.insert(32);
532  }
533 
534  // check connections to function units
535  for (auto fu: fuNav) {
536  for (int j = 0; j < fu->portCount(); j++ ) {
537  Port& port = *fu->port(j);
538  // connections from RF to FU's
539  if (port.inputSocket() != NULL &&
540  isPortApplicableToWidths(port, widthsExt)) {
541  std::set<const TTAMachine::Bus*> sharedBuses;
543  rfBuses, connectedSourceBuses(port), sharedBuses);
544  if (sharedBuses.size() == 0) {
545  return false;
546  }
547  }
548  }
549  }
550 
551  // no need to transfer data from vector regs to control unit.
552  if (isVectorRegs) {
553  return true;
554  }
555 
556  // check connections to control unit
557  TTAMachine::ControlUnit& cu = *mach.controlUnit();
558  for (int i = 0; i < cu.portCount(); i++ ) {
559  Port& port = *cu.port(i);
560 
561  // connections from RF to CU
562  if (port.inputSocket() != NULL &&
563  isPortApplicableToWidths(port, widths)) {
564  std::set<const TTAMachine::Bus*> sharedBuses;
566  rfBuses, connectedSourceBuses(port), sharedBuses);
567  if (sharedBuses.size() == 0) {
568  return false;
569  }
570  }
571  }
572  return true;
573 }
574 
575 /**
576  * Checks if an RF is connected to all other units
577  *
578  * It this returns true,
579  * then this FU can be used as the only register file
580  * to be used for reduced connectivity-register copying.
581  *
582  * @param rf Register file to be checked.
583  * @return Returns true if the given RF is connected to all ports in all FU's
584  * and at least to some output port in all immediate units.
585  */
586 bool
588  const TTAMachine::RegisterFile& rf) {
589 
590  return fromRfConnected(rf) && toRfConnected(rf);
591 }
592 
593 std::pair<int, int>
595  const TTAMachine::Machine& mach) {
596  std::pair<int, int> rv;
597  std::set<const TTAMachine::Bus*> buses;
598  for (auto b: mach.busNavigator()) {
599  buses.insert(b);
600  }
601  shortImmBits(buses, rv);
602  return rv;
603 }
604 
605 void
607  std::set<const TTAMachine::Bus*>& buses, std::pair<int, int>& immBits) {
608 
609  for (auto b: buses) {
610  int w = b->immediateWidth();
611  if (b->signExtends()) {
612  immBits.first = std::max(immBits.first, w);
613  } else {
614  immBits.second = std::max(immBits.second,w);
615  }
616  }
617 }
618 
619 std::pair<int, int>
621  const TTAMachine::RegisterFile& rf) {
622  auto mach = rf.machine();
623  std::pair<int, int> rv(0,0);
624  std::set<const TTAMachine::Bus*> rfBuses;
625 
626  if (mach == nullptr) {
627  return rv;
628  }
629 
630  for (int i = 0; i < rf.portCount(); i++) {
631  auto port = rf.port(i);
632  if (port->inputSocket() != NULL) {
633  appendConnectedSourceBuses(*port, rfBuses);
634  }
635  }
636  shortImmBits(rfBuses, rv);
637 
638  // then check LIMM connections.
639  for (auto iu: mach->immediateUnitNavigator()) {
640  int w = iu->width();
641  for (int j = 0; j < iu->portCount(); j++ ) {
642  Port& port = *iu->port(j);
643  if (port.outputSocket() == nullptr)
644  continue;
645 
646  std::set<const TTAMachine::Bus*> sharedBuses;
648  rfBuses, connectedDestinationBuses(port),sharedBuses);
649  // TODO: check bus widths.
650  if (sharedBuses.size() != 0) {
651  if (iu->signExtends()) {
652  rv.first = std::max(rv.first, w);
653  } else {
654  rv.second = std::max(rv.second, w);
655  }
656  }
657  }
658  }
659  return rv;
660 }
661 
662 /**
663  * Checks whether there is a connection to the given Register file
664  * from all FU's and control unit of the machine.
665  *
666  * It both this and fromRfConnected() returns true,
667  * then this FU can be used as the only register file
668  * to be used for reduced connectivity-register copying.
669  *
670  * @param brf Register file or immediate unit being checked.
671  * @return true if this RF can write to all ports af all FU's.
672  */
673 bool
675  const TTAMachine::RegisterFile& rf) {
676 
677  int width = rf.width();
678  bool isVectorRF = width > 32;
679  TTAMachine::Machine& mach = *rf.machine();
681  mach.functionUnitNavigator();
683  mach.immediateUnitNavigator();
684 
685  std::set<const TTAMachine::Bus*> rfBuses;
686 
687  std::set<int> widths;
688  widths.insert(rf.width());
689  if (width == 32) {
690  widths.insert(1);
691  widths.insert(16); // Needed for half-floats?
692 
693  }
694  if (width == 1) {
695  widths.insert(32);
696  }
697 
698  for (int i = 0; i < rf.portCount(); i++) {
699  const TTAMachine::Port& port = *rf.port(i);
700  if (port.inputSocket() != NULL) {
701  appendConnectedSourceBuses(port, rfBuses);
702  }
703  }
704 
705  // check connections from function units
706  for (auto fu: fuNav) {
707  for (int j = 0; j < fu->portCount(); j++ ) {
708  Port& port = *fu->port(j);
709  // connections from FU to RF
710  if (port.outputSocket() != NULL &&
711  isPortApplicableToWidths(port, widths) &&
712  port.width() >= width) {
713  std::set<const TTAMachine::Bus*> sharedBuses;
715  rfBuses, connectedDestinationBuses(port), sharedBuses);
716  if (sharedBuses.size() == 0) {
717  return false;
718  }
719  }
720  }
721  }
722 
723  // no need to check for imms or cu connections for vector RFs
724  if (isVectorRF) {
725  return true;
726  }
727 
728  // check connections from control unit
729  TTAMachine::ControlUnit& cu = *mach.controlUnit();
730  for (int i = 0; i < cu.portCount(); i++ ) {
731  Port& port = *cu.port(i);
732 
733  // connections from CU to RF
734  if (port.width() == width) {
735  if (port.outputSocket() != NULL) {
736  std::set<const TTAMachine::Bus*> sharedBuses;
738  rfBuses, connectedDestinationBuses(port), sharedBuses);
739  if (sharedBuses.size() == 0) {
740  return false;
741  }
742  }
743  }
744  }
745 
746  // if all immediates can be written to the RF?
747  auto rfImmBits = immBits(rf);
748  if (rfImmBits.first >= width || rfImmBits.second >= width) {
749  return true;
750  }
751 
752  // if there are wider imms in the adf, not ok
753  auto allImmBits = immBits(*rf.machine());
754  if (rfImmBits.first < allImmBits.first ||
755  (rfImmBits.second < allImmBits.second &&
756  (rfImmBits.first-1) < allImmBits.second)) {
757  return false;
758  }
759  return true;
760 }
761 
762 /**
763  * Returns all buses the given port can read from.
764  *
765  * @param port The port to check.
766  * @return The set of buses connected to the port.
767  */
768 std::set<const TTAMachine::Bus*>
770  const TTAMachine::Port& port) {
771 
772  std::set<const TTAMachine::Bus*> buses;
773  appendConnectedSourceBuses(port,buses);
774  return buses;
775 }
776 
777 /**
778  * Returns all buses the given port can write to
779  *
780  * @param port The port to check.
781  * @return The set of buses connected to the port.
782  */
783 std::set<const TTAMachine::Bus*>
785  const TTAMachine::Port& port) {
786 
787  std::set<const TTAMachine::Bus*> buses;
789  return buses;
790 }
791 
792 /**
793  * Appends source buses connected to a given (input) port.
794  *
795  * @param port The port to check
796  * @param buses Set where the connected buses are appended.
797  */
798 void
800  const TTAMachine::Port& port, std::set<const TTAMachine::Bus*>& buses) {
801 
802  const TTAMachine::Socket* inputS = port.inputSocket();
803 
804  if (inputS != NULL) {
805  for (int i = 0; i < inputS->segmentCount(); ++i) {
806  buses.insert(inputS->segment(i)->parentBus());
807  }
808  }
809 }
810 
811 /**
812  * Appends destination buses connected to a given (output) port.
813  *
814  * @param port The port to check
815  * @param buses Set where the connected buses are appended.
816  */
817 void
819  const TTAMachine::Port& port, std::set<const TTAMachine::Bus*>& buses) {
820 
821  const TTAMachine::Socket* outputS = port.outputSocket();
822 
823  if (outputS != NULL) {
824  for (int i = 0; i < outputS->segmentCount(); ++i) {
825  buses.insert(outputS->segment(i)->parentBus());
826  }
827  }
828 }
829 
830 /**
831  * Appends source buses connected to a given unit.
832  *
833  * Source buses are the buses the unit can read data from.
834  *
835  * @param unit The unit to check
836  * @param buses Set where the connected buses are appended.
837  */
838 void
840  const TTAMachine::Unit& unit, std::set<const TTAMachine::Bus*>& buses) {
841 
842  for (int p = 0; p < unit.portCount(); ++p) {
843  const TTAMachine::Port& port = *unit.port(p);
844  appendConnectedSourceBuses(port, buses);
845  }
846 }
847 
848 /**
849  * Appends destination buses connected to a given unit.
850  *
851  * Destination buses are the buses the unit can write data to.
852  *
853  * @param unit The unit to check
854  * @param buses Set where the connected buses are appended.
855  */
856 void
858  const TTAMachine::Unit& unit, std::set<const TTAMachine::Bus*>& buses) {
859 
860  for (int p = 0; p < unit.portCount(); ++p) {
861  appendConnectedDestinationBuses(*unit.port(p), buses);
862  }
863 }
864 
865 /**
866  * Checks if given RF is connected to differently connected RFs,
867  * to know if we need to reserve temp registers for transfers between
868  * the two RFs.
869  *
870  * TODO: This isn't always needed: there is no need to reserve a register
871  * from an RF if it is only connected to RFs with a subset of the
872  * connectivity it offers.
873  */
874 bool
876  const TTAMachine::RegisterFile& rf) {
877  auto regNav = rf.machine()->registerFileNavigator();
878  for (auto rf2: regNav) {
879  if ((rf2 != &rf) &&
880  (isConnected(rf,*rf2) || isConnected(*rf2,rf)) &&
881  !isEquallyConnected(rf, *rf2) &&
882  ((rf.width() <= 32 && rf2->width() <= 32) ||
883  (rf.width() == rf2->width()))) {
884  return true;
885  }
886  }
887  return false;
888 }
889 
891  const TTAMachine::HWOperation& hwop, int index) {
892  OperationPool opPool;
893  Operation& op = opPool.operation(hwop.name().c_str());
894  if (&op == &NullOperation::instance()) {
895  TCEString msg = "ADF has unknown operation: "; msg << hwop.name();
896  throw Exception(__FILE__, __LINE__, __func__, msg);
897  }
898  Operand& operand = op.operand(index);
899  return operand.width();
900 }
901 
902 
903 std::set<const RegisterFile*>
905  const TTAMachine::Machine& machine) {
906 
907  std::map<int, int> noRegInputCount;
908  auto fuNav = machine.functionUnitNavigator();
909  auto regNav = machine.registerFileNavigator();
910 
911  std::set<const RegisterFile*> rv;
912 
913  for (auto fu : fuNav) {
914  for (int j = 0; j < fu->operationCount(); j++) {
915  auto hwop = fu->operation(j);
916  std::map<int, int> myNoRegInputCount;
917  for (int k = 1; k <= hwop->operandCount(); k++) {
918  auto p = hwop->port(k);
919  if (p->inputSocket() != NULL &&
920  (p->noRegister() || p->isTriggering())) {
921  int w = operandWidth(*hwop, k);
922  myNoRegInputCount[w]++;
923  if (w == 1) {
924  myNoRegInputCount[32]++;
925  } else if (w == 32) {
926  myNoRegInputCount[1]++;
927  }
928  }
929  }
930 
931  for(auto mw : myNoRegInputCount) {
932  int w = mw.first;
933  noRegInputCount[w] = std::max(noRegInputCount[w], mw.second);
934  }
935  }
936  }
937  for (auto rf: regNav) {
938  // one read needed for trigger so <= instead of <
939  if (rf->maxReads() < noRegInputCount[rf->width()]) {
940  rv.insert(rf);
941  }
942  }
943  return rv;
944 }
945 
946 bool
948  const TTAMachine::Machine& mach) {
949 
950  std::set<int> scalarWidths = {1,32};
951  for (auto fu: mach.functionUnitNavigator()) {
952  for (int j = 0; j < fu->portCount(); j++ ) {
953  Port& port = *fu->port(j);
954  // connections from RF to FU's
955  if (port.inputSocket() != NULL &&
956  isPortApplicableToWidths(port, scalarWidths)) {
957  if (!canWriteAllImmediates(port)) {
958  return true;
959  }
960  }
961  }
962  }
963  return false;
964 }
965 
967 
968  static bool spammed = false;
969  // check connection from RA to jump for fn return.
972  if (cu.hasOperation("jump")) {
973  auto jumpOp = cu.operation("jump");
974  auto port = jumpOp->port(1);
975  if (!isConnected(ra, *port)) {
976  if (Application::verboseLevel() > 0 && !spammed) {
977  std::cout << "Reserving registers for temp reg use because "
978  << "a connection is missing between the RA port "
979  << "and the address port of jump operation." << std::endl;
980  spammed = true;
981  }
982  return false;
983  }
984  }
985 
986  // check that RA can be loaded and stored
987  TCEString ldOp = machine.isLittleEndian() ? "LD32" : "LDW";
988  TCEString stOp = machine.isLittleEndian() ? "ST32" : "STW";
989  bool hasLoad = false;
990  bool hasStore = false;
991  bool raConnectedToLoad = false;
992  bool raConnectedToStore = false;
993  for (auto fu: machine.functionUnitNavigator()) {
994  if (!fu->hasAddressSpace() ||
995  !fu->addressSpace()->hasNumericalId(0)) {
996  continue;
997  }
998  if (fu->hasOperation(ldOp)) {
999  hasLoad = true;
1000  auto ldhwop = fu->operation(ldOp);
1001  auto port = ldhwop->port(2);
1002  if (isConnected(*port, ra)) {
1003  raConnectedToLoad = true;
1004  }
1005  }
1006 
1007  if (fu->hasOperation(stOp)) {
1008  hasStore = true;
1009  auto sthwop = fu->operation(stOp);
1010  auto port = sthwop->port(2);
1011  if (isConnected(ra, *port)) {
1012  raConnectedToStore = true;
1013  }
1014  }
1015  }
1016 
1017  if ((raConnectedToLoad || !hasLoad) &&
1018  (raConnectedToStore || !hasStore)) {
1019  return true;
1020  } else {
1021  if (Application::verboseLevel() > 0 && !spammed) {
1022  std::cout << "Reserving registers for temp reg use because "
1023  << "a connection is missing between the RA port "
1024  << "and the LSU." << std::endl;
1025  spammed = true;
1026  }
1027  return false;
1028  }
1029 }
1030 
1031 /**
1032  * Gets all register files needed for limited connectivity temp registers
1033  *
1034  * @param machine machine we are checking
1035  * @return vector of registerfiles whose last register is to be used for
1036  */
1037 std::set<const RegisterFile*, MachinePart::Comparator>
1039  const TTAMachine::Machine& machine) {
1040  static bool spammed = false;
1041 
1042  std::set<const RegisterFile*, TTAMachine::MachinePart::Comparator> rfs;
1043 
1044  auto regNav = machine.registerFileNavigator();
1045  auto iuNav = machine.immediateUnitNavigator();
1046  auto fuNav = machine.functionUnitNavigator();
1047 
1048  auto reducedConnRfs = needRegCopiesDueReadPortConflicts(machine);
1049  std::set<int> portConflictWidths;
1050  for (auto rf: reducedConnRfs) {
1051  int w = rf->width();
1052  portConflictWidths.insert(w);
1053  }
1054 
1055  bool portConflicts = !reducedConnRfs.empty();
1056  bool allConnected = true;
1057  if (portConflicts) {
1058  if (Application::verboseLevel() > 0 && !spammed) {
1059  std::cout << "Reserving registers for temp reg use because " <<
1060  "of possible RF port conflicts; There are operations " <<
1061  "on registerless FUs with more operations than there are " <<
1062  "read ports on some RFs." << std::endl;
1063  spammed = true;
1064  }
1065  allConnected = false;
1066  }
1067  int widestRFWidth = 0;
1068 
1069  std::set<int> lackingConnectivityWidths;
1070  std::set<const TTAMachine::RegisterFile*> allConnectedRFs;
1071  std::map<int, const RegisterFile*> priorityConnectedRFs;
1072  std::map<int, int> regCounts;
1073  std::map<int, int> regFileCounts;
1074 
1075  // may need temp reg copies because immediate operands cannto be
1076  // transferred to all operations directly.
1077  if (allConnected && needsRegisterCopiesDueImmediateOperands(machine)) {
1078  lackingConnectivityWidths.insert(32);
1079  allConnected = false;
1080  if (Application::verboseLevel() > 0 && !spammed) {
1081  std::cout << "Reserving registers for temp reg use because " <<
1082  "all immediate operands are not possible to transfer " <<
1083  "directly. This reduces the number of registers available " <<
1084  "for storing usable values." << std::endl;
1085  spammed = true;
1086  }
1087  }
1088 
1089  for (auto rf: regNav) {
1090  int w = rf->width();
1091  if (w > widestRFWidth) {
1092  widestRFWidth = w;
1093  }
1094  regCounts[w] += rf->size();
1095  regFileCounts[w]++;
1096  }
1097 
1098  for (auto rf: regNav) {
1099  int width = rf->width();
1100  if (!rfConnected(*rf)) {
1101  reducedConnRfs.insert(rf);
1102  allConnected = false;
1103  lackingConnectivityWidths.insert(width);
1104  if (Application::verboseLevel() > 0 && !spammed) {
1105  std::cout << "Reserving registers for temp reg use because RF: "
1106  << rf->name() << " has reduced connectivity to FUs or "
1107  << "immediates." << std::endl;
1108  spammed = true;
1109  }
1110  } else {
1111  allConnectedRFs.insert(rf);
1112  // we have at least on RF connected to everywhere so use it.
1113  // but only if it's wide enough (as wide as the widest RF)
1114  auto connectedRF = priorityConnectedRFs[width];
1115 
1116  // ra/imm/narrowed connectivity for 32bit
1117  if ((width <= 32 || isConnectedToDifferentlyConnectedRFs(*rf)) &&
1118  (connectedRF == nullptr ||
1119  rf->maxReads() * rf->maxWrites() >
1120  connectedRF->maxReads() * connectedRF->maxWrites())) {
1121  priorityConnectedRFs[width] = rf;
1122  }
1123  }
1124  }
1125 
1126  if (!raConnected(machine)) {
1127  allConnected = false;
1128  lackingConnectivityWidths.insert(32);
1129  }
1130 
1131  if (allConnected) {
1132  return rfs;
1133  }
1134 
1135  bool needNextBigger = false;
1136  if (AssocTools::containsKey(lackingConnectivityWidths, 1)) {
1137  if (priorityConnectedRFs[1] != nullptr &&
1138  regCounts[1] > 2 &&
1139  regFileCounts[1] > 1) {
1140  rfs.insert(priorityConnectedRFs[1]);
1141  } else {
1142  needNextBigger = true;
1143  }
1144  }
1145  // 32-bit.
1146  if (needNextBigger ||
1147  AssocTools::containsKey(lackingConnectivityWidths, 32) ||
1148  portConflicts) {
1149  if (!portConflicts && priorityConnectedRFs[32] != nullptr) {
1150  rfs.insert(priorityConnectedRFs[32]);
1151  } else {
1152  for (auto rf: regNav) {
1153  if (rf->width() == 32 &&
1155  portConflicts)) {
1156  rfs.insert(rf);
1157  }
1158  }
1159  }
1160  }
1161 
1162  // vector.
1163  for (int w = 64; w <= widestRFWidth; w*=2) {
1164  if (AssocTools::containsKey(lackingConnectivityWidths, w) ||
1165  portConflicts) {
1166  if (!portConflicts && priorityConnectedRFs[w] != nullptr) {
1167  rfs.insert(priorityConnectedRFs[w]);
1168  } else {
1169  for (auto rf: regNav) {
1170  if (rf->width() == w &&
1172  portConflicts)) {
1173  rfs.insert(rf);
1174  }
1175  }
1176  }
1177  }
1178  }
1179 
1180  return rfs;
1181 }
1182 
1183 
1184 /**
1185  * Checks if there is a way to write immediate directly from bus or from immu
1186  * to the given port
1187  *
1188  * @param port Port where to check immediate write ability.
1189  */
1190 bool
1192  /** First check if there is a bus that can transfer the immediates */
1193  int portWidth = destPort.width();
1194  int sextImm = 0;
1195  int zextImm = 0;
1196 
1197  Socket& socket = *destPort.inputSocket();
1198 
1199  // check immediates from buses
1200  for (int i = 0; i < socket.segmentCount(); ++i) {
1201  auto bus = socket.segment(i)->parentBus();
1202  int immw = bus->immediateWidth();
1203  if (bus->signExtends()) {
1204  sextImm = std::max(immw, sextImm);
1205  } else {
1206  zextImm = std::max(immw, zextImm);
1207  }
1208  if (immw >= portWidth) {
1209  return true;
1210  }
1211  }
1212 
1213  // then check directly connected imm units
1214  const TTAMachine::Machine& mach = *destPort.parentUnit()->machine();
1216  mach.immediateUnitNavigator();
1217 
1218  for (int i = 0; i < iuNav.count(); i++) {
1219  ImmediateUnit& iu = *iuNav.item(i);
1220  int immw = iu.width();
1221  if (isConnected(iu, destPort)) {
1222  if (iu.signExtends()) {
1223  sextImm = std::max(immw, sextImm);
1224  } else {
1225  zextImm = std::max(immw, zextImm);
1226  }
1227  }
1228  }
1229 
1230  auto widestImms = immBits(mach);
1231  // wide zext imm not needed if has one bit wider sext imm.
1232  if (widestImms.first > sextImm ||
1233  (widestImms.second > zextImm && (sextImm-1) < widestImms.second)) {
1234  return false;
1235  }
1236  return true;
1237 }
1238 
1239 /**
1240  * Returns the bit width the immediate requires.
1241  *
1242  * @param signExtension Whether sign extension is used.
1243  * @param source The immediate terminal.
1244  * @return Bitwidth required for the immediate.
1245  */
1246 int
1248  bool signExtension,
1249  const TTAProgram::TerminalImmediate& source,
1250  const TTAMachine::Machine& mach) {
1251 
1252  if (source.isCodeSymbolReference()) {
1253  const AddressSpace& instrAS = *mach.controlUnit()->addressSpace();
1254  if (source.toString() == "_end") {
1255  AddressSpace* dataAS;
1256  try {
1257  dataAS = MachineInfo::defaultDataAddressSpace(mach);
1258  } catch (Exception&) {
1259  assert(false && "No default data address space");
1260  }
1261 
1262  return signExtension ?
1264  MathTools::requiredBits(dataAS->end());
1265  } else {
1266  return signExtension ?
1267  MathTools::requiredBitsSigned (instrAS.end()):
1268  MathTools::requiredBits(instrAS.end());
1269  }
1270  }
1271  if (source.isInstructionAddress() || source.isBasicBlockReference()) {
1272  const AddressSpace& as = *mach.controlUnit()->addressSpace();
1273  return signExtension ?
1276  }
1277 
1278  int bits = -1;
1279  if (signExtension) {
1280  bits =
1282  } else if (!signExtension) {
1283  bits =
1285  }
1286 
1287  return bits;
1288 }
1289 
1291  const TTAMachine::Bus& bus, const TTAMachine::Port& port) {
1292  const TTAMachine::Socket* inputS = port.inputSocket();
1293  if (inputS != NULL) {
1294  for (int i = 0; i < inputS->segmentCount(); ++i) {
1295  if (inputS->segment(i)->parentBus() == &bus) {
1296  return true;
1297  }
1298  }
1299  }
1300  return false;
1301 }
1302 
1303 /**
1304  * Returns true if bus is connected to the RF's any writing port.
1305  */
1307  const TTAMachine::Bus& bus, const TTAMachine::Unit& destRF) {
1308  for (int i = 0; i < destRF.portCount(); i++) {
1309  const TTAMachine::Port& port = *destRF.port(i);
1311  return true;
1312  }
1313  }
1314  return false;
1315 }
1316 
1317 
1318 bool
1320  const TTAMachine::Bus& bus, const FunctionUnit& fu,
1321  const TCEString& opName, int opIndex) {
1322 
1323  if (fu.hasOperationLowercase(opName)) {
1324  const TTAMachine::HWOperation& hwop =
1325  *fu.operationLowercase(opName);
1326 
1327  TTAMachine::FUPort* port = hwop.port(opIndex);
1328  if (port == NULL){
1329  throw IllegalMachine(
1330  __FILE__, __LINE__, __func__,
1331  "Target is missing operand bindings for: "
1332  + opName);
1333  }
1335  }
1336  return false;
1337 }
1338 
1339 
1340 bool
1342  const TTAMachine::Bus& bus, const MoveNode& moveNode) {
1343 
1344  const TTAProgram::Move& move = moveNode.move();
1346  static_cast<TTAProgram::TerminalFUPort*>(&move.destination());
1347  int opIndex = tfp->operationIndex();
1348 
1349  ProgramOperation& po = moveNode.destinationOperation();
1350  auto fu = po.scheduledFU();
1351 /*
1352  for (int i = 0; i < po.inputMoveCount(); i++ ) {
1353  MoveNode& inputNode = po.inputMove(i);
1354  if (inputNode.isAssigned()) {
1355  unit = inputNode.move().destination().port().parentUnit();
1356  break;
1357  }
1358  }
1359  if (unit == NULL) { // goto over this would have been better
1360  for (int i = 0; i < po.outputMoveCount(); i++ ) {
1361  MoveNode& outputNode = po.outputMove(i);
1362  if (outputNode.isAssigned()) {
1363  if (outputNode.isSourceOperation() &&
1364  &outputNode.sourceOperation() == &po) {
1365  unit = outputNode.move().source().port().parentUnit();
1366  break;
1367  } else {
1368  assert (!outputNode.move().isUnconditional());
1369  assert (&outputNode.guardOperation() == &po);
1370  const TTAMachine::Guard& guard =
1371  outputNode.move().guard().guard();
1372  const TTAMachine::PortGuard* pg =
1373  dynamic_cast<const TTAMachine::PortGuard*>(&guard);
1374  assert(pg); // todo: throw?
1375  unit = pg->port()->parentUnit();
1376  break;
1377  }
1378  }
1379  }
1380  }
1381 */
1382 
1383  Operation& op = move.destination().hintOperation();
1384  TCEString opName = StringTools::stringToLower(op.name());
1385 
1386  if (fu != NULL) {
1387 // const FunctionUnit* fu = dynamic_cast<const FunctionUnit*>(unit);
1388  assert(fu != NULL);
1389  return busConnectedToFU(bus, *fu, opName, opIndex);
1390  }
1391 
1392  // check if the move has a candidate FU set which limits the
1393  // choice of FU for the node
1394  std::set<TCEString> candidateFUs;
1395  std::set<TCEString> allowedFUs;
1396 
1398  candidateFUs, move,
1401  allowedFUs, move,
1403 
1405  if (candidateFUs.empty() || AssocTools::containsKey(
1406  candidateFUs,gcu->name())) {
1407  if (busConnectedToFU(bus, *gcu, opName, opIndex)) {
1408  return true;
1409  }
1410  }
1411 
1412 
1414  bus.machine()->functionUnitNavigator();
1415  for (int i = 0; i < fuNav.count(); i++) {
1416  TTAMachine::FunctionUnit& fu = *fuNav.item(i);
1417  if (!candidateFUs.empty() && !AssocTools::containsKey(
1418  candidateFUs,fu.name())) {
1419  continue;
1420  }
1421  if (!allowedFUs.empty() && !AssocTools::containsKey(
1422  allowedFUs,fu.name())) {
1423  continue;
1424  }
1425  if (busConnectedToFU(bus, fu, opName, opIndex)) {
1426  return true;
1427  }
1428  }
1429  return false;
1430 }
1431 
1432 bool
1434  const TTAMachine::Bus& bus,
1435  const MoveNode& moveNode) {
1436  const TTAProgram::Move& move = moveNode.move();
1437  if (move.destination().isGPR()) {
1438  TTAMachine::Unit& destRF =
1439  *move.destination().port().parentUnit();
1440  return MachineConnectivityCheck::busConnectedToRF(bus, destRF);
1441 
1442  }
1443  if (move.destination().isFUPort()) {
1444  if (move.destination().isRA()) {
1445  const TTAMachine::ControlUnit* gcu = bus.machine()->controlUnit();
1446  const TTAMachine::SpecialRegisterPort* ra =
1447  gcu->returnAddressPort();
1448  // TODO:: machineconcctivitycheck, bus connected to port?
1450  return true;
1451  }
1452  } else {
1454  bus, moveNode);
1455  }
1456  }
1457  return false;
1458 }
1459 
1460 int
1462  const TTAMachine::Machine& mach) {
1463  int totalFound = 0;
1464  for (int bi = 0; bi < mach.busNavigator().count(); ++bi) {
1465  const TTAMachine::Segment& s =
1466  *mach.busNavigator().item(bi)->segment(0);
1467  totalFound += s.connectionCount();
1468  }
1469  return totalFound;
1470 }
1471 
1472 
1475  const TTAMachine::Machine& mach,
1476  const MoveNode& node) {
1477  PortSet res;
1478  if (node.isScheduled()) {
1479  res.insert(&node.move().destination().port());
1480  return res;
1481  }
1482 
1483  if (node.isDestinationOperation()) {
1485  mach.functionUnitNavigator();
1487  std::set<TCEString> allowedFUNames;
1488 
1489  if (po.isAnyNodeAssigned()) {
1490  for (int i = 0; i < po.inputMoveCount(); i++) {
1491  MoveNode& mn = po.inputMove(i);
1492  if (mn.isScheduled()) {
1493  allowedFUNames.insert(
1494  mn.move().destination().port().parentUnit()->name());
1495  }
1496  }
1497 
1498  for (int i = 0; i < po.outputMoveCount(); i++) {
1499  MoveNode& mn = po.outputMove(i);
1500  if (mn.isScheduled()) {
1501  if (mn.isSourceOperation() && &mn.sourceOperation() == &po) {
1502  allowedFUNames.insert(
1503  mn.move().source().port().parentUnit()->name());
1504  } else {
1505  if (mn.isGuardOperation() &&
1506  &mn.guardOperation() == &po) {
1507  const TTAMachine::Guard& guard =
1508  mn.move().guard().guard();
1509  const TTAMachine::PortGuard* pg =
1510  dynamic_cast<const TTAMachine::PortGuard*>(&guard);
1511  assert(pg); // todo: throw?
1512  const TTAMachine::Unit* u = pg->port()->parentUnit();
1513  allowedFUNames.insert(u->name());
1514  }
1515  }
1516  }
1517  }
1518  }
1519 
1520  std::set<TCEString> candidateFUs;
1521  std::set<TCEString> allowedFUs;
1522 
1524  candidateFUs, node.move(),
1527  allowedFUs, node.move(),
1529 
1530  if (!candidateFUs.empty()) {
1531  if (allowedFUNames.empty()) {
1532  allowedFUNames = candidateFUs;
1533  } else {
1534  std::set<TCEString> tmp;
1535  SetTools::intersection(allowedFUNames, candidateFUs,tmp);
1536  allowedFUNames = tmp;
1537  }
1538 
1539  }
1540 
1541  if (!allowedFUs.empty()) {
1542  if (allowedFUNames.empty()) {
1543  allowedFUNames = allowedFUs;
1544  } else {
1545  std::set<TCEString> tmp;
1546  SetTools::intersection(allowedFUNames, allowedFUs,tmp);
1547  allowedFUNames = tmp;
1548  }
1549  }
1550 
1551  for (int i = 0; i <= nav.count(); i++) {
1553  if (i == nav.count()) { // GCU is not on fu navigator
1554  fu = mach.controlUnit();
1555  } else {
1556  fu = nav.item(i);
1557  }
1558 
1559  if (!allowedFUNames.empty() && !AssocTools::containsKey(
1560  allowedFUNames, fu->name())) {
1561  continue;
1562  }
1563  if (fu->hasOperation(po.operation().name())) {
1564  TTAMachine::HWOperation* hwop =
1565  fu->operation(po.operation().name());
1566  res.insert(
1567  hwop->port(node.move().destination().operationIndex()));
1568  }
1569  }
1570  return res;
1571  }
1572 
1573  if (node.move().destination().isRA()) {
1574  res.insert(mach.controlUnit()->returnAddressPort());
1575  return res;
1576  }
1577 
1578  // destination is register
1579  if (!node.move().destination().isGPR()) {
1580  std::cerr << "node should have dest as reg: " <<
1581  node.toString() << std::endl;
1582  }
1583  assert(node.move().destination().isGPR());
1584  return findWritePorts(
1585  *node.move().destination().port().parentUnit());
1586 }
1587 
1590  PortSet res;
1591  for (int i = 0; i < rf.portCount(); i++) {
1592  const TTAMachine::Port* port = rf.port(i);
1593  if (port->isInput()) {
1594  res.insert(port);
1595  }
1596  }
1597  return res;
1598 }
1599 
1602  PortSet res;
1603  for (int i = 0; i < rf.portCount(); i++) {
1604  TTAMachine::Port* port = rf.port(i);
1605  if (port->isOutput()) {
1606  res.insert(port);
1607  }
1608  }
1609  return res;
1610 }
1611 
1612 /**
1613  * Returns true if there is connection between the port and the bus.
1614  */
1615  bool
1617  const TTAMachine::Bus& bus,
1618  const TTAMachine::Port& port) {
1619  std::vector<const Socket*> sockets{
1620  port.inputSocket(), port.outputSocket()};
1621 
1622  for (const Socket* socket : sockets) {
1623  if (socket != nullptr && socket->isConnectedTo(bus)) {
1624  return true;
1625  }
1626  }
1627  return false;
1628  }
1629 
1630  /**
1631  * Returns true if there is connection between the port and the bus.
1632  */
1633  bool
1635  const TTAMachine::Port& port,
1636  const TTAMachine::Bus& bus) {
1637  return isConnected(bus, port);
1638  }
1639 
1640  /**
1641  * Returns true if all ports are connected to the bus.
1642  */
1643  bool
1645  const std::set<TTAMachine::Port*> ports, const TTAMachine::Bus& bus) {
1646  for (const auto& port : ports) {
1647  if (!isConnected(bus, *port)) {
1648  return false;
1649  }
1650  }
1651  return true;
1652  }
1653 
1654 /**
1655  * Returns busses that connects the given ports.
1656  */
1659  TTAMachine::Port& port1,
1660  TTAMachine::Port& port2) {
1661 
1663  const Machine& mach = *port1.parentUnit()->machine();
1664  for (Bus* bus : mach.busNavigator()) {
1665  if (isConnected(port1, *bus) && isConnected(port2, *bus)) {
1666  result.insert(bus);
1667  }
1668  }
1669  return result;
1670 }
1671 
1674  const TTAMachine::Machine& mach, const MoveNode& node) {
1675  PortSet res;
1676  if (node.isScheduled() && !node.isSourceConstant()) {
1677  res.insert(&node.move().source().port());
1678  return res;
1679  }
1680 
1681  if (node.isSourceOperation()) {
1683  mach.functionUnitNavigator();
1684  ProgramOperation& po = node.sourceOperation();
1685 
1686  std::set<TCEString> candidateFUs;
1687  std::set<TCEString> allowedFUs;
1688 
1689  addAnnotatedFUs(candidateFUs, node.move(),
1691  addAnnotatedFUs(allowedFUs, node.move(),
1693 
1694  for (int i = 0; i < nav.count(); i++) {
1695  TTAMachine::FunctionUnit* fu = nav.item(i);
1696  if (!allowedFUs.empty() && !AssocTools::containsKey(
1697  allowedFUs, fu->name())) {
1698  continue;
1699  }
1700  if (!candidateFUs.empty() && !AssocTools::containsKey(
1701  candidateFUs, fu->name())) {
1702  continue;
1703  }
1704 
1705  if (fu->hasOperation(po.operation().name())) {
1706  TTAMachine::HWOperation* hwop =
1707  fu->operation(po.operation().name());
1708  res.insert(
1709  hwop->port(node.move().source().operationIndex()));
1710  }
1711  }
1712  return res;
1713  }
1714 
1715  if (node.isSourceVariable()) {
1716  // source is register
1717  return findReadPorts(
1718  *node.move().source().port().parentUnit());
1719  }
1720 
1721  // consider only long immediates here.
1722  if (node.isSourceConstant()) {
1724  static_cast<TTAProgram::TerminalImmediate&>(node.move().source());
1726  mach.immediateUnitNavigator();
1727  for (int i = 0; i < nav.count(); i++) {
1728  TTAMachine::ImmediateUnit* iu = nav.item(i);
1729  if (iu->width() >=
1731  iu->extensionMode() == Machine::SIGN, imm, mach)) {
1732  for (int i = 0; i < iu->portCount(); i++) {
1733  TTAMachine::Port* port = iu->port(i);
1734  assert(port->isOutput());
1735  res.insert(port);
1736  }
1737  }
1738  }
1739  return res;
1740  }
1741 
1742  if (node.move().source().isRA()) {
1743  res.insert(mach.controlUnit()->returnAddressPort());
1744  }
1745 
1746  return res;
1747 }
1748 
1749 /**
1750  * 1 = can write
1751  * 0 = cannot write
1752  * -1 = can write through limm
1753  */
1755  const MoveNode& src, PortSet& destinationPorts, bool ignoreGuard) {
1756 
1757  int trueVal = 1;
1758  if (destinationPorts.empty()) {
1759  return false;
1760  }
1761 
1762  if (src.isSourceConstant()) {
1764  static_cast<TTAProgram::TerminalImmediate*>(
1765  &src.move().source());
1767  *imm, destinationPorts)) {
1768  return true; // can transfer via short imm.
1769  } else {
1770  trueVal = -1; // mayby through LIMM?
1771  }
1772  }
1773 
1774  PortSet sourcePorts = findPossibleSourcePorts(
1775  *(*destinationPorts.begin())->parentUnit()->machine(), src);
1776 
1777  // TODO: Why cannot move.guard return pointer which is NULL if unconditional?
1778  const TTAProgram::Move& move = src.move();
1780  sourcePorts, destinationPorts,
1781  (ignoreGuard || move.isUnconditional()) ?
1782  NULL : &move.guard().guard())) {
1783  return trueVal;
1784  }
1785 
1786  return false;
1787 }
1788 
1790  const MoveNode& src, const MoveNode& user,
1791  const TTAMachine::Machine& targetMachine) {
1792 
1793  MachineConnectivityCheck::PortSet destinationPorts =
1795  targetMachine, user);
1796 
1797  int trueVal = 1;
1798  if (destinationPorts.empty()) {
1799  return false;
1800  }
1801 
1802  if (src.isSourceConstant()) {
1804  static_cast<TTAProgram::TerminalImmediate*>(
1805  &src.move().source());
1807  *imm, destinationPorts)) {
1808  return true; // can transfer via short imm.
1809  } else {
1810  trueVal = -1; // mayby through LIMM?
1811  }
1812  }
1813 
1814  PortSet sourcePorts = findPossibleSourcePorts(targetMachine, src);
1815 
1816  // TODO: Why cannot move.guard return pointer which is NULL if
1817  // unconditional?
1818  const TTAProgram::Move& userMove = user.move();
1820  sourcePorts, destinationPorts,
1821  userMove.isUnconditional() ? NULL : &userMove.guard().guard())) {
1822  return trueVal;
1823  }
1824 
1825  return false;
1826 }
1827 
1828 
1829 bool
1831  PortSet& sourcePorts, const MoveNode& dest) {
1832 
1833  if (sourcePorts.empty()) {
1834  return false;
1835  }
1836 
1838  *(*sourcePorts.begin())->parentUnit()->machine(), dest);
1839  return MachineConnectivityCheck::isConnected(sourcePorts, destPorts);
1840 }
1841 
1842 bool
1844  const MoveNode& moveNode,
1846  bool ignoreGuard) {
1847  PortSet destinationPorts =
1849  machine,moveNode);
1850 
1852  moveNode, destinationPorts, ignoreGuard);
1853 }
1854 
1855 void
1857  std::set<TCEString>& candidateFUs,
1858  const TTAProgram::Move& m,
1860 
1861  const int annotationCount = m.annotationCount(id);
1862  for (int i = 0; i < annotationCount; ++i) {
1863  std::string candidateFU = m.annotation(i, id).stringValue();
1864  candidateFUs.insert(candidateFU);
1865  }
1866 }
1867 
1868 /* These are static */
1873 
1874 
1875 bool
1877  const TTAMachine::Machine& mach, const std::set<int>& rfWidths) {
1878 
1879  const Machine::RegisterFileNavigator regNav =
1880  mach.registerFileNavigator();
1881 
1882  std::set<std::pair<const RegisterFile*,int> > allGuardRegs;
1883  const Machine::BusNavigator& busNav = mach.busNavigator();
1884 
1885  // first just collect all guard registers.
1886  for (int bi = 0; bi < busNav.count(); ++bi) {
1887  Bus* bus = busNav.item(bi);
1888  for (int gi = 0; gi < bus->guardCount(); gi++) {
1889  const Guard* guard = bus->guard(gi);
1890  const TTAMachine::RegisterGuard* rg =
1891  dynamic_cast<const RegisterGuard*>(guard);
1892  if (rg != NULL) {
1893  allGuardRegs.insert(
1894  std::pair<const RegisterFile*,int>(rg->registerFile(),
1895  rg->registerIndex()));
1896  }
1897  }
1898  }
1899 
1900  if (allGuardRegs.empty()) {
1901  return false;
1902  }
1903 
1904  // then check for the connections.
1905  for (int i = 0; i < regNav.count(); i++) {
1906  const TTAMachine::RegisterFile* srf = regNav.item(i);
1907  for (int j = 0; j < regNav.count(); j++) {
1908  const TTAMachine::RegisterFile* drf = regNav.item(i);
1909  int width = drf->width();
1910 
1911  // if we do not care about RFs of this size
1912  if (!rfWidths.empty() &&
1913  !AssocTools::containsKey(rfWidths, width)) {
1914  continue;
1915  }
1916 
1917  for (std::set<std::pair<const RegisterFile*,int> >::iterator k =
1918  allGuardRegs.begin(); k != allGuardRegs.end(); k++) {
1919  if (!isConnectedWithBothGuards(*srf, *drf, *k)) {
1920  return false;
1921  }
1922  }
1923  }
1924  }
1925  return true;
1926 }
1927 /*
1928 bool
1929 MachineConnectivityCheck::hasConditionalOperations(
1930  const TTAMachine::Machine& mach) {
1931 
1932 }
1933 */
1934 
1935 /**
1936  * Checks whether there is a connection from some outport port of a
1937  * register file or immediate unit into some input port of the given
1938  * target register file or immediate unit.
1939  *
1940  * @param sourceRF Source RF/Immediate unit.
1941  * @param destRF Source RF/Immediate unit.
1942  * @return True if there is at least one connection from any of the output
1943  * ports of the source RF/Imm unit into the destination RF.
1944  */
1945 bool
1947  const TTAMachine::BaseRegisterFile& sourceRF,
1948  const TTAMachine::BaseRegisterFile& destRF,
1949  std::pair<const RegisterFile*,int> guardReg) {
1950 
1951  RfRfBoolMap::const_iterator
1952  i = rfRfCache_.find(RfRfPair(&sourceRF, &destRF));
1953  if (i != rfRfCache_.end()) {
1954  if (i->second == false) {
1955  return false;
1956  }
1957  }
1958  std::set<const TTAMachine::Bus*> srcBuses;
1959  appendConnectedDestinationBuses(sourceRF, srcBuses);
1960 
1961  std::set<const TTAMachine::Bus*> dstBuses;
1962  appendConnectedSourceBuses(destRF, dstBuses);
1963 
1964  std::set<const TTAMachine::Bus*> sharedBuses;
1965  SetTools::intersection(srcBuses, dstBuses, sharedBuses);
1966 
1967  bool trueOK = false;
1968  bool falseOK = false;
1969  if (sharedBuses.size() > 0) {
1970  rfRfCache_[RfRfPair(&sourceRF,&destRF)] = true;
1971  for (auto bus: sharedBuses) {
1972  std::pair<bool, bool> guardsOK = hasBothGuards(bus, guardReg);
1973  trueOK |= guardsOK.first;
1974  falseOK |= guardsOK.second;
1975  if (trueOK && falseOK) {
1976  return true;
1977  }
1978  }
1979  }
1980  return false;
1981 }
1982 
1984  const TTAMachine::Bus* bus, std::pair<const RegisterFile*,int> guardReg) {
1985  bool trueOK = false;
1986  bool falseOK = false;
1987 
1988  for (int gi = 0; gi < bus->guardCount(); gi++) {
1989  const TTAMachine::Guard* guard = bus->guard(gi);
1990  const TTAMachine::RegisterGuard* rg =
1991  dynamic_cast<const TTAMachine::RegisterGuard*>(guard);
1992  if (rg != NULL) {
1993  if (rg->registerFile() == guardReg.first &&
1994  rg->registerIndex() == guardReg.second) {
1995  if (rg->isInverted()) {
1996  falseOK = true;
1997  } else {
1998  trueOK = true;
1999  }
2000  if (falseOK && trueOK) {
2001  return std::pair<bool, bool>(true, true);
2002  }
2003  }
2004  }
2005  }
2006  return std::pair<bool, bool>(trueOK, falseOK);
2007 }
2008 
2010  const TTAMachine::Machine& targetMachine) {
2011  auto iuNav = targetMachine.immediateUnitNavigator();
2012  int limmCount = 0;
2013  for (auto iu : iuNav) {
2014  limmCount += iu->maxReads();
2015  }
2016  return limmCount;
2017 }
2018 
2020  const TTAMachine::Machine& targetMachine) {
2021 
2022  auto busNav = targetMachine.busNavigator();
2023  int simmCount = 0;
2024  for (auto bus : busNav) {
2025  if (bus->immediateWidth() > 0) {
2026  simmCount++;
2027  }
2028  }
2029  return simmCount;
2030 }
2031 
2032 /**
2033  * Find FU which has copy op that can be used to schedule this move.
2034  *
2035  * Prioritizes FUs which can schedule the move directly with one
2036  * copy op. If none found, then fives FU which has copy op and
2037  * can recursively be used with later copy.
2038  * If none found at all, returns empty set.
2039  */
2041  const TTAMachine::Machine& mach,
2042  const MoveNode& mn) {
2043 
2044  // with these, single copy op is enough
2045  FUSet suitableFUs;
2046  // with these, have to use multiple copy ops or copy+regcopy
2047  FUSet partiallySuitableFUs;
2048 
2049  std::string opName = "COPY";
2050  const TTAProgram::Move& move = mn.move();
2051  auto destinationPorts = findPossibleDestinationPorts(mach, mn);
2052 
2053  for (auto fu: mach.functionUnitNavigator()) {
2054  PortSet copyOutPorts;
2055  PortSet copyTriggerPorts;
2056  if (fu->hasOperation(opName)) {
2057  TTAMachine::HWOperation* hwop = fu->operation(opName);
2058  copyOutPorts.insert(hwop->port(2));
2059  copyTriggerPorts.insert(hwop->port(1));
2061  copyOutPorts, destinationPorts,
2062  (move.isUnconditional()) ?
2063  nullptr : &move.guard().guard())) {
2064  partiallySuitableFUs.insert(fu);
2066  mn, copyTriggerPorts)) {
2067  suitableFUs.insert(fu);
2068  }
2069  }
2070  }
2071  }
2072  return suitableFUs.empty() ? partiallySuitableFUs : suitableFUs;
2073 }
2074 
2076  const TTAMachine::Machine& mach,
2077  const TCEString& opName,
2078  int outIndex,
2079  const MoveNode& mn) {
2080 
2081  PortSet sourcePorts;
2082 
2084  mach.functionUnitNavigator();
2085  for (auto fu: fuNav) {
2086  if (fu->hasOperation(opName)) {
2087  TTAMachine::HWOperation* hwop = fu->operation(opName);
2088  sourcePorts.insert(hwop->port(outIndex));
2089  }
2090  }
2091 
2092  MachineConnectivityCheck::PortSet destinationPorts =
2094 
2095  const TTAProgram::Move& move = mn.move();
2097  sourcePorts, destinationPorts,
2098  (move.isUnconditional()) ?
2099  nullptr : &move.guard().guard());
2100 }
Operand
Definition: Operand.hh:52
TTAMachine::Bus::hasGuard
bool hasGuard(const Guard &guard) const
Definition: Bus.cc:393
TTAMachine::Bus::immediateWidth
int immediateWidth() const
Definition: Bus.cc:160
TTAMachine::Guard
Definition: Guard.hh:55
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
MachineConnectivityCheck::PortPortBoolMap
std::map< PortPortPair, bool > PortPortBoolMap
Definition: MachineConnectivityCheck.hh:314
MachineConnectivityCheck::findPossibleDestinationPorts
static PortSet findPossibleDestinationPorts(const TTAMachine::Machine &mach, const MoveNode &node)
Definition: MachineConnectivityCheck.cc:1474
MachineConnectivityCheck::busConnectedToPort
static bool busConnectedToPort(const TTAMachine::Bus &bus, const TTAMachine::Port &port)
Definition: MachineConnectivityCheck.cc:1290
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
OperationPool::operation
Operation & operation(const char *name)
Definition: OperationPool.cc:99
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
MachineConnectivityCheck::PortPortPair
std::pair< const TTAMachine::Port *, const TTAMachine::Port * > PortPortPair
Definition: MachineConnectivityCheck.hh:303
MachineConnectivityCheck::findPossibleSourcePorts
static PortSet findPossibleSourcePorts(const TTAMachine::Machine &mach, const MoveNode &node)
Definition: MachineConnectivityCheck.cc:1673
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
MachineConnectivityCheck.hh
MachineConnectivityCheck::appendConnectedSourceBuses
static void appendConnectedSourceBuses(const TTAMachine::Port &port, std::set< const TTAMachine::Bus * > &buses)
Definition: MachineConnectivityCheck.cc:799
TTAMachine::PortGuard::port
FUPort * port() const
SimValue::sLongWordValue
SLongWord sLongWordValue() const
Definition: SimValue.cc:997
TTAProgram::Terminal::isInstructionAddress
virtual bool isInstructionAddress() const
Definition: Terminal.cc:87
MachineConnectivityCheck::isConnectedToDifferentlyConnectedRFs
static bool isConnectedToDifferentlyConnectedRFs(const TTAMachine::RegisterFile &rf)
Definition: MachineConnectivityCheck.cc:875
machine
TTAMachine::Machine * machine
the architecture definition of the estimated processor
Definition: EstimatorCmdLineUI.cc:59
MachineConnectivityCheck::isConnectedWithBothGuards
static bool isConnectedWithBothGuards(const TTAMachine::BaseRegisterFile &sourceRF, const TTAMachine::BaseRegisterFile &destRF, std::pair< const TTAMachine::RegisterFile *, int > guardReg)
Definition: MachineConnectivityCheck.cc:1946
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::AddressSpace
Definition: AddressSpace.hh:51
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
MachineConnectivityCheck::RfRfBoolMap
std::map< RfRfPair, bool > RfRfBoolMap
Definition: MachineConnectivityCheck.hh:315
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
MoveNode::isDestinationOperation
bool isDestinationOperation() const
TTAMachine::Segment
Definition: Segment.hh:54
AssocTools::containsKey
static bool containsKey(const ContainerType &aContainer, const KeyType &aKey)
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
MachineConnectivityCheck::canTransportImmediate
static bool canTransportImmediate(const TTAProgram::TerminalImmediate &immediate, const TTAMachine::BaseRegisterFile &destRF, const TTAMachine::Guard *guard=NULL)
Definition: MachineConnectivityCheck.cc:181
TTAProgram::ProgramAnnotation::stringValue
std::string stringValue() const
Definition: ProgramAnnotation.cc:90
TTAMachine::Bus
Definition: Bus.hh:53
TTAMachine::Port::width
virtual int width() const =0
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
MachineConnectivityCheck::RfPortPair
std::pair< const TTAMachine::BaseRegisterFile *, const TTAMachine::Port * > RfPortPair
Definition: MachineConnectivityCheck.hh:309
TTAMachine::FunctionUnit::operationLowercase
virtual HWOperation * operationLowercase(const std::string &name) const
Definition: FunctionUnit.cc:378
TTAMachine::ImmediateUnit::signExtends
bool signExtends() const
Definition: ImmediateUnit.hh:62
Operand::width
virtual int width() const
Definition: Operand.cc:318
MachineInfo.hh
TTAProgram::Terminal::hintOperation
virtual Operation & hintOperation() const
Definition: Terminal.cc:341
TTAProgram::Terminal::isBasicBlockReference
virtual bool isBasicBlockReference() const
Definition: Terminal.cc:139
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
MachineConnectivityCheck::rfConnected
static bool rfConnected(const TTAMachine::RegisterFile &rf)
Definition: MachineConnectivityCheck.cc:587
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
TTAMachine::FunctionUnit::addressSpace
virtual AddressSpace * addressSpace() const
Definition: FunctionUnit.cc:580
MachineConnectivityCheck::canTransportMove
static bool canTransportMove(const MoveNode &moveNode, const TTAMachine::Machine &machine, bool ignoreGuard=false)
Definition: MachineConnectivityCheck.cc:1843
MachineConnectivityCheck::isEquallyConnected
static bool isEquallyConnected(const TTAMachine::BaseRegisterFile &RF1, const TTAMachine::BaseRegisterFile &RF2)
Definition: MachineConnectivityCheck.cc:447
TTAMachine::Socket::segment
Segment * segment(int index) const
Definition: Socket.cc:401
TTAMachine::Machine::Navigator::count
int count() const
NullOperation::instance
static NullOperation & instance()
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
MachineConnectivityCheck::hasConditionalMoves
static bool hasConditionalMoves(const TTAMachine::Machine &mach, const std::set< int > &rfWidths)
Definition: MachineConnectivityCheck.cc:1876
MachineConnectivityCheck::findWritePorts
static PortSet findWritePorts(const TTAMachine::Unit &rf)
Definition: MachineConnectivityCheck.cc:1589
TTAMachine::Bus::signExtends
bool signExtends() const
Definition: Bus.cc:171
TTAMachine::Machine::isLittleEndian
bool isLittleEndian() const
Definition: Machine.hh:258
MachineInfo::defaultDataAddressSpace
static TTAMachine::AddressSpace * defaultDataAddressSpace(const TTAMachine::Machine &mach)
Definition: MachineInfo.cc:176
TCEString.hh
TTAProgram::ProgramAnnotation::Id
Id
the ID in TPEF is 24 bits, here enum
Definition: ProgramAnnotation.hh:52
TTAProgram::TerminalImmediate::toString
virtual TCEString toString() const
Definition: TerminalImmediate.cc:108
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
StringTools.hh
assert
#define assert(condition)
Definition: Application.hh:86
MachineConnectivityCheck::canBypass
static bool canBypass(const MoveNode &src, const MoveNode &user, const TTAMachine::Machine &targetMachine)
Definition: MachineConnectivityCheck.cc:1789
TTAProgram::TerminalImmediate::value
virtual SimValue value() const
Definition: TerminalImmediate.cc:75
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TemplateSlot.hh
TTAMachine::Segment::connectionCount
int connectionCount() const
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
MachineConnectivityCheck::needRegCopiesDueReadPortConflicts
static std::set< const TTAMachine::RegisterFile * > needRegCopiesDueReadPortConflicts(const TTAMachine::Machine &machine)
Definition: MachineConnectivityCheck.cc:904
MachineConnectivityCheck::RfRfPair
std::pair< const TTAMachine::BaseRegisterFile *, const TTAMachine::BaseRegisterFile * > RfRfPair
Definition: MachineConnectivityCheck.hh:306
TTAMachine::FUPort
Definition: FUPort.hh:46
MachineConnectivityCheck::hasBothGuards
static std::pair< bool, bool > hasBothGuards(const TTAMachine::Bus *bus, std::pair< const TTAMachine::RegisterFile *, int > guardReg)
Definition: MachineConnectivityCheck.cc:1983
MachineConnectivityCheck::busConnectedToAnyFU
static bool busConnectedToAnyFU(const TTAMachine::Bus &bus, const MoveNode &moveNode)
Definition: MachineConnectivityCheck.cc:1341
MachineConnectivityCheck::MachineConnectivityCheck
MachineConnectivityCheck()
Definition: MachineConnectivityCheck.cc:67
Segment.hh
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...
Definition: ProgramAnnotation.hh:112
MachineConnectivityCheck::connectedDestinationBuses
static std::set< const TTAMachine::Bus * > connectedDestinationBuses(const TTAMachine::Port &port)
Definition: MachineConnectivityCheck.cc:784
MoveNode::isGuardOperation
bool isGuardOperation() const
Definition: MoveNode.cc:181
MachineConnectivityCheck::addAnnotatedFUs
static void addAnnotatedFUs(std::set< TCEString > &candidateFUs, const TTAProgram::Move &m, TTAProgram::ProgramAnnotation::Id id)
Definition: MachineConnectivityCheck.cc:1856
TTAMachine::BaseRegisterFile
Definition: BaseRegisterFile.hh:48
TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
Definition: ProgramAnnotation.hh:115
MachineConnectivityCheck::rfRfCache_
static RfRfBoolMap rfRfCache_
Definition: MachineConnectivityCheck.hh:320
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
MachineConnectivityCheck::check
virtual bool check(const TTAMachine::Machine &mach, MachineCheckResults &results) const
Definition: MachineConnectivityCheck.cc:115
HWOperation.hh
TTAProgram::TerminalFUPort::operationIndex
virtual int operationIndex() const
Definition: TerminalFUPort.cc:238
TTAMachine::Unit
Definition: Unit.hh:51
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
MachineConnectivityCheck::totalConnectionCount
static int totalConnectionCount(const TTAMachine::Machine &mach)
Definition: MachineConnectivityCheck.cc:1461
TTAMachine::HWOperation::name
const std::string & name() const
Definition: HWOperation.cc:141
MachineConnectivityCheck::fromRfConnected
static bool fromRfConnected(const TTAMachine::BaseRegisterFile &brf)
Definition: MachineConnectivityCheck.cc:502
TTAMachine::Machine::immediateUnitNavigator
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition: Machine.cc:416
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
MachineConnectivityCheck::FUSet
std::set< const TTAMachine::FunctionUnit *, const TTAMachine::MachinePart::Comparator > FUSet
Definition: MachineConnectivityCheck.hh:76
MachineConnectivityCheck::PortRfPair
std::pair< const TTAMachine::Port *, const TTAMachine::BaseRegisterFile * > PortRfPair
Definition: MachineConnectivityCheck.hh:312
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAMachine::Segment::parentBus
Bus * parentBus() const
TTAMachine::Port
Definition: Port.hh:54
Application.hh
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
TTAMachine::Unit::port
virtual Port * port(const std::string &name) const
Definition: Unit.cc:116
MachineConnectivityCheck::isConnected
static bool isConnected(const TTAMachine::Port &sourcePort, const TTAMachine::Port &destinationPort, const TTAMachine::Guard *guard=NULL)
Definition: MachineConnectivityCheck.cc:128
MachineConnectivityCheck::canSourceWriteToAnyDestinationPort
static int canSourceWriteToAnyDestinationPort(const MoveNode &src, PortSet &ports, bool ignoreGuard=false)
Definition: MachineConnectivityCheck.cc:1754
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
MachineConnectivityCheck::PortRfBoolMap
std::map< PortRfPair, bool > PortRfBoolMap
Definition: MachineConnectivityCheck.hh:317
TTAMachine::Socket
Definition: Socket.hh:53
MachineConnectivityCheck::maxSIMMCount
static int maxSIMMCount(const TTAMachine::Machine &targetMachine)
Definition: MachineConnectivityCheck.cc:2019
SimValue::uLongWordValue
ULongWord uLongWordValue() const
Definition: SimValue.cc:1027
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
Guard.hh
MachineConnectivityCheck::portPortCache_
static PortPortBoolMap portPortCache_
Definition: MachineConnectivityCheck.hh:319
Operation.hh
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
MachineConnectivityCheck::immBits
static std::pair< int, int > immBits(const TTAMachine::RegisterFile &rf)
Definition: MachineConnectivityCheck.cc:620
MathTools::requiredBits
static int requiredBits(unsigned long int number)
TerminalFUPort.hh
MachineConnectivityCheck::raConnected
static bool raConnected(const TTAMachine::Machine &machine)
Definition: MachineConnectivityCheck.cc:966
ProgramOperation::isAnyNodeAssigned
bool isAnyNodeAssigned()
Definition: ProgramOperation.cc:398
MachineConnectivityCheck::findReadPorts
static PortSet findReadPorts(const TTAMachine::Unit &rf)
Definition: MachineConnectivityCheck.cc:1601
MachineConnectivityCheck::busConnectedToRF
static bool busConnectedToRF(const TTAMachine::Bus &bus, const TTAMachine::Unit &destRF)
Definition: MachineConnectivityCheck.cc:1306
MachineCheckResults
Definition: MachineCheckResults.hh:46
TTAProgram::Move
Definition: Move.hh:55
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
MachineConnectivityCheck::portRfCache_
static PortRfBoolMap portRfCache_
Definition: MachineConnectivityCheck.hh:322
Exception
Definition: Exception.hh:54
MachineConnectivityCheck::isPortApplicableToWidths
static bool isPortApplicableToWidths(const TTAMachine::Port &port, std::set< int > widths)
Definition: MachineConnectivityCheck.cc:463
Bus.hh
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:113
MachineConnectivityCheck::appendConnectedDestinationBuses
static void appendConnectedDestinationBuses(const TTAMachine::Port &port, std::set< const TTAMachine::Bus * > &buses)
Definition: MachineConnectivityCheck.cc:818
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
TTAMachine::Bus::guardCount
int guardCount() const
Definition: Bus.cc:441
TTAMachine::Port::isOutput
virtual bool isOutput() const
Definition: Port.cc:308
MachineConnectivityCheck::canWriteAllImmediates
static bool canWriteAllImmediates(TTAMachine::Port &destPort)
Definition: MachineConnectivityCheck.cc:1191
TTAMachine::Bus::guard
Guard * guard(int index) const
Definition: Bus.cc:456
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
Operation
Definition: Operation.hh:59
ProgramOperation::scheduledFU
const TTAMachine::FunctionUnit * scheduledFU() const
Definition: ProgramOperation.cc:866
MachineConnectivityCheck::tempRegisterFiles
static std::set< const TTAMachine::RegisterFile *, TTAMachine::MachinePart::Comparator > tempRegisterFiles(const TTAMachine::Machine &machine)
Definition: MachineConnectivityCheck.cc:1038
ProgramOperation::outputMoveCount
int outputMoveCount() const
Definition: ProgramOperation.cc:610
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
ProgramOperation.hh
Operand.hh
MachineConnectivityCheck::canBypassOpToDst
static bool canBypassOpToDst(const TTAMachine::Machine &mach, const TCEString &opName, int outIndex, const MoveNode &mn)
Definition: MachineConnectivityCheck.cc:2075
MoveNode::isSourceVariable
bool isSourceVariable() const
Definition: MoveNode.cc:196
TTAProgram::TerminalImmediate
Definition: TerminalImmediate.hh:44
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
SetTools::intersection
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
TTAProgram::AnnotatedInstructionElement::annotation
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:100
Operation::operand
virtual Operand & operand(int id) const
Definition: Operation.cc:541
MoveNode::move
TTAProgram::Move & move()
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
TTAMachine::Machine::registerFileNavigator
virtual RegisterFileNavigator registerFileNavigator() const
Definition: Machine.cc:450
MachineConnectivityCheck::toRfConnected
static bool toRfConnected(const TTAMachine::RegisterFile &brf)
Definition: MachineConnectivityCheck.cc:674
SetTools.hh
IllegalMachine
Definition: Exception.hh:878
TTAMachine::Guard::isInverted
virtual bool isInverted() const
TerminalImmediate.hh
TTAMachine::FunctionUnit::hasOperationLowercase
virtual bool hasOperationLowercase(const std::string &name) const
Definition: FunctionUnit.cc:341
TTAMachine::Component::machine
virtual Machine * machine() const
MachineConnectivityCheck::shortImmBits
static std::pair< int, int > shortImmBits(std::set< const TTAMachine::Bus * > &buses)
RegisterFile.hh
AssocTools.hh
TCEString
Definition: TCEString.hh:53
FUPort.hh
ControlUnit.hh
MachineConnectivityCheck::RfPortBoolMap
std::map< RfPortPair, bool > RfPortBoolMap
Definition: MachineConnectivityCheck.hh:316
TTAMachine::Machine::busNavigator
virtual BusNavigator busNavigator() const
Definition: Machine.cc:356
SpecialRegisterPort.hh
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
TTAMachine::Port::isInput
virtual bool isInput() const
Definition: Port.cc:298
MachineConnectivityCheck::findRoutes
static BusSet findRoutes(TTAMachine::Port &port1, TTAMachine::Port &port2)
Definition: MachineConnectivityCheck.cc:1658
MachineConnectivityCheck::connectedSourceBuses
static std::set< const TTAMachine::Bus * > connectedSourceBuses(const TTAMachine::Port &port)
Definition: MachineConnectivityCheck.cc:769
MachineCheck
Definition: MachineCheck.hh:50
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
MachineConnectivityCheck::rfPortCache_
static RfPortBoolMap rfPortCache_
Definition: MachineConnectivityCheck.hh:321
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
TTAProgram::Terminal::isCodeSymbolReference
virtual bool isCodeSymbolReference() const
Definition: Terminal.cc:154
MachineConnectivityCheck::~MachineConnectivityCheck
virtual ~MachineConnectivityCheck()
Definition: MachineConnectivityCheck.cc:74
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
TTAMachine::Socket::segmentCount
int segmentCount() const
MathTools.hh
TTAMachine::ImmediateUnit::extensionMode
virtual Machine::Extension extensionMode() const
Definition: ImmediateUnit.cc:143
OperationPool
Definition: OperationPool.hh:52
MachineConnectivityCheck::canAnyPortWriteToDestination
static bool canAnyPortWriteToDestination(PortSet &ports, const MoveNode &dest)
Definition: MachineConnectivityCheck.cc:1830
Move.hh
TTAMachine
Definition: Assembler.hh:48
TTAMachine::ControlUnit::returnAddressPort
SpecialRegisterPort * returnAddressPort() const
Definition: ControlUnit.cc:307
TTAProgram::Terminal::isRA
virtual bool isRA() const
Definition: Terminal.cc:129
MoveNode.hh
TTAMachine::BaseRegisterFile::width
virtual int width() const
MachineConnectivityCheck::copyOpFUs
static FUSet copyOpFUs(const TTAMachine::Machine &mach, const MoveNode &mn)
Definition: MachineConnectivityCheck.cc:2040
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
ProgramOperation::outputMove
MoveNode & outputMove(int index) const
Definition: ProgramOperation.cc:632
OperationPool.hh
MachineConnectivityCheck::busConnectedToFU
static bool busConnectedToFU(const TTAMachine::Bus &bus, const TTAMachine::FunctionUnit &fu, const TCEString &opName, int opIndex)
Definition: MachineConnectivityCheck.cc:1319
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
TTAMachine::AddressSpace::end
virtual ULongWord end() const
Definition: AddressSpace.cc:177
MachineConnectivityCheck::needsRegisterCopiesDueImmediateOperands
static bool needsRegisterCopiesDueImmediateOperands(const TTAMachine::Machine &mach)
Definition: MachineConnectivityCheck.cc:947
MathTools::requiredBitsSigned
static int requiredBitsSigned(SLongWord number)
MachineConnectivityCheck::operandWidth
static int operandWidth(const TTAMachine::HWOperation &hwop, int index)
Definition: MachineConnectivityCheck.cc:890
MachineConnectivityCheck::BusSet
std::set< TTAMachine::Bus *, const TTAMachine::MachinePart::Comparator > BusSet
Definition: MachineConnectivityCheck.hh:74
StringTools::stringToLower
static std::string stringToLower(const std::string &source)
Definition: StringTools.cc:160
MachineConnectivityCheck::PortSet
std::set< const TTAMachine::Port *, const TTAMachine::MachinePart::Comparator > PortSet
Definition: MachineConnectivityCheck.hh:72
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
TTAMachine::Machine
Definition: Machine.hh:73
TTAProgram::AnnotatedInstructionElement::annotationCount
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:133
TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_DST
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:116
MoveNode::guardOperation
ProgramOperation & guardOperation() const
Definition: MoveNode.cc:479
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const
TTAMachine::ImmediateUnit
Definition: ImmediateUnit.hh:50
MachineConnectivityCheck::maxLIMMCount
static int maxLIMMCount(const TTAMachine::Machine &targetMachine)
Definition: MachineConnectivityCheck.cc:2009