OpenASIP  2.0
ProgramOperation.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 ProgramOperation.cc
26  *
27  * Implementation of ProgramOperation class.
28  *
29  * ProgramOperation represents an instance of operation execution in
30  * the program and should hold the reference to each MoveNode that belongs
31  * to the operation execution instance.
32  *
33  * @author Vladimir Guzma 2006 (vladimir.guzma-no.spam-tut.fi)
34  * @note rating: red
35  */
36 
37 #include <string>
38 
39 #include "ProgramOperation.hh"
40 #include "MoveNode.hh"
41 #include "MoveNodeSet.hh"
42 #include "Operation.hh"
43 #include "MapTools.hh"
44 #include "TerminalFUPort.hh"
45 #include "AssocTools.hh"
46 #include "ContainerTools.hh"
47 #include "Move.hh"
48 #include "Terminal.hh"
49 #include "BaseFUPort.hh"
50 #include "FunctionUnit.hh"
51 #include "TCEString.hh"
52 #include "UniversalFUPort.hh"
53 #include "HWOperation.hh"
54 #include "Guard.hh"
55 #include "MoveGuard.hh"
56 #include "TerminalFUPort.hh"
57 
58 namespace TTAProgram{
59  class NullOperation;
60 }
61 /**
62  * Constructor.
63  *
64  * Creates a ProgramOperation from operation
65  * @param operation Operation
66  */
68  const Operation &operation,
69  const llvm::MachineInstr* instr) :
70  operation_(&operation), poId_(idCounter++), mInstr_(instr) {
71 }
72 
73 /**
74  * Constructor.
75  *
76  * Creates a ProgramOperation from NullOperation
77  */
78  ///TODO: this better go, just for testing with empty operation...
80  operation_(&NullOperation::instance()), poId_(idCounter++) {
81  inputMoves_.clear();
82  outputMoves_.clear();
83 }
84 /**
85  * Destructor.
86  *
87  * Deletes MoveNodeSets.
88  * Does not unregister these program operations from movenodes.
89  */
91  // If MoveNodes of PO are not destroyed before PO they need to unset
92  // their source or destination operation respectively
93  for (int i = 0; i < inputMoveCount(); i++) {
95  }
96  for (int i = 0; i < outputMoveCount(); i++) {
97  if (&outputMove(i).sourceOperation() == this) {
99  } else {
100  if (&outputMove(i).guardOperation() == this) {
102  }
103  }
104  }
107 }
108 
109 /**
110  * Add given node to the set of nodes that belong to this program
111  * operation.
112  *
113  * Warning: this should not be used with bypassed moves!
114  *
115  * Add node to nodes of program operation
116  * @param node MoveNode to add to operation
117  */
118 void
120  if (node.move().source().isFUPort()) {
121  if (node.move().source().hintOperation().name() ==
122  operation().name()) {
123  addOutputNode(node);
124  }
125  } else {
126  if (node.move().destination().isFUPort()) {
127  if (node.move().destination().hintOperation().name() ==
128  operation().name()) {
129  addInputNode(node);
130  }
131  }
132  }
133 }
134 
135 /**
136  * Add given node to the set of input nodes that belong to this program
137  * operation.
138  *
139  * Input node is a move that writes an operand of the operation.
140  *
141  * @param node MoveNode to add to operation
142  */
143 void
145  int inputIndex = node.move().destination().operationIndex();
146  if (MapTools::containsKey(inputMoves_, inputIndex)) {
147  MoveNodeSet* nodeSet =
148  MapTools::valueForKey<MoveNodeSet*>(inputMoves_, inputIndex);
149  nodeSet->addMoveNode(node);
150  allInputMoves_.push_back(&node);
151  } else {
152  MoveNodeSet* nodeSet = new MoveNodeSet;
153  nodeSet->addMoveNode(node);
154  inputMoves_[inputIndex] = nodeSet;
155  allInputMoves_.push_back(&node);
156  }
157 }
158 
159 /**
160  * Add given node to the set of nodes that belong to this program operation.
161  *
162  * Add node to nodes of program operation
163  * @param node MoveNode to add to operation
164  * @param outputIndex output index of the operation.
165  */
166 void
168  if (MapTools::containsKey(outputMoves_, outputIndex)) {
169  MoveNodeSet* nodeSet =
170  MapTools::valueForKey<MoveNodeSet*>(outputMoves_,outputIndex);
171  nodeSet->addMoveNode(node);
172  allOutputMoves_.push_back(&node);
173  } else {
174  MoveNodeSet* nodeSet = new MoveNodeSet;
175  nodeSet->addMoveNode(node);
176  allOutputMoves_.push_back(&node);
177  outputMoves_[outputIndex] = nodeSet;
178  }
179 }
180 
181 /**
182  * Add given node to the set of nodes that belong to this program operation.
183  *
184  * Add node to nodes of program operation
185  * @param node MoveNode to add to operation
186  */
187 void
189 
190  int outputIndex = node.move().source().operationIndex();
191  addOutputNode(node, outputIndex);
192 }
193 
194 /**
195  * Add given node to the set of nodes that belong to this program operation.
196  *
197  * Add node to nodes of program operation
198  * @param node MoveNode to add to operation
199  */
200 void
202 
204 }
205 
206 
207 /**
208  * Removes output node from set of nodes that belong to this program operation.
209  *
210  * @param node MoveNode being removed from this program operation
211  * @param outputIndex the output index.
212  */
213 void
215  if (MapTools::containsKey(outputMoves_,outputIndex)) {
216  MoveNodeSet* nodeSet =
217  MapTools::valueForKey<MoveNodeSet*>(outputMoves_,outputIndex);
218  nodeSet->removeMoveNode(node);
219  for (std::vector<MoveNode*>::iterator i = allOutputMoves_.begin();
220  i != allOutputMoves_.end(); i++) {
221  if (*i == &node) {
222  allOutputMoves_.erase(i);
223  break;
224  }
225  }
226  } else {
227  throw IllegalRegistration(
228  __FILE__,__LINE__,__func__,"MoveNode not part of PO");
229  }
230 }
231 
232 /**
233  * Removes output node from set of nodes that belong to this program operation.
234  *
235  * @param node MoveNode being removed from this program operation
236  */
237 void
239  int outputIndex = node.move().source().operationIndex();
240  removeOutputNode(node, outputIndex);
241 }
242 
243 /**
244  * Removes output node from set of nodes that belong to this program operation.
245  *
246  * @param node MoveNode being removed from this program operation
247  */
248 void
250 
252 }
253 
254 
255 int
257  assert(!node.move().isUnconditional()); // todo: throw?
258  const TTAMachine::Guard& guard = node.move().guard().guard();
259  const TTAMachine::PortGuard* pg =
260  dynamic_cast<const TTAMachine::PortGuard*>(&guard);
261  assert(pg); // todo: throw?
262  return outputIndexFromGuard(*pg);
263 }
264 
265 int
267  return outputIndexFromGuard(pg, operation());
268 }
269 
270 int
272  const TTAMachine::PortGuard& pg, const Operation& op) {
273 
274  const TTAMachine::Port* p = pg.port();
275  const TTAMachine::FUPort* fup = static_cast<const TTAMachine::FUPort*>(p);
276  const TTAMachine::Unit* u = p->parentUnit();
277  const TTAMachine::FunctionUnit* fu =
278  static_cast<const TTAMachine::FunctionUnit*>(u);
279  const TTAMachine::HWOperation* hwop = fu->operation(op.name());
280  return hwop->io(*fup);
281 }
282 
283 /**
284  * Removes output node from set of nodes that belong to this program operation.
285  *
286  * @param node MoveNode being removed from this program operation
287  */
288 void
290  int inputIndex = node.move().destination().operationIndex();
291  if (MapTools::containsKey(inputMoves_,inputIndex)) {
292  MoveNodeSet* nodeSet =
293  MapTools::valueForKey<MoveNodeSet*>(inputMoves_,inputIndex);
294  nodeSet->removeMoveNode(node);
295  for (std::vector<MoveNode*>::iterator i = allInputMoves_.begin();
296  i != allInputMoves_.end(); i++) {
297  if (*i == &node) {
298  allInputMoves_.erase(i);
299  break;
300  }
301  }
302  } else {
303  throw IllegalRegistration(
304  __FILE__,__LINE__,__func__,"MoveNode not part of PO");
305  }
306 }
307 
308 /**
309  * Return true if each input and each output of the operation has a
310  * corresponding node reference in this program operation
311  *
312  * @return True if each input and output of operation has node reference
313  */
314 bool
316  if (!isReady()) {
317  return false;
318  }
319  // numbering of output does not start from 1 but input count +1
320  int begin = operation_->numberOfInputs() + 1;
322  for (int i = begin; i <= end; i++) {
324  return false;
325  }
326  }
327  return true;
328 }
329 
330 /**
331  * Return true if each input node has corresponding node reference
332  *
333  * @return True if each input of operation has corresponding node reference
334  */
335 bool
337  for (int i = 1; i <= operation_->numberOfInputs(); i++) {
339  return false;
340  }
341  }
342  return true;
343 }
344 
345 /**
346  * Return true if this program operation has more then one reference for some
347  * input or output of the operation.
348  *
349  * @return True if some of inputs or outputs has more then one reference
350  */
351 bool
353  std::map<int,MoveNodeSet*>::iterator moveIt = inputMoves_.begin();
354  while (moveIt != inputMoves_.end()) {
355  if ((*moveIt).second->count() > 1) {
356  return true;
357  }
358  moveIt++;
359  }
360  moveIt = outputMoves_.begin();
361  while (moveIt != outputMoves_.end()) {
362  if ((*moveIt).second->count() > 1) {
363  return true;
364  }
365  moveIt++;
366  }
367  return false;
368 }
369 
370 /**
371  * Return true if nodes of this operation have function unit assigned to
372  * their source or destination respectively
373  *
374  * @return True if nodes have source or destination function unit assigned
375  */
376 bool
378  for (int i = 0; i < inputMoveCount(); i++ ) {
379  if (!inputMove(i).isAssigned()) {
380  return false;
381  }
382  }
383  for (int i = 0; i < outputMoveCount(); i++ ) {
384  if (!outputMove(i).isAssigned()) {
385  return false;
386  }
387  }
388  return true;
389 }
390 
391 /**
392  * Return true if any node of this operation have function unit assigned to
393  * their source or destination respectively
394  *
395  * @return True if any node has source or destination function unit assigned
396  */
397 bool
399  for (int i = 0; i < inputMoveCount(); i++ ) {
400  if (inputMove(i).isAssigned()) {
401  return true;
402  }
403  }
404  for (int i = 0; i < outputMoveCount(); i++ ) {
405  if (outputMove(i).isAssigned()) {
406  return true;
407  }
408  }
409  return false;
410 }
411 
412 /**
413  * Return true if any node of this operation have function unit assigned to
414  * their source or destination respectively
415  *
416  * @return True if any node has source or destination function unit assigned
417  */
418 bool
420  for (int i = 0; i < inputMoveCount(); i++ ) {
421  if (inputMove(i).isAssigned()) {
422  return true;
423  }
424  }
425  return false;
426 }
427 
428 /**
429  * Return true if nodes of this operation have function unit assigned to
430  * their source or destination respectively
431  *
432  * @return True if nodes have source or destination function unit assigned
433  */
434 bool
436  for (int i = 0; i < inputMoveCount(); i++ ) {
437  if (!inputMove(i).isAssigned()) {
438  return false;
439  }
440  }
441  return true;
442 }
443 
444 /**
445  * Return true if any output node of this operation have function unit assigned to
446  * their source or destination respectively
447  *
448  * @return True if any node has source or destination function unit assigned
449  */
450 bool
452  for (int i = 0; i < outputMoveCount(); i++ ) {
453  if (outputMove(i).isAssigned()) {
454  return true;
455  }
456  }
457  return false;
458 }
459 
460 /**
461  * Return true if nodes of this operation have function unit assigned to
462  * their source or destination respectively
463  *
464  * @return True if nodes have source or destination function unit assigned
465  */
466 bool
468  for (int i = 0; i < outputMoveCount(); i++ ) {
469  if (!outputMove(i).isAssigned()) {
470  return false;
471  }
472  }
473  return true;
474 }
475 
476 /**
477  * Return the MoveNode of program operation that sets the opcode and triggers
478  * operation execution.
479  *
480  * Such a MoveNode is usually one of input nodes and can not have multiple
481  * copies.
482  * @return MoveNode that sets opcode and triggers execution
483  * @throw InvalidData In case there is no opcode setting node register in
484  * operation
485  */
486 MoveNode&
488  std::map<int,MoveNodeSet*>::iterator moveIt = inputMoves_.begin();
489  while (moveIt != inputMoves_.end()) {
490  if ((*moveIt).second->at(0).move().destination().isOpcodeSetting()) {
491  if ((*moveIt).second->count() > 1) {
492  std::string msg = "ProgramOperation has more then one opcode\
493  setting node.";
494  throw InvalidData(__FILE__, __LINE__, __func__, msg);
495  }
496  return (*moveIt).second->at(0);
497  }
498  moveIt++;
499  }
500  std::string msg = "ProgramOperation is missing opcode setting node.";
501  throw InvalidData(__FILE__, __LINE__, __func__, msg);
502 }
503 
504 /**
505  * Return the nodes that writes input Index of operation
506  *
507  * @param index Index of a operation to test
508  * @return Set of nodes that writes particular input of operation
509  * @throw OutOfRange In case the index is higher then number of operation
510  * inputs
511  */
513 ProgramOperation::inputNode(int index) const {
514  if (index < 1 || index > operation_->numberOfInputs()) {
515  std::string msg = "InputNode index out of range.";
516  throw OutOfRange(__FILE__, __LINE__, __func__, msg);
517  }
518 
519  std::map<int, MoveNodeSet*>::const_iterator i = inputMoves_.find(index);
520  if (i != inputMoves_.end()) {
521  return *(i->second);
522  } else {
523  std::string msg = "InputNode index not found.";
524  throw KeyNotFound(__FILE__, __LINE__, __func__, msg);
525  }
526 }
527 /**
528  * Return the nodes that writes output Index of operation
529  *
530  * @param index Index of a operation to test
531  * @return Set of nodes that writes particular output of operation
532  * @throw OutOfRange If index is not found
533  */
536  if (index <= operation_->numberOfInputs() ||
537  index > operation_->numberOfInputs()+
539  std::string msg = "OutputNode index out of range.";
540  throw OutOfRange(__FILE__, __LINE__, __func__, msg);
541  }
542 
543  if (MapTools::containsKey(outputMoves_, index)) {
544  MoveNodeSet* nodeSet =
545  MapTools::valueForKey<MoveNodeSet*>(outputMoves_, index);
546  return *nodeSet;
547  } else {
548  std::string msg = "OutputNode index not found.";
549  throw KeyNotFound(__FILE__, __LINE__, __func__, msg);
550  }
551 }
552 /**
553  * Return true if program operation has node registered for input identified
554  * by index.
555  *
556  * @param Index Operation input to test
557  * @return True if the operation input Index has node registered
558  */
559 bool
561  if (MapTools::containsKey(inputMoves_,index)) {
562  return true;
563  } else {
564  return false;
565  }
566 }
567 
568 /**
569  * Return true if program operation has node registered for output identified
570  * by index.
571  *
572  * @param Index Operation output to test
573  * @return True if the operation output Index has node registered
574  */
575 bool
577  if (MapTools::containsKey(outputMoves_,index)) {
578  return true;
579  } else {
580  return false;
581  }
582 }
583 
584 /**
585  * Return the operation from OSAL
586  *
587  * @return Return the operation object handle from OSAL
588  */
589 const Operation&
591  return *operation_;
592 }
593 
594 /**
595  * Count of input moves to this operation.
596  *
597  * @return The count of input moves.
598  */
599 int
601  return allInputMoves_.size();
602 }
603 
604 /**
605  * Count of output moves to this operation.
606  *
607  * @return The count of output moves.
608  */
609 int
611  return allOutputMoves_.size();
612 }
613 
614 /**
615  * Returns the given input move.
616  *
617  * @param index Index of the move.
618  * @return The input move.
619  */
620 MoveNode&
621 ProgramOperation::inputMove(int index) const {
622  return *allInputMoves_.at(index);
623 }
624 
625 /**
626  * Returns the given output move.
627  *
628  * @param index Index of the move.
629  * @return The output move.
630  */
631 MoveNode&
633  return *allOutputMoves_.at(index);
634 }
635 
636 /**
637  * Returns the triggering move of the operation.
638  *
639  * @return The triggering move. NULL in case the operation is not yet
640  * assigned to an FU, or the triggering move has not been assigned yet.
641  */
642 MoveNode*
644 
645  for (std::size_t i = 0; i < allInputMoves_.size(); ++i) {
646  MoveNode& moveNode = *allInputMoves_.at(i);
647  const TTAProgram::Move& move = moveNode.move();
648  TTAProgram::Terminal& dest = move.destination();
649  if (!dest.isFUPort()) {
650  continue;
651  }
652  const TTAMachine::BaseFUPort* fup =
653  static_cast<const TTAMachine::BaseFUPort*>(&dest.port());
654  if (dynamic_cast<const UniversalFUPort*>(fup)) {
655  continue;
656  }
657 
658  if (fup->isTriggering()) {
659  return &moveNode;
660  } else {
661  return findTriggerFromUnit(
662  *fup->parentUnit());
663  }
664  }
665 
666  for (std::size_t i = 0; i< allOutputMoves_.size(); ++i) {
669  if (fu != nullptr) {
670  return findTriggerFromUnit(*fu);
671  }
672  }
673  return NULL;
674 }
675 
676 MoveNode*
678  const TTAMachine::Unit& unit) const {
679  const TTAMachine::FunctionUnit* fu =
680  dynamic_cast<const TTAMachine::FunctionUnit*>(&unit);
681  int ioIndex = -1;
682  assert(fu);
683 
684  int portC = fu->portCount();
685  for (int i = 0; i < portC; i++) {
686  auto p = fu->port(i);
687  const TTAMachine::FUPort* port = dynamic_cast<const TTAMachine::FUPort*>(p);
688  if (port != nullptr && port->isTriggering()) {
689  const TTAMachine::HWOperation* hwop =
690  fu->operation(operation().name());
691  ioIndex = hwop->io(*port);
692  auto ngi = inputMoves_.find(ioIndex);
693  if (ngi == inputMoves_.end()) {
694  return NULL;
695  }
696  auto mng = *ngi->second;
697  if (mng.count() < 1)
698  return NULL;
699  return &mng.at(0);
700  }
701  }
702  return NULL;
703 }
704 
705 MoveNode&
707 
708  for (std::size_t i = 0; i < allInputMoves_.size(); ++i) {
709  MoveNode& moveNode = *allInputMoves_.at(i);
710  if (&moveNode.move() == &move)
711  return moveNode;
712  }
713  for (std::size_t i = 0; i < allOutputMoves_.size(); ++i) {
715  if (&moveNode.move() == &move)
716  return moveNode;
717  }
718  throw KeyNotFound(__FILE__, __LINE__, __func__,
719  "No MoveNode for the Move found in the ProgramOperation.");
720 }
721 
722 bool
724  const {
725 
726  for (std::size_t i = 0; i < allInputMoves_.size(); ++i) {
727  MoveNode& moveNode = *allInputMoves_.at(i);
728  if (&moveNode.move() == &move)
729  return true;
730  }
731  for (std::size_t i = 0; i < allOutputMoves_.size(); ++i) {
733  if (&moveNode.move() == &move)
734  return true;
735  }
736  return false;
737 }
738 
739 
740 /**
741  * The moves of the program operation in human readable format.
742  *
743  * @return The program operation as a string.
744  */
745 std::string
748  output << " Inputs: ";
749  for (std::size_t i = 0; i < allInputMoves_.size(); ++i) {
750  output += allInputMoves_.at(i)->toString() + " ";
751  }
752  output << " Outputs: ";
753  for (std::size_t i = 0; i < allOutputMoves_.size(); ++i) {
754  output += allOutputMoves_.at(i)->toString() + " ";
755  }
756  return output;
757 }
758 
759 /**
760  * Returns an unique id of this program operation.
761  *
762  * These can be used instead of pointers for comparison,
763  * and are more deterministic as they are given in order.
764  */
765 unsigned int ProgramOperation::poId() const {
766  return poId_;
767 }
768 
769 /**
770  * Comparison based on ID's for maps and sets.
771  */
772 bool
774  const ProgramOperation* po1, const ProgramOperation* po2) const {
775  if (po1 == NULL) {
776  return false;
777  }
778  if (po2 == NULL) {
779  return true;
780  }
781  return po1->poId() < po2->poId();
782 }
783 
784 bool
786  const ProgramOperationPtr &po1, const ProgramOperationPtr &po2) const {
787  return po1.get()->poId() < po2.get()->poId();
788 }
789 
790 
791 /**
792  * Switches inputs of 2-operand commutative operations
793  */
794 void
795 ProgramOperation::switchInputs(int idx1, int idx2) {
796 
797  const Operation& op = operation();
798  assert (op.numberOfInputs() >= 2);
799 
800  // switch input nodes.
801  MoveNodeSet tmpSet = *inputMoves_[idx1];
802  *inputMoves_[idx1] = *inputMoves_[idx2];
803  *inputMoves_[idx2] = tmpSet;
804 
805  for (int i = 0; i < inputMoveCount(); i++) {
806  MoveNode& node = inputMove(i);
807  TTAProgram::Move& move = node.move();
808  TTAProgram::Terminal& oldDest = move.destination();
809 
810  // then update the moves.
811  if (move.destination().operationIndex() == idx1) {
812  move.setDestination(
814  *static_cast<TTAProgram::TerminalFUPort&>(oldDest).
815  hwOperation(), idx2));
816 
817  } else if (move.destination().operationIndex() == idx2) {
818  move.setDestination(
820  *static_cast<TTAProgram::TerminalFUPort&>(oldDest).
821  hwOperation(), idx1));
822  }
823  }
824 }
825 
826 /**
827  * Returns true in case the operation has at least one operand that
828  * is a contant/immediate.
829  */
830 bool
832  for (MoveVector::const_iterator i = allInputMoves_.begin();
833  i != allInputMoves_.end(); ++i) {
834  MoveNode* mn = *i;
835  if (mn->isSourceConstant())
836  return true;
837  }
838  return false;
839 }
840 
841 unsigned int ProgramOperation::idCounter = 0;
842 
845  if (outputNode.isAssigned() &&
846  outputNode.isSourceOperation() &&
847  &outputNode.sourceOperation() == this) {
848  return static_cast<const TTAMachine::FunctionUnit*>(
849  outputNode.move().source().port().parentUnit());
850  }
851  if (!outputNode.move().isUnconditional() &&
852  outputNode.isGuardOperation() &&
853  outputNode.guardOperationPtr().get() == this) {
854  const TTAMachine::Guard& guard =
855  outputNode.move().guard().guard();
856  const TTAMachine::PortGuard* pg =
857  dynamic_cast<const TTAMachine::PortGuard*>(&guard);
858  assert(pg); // todo: throw?
859  return static_cast<const TTAMachine::FunctionUnit*>(
860  pg->port()->parentUnit());
861  }
862  return nullptr;
863 }
864 
867 
868  for (int i = 0; i < inputMoveCount(); i++ ) {
870  if (inputNode.isAssigned()) {
871  return static_cast<const TTAMachine::FunctionUnit*>(
872  inputNode.move().destination().port().parentUnit());
873  }
874  }
875  for (int i = 0; i < outputMoveCount(); i++ ) {
878  if (fu != nullptr) {
879  return fu;
880  }
881  }
882  return nullptr;
883 }
884 
885 int
887  if (mn.isSourceOperation() &&
888  &mn.sourceOperation() == this) {
889  return mn.move().source().operationIndex();
890  } else {
891  return outputIndexFromGuardOfMove(mn);
892  }
893 }
894 
896  const MoveNode& outputNode) const {
897  if (outputNode.isSourceOperation() &&
898  &outputNode.sourceOperation() == this) {
899  return outputNode.move().source().functionUnit().operation(
900  operation().name());
901  } else {
902  const TTAMachine::Guard& guard =
903  outputNode.move().guard().guard();
904  const TTAMachine::PortGuard* pg =
905  dynamic_cast<const TTAMachine::PortGuard*>(&guard);
906  assert(pg); // todo: throw?
907  const TTAMachine::Port* p = pg->port();
908  const TTAMachine::Unit* u = p->parentUnit();
909  const TTAMachine::FunctionUnit* fu =
910  static_cast<const TTAMachine::FunctionUnit*>(u);
911  return fu->operation(operation().name());
912  }
913 }
914 
916 
917  if (!fu.hasOperation(operation_->name())) {
918  return false;
919  }
920  for (int i = 0; i < inputMoveCount(); i++) {
921  MoveNode& mn = inputMove(i);
922  TTAProgram::Move& move = mn.move();
923  if (move.hasAnnotation(
925  fu.name())) {
926  return false;
927  }
928  }
929  for (int i = 0; i < outputMoveCount(); i++) {
930  MoveNode& mn = outputMove(i);
931  TTAProgram::Move& move = mn.move();
932  if (move.hasAnnotation(
934  fu.name())) {
935  return false;
936  }
937  }
938  return true;
939 }
940 
942  operation_ = &op;
943  for (int i = 0; i < inputMoveCount(); i++) {
944  MoveNode& mn = inputMove(i);
946  &mn.move().destination());
947  assert(tfp);
948  tfp->setHintOperation(op.name().c_str());
949  }
950 
951  for (int i = 0; i < outputMoveCount(); i++) {
952  MoveNode& mn = outputMove(i);
954  &mn.move().source());
955  assert(tfp);
956  tfp->setHintOperation(op.name().c_str());
957  }
958 }
NullOperation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:812
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
TTAProgram
Definition: Estimator.hh:65
NullOperation
Definition: Operation.hh:186
ProgramOperation::outputIndexFromGuardOfMove
int outputIndexFromGuardOfMove(const MoveNode &node) const
Definition: ProgramOperation.cc:256
TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_SRC
@ ANN_REJECTED_UNIT_SRC
Src. unit rejected.
Definition: ProgramAnnotation.hh:118
ProgramOperation::addGuardOutputNode
void addGuardOutputNode(MoveNode &node)
Definition: ProgramOperation.cc:201
ProgramOperation::removeInputNode
void removeInputNode(MoveNode &node)
Definition: ProgramOperation.cc:289
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
TTAMachine::PortGuard::port
FUPort * port() const
ProgramOperation::hasOutputNode
bool hasOutputNode(int out) const
Definition: ProgramOperation.cc:576
TTAMachine::HWOperation
Definition: HWOperation.hh:52
TTAMachine::BaseFUPort::parentUnit
FunctionUnit * parentUnit() const
Definition: BaseFUPort.cc:96
ProgramOperation::outputNode
MoveNodeSet & outputNode(int out) const
Definition: ProgramOperation.cc:535
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
OutOfRange
Definition: Exception.hh:320
MapTools.hh
ProgramOperation::isAnyOutputAssigned
bool isAnyOutputAssigned()
Definition: ProgramOperation.cc:451
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
ProgramOperation::fuFromOutMove
const TTAMachine::FunctionUnit * fuFromOutMove(const MoveNode &outputNode) const
Definition: ProgramOperation.cc:844
TTAProgram::Terminal::hintOperation
virtual Operation & hintOperation() const
Definition: Terminal.cc:341
MoveNodeSet::removeMoveNode
void removeMoveNode(MoveNode &)
Definition: MoveNodeSet.cc:73
ProgramOperation::areInputsAssigned
bool areInputsAssigned()
Definition: ProgramOperation.cc:435
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
ProgramOperation::switchInputs
void switchInputs(int idx1=1, int idx2=2)
Definition: ProgramOperation.cc:795
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
ProgramOperation::addNode
void addNode(MoveNode &node)
Definition: ProgramOperation.cc:119
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
ProgramOperation::outputMoves_
std::map< int, MoveNodeSet * > outputMoves_
Definition: ProgramOperation.hh:168
Terminal.hh
ProgramOperation::opcodeSettingNode
MoveNode & opcodeSettingNode()
Definition: ProgramOperation.cc:487
ProgramOperation::outputIndexFromGuard
int outputIndexFromGuard(const TTAMachine::PortGuard &pg) const
Definition: ProgramOperation.cc:266
TTAMachine::FUPort::isTriggering
virtual bool isTriggering() const
Definition: FUPort.cc:182
NullOperation::instance
static NullOperation & instance()
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
ProgramOperation::isLegalFU
bool isLegalFU(const TTAMachine::FunctionUnit &fu) const
Definition: ProgramOperation.cc:915
Conversion::toString
static std::string toString(const T &source)
TTAProgram::TerminalFUPort::setHintOperation
void setHintOperation(const char *name)
Definition: TerminalFUPort.cc:270
ProgramOperation::triggeringMove
MoveNode * triggeringMove() const
Definition: ProgramOperation.cc:643
NullOperation::name
virtual TCEString name() const
Definition: Operation.cc:790
BaseFUPort.hh
ProgramOperation::poId_
unsigned int poId_
Definition: ProgramOperation.hh:173
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
ProgramOperation::addOutputNode
void addOutputNode(MoveNode &node, int outputIndex)
Definition: ProgramOperation.cc:167
TCEString.hh
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
UniversalFUPort
Definition: UniversalFUPort.hh:47
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::FUPort
Definition: FUPort.hh:46
TTAProgram::ProgramAnnotation::ANN_REJECTED_UNIT_DST
@ ANN_REJECTED_UNIT_DST
Dst. unit rejected.
Definition: ProgramAnnotation.hh:119
TTAProgram::Move::setDestination
void setDestination(Terminal *dst)
Definition: Move.cc:333
ProgramOperation::isComplete
bool isComplete()
Definition: ProgramOperation.cc:315
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
TTAMachine::HWOperation::io
int io(const FUPort &port) const
Definition: HWOperation.cc:364
HWOperation.hh
TTAMachine::Unit
Definition: Unit.hh:51
InvalidData
Definition: Exception.hh:149
ProgramOperation::idCounter
static unsigned int idCounter
Definition: ProgramOperation.hh:174
TTAMachine::Port
Definition: Port.hh:54
TTAProgram::AnnotatedInstructionElement::hasAnnotation
bool hasAnnotation(ProgramAnnotation::Id id, const TCEString &data) const
Definition: AnnotatedInstructionElement.cc:174
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
ProgramOperation::allOutputMoves_
MoveVector allOutputMoves_
Definition: ProgramOperation.hh:172
__func__
#define __func__
Definition: Application.hh:67
ProgramOperation::inputMoves_
std::map< int, MoveNodeSet * > inputMoves_
Definition: ProgramOperation.hh:166
ProgramOperation::ProgramOperation
ProgramOperation()
TODO: this better go, just for testing with empty operation...
Definition: ProgramOperation.cc:79
Guard.hh
Operation.hh
ProgramOperation::hwopFromOutMove
const TTAMachine::HWOperation * hwopFromOutMove(const MoveNode &outputNode) const
Definition: ProgramOperation.cc:895
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
ProgramOperation::hasConstantOperand
bool hasConstantOperand() const
Definition: ProgramOperation.cc:831
ProgramOperation::allInputMoves_
MoveVector allInputMoves_
Definition: ProgramOperation.hh:170
MoveNode::unsetSourceOperation
void unsetSourceOperation()
Definition: MoveNode.cc:760
TerminalFUPort.hh
ProgramOperation::isAnyNodeAssigned
bool isAnyNodeAssigned()
Definition: ProgramOperation.cc:398
TTAProgram::Move
Definition: Move.hh:55
TTAMachine::FunctionUnit::hasOperation
virtual bool hasOperation(const std::string &name) const
Definition: FunctionUnit.cc:330
ProgramOperation::removeGuardOutputNode
void removeGuardOutputNode(MoveNode &node)
Definition: ProgramOperation.cc:249
NullOperation::output
virtual Operand & output(int id) const
Definition: Operation.cc:749
MoveNode::unsetGuardOperation
void unsetGuardOperation()
Definition: MoveNode.cc:771
MoveNodeSet
Definition: MoveNodeSet.hh:41
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
TTAMachine::BaseFUPort::isTriggering
virtual bool isTriggering() const =0
ProgramOperation::isAssigned
bool isAssigned()
Definition: ProgramOperation.cc:377
ProgramOperation::findTriggerFromUnit
MoveNode * findTriggerFromUnit(const TTAMachine::Unit &unit) const
Definition: ProgramOperation.cc:677
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
IllegalRegistration
Definition: Exception.hh:532
ProgramOperation::outputMoveCount
int outputMoveCount() const
Definition: ProgramOperation.cc:610
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
ProgramOperation.hh
UniversalFUPort.hh
ProgramOperation::addInputNode
void addInputNode(MoveNode &node)
Definition: ProgramOperation.cc:144
ProgramOperation::isMultinode
bool isMultinode()
Definition: ProgramOperation.cc:352
MoveNode::move
TTAProgram::Move & move()
ProgramOperation::toString
std::string toString() const
Definition: ProgramOperation.cc:746
ProgramOperation::moveNode
MoveNode & moveNode(const TTAProgram::Move &move) const
Definition: ProgramOperation.cc:706
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
ProgramOperation::isReady
bool isReady()
Definition: ProgramOperation.cc:336
ProgramOperation::setOperation
void setOperation(const Operation &op)
Definition: ProgramOperation.cc:941
MoveNodeSet::addMoveNode
void addMoveNode(MoveNode &)
Definition: MoveNodeSet.cc:62
MoveNode::removeDestinationOperation
void removeDestinationOperation(const ProgramOperation *po)
Definition: MoveNode.cc:741
MoveNodeSet.hh
AssocTools.hh
TCEString
Definition: TCEString.hh:53
ProgramOperation::inputNode
MoveNodeSet & inputNode(int in) const
Definition: ProgramOperation.cc:513
ProgramOperation::hasInputNode
bool hasInputNode(int in) const
Definition: ProgramOperation.cc:560
ProgramOperation::areOutputsAssigned
bool areOutputsAssigned()
Definition: ProgramOperation.cc:467
TTAProgram::Terminal
Definition: Terminal.hh:60
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
ProgramOperation::hasMoveNodeForMove
bool hasMoveNodeForMove(const TTAProgram::Move &move) const
Definition: ProgramOperation.cc:723
ProgramOperation::poId
unsigned int poId() const
Definition: ProgramOperation.cc:765
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
KeyNotFound
Definition: Exception.hh:285
TTAMachine::PortGuard
Definition: Guard.hh:99
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
ProgramOperation::Comparator::operator()
bool operator()(const ProgramOperation *po1, const ProgramOperation *po2) const
Definition: ProgramOperation.cc:773
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
MoveNode::isAssigned
bool isAssigned() const
Definition: MoveNode.cc:367
ProgramOperation::~ProgramOperation
~ProgramOperation()
Definition: ProgramOperation.cc:90
Move.hh
MoveNode.hh
ProgramOperation::operation_
const Operation * operation_
Definition: ProgramOperation.hh:164
ProgramOperation::outputMove
MoveNode & outputMove(int index) const
Definition: ProgramOperation.cc:632
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
AssocTools::deleteAllValues
static void deleteAllValues(ContainerType &aMap)
ProgramOperation::outputIndexOfMove
int outputIndexOfMove(const MoveNode &mn) const
Definition: ProgramOperation.cc:886
ProgramOperation::isAnyInputAssigned
bool isAnyInputAssigned()
Definition: ProgramOperation.cc:419
ProgramOperation::removeOutputNode
void removeOutputNode(MoveNode &node, int outputIndex)
Definition: ProgramOperation.cc:214
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
FunctionUnit.hh
ContainerTools.hh
MoveGuard.hh
TTAMachine::Port::parentUnit
Unit * parentUnit() const