OpenASIP 2.2
Loading...
Searching...
No Matches
SequentialScheduler.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2010 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 SequentialScheduler.cc
26 *
27 * Definition of SequentialScheduler class.
28 *
29 * @author Heikki Kultala 2008 (hkultala-no.spam-cs.tut.fi)
30 * @author Pekka Jääskeläinen 2010 (pjaaskel)
31 * @author Fabio Garzia 2010 (fabio.garzia-no.spam-tut.fi)
32 * @note rating: red
33 */
34
35#include <string>
36#include <climits>
37
38#include <boost/config.hpp>
39#include <boost/format.hpp>
40
41#include "AssocTools.hh"
42#include "MapTools.hh"
44#include "Procedure.hh"
45#include "ProgramOperation.hh"
46#include "ControlUnit.hh"
47#include "Machine.hh"
48#include "UniversalMachine.hh"
49#include "Instruction.hh"
52#include "BasicBlock.hh"
54#include "RegisterCopyAdder.hh"
55#include "SchedulerPass.hh"
56#include "Guard.hh"
57#include "MoveGuard.hh"
58#include "MoveNodeSet.hh"
60#include "Terminal.hh"
61#include "MoveNodeGroup.hh"
62#include "MoveNode.hh"
64#include "Program.hh"
65#include "Move.hh"
66
67//#define DEBUG_OUTPUT
68//#define DEBUG_REG_COPY_ADDER
69//#define CFG_SNAPSHOTS
70
71class SequentialSelector;
72
73/**
74 * Constructs the sequential scheduler.
75 *
76 * @param data Interpass data
77 */
85
86/**
87 * Destructor.
88 */
91
92/**
93 * Schedules a single basic block.
94 *
95 * @param bb The basic block to schedule.
96 * @param targetMachine The target machine.
97 * @exception Exception several TCE exceptions can be thrown in case of
98 * a scheduling error.
99 */
100void
102 TTAProgram::BasicBlock& bb, const TTAMachine::Machine& targetMachine,
104 if (bb.instructionCount() == 0)
105 return;
106
107 targetMachine_ = &targetMachine;
108 rm_ = SimpleResourceManager::createRM(targetMachine);
109
110 int cycle = 0;
111
112 SequentialMoveNodeSelector selector(bb);
113 selector_ = &selector;
114
115 // loop as long as selector gives things to schedule
116 MoveNodeGroup moves = selector.candidates();
117 while (moves.nodeCount() > 0) {
118
119 MoveNode& firstMove = moves.node(0);
120 if (firstMove.isOperationMove()) {
121 cycle = scheduleOperation(moves, cycle) + 1;
122 } else {
123 if (firstMove.move().destination().isRA()) {
124 cycle = scheduleMove(cycle, firstMove) + 1;
125 } else {
126 cycle = scheduleRRMove(cycle, firstMove) + 1;
127 }
128 }
129
130 if (!moves.isScheduled()) {
131 std::string message = " Move(s) did not get scheduled: ";
132 for (int i = 0; i < moves.nodeCount(); i++) {
133 message += moves.node(i).toString() + " ";
134 }
135 throw ModuleRunTimeError(__FILE__, __LINE__, __func__, message);
136 }
137
138 for (int moveIndex = 0; moveIndex < moves.nodeCount(); ++moveIndex) {
139 MoveNode& moveNode = moves.node(moveIndex);
140 selector.notifyScheduled(moveNode);
141 }
142 moves = selector.candidates();
143 }
144 copyRMToBB(*rm_, bb, targetMachine, irm);
146}
147
148#ifdef DEBUG_REG_COPY_ADDER
149static int graphCount = 0;
150#endif
151
152/**
153 * Schedules moves in a single operation execution.
154 *
155 * Assumes the given MoveNodeGroup contains all moves in the operation
156 * execution. Also assumes that all inputs to the MoveNodeGroup have
157 * been scheduled.
158 *
159 * @param moves Moves of the operation execution.
160 * @return returns the last cycle of the operation.
161 */
162int
164 MoveNodeGroup& moves, int earliestCycle) {
165 ProgramOperation& po =
166 (moves.node(0).isSourceOperation())?
167 (moves.node(0).sourceOperation()):
168 (moves.node(0).destinationOperation());
169
170 RegisterCopyAdder regCopyAdder(
172
173
174 // TODO: registercopyader and ddg..
176 regCopyAdder.addMinimumRegisterCopies(po, *targetMachine_, NULL);
177
178#ifdef DEBUG_REG_COPY_ADDER
179 const int tempsAdded = addedCopies.count_;
180#endif
181
182 MoveNodeSet tempSet;
183 for (int i = 0; i < moves.nodeCount(); i++) {
184 // MoveNodeGroup relates to DDG so we copy it to more
185 // simple MoveNodeSet container
186 tempSet.addMoveNode(moves.node(i));
187 }
188
189 int triggerCycle = scheduleOperandWrites(
190 earliestCycle, moves, addedCopies);
191 if (triggerCycle == -1) {
192 throw ModuleRunTimeError(
193 __FILE__,__LINE__,__func__,
194 "Scheduling operands failed for: " +moves.toString());
195 }
196
197 int lastCycle = scheduleResultReads(triggerCycle+1, moves, addedCopies);
198
199 if (lastCycle == -1) {
200 throw ModuleRunTimeError(
201 __FILE__,__LINE__,__func__,
202 "Scheduling results failed for: " +moves.toString());
203 }
204 return lastCycle;
205}
206
207/**
208 * Schedules operand moves of an operation execution.
209 *
210 * Assumes the given MoveNodeGroup contains all moves in the operation
211 * execution. Also assumes that all inputs to the MoveNodeGroup have
212 * been scheduled.
213 * Exception to this are the possible temporary register
214 * copies inserted before the operand move due to missing connectivity.
215 * If found, the temp moves are scheduled atomically with the operand move.
216 * Assumes top-down scheduling.
217 *
218 * @param cycle Earliest cycle for starting scheduling of operands
219 * @param moves Moves of the operation execution.
220 * @return The cycle the trigger got scheduled
221 */
222int
224 int cycle, MoveNodeGroup& moves,
226 // Counts operands that are not scheduled at beginning.
227 int scheduledMoves = 0;
228 MoveNode* trigger = NULL;
229 MoveNode& firstNode = moves.node(0);
230 ProgramOperation& po = firstNode.destinationOperation();
231
232 for (int i = 0; i < moves.nodeCount(); i++) {
233
234 MoveNode& node = moves.node(i);
235 // result read?
236 if (!node.isDestinationOperation()) {
237 continue;
238 }
239
240 cycle = scheduleInputOperandTempMoves(cycle, node, regCopies);
241 scheduleMove(cycle, node);
242 scheduledMoves++;
243
244 TTAProgram::Terminal& dest = node.move().destination();
245 // got trigger?
246 if (dest.isFUPort() && dest.isTriggering()) {
247
248 // if all operands not scheduled, delay trigger
249 if (scheduledMoves < po.inputMoveCount()) {
250 unscheduleInputOperandTempMoves(node, regCopies);
251 trigger = &node;
252 unschedule(node);
253 scheduledMoves--;
254 continue;
255 }
256 }
257 cycle = node.cycle() + 1;
258 }
259 // trigger scheduling delayed, schedule at end
260 if (trigger != NULL && !trigger->isScheduled()) {
261 assert(scheduledMoves == po.inputMoveCount()-1);
262 cycle = scheduleInputOperandTempMoves(cycle, *trigger, regCopies);
263 return scheduleMove(cycle, *trigger);
264 }
265 return cycle - 1;
266}
267
268/**
269 * Schedules the result read moves of an operation execution.
270 *
271 * Assumes the given MoveNodeGroup contains all moves in the operation
272 * execution. Also assumes that all operand moves have been scheduled.
273 *
274 * @param moves Moves of the operation execution.
275 * @return cycle of last operand read, or -1 if fails
276 */
277int
279 int cycle, MoveNodeGroup& moves,
281 for (int moveIndex = 0; moveIndex < moves.nodeCount(); ++moveIndex) {
282 MoveNode& node = moves.node(moveIndex);
283
284 if (!node.isScheduled()) {
285 if (!node.isSourceOperation()) {
286 throw InvalidData(
287 __FILE__, __LINE__, __func__,
288 (boost::format("Move to schedule '%s' is not "
289 "result move!") % node.toString()).str());
290 }
291
292 cycle = std::max(cycle, node.earliestResultReadCycle());
293 cycle = scheduleMove(cycle, node);
294 cycle = scheduleResultTempMoves(cycle, node, regCopies);
295
296 if (!node.isScheduled()) {
297 throw InvalidData(
298 __FILE__, __LINE__, __func__,
299 (boost::format("Move '%s' did not get scheduled!")
300 % node.toString()).str());
301 }
302 }
303 }
304 return cycle;
305}
306
307/**
308 * Schedules a RR move and its temp compies.
309 *
310 * @param cycle The earliest cycle to try.
311 * @param moveNode R-R Move to schedule.
312 * @return Last cycle where the moves got scheduled.
313 */
314int
316 RegisterCopyAdder regCopyAdder(
318
320 regCopyAdder.addRegisterCopiesToRRMove(moveNode, NULL);
321
322 cycle = scheduleMove(cycle, moveNode) + 1;
323 cycle = scheduleRRTempMoves(cycle, moveNode, addedCopies);
324
325 return cycle - 1;
326}
327
328/**
329 * Schedules a single move to the earliest possible cycle, taking in
330 * account the resource constraints, and latencies in producing
331 * source values.
332 *
333 * This method assumes the move is possible to schedule with regards to
334 * connectivity and resources. Short immediates are converted to long
335 * immediates when needed.
336 *
337 * @param move The move to schedule.
338 * @param earliestCycle The earliest cycle to try.
339 * @return cycle where the move got scheduled.
340 */
341int
342SequentialScheduler::scheduleMove(int earliestCycle, MoveNode& moveNode) {
343 if (moveNode.isScheduled()) {
344 throw InvalidData(
345 __FILE__, __LINE__, __func__,
346 (boost::format("Move '%s' is already scheduled!")
347 % moveNode.toString()).str());
348 }
349
350 // if it's a conditional move then we have to be sure that the guard
351 // is defined before executing the move
352 if (!moveNode.move().isUnconditional()) {
353 int guardLatency =
355
356 const TTAMachine::Guard& guard = moveNode.move().guard().guard();
357 const TTAMachine::RegisterGuard* rg =
358 dynamic_cast<const TTAMachine::RegisterGuard*>(&guard);
359 if (rg != NULL) {
360 guardLatency += rg->registerFile()->guardLatency();
361 }
362 earliestCycle += std::max(0, guardLatency - 1);
363 }
364
365 // RM hasConnection takes MoveNodeSet, however is called only for one
366 // moveNode here.
367 MoveNodeSet tempSet;
368 tempSet.addMoveNode(moveNode);
369 if (moveNode.isSourceConstant() &&
370 !moveNode.move().hasAnnotations(
372
373 // If source is constant and node does not have annotation already,
374 // we add it if constant can not be transported so IU broker and
375 // OutputPSocket brokers will add Immediate
376 // Example : 999999 -> integer0.2
377 if (!rm_->canTransportImmediate(moveNode)){
380 moveNode.move().setAnnotation(annotation);
381
382 } else if (!moveNode.isDestinationOperation() &&
383 rm_->earliestCycle(rm_->largestCycle()+1,moveNode) == -1) {
384 // If source is constant and node does not have annotation
385 // already, we add it if node has no connection, so IU broker and
386 // OutputPSocket brokers will add Immediate
387 // Example: 27 -> integer0.2
388 // With bus capable of transporting 27 as short immediate but
389 // no connection from that bus to integer0 unit
392 moveNode.move().setAnnotation(annotation);
393 }
394 }
395 // annotate the return move otherwise it might get undetected in the
396 // simulator after the short to long immediate conversion and thus
397 // stopping simulation automatically might not work
398 if (moveNode.isSourceConstant() &&
399 moveNode.move().isReturn() &&
400 !rm_->canTransportImmediate(moveNode)) {
403 moveNode.move().setAnnotation(annotation);
404 }
405
406 earliestCycle = rm_->earliestCycle(earliestCycle, moveNode);
407 if (earliestCycle == -1 || earliestCycle == INT_MAX) {
408 if (moveNode.isSourceConstant() &&
409 !moveNode.isDestinationOperation() &&
410 moveNode.move().hasAnnotations(
412 // If earliest cycle returns -1 and source is constant
413 // and moveNode needs long immediate
414 // there is most likely missing long immediate unit
415 std::string msg = "Assignment of MoveNode " + moveNode.toString();
416 msg += " failed! Most likely missing Long Immediate Unit";
417 msg += " or Instruction Template!";
418 throw IllegalMachine(
419 __FILE__, __LINE__, __func__, msg);
420 }
421 std::string msg = "Assignment of MoveNode " + moveNode.toString();
422 msg += " failed!";
423 throw ModuleRunTimeError(
424 __FILE__, __LINE__, __func__, msg);
425 }
426 rm_->assign(earliestCycle, moveNode);
427 if (!moveNode.isScheduled()) {
428 throw ModuleRunTimeError(
429 __FILE__, __LINE__, __func__,
430 (boost::format("Assignment of MoveNode '%s' failed!")
431 % moveNode.toString()).str());
432 }
433 return earliestCycle;
434}
435
436/**
437 * Schedules the (possible) temporary register copy moves (due to missing
438 * connectivity) succeeding the given RR move.
439 *
440 * The function recursively goes through all the temporary moves added to
441 * the given RR move.
442 *
443 * @param cycle Earliest cycle for starting scheduling
444 * @param regToRegMove A temp move whose successor has to be scheduled.
445 * @param lastUse Recursive function parameter, it should be set as 0
446 * for the first function call.
447 * @return cycle next available cycle
448 */
449int
451 int cycle, MoveNode& regToRegMove,
453 if (regCopies.count_ > 0) {
454 if (MapTools::containsKey(regCopies.operandCopies_,&regToRegMove)) {
456 regCopies.operandCopies_[&regToRegMove];
457 //in the tempMoves nodeset, the first move is the original one,
458 //in case of RR temp moves it must be scheduled at the end;
459 //all the temp moves must be scheduled in reverse order
460 DataDependenceGraph::NodeSet::iterator i = tempMoves.end();
461 while(i != tempMoves.begin()){
462 --i;
463 cycle = scheduleMove(cycle, **i) + 1;
464 }
465 }
466 }
467 return cycle;
468}
469
470/**
471 * Schedules the (possible) temporary register copy moves (due to missing
472 * connectivity) preceeding the given input move.
473 *
474 * @param operandMove The move of which temp moves to schedule.
475 * @param regCopies Temp register copy moves associated with operandMove
476 * @return cycle next available cycle
477 */
478int
480 int cycle, MoveNode& operandMove,
482 if (regCopies.count_ > 0) {
483 if (MapTools::containsKey(regCopies.operandCopies_,&operandMove)) {
485 regCopies.operandCopies_[&operandMove];
486 //in the tempMoves nodeset, the first move is the original one;
487 //in case of input operand temp moves, it must be scheduled first
488 DataDependenceGraph::NodeSet::iterator i = tempMoves.begin();
489 cycle = scheduleMove(cycle, **i) + 1;
490 //then all the other moves follows;
491 //they must be scheduled in reverse order
492 i = tempMoves.end();
493 --i;
494 while(i != tempMoves.begin()){
495 cycle = scheduleMove(cycle, **i) + 1;
496 --i;
497 }
498 }
499 }
500 return cycle;
501}
502
503/**
504 * Unschedules the (possible) temporary register copy moves (due to missing
505 * connectivity) preceeding the given input move.
506 *
507 * @param operandMove Move to unschedule.
508 * @param regCopies Temp register copy moves associated with operandMove
509 */
510void
512 MoveNode& operandMove, RegisterCopyAdder::AddedRegisterCopies& regCopies) {
513
514 if (regCopies.count_ > 0) {
515 if (MapTools::containsKey(regCopies.operandCopies_,&operandMove)) {
517 regCopies.operandCopies_[&operandMove];
518 for (DataDependenceGraph::NodeSet::iterator i = tempMoves.begin();
519 i != tempMoves.end(); ++i) {
520 unschedule(**i);
521 }
522 }
523 }
524}
525
526
527/**
528 * Schedules the (possible) temporary register copy moves (due to missing
529 * connectivity) succeeding the given result move.
530 *
531 * @param operandMove The move of which temp moves to schedule.
532 * @param cycle of the last actual result move
533 * @return cycle cycle of last scheduled temp move
534 *
535 */
536int
538 int cycle, MoveNode& resultMove,
540 if (regCopies.count_ > 0) {
541 if (MapTools::containsKey(regCopies.resultCopies_,&resultMove)) {
543 regCopies.resultCopies_[&resultMove];
544 //in the tempMoves nodeset, the first move is the original one,
545 //in case of result temp moves it must be scheduled at the end;
546 //all the temp moves must be scheduled in reverse order
547 DataDependenceGraph::NodeSet::iterator i = tempMoves.end();
548 while (i != tempMoves.begin()) {
549 --i;
550 cycle = scheduleMove(cycle + 1, **i);
551 }
552 }
553 }
554 return cycle;
555}
556
557/**
558 * Unschedules the given move.
559 *
560 * Also restores a possible short immediate source in case it was converted
561 * to a long immediate register read during scheduling.
562 *
563 * @param moveNode Move to unschedule.
564 */
565void
567 if (!moveNode.isScheduled()) {
568 throw InvalidData(
569 __FILE__, __LINE__, __func__,
570 (boost::format("Trying to unschedule move '%s' which "
571 "is not scheduled!") % moveNode.toString()).str());
572 }
573 rm_->unassign(moveNode);
574 if (moveNode.move().hasAnnotations(
576 // If we added annotation during scheduleMove delete it
577 moveNode.move().removeAnnotations(
579 }
580 if (moveNode.isScheduled() || moveNode.isPlaced()) {
581 throw InvalidData(
582 __FILE__, __LINE__, __func__,
583 (boost::format("Unscheduling of move '%s' failed!")
584 % moveNode.toString()).str());
585 }
586}
587
588/**
589 * Schedules a procedure.
590 *
591 * The original procedure is modified during scheduling.
592 *
593 * @param procedure The procedure to schedule.
594 * @param targetMachine The target machine.
595 * @exception Exception In case of an error during scheduling. The exception
596 * type can be any subtype of Exception.
597 */
598void
600 TTAProgram::Procedure& procedure,
601 const TTAMachine::Machine& targetMachine) {
602 std::vector<TTAProgram::BasicBlock*> basicBlocks;
603 std::vector<int> bbAddresses;
604 createBasicBlocks(procedure, basicBlocks, bbAddresses);
605
606 for (unsigned int i = 0; i < basicBlocks.size();i++) {
608 *basicBlocks[i], targetMachine,
609 procedure.parent().instructionReferenceManager());
610 }
611
612 copyBasicBlocksToProcedure(procedure, basicBlocks, bbAddresses);
613
614 // delete the basic blocks.
615 for (unsigned int i = 0; i < basicBlocks.size();i++) {
616 delete basicBlocks[i];
617 }
618}
619
620/**
621 * A short description of the pass, usually the optimization name,
622 * such as "basic block scheduler".
623 *
624 * @return The description as a string.
625 */
626std::string
628 return "Sequential Instruction scheduler";
629}
630
631/**
632 * Optional longer description of the pass.
633 *
634 * This description can include usage instructions, details of choice of
635 * algorithmic details, etc.
636 *
637 * @return The description as a string.
638 */
639std::string
641 return "Sequential Instruction scheduler";
642}
643
644/**
645 * Splits a procedure into basic blocks.
646 */
647void
650 std::vector<TTAProgram::BasicBlock*> &basicBlocks,
651 std::vector<int>& bbAddresses) {
654 TTAProgram::BasicBlock* currentBB = NULL;
655 int lastStartAddress = 0;
656 // loop thru all instructions in the given BB.
657 for (int i = 0; i < proc.instructionCount(); i++) {
659 TTAProgram::Instruction* insCopy = ins.copy();
660
661 // if has references, starts a new BB, from this instruction.
662 if (irm.hasReference(ins)) {
663 if (currentBB != NULL) {
664 // only add non-empty BBs.
665 if (currentBB->instructionCount() != 0) {
666 basicBlocks.push_back(currentBB);
667 bbAddresses.push_back(lastStartAddress);
668 } else {
669 delete currentBB;
670 }
671 }
672 lastStartAddress = ins.address().location();
673 currentBB = new TTAProgram::BasicBlock(lastStartAddress);
674 // update instruction references.
675// irm.replace(ins, *insCopy);
676 }
677 assert(currentBB != NULL); // first ins of proc should have a ref.
678 currentBB->add(insCopy);
679
680 // jump or call starts a new BB, after this instruction.
681 if (ins.hasControlFlowMove()) {
682 basicBlocks.push_back(currentBB);
683 bbAddresses.push_back(lastStartAddress);
684 lastStartAddress = ins.address().location() + 1;
685 currentBB = new TTAProgram::BasicBlock(lastStartAddress);
686 }
687 }
688
689 if (currentBB != nullptr) {
690 // at end, add last BB if non-empty
691 if (currentBB->instructionCount() != 0) {
692 basicBlocks.push_back(currentBB);
693 bbAddresses.push_back(lastStartAddress);
694 } else {
695 delete currentBB;
696 }
697 }
698}
699
700void
703 std::vector<TTAProgram::BasicBlock*>& basicBlocks,
704 std::vector<int>& bbAddresses) {
707
708 for (unsigned int i = 0; i < basicBlocks.size(); i++) {
709 TTAProgram::BasicBlock& bb = *basicBlocks.at(i);
711 TTAProgram::Instruction& oldProcIns = proc.instructionAt(
712 bbAddresses[i]);
713 if (irm.hasReference(oldProcIns)) {
714 irm.replace(oldProcIns, bbIns);
715 }
716 }
717
718 proc.clear();
719 for (unsigned int i = 0; i < basicBlocks.size(); i++) {
720 TTAProgram::BasicBlock& bb = *basicBlocks.at(i);
721
722 // first one is a special case. can contain ref which need to
723 // be update
725 TTAProgram::Instruction* insCopy = ins.copy();
726 proc.CodeSnippet::add(insCopy); // delay address fix
727
728 if (irm.hasReference(ins)) {
729 irm.replace(ins, *insCopy);
730 }
731
732 for (int j = 1; j < bb.instructionCount(); j++) {
734 TTAProgram::Instruction* insCopy = ins.copy();
735 proc.CodeSnippet::add(insCopy); // delay address fix
736 }
737 }
738
739 // update inst addresses
740 if (proc.isInProgram()) {
741 if (!(&proc == &proc.parent().lastProcedure())) {
742 proc.parent().moveProcedure(
743 proc.parent().nextProcedure(proc),
744 proc.instructionCount());
745 }
746 }
747}
#define __func__
#define assert(condition)
static void copyRMToBB(SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
static bool containsKey(const MapType &aMap, const KeyType &aKey)
int nodeCount() const
MoveNode & node(int index) const
std::string toString() const
bool isScheduled() const
void addMoveNode(MoveNode &)
int earliestResultReadCycle() const
Definition MoveNode.cc:652
bool isOperationMove() const
Definition MoveNode.cc:253
int cycle() const
Definition MoveNode.cc:421
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
bool isDestinationOperation() const
std::string toString() const
Definition MoveNode.cc:576
bool isPlaced() const
Definition MoveNode.cc:352
TTAProgram::Move & move()
bool isSourceOperation() const
Definition MoveNode.cc:168
bool isScheduled() const
Definition MoveNode.cc:409
bool isSourceConstant() const
Definition MoveNode.cc:238
ProgramOperation & destinationOperation(unsigned int index=0) const
int inputMoveCount() const
AddedRegisterCopies addRegisterCopiesToRRMove(MoveNode &moveNode, DataDependenceGraph *ddg)
AddedRegisterCopies addMinimumRegisterCopies(ProgramOperation &programOperation, const TTAMachine::Machine &targetMachine, DataDependenceGraph *ddg)
InterPassData & interPassData()
virtual void notifyScheduled(MoveNode &node)
int scheduleInputOperandTempMoves(int cycle, MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
void createBasicBlocks(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
SequentialScheduler(InterPassData &data)
void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine)
void unschedule(MoveNode &moveNode)
int scheduleMove(int earliestCycle, MoveNode &move)
SimpleResourceManager * rm_
Resource Manager of the currently scheduled BB.
int scheduleResultTempMoves(int cycle, MoveNode &resultMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
int scheduleRRMove(int cycle, MoveNode &moveNode)
int scheduleOperandWrites(int cycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
int scheduleRRTempMoves(int cycle, MoveNode &regToRegMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
virtual void handleBasicBlock(TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, BasicBlockNode *bbn=NULL)
virtual std::string shortDescription() const
int scheduleOperation(MoveNodeGroup &moves, int earliestCycle)
int scheduleResultReads(int triggerCycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
virtual std::string longDescription() const
MoveNodeSelector * selector_
void copyBasicBlocksToProcedure(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
void unscheduleInputOperandTempMoves(MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
const TTAMachine::Machine * targetMachine_
The target machine we are scheduling the program against.
virtual void assign(int cycle, MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) override
static void disposeRM(SimpleResourceManager *rm, bool allowReuse=true)
virtual int earliestCycle(MoveNode &node, const TTAMachine::Bus *bus=NULL, const TTAMachine::FunctionUnit *srcFU=NULL, const TTAMachine::FunctionUnit *dstFU=NULL, int immWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1) const override
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssignedBus=NULL) const
virtual void unassign(MoveNode &node) override
static SimpleResourceManager * createRM(const TTAMachine::Machine &machine, unsigned int ii=0)
virtual int largestCycle() const override
int globalGuardLatency() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual int guardLatency() const
const RegisterFile * registerFile() const
InstructionAddress location() const
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
void setAnnotation(const ProgramAnnotation &annotation)
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual Instruction & firstInstruction() const
virtual bool isInProgram() const
virtual void add(Instruction *ins)
virtual int instructionCount() const
virtual Instruction & instructionAt(UIntWord address) const
virtual Program & parent() const
virtual Instruction & instructionAtIndex(int index) const
void replace(Instruction &insA, Instruction &insB)
Instruction * copy() const
Address address() const
bool hasControlFlowMove() const
const TTAMachine::Guard & guard() const
Definition MoveGuard.cc:86
MoveGuard & guard() const
Definition Move.cc:345
bool isReturn() const
Definition Move.cc:259
bool isUnconditional() const
Definition Move.cc:154
Terminal & destination() const
Definition Move.cc:323
@ ANN_STACKFRAME_PROCEDURE_RETURN
precedure return jmp
void moveProcedure(Procedure &proc, int howMuch)
Definition Program.cc:588
Procedure & nextProcedure(const Procedure &proc) const
Definition Program.cc:250
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688
Procedure & lastProcedure() const
Definition Program.cc:230
virtual bool isRA() const
Definition Terminal.cc:129
virtual bool isTriggering() const
Definition Terminal.cc:298
virtual bool isFUPort() const
Definition Terminal.cc:118