OpenASIP 2.2
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
SequentialScheduler Class Reference

#include <SequentialScheduler.hh>

Inheritance diagram for SequentialScheduler:
Inheritance graph
Collaboration diagram for SequentialScheduler:
Collaboration graph

Public Member Functions

 SequentialScheduler (InterPassData &data)
 
virtual ~SequentialScheduler ()
 
void handleProcedure (TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetMachine)
 
virtual void handleBasicBlock (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, BasicBlockNode *bbn=NULL)
 
virtual std::string shortDescription () const
 
virtual std::string longDescription () const
 
- Public Member Functions inherited from BasicBlockPass
 BasicBlockPass (InterPassData &data)
 
virtual ~BasicBlockPass ()
 
virtual void executeDDGPass (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, std::vector< DDGPass * > ddgPasses, BasicBlockNode *bbn=NULL)
 
virtual bool executeLoopPass (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, std::vector< DDGPass * > ddgPasses, BasicBlockNode *bbn=NULL)
 
virtual DataDependenceGraphBuilderddgBuilder ()
 
- Public Member Functions inherited from SchedulerPass
 SchedulerPass (InterPassData &data)
 
virtual ~SchedulerPass ()
 
InterPassDatainterPassData ()
 
- Public Member Functions inherited from ControlFlowGraphPass
 ControlFlowGraphPass (InterPassData &data)
 
virtual ~ControlFlowGraphPass ()
 
virtual void handleControlFlowGraph (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine)
 
void executeBasicBlockPass (ControlFlowGraph &cfg, const TTAMachine::Machine &targetMachine, BasicBlockPass &bbPass)
 
- Public Member Functions inherited from ProcedurePass
 ProcedurePass (InterPassData &data)
 
virtual ~ProcedurePass ()
 
- Public Member Functions inherited from ProgramPass
 ProgramPass (InterPassData &data)
 
virtual ~ProgramPass ()
 
virtual void handleProgram (TTAProgram::Program &program, const TTAMachine::Machine &targetMachine)
 

Private Member Functions

int scheduleOperation (MoveNodeGroup &moves, int earliestCycle)
 
