OpenASIP  2.0
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"
43 #include "SimpleResourceManager.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"
50 #include "InstructionReference.hh"
52 #include "BasicBlock.hh"
53 #include "ControlFlowGraphPass.hh"
54 #include "RegisterCopyAdder.hh"
55 #include "SchedulerPass.hh"
56 #include "Guard.hh"
57 #include "MoveGuard.hh"
58 #include "MoveNodeSet.hh"
59 #include "SequentialScheduler.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 
71 class SequentialSelector;
72 
73 /**
74  * Constructs the sequential scheduler.
75  *
76  * @param data Interpass data
77  */
79  BasicBlockPass(data),
81  ProcedurePass(data),
82  ProgramPass(data),
83  rm_(NULL) {
84 }
85 
86 /**
87  * Destructor.
88  */
90 }
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  */
100 void
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
149 static 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  */
162 int
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  */
222 int
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  */
277 int
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  */
314 int
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  */
341 int
342 SequentialScheduler::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  */
449 int
451  int cycle, MoveNode& regToRegMove,
453  if (regCopies.count_ > 0) {
454  if (MapTools::containsKey(regCopies.operandCopies_,&regToRegMove)) {
455  DataDependenceGraph::NodeSet tempMoves =
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  */
478 int
480  int cycle, MoveNode& operandMove,
482  if (regCopies.count_ > 0) {
483  if (MapTools::containsKey(regCopies.operandCopies_,&operandMove)) {
484  DataDependenceGraph::NodeSet tempMoves =
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  */
510 void
512  MoveNode& operandMove, RegisterCopyAdder::AddedRegisterCopies& regCopies) {
513 
514  if (regCopies.count_ > 0) {
515  if (MapTools::containsKey(regCopies.operandCopies_,&operandMove)) {
516  DataDependenceGraph::NodeSet tempMoves =
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  */
536 int
538  int cycle, MoveNode& resultMove,
540  if (regCopies.count_ > 0) {
541  if (MapTools::containsKey(regCopies.resultCopies_,&resultMove)) {
542  DataDependenceGraph::NodeSet tempMoves =
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  */
565 void
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  */
598 void
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  */
626 std::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  */
639 std::string
641  return "Sequential Instruction scheduler";
642 }
643 
644 /**
645  * Splits a procedure into basic blocks.
646  */
647 void
649  TTAProgram::Procedure& proc,
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 
700 void
702  TTAProgram::Procedure& proc,
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 }
TTAMachine::Guard
Definition: Guard.hh:55
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
SequentialScheduler::unscheduleInputOperandTempMoves
void unscheduleInputOperandTempMoves(MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:511
ProcedurePass
Definition: ProcedurePass.hh:53
RegisterCopyAdder::AddedRegisterCopies
Definition: RegisterCopyAdder.hh:104
TTAProgram::Terminal::isTriggering
virtual bool isTriggering() const
Definition: Terminal.cc:298
SequentialScheduler::scheduleOperandWrites
int scheduleOperandWrites(int cycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:223
SequentialScheduler::SequentialScheduler
SequentialScheduler(InterPassData &data)
Definition: SequentialScheduler.cc:78
TTAProgram::CodeSnippet::firstInstruction
virtual Instruction & firstInstruction() const
Definition: CodeSnippet.cc:216
SimpleResourceManager::largestCycle
virtual int largestCycle() const override
Definition: SimpleResourceManager.cc:463
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
MoveNodeGroup::node
MoveNode & node(int index) const
Definition: MoveNodeGroup.cc:152
SequentialScheduler::longDescription
virtual std::string longDescription() const
Definition: SequentialScheduler.cc:640
RegisterCopyAdder
Definition: RegisterCopyAdder.hh:91
SchedulerPass.hh
MoveNodeGroup.hh
SequentialScheduler.hh
MoveNode::isDestinationOperation
bool isDestinationOperation() const
TTAProgram::Move::isReturn
bool isReturn() const
Definition: Move.cc:259
BoostGraph< MoveNode, DataDependenceEdge >::NodeSet
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
MapTools.hh
Procedure.hh
TTAProgram::AnnotatedInstructionElement::setAnnotation
void setAnnotation(const ProgramAnnotation &annotation)
Definition: AnnotatedInstructionElement.cc:79
SequentialScheduler::rm_
SimpleResourceManager * rm_
Resource Manager of the currently scheduled BB.
Definition: SequentialScheduler.hh:124
ProgramPass
Definition: ProgramPass.hh:52
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
SequentialMoveNodeSelector::candidates
virtual MoveNodeGroup candidates()
Definition: SequentialMoveNodeSelector.cc:85
RegisterCopyAdder::AddedRegisterCopies::operandCopies_
AddedRegisterCopyMap operandCopies_
Definition: RegisterCopyAdder.hh:108
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
MoveNode::isSourceConstant
bool isSourceConstant() const
Definition: MoveNode.cc:238
SimpleResourceManager::assign
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
Definition: SimpleResourceManager.cc:221
Terminal.hh
SequentialScheduler::targetMachine_
const TTAMachine::Machine * targetMachine_
The target machine we are scheduling the program against.
Definition: SequentialScheduler.hh:122
MoveNodeGroup::nodeCount
int nodeCount() const
Definition: MoveNodeGroup.cc:140
SequentialScheduler::scheduleMove
int scheduleMove(int earliestCycle, MoveNode &move)
Definition: SequentialScheduler.cc:342
SimpleResourceManager::unassign
virtual void unassign(MoveNode &node) override
Definition: SimpleResourceManager.cc:252
MoveNode::isPlaced
bool isPlaced() const
Definition: MoveNode.cc:352
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
BasicBlockPass
Definition: BasicBlockPass.hh:60
assert
#define assert(condition)
Definition: Application.hh:86
UniversalMachine.hh
SequentialScheduler::scheduleInputOperandTempMoves
int scheduleInputOperandTempMoves(int cycle, MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:479
TTAProgram::Program::nextProcedure
Procedure & nextProcedure(const Procedure &proc) const
Definition: Program.cc:250
MoveNode::earliestResultReadCycle
int earliestResultReadCycle() const
Definition: MoveNode.cc:652
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
InvalidData
Definition: Exception.hh:149
RegisterCopyAdder::addRegisterCopiesToRRMove
AddedRegisterCopies addRegisterCopiesToRRMove(MoveNode &moveNode, DataDependenceGraph *ddg)
Definition: RegisterCopyAdder.cc:212
Instruction.hh
TTAProgram::Program::moveProcedure
void moveProcedure(Procedure &proc, int howMuch)
Definition: Program.cc:588
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
TTAProgram::CodeSnippet::add
virtual void add(Instruction *ins)
Definition: CodeSnippet.cc:432
SequentialScheduler::scheduleResultTempMoves
int scheduleResultTempMoves(int cycle, MoveNode &resultMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:537
SequentialMoveNodeSelector::notifyScheduled
virtual void notifyScheduled(MoveNode &node)
Definition: SequentialMoveNodeSelector.cc:100
TTAMachine::RegisterGuard
Definition: Guard.hh:137
TTAProgram::Instruction::copy
Instruction * copy() const
Definition: Instruction.cc:379
TTAProgram::InstructionReferenceManager::hasReference
bool hasReference(Instruction &ins) const
Definition: InstructionReferenceManager.cc:143
TTAProgram::InstructionReferenceManager::replace
void replace(Instruction &insA, Instruction &insB)
Definition: InstructionReferenceManager.cc:96
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
__func__
#define __func__
Definition: Application.hh:67
BasicBlockNode
Definition: BasicBlockNode.hh:64
RegisterCopyAdder::AddedRegisterCopies::count_
int count_
Definition: RegisterCopyAdder.hh:107
SimpleResourceManager::earliestCycle
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
Definition: SimpleResourceManager.cc:278
InterPassData
Definition: InterPassData.hh:48
Guard.hh
SequentialScheduler::~SequentialScheduler
virtual ~SequentialScheduler()
Definition: SequentialScheduler.cc:89
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
SimpleResourceManager::disposeRM
static void disposeRM(SimpleResourceManager *rm, bool allowReuse=true)
Definition: SimpleResourceManager.cc:92
TTAProgram::Procedure::clear
void clear()
Definition: Procedure.cc:345
TTAProgram::Address::location
InstructionAddress location() const
TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM
@ ANN_REQUIRES_LIMM
Definition: ProgramAnnotation.hh:125
SequentialScheduler::shortDescription
virtual std::string shortDescription() const
Definition: SequentialScheduler.cc:627
Machine.hh
ModuleRunTimeError
Definition: Exception.hh:1043
MoveNodeSet
Definition: MoveNodeSet.hh:41
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
BasicBlockPass::copyRMToBB
static void copyRMToBB(SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
Definition: BasicBlockPass.cc:213
TTAProgram::AnnotatedInstructionElement::hasAnnotations
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:165
MoveNodeGroup::toString
std::string toString() const
Definition: MoveNodeGroup.cc:248
SimpleResourceManager::createRM
static SimpleResourceManager * createRM(const TTAMachine::Machine &machine, unsigned int ii=0)
Definition: SimpleResourceManager.cc:73
ProgramOperation.hh
SequentialScheduler::handleBasicBlock
virtual void handleBasicBlock(TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, BasicBlockNode *bbn=NULL)
Definition: SequentialScheduler.cc:101
SequentialScheduler::copyBasicBlocksToProcedure
void copyBasicBlocksToProcedure(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
Definition: SequentialScheduler.cc:701
SequentialScheduler::scheduleRRTempMoves
int scheduleRRTempMoves(int cycle, MoveNode &regToRegMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:450
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
MoveNode::move
TTAProgram::Move & move()
SchedulerPass::interPassData
InterPassData & interPassData()
Definition: SchedulerPass.cc:53
SequentialScheduler::scheduleResultReads
int scheduleResultReads(int triggerCycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
Definition: SequentialScheduler.cc:278
MapTools::containsKey
static bool containsKey(const MapType &aMap, const KeyType &aKey)
TTAProgram::InstructionReferenceManager
Definition: InstructionReferenceManager.hh:82
TTAProgram::Program::instructionReferenceManager
InstructionReferenceManager & instructionReferenceManager() const
Definition: Program.cc:688
RegisterCopyAdder::AddedRegisterCopies::resultCopies_
AddedRegisterCopyMap resultCopies_
Definition: RegisterCopyAdder.hh:109
TTAProgram::ProgramAnnotation::ANN_STACKFRAME_PROCEDURE_RETURN
@ ANN_STACKFRAME_PROCEDURE_RETURN
precedure return jmp
Definition: ProgramAnnotation.hh:76
IllegalMachine
Definition: Exception.hh:878
Program.hh
MoveNodeSet::addMoveNode
void addMoveNode(MoveNode &)
Definition: MoveNodeSet.cc:62
SimpleResourceManager::canTransportImmediate
virtual bool canTransportImmediate(const MoveNode &node, const TTAMachine::Bus *preAssignedBus=NULL) const
Definition: SimpleResourceManager.cc:411
MoveNodeSet.hh
AssocTools.hh
InstructionReference.hh
TTAProgram::CodeSnippet::parent
virtual Program & parent() const
Definition: CodeSnippet.cc:118
BasicBlock.hh
ControlFlowGraphPass.hh
ControlUnit.hh
SequentialScheduler::handleProcedure
void handleProcedure(TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine)
Definition: SequentialScheduler.cc:599
MoveNode::isOperationMove
bool isOperationMove() const
Definition: MoveNode.cc:253
InstructionReferenceManager.hh
RegisterCopyAdder.hh
TTAProgram::Terminal
Definition: Terminal.hh:60
SimpleResourceManager.hh
MoveNodeGroup::isScheduled
bool isScheduled() const
Definition: MoveNodeGroup.cc:164
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
SequentialScheduler::selector_
MoveNodeSelector * selector_
Definition: SequentialScheduler.hh:126
SequentialScheduler::createBasicBlocks
void createBasicBlocks(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
Definition: SequentialScheduler.cc:648
TTAProgram::Instruction::hasControlFlowMove
bool hasControlFlowMove() const
Definition: Instruction.cc:471
ControlFlowGraphPass
Definition: ControlFlowGraphPass.hh:50
TTAMachine::RegisterFile::guardLatency
virtual int guardLatency() const
Definition: RegisterFile.cc:333
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
TTAProgram::Program::lastProcedure
Procedure & lastProcedure() const
Definition: Program.cc:230
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
MoveNodeGroup
Definition: MoveNodeGroup.hh:48
TTAProgram::AnnotatedInstructionElement::removeAnnotations
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)
Definition: AnnotatedInstructionElement.cc:146
TTAProgram::CodeSnippet::instructionAt
virtual Instruction & instructionAt(UIntWord address) const
Definition: CodeSnippet.cc:241
Move.hh
TTAMachine::ControlUnit::globalGuardLatency
int globalGuardLatency() const
TTAProgram::Terminal::isRA
virtual bool isRA() const
Definition: Terminal.cc:129
MoveNode.hh
SequentialScheduler::unschedule
void unschedule(MoveNode &moveNode)
Definition: SequentialScheduler.cc:566
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
SequentialMoveNodeSelector.hh
TTAProgram::Procedure
Definition: Procedure.hh:55
SequentialMoveNodeSelector
Definition: SequentialMoveNodeSelector.hh:47
TTAProgram::Instruction::address
Address address() const
Definition: Instruction.cc:327
TTAProgram::CodeSnippet::isInProgram
virtual bool isInProgram() const
Definition: CodeSnippet.cc:151
TTAMachine::Machine
Definition: Machine.hh:73
SequentialScheduler::scheduleOperation
int scheduleOperation(MoveNodeGroup &moves, int earliestCycle)
Definition: SequentialScheduler.cc:163
RegisterCopyAdder::addMinimumRegisterCopies
AddedRegisterCopies addMinimumRegisterCopies(ProgramOperation &programOperation, const TTAMachine::Machine &targetMachine, DataDependenceGraph *ddg)
Definition: RegisterCopyAdder.cc:139
MoveGuard.hh
SequentialScheduler::scheduleRRMove
int scheduleRRMove(int cycle, MoveNode &moveNode)
Definition: SequentialScheduler.cc:315