OpenASIP 2.2
Loading...
Searching...
No Matches
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
58namespace 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 */
118void
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 */
143void
145 int inputIndex = node.move().destination().operationIndex();
146 if (MapTools::containsKey(inputMoves_, inputIndex)) {
147 MoveNodeSet* nodeSet =
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 */
166void
168 if (MapTools::containsKey(outputMoves_, outputIndex)) {
169 MoveNodeSet* nodeSet =
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 */
187void
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 */
200void
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 */
213void
215 if (MapTools::containsKey(outputMoves_,outputIndex)) {
216 MoveNodeSet* nodeSet =
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 {
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 */
237void
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 */
248void
253
254
255int
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
265int
269
270int
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 */
288void
290 int inputIndex = node.move().destination().operationIndex();
291 if (MapTools::containsKey(inputMoves_,inputIndex)) {
292 MoveNodeSet* nodeSet =
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 {
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 */
314bool
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 */
335bool
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 */
351bool
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 */
376bool
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 */
397bool
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 */
418bool
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 */
434bool
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 */
450bool
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 */
466bool
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 */
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 */
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
544 MoveNodeSet* nodeSet =
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 */
559bool
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 */
575bool
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 */
589const Operation&
591 return *operation_;
592}
593
594/**
595 * Count of input moves to this operation.
596 *
597 * @return The count of input moves.
598 */
599int
601 return allInputMoves_.size();
602}
603
604/**
605 * Count of output moves to this operation.
606 *
607 * @return The count of output moves.
608 */
609int
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 */
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 */
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 */
644
645 for (std::size_t i = 0; i < allInputMoves_.size(); ++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
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
707
708 for (std::size_t i = 0; i < allInputMoves_.size(); ++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
722bool
724 const {
725
726 for (std::size_t i = 0; i < allInputMoves_.size(); ++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 */
745std::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 */
765unsigned int ProgramOperation::poId() const {
766 return poId_;
767}
768
769/**
770 * Comparison based on ID's for maps and sets.
771 */
772bool
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
784bool
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 */
794void
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 */
830bool
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
841unsigned 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
885int
887 if (mn.isSourceOperation() &&
888 &mn.sourceOperation() == this) {
889 return mn.move().source().operationIndex();
890 } else {
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}
#define __func__
#define assert(condition)
std::shared_ptr< ProgramOperation > ProgramOperationPtr
static void deleteAllValues(ContainerType &aMap)
static std::string toString(const T &source)
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
void addMoveNode(MoveNode &)
void removeMoveNode(MoveNode &)
void unsetSourceOperation()
Definition MoveNode.cc:760
void removeDestinationOperation(const ProgramOperation *po)
Definition MoveNode.cc:741
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
void unsetGuardOperation()
Definition MoveNode.cc:771
TTAProgram::Move & move()
bool isSourceOperation() const
Definition MoveNode.cc:168
bool isAssigned() const
Definition MoveNode.cc:367
bool isSourceConstant() const
Definition MoveNode.cc:238
static NullOperation & instance()
virtual TCEString name() const
Definition Operation.cc:93
virtual int numberOfInputs() const
Definition Operation.cc:192
virtual int numberOfOutputs() const
Definition Operation.cc:202
bool operator()(const ProgramOperation *po1, const ProgramOperation *po2) const
const TTAMachine::HWOperation * hwopFromOutMove(const MoveNode &outputNode) const
std::map< int, MoveNodeSet * > inputMoves_
void addGuardOutputNode(MoveNode &node)
bool hasOutputNode(int out) const
int outputMoveCount() const
const Operation & operation() const
int outputIndexFromGuard(const TTAMachine::PortGuard &pg) const
void addOutputNode(MoveNode &node, int outputIndex)
MoveNode * findTriggerFromUnit(const TTAMachine::Unit &unit) const
unsigned int poId() const
const TTAMachine::FunctionUnit * scheduledFU() const
int outputIndexFromGuardOfMove(const MoveNode &node) const
int inputMoveCount() const
MoveNode & moveNode(const TTAProgram::Move &move) const
MoveNode * triggeringMove() const
bool hasInputNode(int in) const
MoveNode & opcodeSettingNode()
void addNode(MoveNode &node)
ProgramOperation()
TODO: this better go, just for testing with empty operation...
std::map< int, MoveNodeSet * > outputMoves_
MoveNodeSet & inputNode(int in) const
std::string toString() const
MoveNode & inputMove(int index) const
bool hasMoveNodeForMove(const TTAProgram::Move &move) const
void removeInputNode(MoveNode &node)
void removeGuardOutputNode(MoveNode &node)
void switchInputs(int idx1=1, int idx2=2)
const TTAMachine::FunctionUnit * fuFromOutMove(const MoveNode &outputNode) const
void removeOutputNode(MoveNode &node, int outputIndex)
bool isLegalFU(const TTAMachine::FunctionUnit &fu) const
void addInputNode(MoveNode &node)
MoveNode & outputMove(int index) const
int outputIndexOfMove(const MoveNode &mn) const
static unsigned int idCounter
MoveNodeSet & outputNode(int out) const
void setOperation(const Operation &op)
const Operation * operation_
bool hasConstantOperand() const
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual bool isTriggering() const =0
virtual TCEString name() const
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual HWOperation * operation(const std::string &name) const
virtual bool hasOperation(const std::string &name) const
virtual BaseFUPort * port(const std::string &name) const
int io(const FUPort &port) const
FUPort * port() const
Unit * parentUnit() const
virtual int portCount() const
Definition Unit.cc:135
bool hasAnnotation(ProgramAnnotation::Id id, const TCEString &data) const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isUnconditional() const
Definition Move.cc:154
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
void setDestination(Terminal *dst)
Definition Move.cc:333
@ ANN_REJECTED_UNIT_SRC
Src. unit rejected.
@ ANN_REJECTED_UNIT_DST
Dst. unit rejected.
void setHintOperation(const char *name)
virtual Operation & hintOperation() const
Definition Terminal.cc:341
virtual int operationIndex() const
Definition Terminal.cc:364
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
virtual bool isFUPort() const
Definition Terminal.cc:118