int scheduleOperandWrites (int cycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
int scheduleResultReads (int triggerCycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
int scheduleRRMove (int cycle, MoveNode &moveNode)
 
int scheduleRRTempMoves (int cycle, MoveNode &regToRegMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
int scheduleMove (int earliestCycle, MoveNode &move)
 
int scheduleInputOperandTempMoves (int cycle, MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
void unscheduleInputOperandTempMoves (MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
int scheduleResultTempMoves (int cycle, MoveNode &resultMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
 
void createBasicBlocks (TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
 
void copyBasicBlocksToProcedure (TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
 
void unschedule (MoveNode &moveNode)
 

Private Attributes

const TTAMachine::MachinetargetMachine_
 The target machine we are scheduling the program against.
 
SimpleResourceManagerrm_
 Resource Manager of the currently scheduled BB.
 
MoveNodeSelectorselector_
 

Additional Inherited Members

- Static Public Member Functions inherited from BasicBlockPass
static void copyRMToBB (SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
 
- Static Public Member Functions inherited from ProcedurePass
static void copyCfgToProcedure (TTAProgram::Procedure &procedure, ControlFlowGraph &cfg)
 
static void executeControlFlowGraphPass (TTAProgram::Procedure &procedure, const TTAMachine::Machine &targetmachine, ControlFlowGraphPass &cfgp)
 
- Static Public Member Functions inherited from ProgramPass
static void executeProcedurePass (TTAProgram::Program &program, const TTAMachine::Machine &targetMachine, ProcedurePass &procedurePass)
 
- Protected Member Functions inherited from BasicBlockPass
void ddgSnapshot (DataDependenceGraph *ddg, std::string &name, DataDependenceGraph::DumpFileFormat format, bool final)
 
virtual DataDependenceGraphcreateDDGFromBB (TTAProgram::BasicBlock &bb, const TTAMachine::Machine &mach)
 

Detailed Description

A class that implements the functionality of a basic block scheduler.

Schedules the program one basic block at a time. Does not fill delay slots if they couldn't be filled with the basic block's contents itself (no instruction importing).

Definition at line 56 of file SequentialScheduler.hh.

Constructor & Destructor Documentation

◆ SequentialScheduler()

SequentialScheduler::SequentialScheduler ( InterPassData data)

Constructs the sequential scheduler.

Parameters
dataInterpass data

Definition at line 78 of file SequentialScheduler.cc.

78 :
79 BasicBlockPass(data),
81 ProcedurePass(data),
82 ProgramPass(data),
83 rm_(NULL) {
84}
SimpleResourceManager * rm_
Resource Manager of the currently scheduled BB.

◆ ~SequentialScheduler()

SequentialScheduler::~SequentialScheduler ( )
virtual

Destructor.

Definition at line 89 of file SequentialScheduler.cc.

89 {
90}

Member Function Documentation

◆ copyBasicBlocksToProcedure()

void SequentialScheduler::copyBasicBlocksToProcedure ( TTAProgram::Procedure cs,
std::vector< TTAProgram::BasicBlock * > &  basicBlocks,
std::vector< int > &  bbAddresses 
)
private

Definition at line 701 of file SequentialScheduler.cc.

704 {
706 proc.parent().instructionReferenceManager();
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}
virtual Instruction & firstInstruction() const
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
void replace(Instruction &insA, Instruction &insB)
Instruction * copy() const
CodeSnippet & parent() const

References TTAProgram::Procedure::clear(), TTAProgram::Instruction::copy(), TTAProgram::CodeSnippet::firstInstruction(), TTAProgram::InstructionReferenceManager::hasReference(), TTAProgram::CodeSnippet::instructionAt(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Program::instructionReferenceManager(), TTAProgram::CodeSnippet::isInProgram(), TTAProgram::Program::lastProcedure(), TTAProgram::Program::moveProcedure(), TTAProgram::Program::nextProcedure(), TTAProgram::CodeSnippet::parent(), and TTAProgram::InstructionReferenceManager::replace().

Referenced by handleProcedure().

Here is the call graph for this function:

◆ createBasicBlocks()

void SequentialScheduler::createBasicBlocks ( TTAProgram::Procedure proc,
std::vector< TTAProgram::BasicBlock * > &  basicBlocks,
std::vector< int > &  bbAddresses 
)
private

Splits a procedure into basic blocks.

Definition at line 648 of file SequentialScheduler.cc.

651 {
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}
#define assert(condition)
InstructionAddress location() const
virtual void add(Instruction *ins)
virtual Program & parent() const
Address address() const
bool hasControlFlowMove() const
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::address(), assert, TTAProgram::Instruction::copy(), TTAProgram::Instruction::hasControlFlowMove(), TTAProgram::InstructionReferenceManager::hasReference(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Program::instructionReferenceManager(), TTAProgram::Address::location(), and TTAProgram::CodeSnippet::parent().

Referenced by handleProcedure().

Here is the call graph for this function:

◆ handleBasicBlock()

void SequentialScheduler::handleBasicBlock ( TTAProgram::BasicBlock bb,
const TTAMachine::Machine targetMachine,
TTAProgram::InstructionReferenceManager irm,
BasicBlockNode bbn = NULL 
)
virtual

Schedules a single basic block.

Parameters
bbThe basic block to schedule.
targetMachineThe target machine.
Exceptions
Exceptionseveral TCE exceptions can be thrown in case of a scheduling error.

Reimplemented from BasicBlockPass.

Definition at line 101 of file SequentialScheduler.cc.

103 {
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}
#define __func__
static void copyRMToBB(SimpleResourceManager &rm, TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, int lastCycle=-1)
int nodeCount() const
MoveNode & node(int index) const
bool isScheduled() const
bool isOperationMove() const
Definition MoveNode.cc:253
std::string toString() const
Definition MoveNode.cc:576
TTAProgram::Move & move()
int scheduleMove(int earliestCycle, MoveNode &move)
int scheduleRRMove(int cycle, MoveNode &moveNode)
int scheduleOperation(MoveNodeGroup &moves, int earliestCycle)
MoveNodeSelector * selector_
const TTAMachine::Machine * targetMachine_
The target machine we are scheduling the program against.
static void disposeRM(SimpleResourceManager *rm, bool allowReuse=true)
static SimpleResourceManager * createRM(const TTAMachine::Machine &machine, unsigned int ii=0)
Terminal & destination() const
Definition Move.cc:323
virtual bool isRA() const
Definition Terminal.cc:129

References __func__, SequentialMoveNodeSelector::candidates(), BasicBlockPass::copyRMToBB(), SimpleResourceManager::createRM(), TTAProgram::Move::destination(), SimpleResourceManager::disposeRM(), TTAProgram::CodeSnippet::instructionCount(), MoveNode::isOperationMove(), TTAProgram::Terminal::isRA(), MoveNodeGroup::isScheduled(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), SequentialMoveNodeSelector::notifyScheduled(), rm_, scheduleMove(), scheduleOperation(), scheduleRRMove(), selector_, targetMachine_, and MoveNode::toString().

Referenced by handleProcedure().

Here is the call graph for this function:

◆ handleProcedure()

void SequentialScheduler::handleProcedure ( TTAProgram::Procedure procedure,
const TTAMachine::Machine targetMachine 
)
virtual

Schedules a procedure.

The original procedure is modified during scheduling.

Parameters
procedureThe procedure to schedule.
targetMachineThe target machine.
Exceptions
ExceptionIn case of an error during scheduling. The exception type can be any subtype of Exception.

Reimplemented from ProcedurePass.

Definition at line 599 of file SequentialScheduler.cc.

601 {
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}
void createBasicBlocks(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)
virtual void handleBasicBlock(TTAProgram::BasicBlock &bb, const TTAMachine::Machine &targetMachine, TTAProgram::InstructionReferenceManager &irm, BasicBlockNode *bbn=NULL)
void copyBasicBlocksToProcedure(TTAProgram::Procedure &cs, std::vector< TTAProgram::BasicBlock * > &basicBlocks, std::vector< int > &bbAddresses)

References copyBasicBlocksToProcedure(), createBasicBlocks(), handleBasicBlock(), TTAProgram::Program::instructionReferenceManager(), and TTAProgram::CodeSnippet::parent().

Here is the call graph for this function:

◆ longDescription()

std::string SequentialScheduler::longDescription ( ) const
virtual

Optional longer description of the pass.

This description can include usage instructions, details of choice of algorithmic details, etc.

Returns
The description as a string.

Reimplemented from SchedulerPass.

Definition at line 640 of file SequentialScheduler.cc.

640 {
641 return "Sequential Instruction scheduler";
642}

◆ scheduleInputOperandTempMoves()

int SequentialScheduler::scheduleInputOperandTempMoves ( int  cycle,
MoveNode operandMove,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Schedules the (possible) temporary register copy moves (due to missing connectivity) preceeding the given input move.

Parameters
operandMoveThe move of which temp moves to schedule.
regCopiesTemp register copy moves associated with operandMove
Returns
cycle next available cycle

Definition at line 479 of file SequentialScheduler.cc.

481 {
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}
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
static bool containsKey(const MapType &aMap, const KeyType &aKey)

References MapTools::containsKey(), RegisterCopyAdder::AddedRegisterCopies::count_, RegisterCopyAdder::AddedRegisterCopies::operandCopies_, and scheduleMove().

Referenced by scheduleOperandWrites().

Here is the call graph for this function:

◆ scheduleMove()

int SequentialScheduler::scheduleMove ( int  earliestCycle,
MoveNode moveNode 
)
private

Schedules a single move to the earliest possible cycle, taking in account the resource constraints, and latencies in producing source values.

This method assumes the move is possible to schedule with regards to connectivity and resources. Short immediates are converted to long immediates when needed.

Parameters
moveThe move to schedule.
earliestCycleThe earliest cycle to try.
Returns
cycle where the move got scheduled.

Definition at line 342 of file SequentialScheduler.cc.

342 {
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}
void addMoveNode(MoveNode &)
bool isDestinationOperation() const
bool isScheduled() const
Definition MoveNode.cc:409
bool isSourceConstant() const
Definition MoveNode.cc:238
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
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 int largestCycle() const override
int globalGuardLatency() const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
virtual int guardLatency() const
const RegisterFile * registerFile() const
void setAnnotation(const ProgramAnnotation &annotation)
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) 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
@ ANN_STACKFRAME_PROCEDURE_RETURN
precedure return jmp

References __func__, MoveNodeSet::addMoveNode(), TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM, TTAProgram::ProgramAnnotation::ANN_STACKFRAME_PROCEDURE_RETURN, SimpleResourceManager::assign(), SimpleResourceManager::canTransportImmediate(), TTAMachine::Machine::controlUnit(), SimpleResourceManager::earliestCycle(), TTAMachine::ControlUnit::globalGuardLatency(), TTAProgram::Move::guard(), TTAProgram::MoveGuard::guard(), TTAMachine::RegisterFile::guardLatency(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), MoveNode::isDestinationOperation(), TTAProgram::Move::isReturn(), MoveNode::isScheduled(), MoveNode::isSourceConstant(), TTAProgram::Move::isUnconditional(), SimpleResourceManager::largestCycle(), MoveNode::move(), TTAMachine::RegisterGuard::registerFile(), rm_, TTAProgram::AnnotatedInstructionElement::setAnnotation(), targetMachine_, and MoveNode::toString().

Referenced by handleBasicBlock(), scheduleInputOperandTempMoves(), scheduleOperandWrites(), scheduleResultReads(), scheduleResultTempMoves(), scheduleRRMove(), and scheduleRRTempMoves().

Here is the call graph for this function:

◆ scheduleOperandWrites()

int SequentialScheduler::scheduleOperandWrites ( int  cycle,
MoveNodeGroup moves,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Schedules operand moves of an operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all inputs to the MoveNodeGroup have been scheduled. Exception to this are the possible temporary register copies inserted before the operand move due to missing connectivity. If found, the temp moves are scheduled atomically with the operand move. Assumes top-down scheduling.

Parameters
cycleEarliest cycle for starting scheduling of operands
movesMoves of the operation execution.
Returns
The cycle the trigger got scheduled

Definition at line 223 of file SequentialScheduler.cc.

225 {
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}
int cycle() const
Definition MoveNode.cc:421
ProgramOperation & destinationOperation(unsigned int index=0) const
int inputMoveCount() const
int scheduleInputOperandTempMoves(int cycle, MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
void unschedule(MoveNode &moveNode)
void unscheduleInputOperandTempMoves(MoveNode &operandMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)
virtual bool isTriggering() const
Definition Terminal.cc:298
virtual bool isFUPort() const
Definition Terminal.cc:118

References assert, MoveNode::cycle(), TTAProgram::Move::destination(), MoveNode::destinationOperation(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), TTAProgram::Terminal::isFUPort(), MoveNode::isScheduled(), TTAProgram::Terminal::isTriggering(), MoveNode::move(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), scheduleInputOperandTempMoves(), scheduleMove(), unschedule(), and unscheduleInputOperandTempMoves().

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ scheduleOperation()

int SequentialScheduler::scheduleOperation ( MoveNodeGroup moves,
int  earliestCycle 
)
private

Schedules moves in a single operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all inputs to the MoveNodeGroup have been scheduled.

Parameters
movesMoves of the operation execution.
Returns
returns the last cycle of the operation.

Definition at line 163 of file SequentialScheduler.cc.

164 {
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}
std::string toString() const
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
bool isSourceOperation() const
Definition MoveNode.cc:168
InterPassData & interPassData()
int scheduleOperandWrites(int cycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)
int scheduleResultReads(int triggerCycle, MoveNodeGroup &moves, RegisterCopyAdder::AddedRegisterCopies &regCopies)

References __func__, RegisterCopyAdder::addMinimumRegisterCopies(), MoveNodeSet::addMoveNode(), RegisterCopyAdder::AddedRegisterCopies::count_, MoveNode::destinationOperation(), SchedulerPass::interPassData(), MoveNode::isSourceOperation(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), rm_, scheduleOperandWrites(), scheduleResultReads(), selector_, MoveNode::sourceOperation(), targetMachine_, and MoveNodeGroup::toString().

Referenced by handleBasicBlock().

Here is the call graph for this function:

◆ scheduleResultReads()

int SequentialScheduler::scheduleResultReads ( int  cycle,
MoveNodeGroup moves,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Schedules the result read moves of an operation execution.

Assumes the given MoveNodeGroup contains all moves in the operation execution. Also assumes that all operand moves have been scheduled.

Parameters
movesMoves of the operation execution.
Returns
cycle of last operand read, or -1 if fails

Definition at line 278 of file SequentialScheduler.cc.

280 {
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}
int earliestResultReadCycle() const
Definition MoveNode.cc:652
int scheduleResultTempMoves(int cycle, MoveNode &resultMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)

References __func__, MoveNode::earliestResultReadCycle(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), MoveNodeGroup::node(), MoveNodeGroup::nodeCount(), scheduleMove(), scheduleResultTempMoves(), and MoveNode::toString().

Referenced by scheduleOperation().

Here is the call graph for this function:

◆ scheduleResultTempMoves()

int SequentialScheduler::scheduleResultTempMoves ( int  cycle,
MoveNode resultMove,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Schedules the (possible) temporary register copy moves (due to missing connectivity) succeeding the given result move.

Parameters
operandMoveThe move of which temp moves to schedule.
cycleof the last actual result move
Returns
cycle cycle of last scheduled temp move

Definition at line 537 of file SequentialScheduler.cc.

539 {
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}

References MapTools::containsKey(), RegisterCopyAdder::AddedRegisterCopies::count_, RegisterCopyAdder::AddedRegisterCopies::resultCopies_, and scheduleMove().

Referenced by scheduleResultReads().

Here is the call graph for this function:

◆ scheduleRRMove()

int SequentialScheduler::scheduleRRMove ( int  cycle,
MoveNode moveNode 
)
private

Schedules a RR move and its temp compies.

Parameters
cycleThe earliest cycle to try.
moveNodeR-R Move to schedule.
Returns
Last cycle where the moves got scheduled.

Definition at line 315 of file SequentialScheduler.cc.

315 {
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}
int scheduleRRTempMoves(int cycle, MoveNode &regToRegMove, RegisterCopyAdder::AddedRegisterCopies &regCopies)

References RegisterCopyAdder::addRegisterCopiesToRRMove(), SchedulerPass::interPassData(), rm_, scheduleMove(), scheduleRRTempMoves(), and selector_.

Referenced by handleBasicBlock().

Here is the call graph for this function:

◆ scheduleRRTempMoves()

int SequentialScheduler::scheduleRRTempMoves ( int  cycle,
MoveNode regToRegMove,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Schedules the (possible) temporary register copy moves (due to missing connectivity) succeeding the given RR move.

The function recursively goes through all the temporary moves added to the given RR move.

Parameters
cycleEarliest cycle for starting scheduling
regToRegMoveA temp move whose successor has to be scheduled.
lastUseRecursive function parameter, it should be set as 0 for the first function call.
Returns
cycle next available cycle

Definition at line 450 of file SequentialScheduler.cc.

452 {
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}

References MapTools::containsKey(), RegisterCopyAdder::AddedRegisterCopies::count_, RegisterCopyAdder::AddedRegisterCopies::operandCopies_, and scheduleMove().

Referenced by scheduleRRMove().

Here is the call graph for this function:

◆ shortDescription()

std::string SequentialScheduler::shortDescription ( ) const
virtual

A short description of the pass, usually the optimization name, such as "basic block scheduler".

Returns
The description as a string.

Implements SchedulerPass.

Definition at line 627 of file SequentialScheduler.cc.

627 {
628 return "Sequential Instruction scheduler";
629}

◆ unschedule()

void SequentialScheduler::unschedule ( MoveNode moveNode)
private

Unschedules the given move.

Also restores a possible short immediate source in case it was converted to a long immediate register read during scheduling.

Parameters
moveNodeMove to unschedule.

Definition at line 566 of file SequentialScheduler.cc.

566 {
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}
bool isPlaced() const
Definition MoveNode.cc:352
virtual void unassign(MoveNode &node) override
void removeAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID)

References __func__, TTAProgram::ProgramAnnotation::ANN_REQUIRES_LIMM, TTAProgram::AnnotatedInstructionElement::hasAnnotations(), MoveNode::isPlaced(), MoveNode::isScheduled(), MoveNode::move(), TTAProgram::AnnotatedInstructionElement::removeAnnotations(), rm_, MoveNode::toString(), and SimpleResourceManager::unassign().

Referenced by scheduleOperandWrites(), and unscheduleInputOperandTempMoves().

Here is the call graph for this function:

◆ unscheduleInputOperandTempMoves()

void SequentialScheduler::unscheduleInputOperandTempMoves ( MoveNode operandMove,
RegisterCopyAdder::AddedRegisterCopies regCopies 
)
private

Unschedules the (possible) temporary register copy moves (due to missing connectivity) preceeding the given input move.

Parameters
operandMoveMove to unschedule.
regCopiesTemp register copy moves associated with operandMove

Definition at line 511 of file SequentialScheduler.cc.

512 {
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}

References MapTools::containsKey(), RegisterCopyAdder::AddedRegisterCopies::count_, RegisterCopyAdder::AddedRegisterCopies::operandCopies_, and unschedule().

Referenced by scheduleOperandWrites().

Here is the call graph for this function:

Member Data Documentation

◆ rm_

SimpleResourceManager* SequentialScheduler::rm_
private

Resource Manager of the currently scheduled BB.

Definition at line 124 of file SequentialScheduler.hh.

Referenced by handleBasicBlock(), scheduleMove(), scheduleOperation(), scheduleRRMove(), and unschedule().

◆ selector_

MoveNodeSelector* SequentialScheduler::selector_
private

Definition at line 126 of file SequentialScheduler.hh.

Referenced by handleBasicBlock(), scheduleOperation(), and scheduleRRMove().

◆ targetMachine_

const TTAMachine::Machine* SequentialScheduler::targetMachine_
private

The target machine we are scheduling the program against.

Definition at line 122 of file SequentialScheduler.hh.

Referenced by handleBasicBlock(), scheduleMove(), and scheduleOperation().


The documentation for this class was generated from the following files: