OpenASIP  2.0
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
ExecutionPipelineBroker Class Reference

#include <ExecutionPipelineBroker.hh>

Inheritance diagram for ExecutionPipelineBroker:
Inheritance graph
Collaboration diagram for ExecutionPipelineBroker:
Collaboration graph

Public Member Functions

 ExecutionPipelineBroker (std::string, unsigned int initiationInterval=0)
 
virtual ~ExecutionPipelineBroker ()
 
virtual void assign (int cycle, MoveNode &node, SchedulingResource &res, int immWriteCycle, int immRegIndex) override
 
virtual void unassign (MoveNode &node) override
 
virtual int earliestCycle (int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
 
virtual int latestCycle (int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const override
 
virtual bool isAlreadyAssigned (int cycle, const MoveNode &node, const TTAMachine::Bus *preassignedBus) const override
 
virtual bool isApplicable (const MoveNode &node, const TTAMachine::Bus *) const override
 
virtual void buildResources (const TTAMachine::Machine &target) override
 
virtual void setupResourceLinks (const ResourceMapper &mapper) override
 
virtual int highestKnownCycle () const
 
virtual bool isExecutionPipelineBroker () const override
 
virtual void setInitiationInterval (unsigned int cycles) override
 
virtual int longestLatency () const
 
virtual void setMaxCycle (unsigned int maxCycle) override
 
void setDDG (const DataDependenceGraph *ddg)
 
- Public Member Functions inherited from ResourceBroker
 ResourceBroker (std::string, unsigned int initiationInterval=0)
 
virtual ~ResourceBroker ()
 
virtual bool isAnyResourceAvailable (int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const
 
virtual SchedulingResourceavailableResource (int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const
 
virtual SchedulingResourceSet allAvailableResources (int cycle, const MoveNode &node, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const
 
virtual bool isAvailable (SchedulingResource &des, const MoveNode &node, int cycle, const TTAMachine::Bus *bus, const TTAMachine::FunctionUnit *srcFU, const TTAMachine::FunctionUnit *dstFU, int immWriteCycle, const TTAMachine::ImmediateUnit *immu, int immRegIndex) const
 
SchedulingResourceresourceOf (const TTAMachine::MachinePart &mp) const
 
virtual const TTAMachine::MachinePartmachinePartOf (const SchedulingResource &r) const
 
bool hasResourceOf (const TTAMachine::MachinePart &mp) const
 
bool hasResource (const SchedulingResource &r) const
 
int resourceCount () const
 
virtual bool isBusBroker () const
 
virtual bool isITemplateBroker () const
 
virtual bool isIUBroker () const
 
void validateResources () const
 
virtual std::string brokerName () const
 
void resources (ResourceSet &contents)
 
virtual void clear ()
 

Private Types

typedef std::map< SchedulingResource *, const TTAMachine::FunctionUnit * > FUPipelineMap
 Map to link FU's and pipelines. More...
 

Private Member Functions

bool isMoveTrigger (const MoveNode &node) const
 
bool isLoopBypass (const MoveNode &node) const
 
int latestFromSource (int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const
 
int latestFromDestination (int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const
 
int earliestFromSource (int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const
 
int earliestFromDestination (int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const
 

Private Attributes

FUPipelineMap fuPipelineMap_
 FU's and their corresponding pipeline resources. More...
 
int longestLatency_
 Longest latency of all operations of all the FUs. More...
 
const DataDependenceGraphddg_
 

Additional Inherited Members

- Public Types inherited from ResourceBroker
typedef std::set< SchedulingResource * > ResourceSet
 
- Protected Types inherited from ResourceBroker
typedef std::map< const TTAMachine::MachinePart *, SchedulingResource *, TTAMachine::MachinePart::ComparatorResourceMap
 
typedef std::map< const MoveNode *, SchedulingResource *, MoveNode::ComparatorMoveResMap
 
- Protected Member Functions inherited from ResourceBroker
void setResourceMapper (const ResourceMapper &mapper)
 
const ResourceMapperresourceMapper () const
 
unsigned int instructionIndex (unsigned int) const
 
void addResource (const TTAMachine::MachinePart &mp, SchedulingResource *res)
 
- Protected Attributes inherited from ResourceBroker
unsigned int initiationInterval_
 
ResourceMap resMap_
 
const ResourceMapperresourceMapper_
 
MoveResMap assignedResources_
 
std::string brokerName_
 

Detailed Description

Execution pipeline broker.

Definition at line 53 of file ExecutionPipelineBroker.hh.

Member Typedef Documentation

◆ FUPipelineMap

Map to link FU's and pipelines.

Definition at line 97 of file ExecutionPipelineBroker.hh.

Constructor & Destructor Documentation

◆ ExecutionPipelineBroker()

ExecutionPipelineBroker::ExecutionPipelineBroker ( std::string  name,
unsigned int  initiationInterval = 0 
)

Constructor.

Definition at line 62 of file ExecutionPipelineBroker.cc.

63  :
64  ResourceBroker(name, initiationInterval), longestLatency_(0), ddg_(NULL) {
65 
66  // change ii for broker's resources also
67  for (FUPipelineMap::iterator i = fuPipelineMap_.begin();
68  i != fuPipelineMap_.end(); ++i) {
69  i->first->setInitiationInterval(initiationInterval);
70  }
71 }

References fuPipelineMap_, and ResourceBroker::setInitiationInterval().

Here is the call graph for this function:

◆ ~ExecutionPipelineBroker()

ExecutionPipelineBroker::~ExecutionPipelineBroker ( )
virtual

Destructor.

Definition at line 85 of file ExecutionPipelineBroker.cc.

85  {
86 }

Member Function Documentation

◆ assign()

void ExecutionPipelineBroker::assign ( int  cycle,
MoveNode node,
SchedulingResource res,
int  immWriteCycle,
int  immRegIndex 
)
overridevirtual

Mark given resource as in use for the given node, and assign the corresponding machine part (if applicable) to the node's move.

If the node is already assigned to given resource, this method does nothing.

Exceptions
WrongSubclassIf this broker does not recognise the given type of resource.
InvalidParametersIf he given resource cannot be assigned to given node or no corresponding machine part is found.
Note
The execution pipeline broker is used only to construct resources.

Implements ResourceBroker.

Definition at line 102 of file ExecutionPipelineBroker.cc.

103 {
104  abortWithError("Not implemented.");
105 }

References abortWithError.

◆ buildResources()

void ExecutionPipelineBroker::buildResources ( const TTAMachine::Machine target)
overridevirtual

Build all resource objects of the controlled type required to model scheduling resources of the given target processor.

This method cannot set up the resource links (dependent and related resources) of the constructed resource objects.

Parameters
targetTarget machine.

Implements ResourceBroker.

Definition at line 255 of file ExecutionPipelineBroker.cc.

255  {
256 
258  for (int i = 0; i < navi.count(); i++) {
259  FunctionUnit* fu = navi.item(i);
260  ExecutionPipelineResource* epResource =
262  *fu, initiationInterval_);
263 
264  ResourceBroker::addResource(*fu, epResource);
265  fuPipelineMap_.insert(
266  pair<SchedulingResource*, const FunctionUnit*>(epResource, fu));
267  longestLatency_ =
268  (longestLatency_ < fu->maxLatency())
269  ? fu->maxLatency() : longestLatency_;
270  }
271 
272  ControlUnit* gcu = target.controlUnit();
273 
274  ExecutionPipelineResource* epResource =
276 
277  ResourceBroker::addResource(*gcu, epResource);
278  fuPipelineMap_.insert(pair<SchedulingResource*, const
279  FunctionUnit*>(epResource, gcu));
280 }

References ResourceBroker::addResource(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), fuPipelineMap_, ResourceBroker::initiationInterval_, TTAMachine::Machine::Navigator< ComponentType >::item(), longestLatency_, and TTAMachine::FunctionUnit::maxLatency().

Here is the call graph for this function:

◆ earliestCycle()

int ExecutionPipelineBroker::earliestCycle ( int  cycle,
const MoveNode node,
const TTAMachine::Bus bus,
const TTAMachine::FunctionUnit srcFU,
const TTAMachine::FunctionUnit dstFU,
int  immWriteCycle,
const TTAMachine::ImmediateUnit immu,
int  immRegIndex 
) const
overridevirtual

Return the earliest cycle, starting from given cycle, where a resource of the type managed by this broker can be assigned to the given node.

Considers source and destination terminals independently and compares the results. Returns -1 if no assignment is possible.

Parameters
cycleCycle.
nodeNode.
srcFUif not null, srcFu that has to be used.
dstFUif not null, dstFU that has to be used.
immWriteCycleif not -1 and src is imm, write cycle of limm.

Implements ResourceBroker.

Definition at line 137 of file ExecutionPipelineBroker.cc.

144  {
145 
146  int efs = earliestFromSource(cycle, node, srcFU);
147  if (efs == -1 || efs == INT_MAX) {
148  debugLogRM("returning -1");
149  return -1;
150  }
151  int efd = earliestFromDestination(efs, node, dstFU);
152  if (efd == -1 || efd == INT_MAX) {
153  debugLogRM("returning -1");
154  return -1;
155  }
156 
157  // Loop as long as we find cycle which work for both source and
158  // destination.
159  while (efd != efs) {
160  efs = earliestFromSource(efd, node, srcFU);
161  if (efs == -1 || efs == INT_MAX) {
162  debugLogRM("returning -1");
163  return -1;
164  }
165  if (efs == efd) {
166  return efd;
167  }
168  efd = earliestFromDestination(efs, node, dstFU);
169  if (efd == -1 || efd == INT_MAX) {
170  debugLogRM("returning -1");
171  return -1;
172  }
173  }
174  return efd;
175 }

References debugLogRM, earliestFromDestination(), and earliestFromSource().

Referenced by SimpleBrokerDirector::earliestCycle().

Here is the call graph for this function:

◆ earliestFromDestination()

int ExecutionPipelineBroker::earliestFromDestination ( int  cycle,
const MoveNode node,
const TTAMachine::FunctionUnit dstFU 
) const
private

Return earliest cycle, starting from given parameter and going towards INT_MAX, in which the node can be scheduled. Taking into account destination terminal of Move (operand write).

This method may return too early for some cases but there is canassign test after this always at higher level in RM so this does not matter; having this method is just performance optimization to avoid calling slow canAssign() for too small values.

Parameters
cycleStarting cycle for tests
nodeMoveNode to find earliest cycle for
Returns
The earliest cycle in which the MoveNode can be scheduled, -1 if scheduling is not possible, 0 if destination is not FUPort

Definition at line 719 of file ExecutionPipelineBroker.cc.

721  {
722 
723  if (!node.isDestinationOperation()) {
724  return cycle;
725  }
726  const FunctionUnit* fu = NULL;
727 
728  int minCycle = cycle;
729 
730  bool triggers = isMoveTrigger(node);
731 
732  for (unsigned int j = 0; j < node.destinationOperationCount(); j++) {
733 
734  const HWOperation* hwop = NULL;
735  // Test other inputs to the operation.
736  ProgramOperation& destOp = node.destinationOperation(j);
737 
738  for (int i = 0; i < destOp.inputMoveCount(); i++) {
739  const MoveNode* tempNode = &destOp.inputMove(i);
740  if (tempNode->isScheduled() && tempNode != &node) {
741  fu = &tempNode->move().destination().functionUnit();
742  hwop = fu->operation(destOp.operation().name());
743  if (dstFU != NULL && fu != dstFU) {
744  return -1;
745  }
746 
747  if (triggers) {
748  // TODO: operand slack
749  minCycle = std::max(tempNode->cycle(), minCycle);
750  }
751  if (tempNode->move().isTriggering()) {
752  // TODO: operand slack
753  int triggerCycle = tempNode->cycle();
754  if (triggerCycle < cycle) {
755  // trying to schedule operand after trigger
756  debugLogRM("returning -1");
757  return -1;
758  }
759  }
760  }
761  }
762 
763  // Then check the already scheduled results, do they limit the cycle
764  // where this can be scheduled.
765  int minResultCycle = INT_MAX;
766  for (int i = 0; i < destOp.outputMoveCount(); i++) {
767  const MoveNode* tempNode = &destOp.outputMove(i);
768  if (tempNode->isScheduled()) {
769  if (fu == NULL) {
770  fu = destOp.fuFromOutMove(*tempNode);
771  hwop = fu->operation(destOp.operation().name());
772  }
773 
774  if (dstFU != NULL && fu != dstFU) {
775  return -1;
776  }
777 
778  const int outputIndex =
779  destOp.outputIndexOfMove(*tempNode);
780 
781  // TODO: slack
782 
783  unsigned int latency = hwop->latency(outputIndex);
784  if (initiationInterval_ != 0 && latency >= initiationInterval_) {
785  debugLogRM("returning -1");
786  return -1;
787  }
788  minResultCycle =
789  std::min(
790  minResultCycle,
791  tempNode->cycle() - hwop->latency(outputIndex));
792  }
793  }
794  if (minResultCycle < minCycle) {
795  // tested cycle is larger then last trigger cycle for results
796  // already scheduled
797  debugLogRM("returning -1");
798  return -1;
799  }
800  }
801 
802  return minCycle;
803 }

References MoveNode::cycle(), debugLogRM, TTAProgram::Move::destination(), MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), ProgramOperation::fuFromOutMove(), TTAProgram::Terminal::functionUnit(), ResourceBroker::initiationInterval_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), isMoveTrigger(), MoveNode::isScheduled(), TTAProgram::Move::isTriggering(), TTAMachine::HWOperation::latency(), MoveNode::move(), Operation::name(), TTAMachine::FunctionUnit::operation(), ProgramOperation::operation(), ProgramOperation::outputIndexOfMove(), ProgramOperation::outputMove(), and ProgramOperation::outputMoveCount().

Referenced by earliestCycle().

Here is the call graph for this function:

◆ earliestFromSource()

int ExecutionPipelineBroker::earliestFromSource ( int  cycle,
const MoveNode node,
const TTAMachine::FunctionUnit srcFU 
) const
private

Returns earliest cycle, starting from given parameter and going towards INT_MAX, in which the node can be scheduled. Taking into account source Terminal of Move (result read) and other operands already scheduled.

Parameters
cycleStarting cycle for tests
nodeMoveNode to find earliest cycle for
Returns
The earliest cycle in which the MoveNode can be scheduled, 0 if source is not FUPort

Definition at line 600 of file ExecutionPipelineBroker.cc.

602  {
603 
604  if (!node.isSourceOperation()) {
605  return cycle;
606  }
607  ProgramOperation& sourceOp = node.sourceOperation();
608  const MoveNode* triggerNode = NULL;
609  int minCycle = -1;
610 
611  const FunctionUnit* fu = NULL;
612  assert(node.move().source().isFUPort());
613 
614  const HWOperation* hwop = NULL;
615  const int outputIndex =
616  node.move().source().operationIndex();
617  int latency = 1;
618 
619  for (int i = 0; i < sourceOp.inputMoveCount(); i++) {
620  const MoveNode* tempNode = &sourceOp.inputMove(i);
621  if (tempNode->isScheduled() && tempNode != &node) {
622  fu = &tempNode->move().destination().functionUnit();
623  if (srcFU != NULL&& fu != srcFU) {
624  return -1;
625  }
626  minCycle = std::max(tempNode->cycle()+1, minCycle);
627  if (tempNode->move().isTriggering()) {
628  triggerNode = tempNode;
629  hwop = fu->operation(sourceOp.operation().name());
630  latency = hwop->latency(outputIndex);
631  minCycle = std::max(triggerNode->cycle() + latency, cycle);
632  }
633  }
634  }
635  if (minCycle == -1) {
636  // no operands scheduled for result of given PO
637  // so earliest cycle is 0 + latency or tested cycle
638  if (initiationInterval_ != 0 && latency >= (int)initiationInterval_) {
639  debugLogRM("returning -1");
640  return -1;
641  }
642  minCycle = std::max(cycle,1);
643  }
644 
645  if (triggerNode != NULL && triggerNode->isScheduled()) {
646  int triggerCycle = triggerNode->cycle();
647 
648  const TTAMachine::Port& port = *hwop->port(outputIndex);
649  SchedulingResource& res = *resourceOf(*fu);
651  static_cast<ExecutionPipelineResource*>(&res);
652 
653  if (!ep->resultNotOverWritten(
654  minCycle, node.earliestResultReadCycle(), node,
655  port, triggerNode, triggerCycle)) {
656  return -1;
657  }
658  }
659 
660  return std::max(minCycle, cycle);
661 }

References assert, MoveNode::cycle(), debugLogRM, TTAProgram::Move::destination(), MoveNode::earliestResultReadCycle(), TTAProgram::Terminal::functionUnit(), ResourceBroker::initiationInterval_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), TTAProgram::Terminal::isFUPort(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAProgram::Move::isTriggering(), TTAMachine::HWOperation::latency(), MoveNode::move(), Operation::name(), TTAMachine::FunctionUnit::operation(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), TTAMachine::HWOperation::port(), ResourceBroker::resourceOf(), ExecutionPipelineResource::resultNotOverWritten(), TTAProgram::Move::source(), and MoveNode::sourceOperation().

Referenced by earliestCycle().

Here is the call graph for this function:

◆ highestKnownCycle()

int ExecutionPipelineBroker::highestKnownCycle ( ) const
virtual

Return the highest cycle any of the pipeline is known to be used

Returns
A highest cycle in which any of the pipelines is used.

Definition at line 366 of file ExecutionPipelineBroker.cc.

366  {
367  int localMax = 0;
368  for (ResourceMap::const_iterator resIter = resMap_.begin();
369  resIter != resMap_.end(); resIter++) {
371  (dynamic_cast<ExecutionPipelineResource*>((*resIter).second));
372  localMax = std::max(ep->highestKnownCycle(), localMax);
373  }
374  return localMax;
375 }

References ExecutionPipelineResource::highestKnownCycle(), and ResourceBroker::resMap_.

Here is the call graph for this function:

◆ isAlreadyAssigned()

bool ExecutionPipelineBroker::isAlreadyAssigned ( int  cycle,
const MoveNode node,
const TTAMachine::Bus preassignedBus 
) const
overridevirtual

Return true if the given node is already assigned a resource of the type managed by this broker, and the assignment appears valid (that is, the broker has marked that resource as in use in the given cycle).

Parameters
cycleCycle.
nodeNode.
Returns
True if the given node is already assigned a resource of the type managed by this broker, and the assignment appears valid (that is, the broker has marked that resource as in use in the given cycle).

Implements ResourceBroker.

Definition at line 222 of file ExecutionPipelineBroker.cc.

223  {
224  abortWithError("Not implemented.");
225  return false;
226 }

References abortWithError.

◆ isApplicable()

bool ExecutionPipelineBroker::isApplicable ( const MoveNode node,
const TTAMachine::Bus  
) const
overridevirtual

Return true if the given node needs a resource of the type managed by this broker, false otherwise.

Parameters
nodeNode.
Returns
Always false. Broker is not used standalone, only for creating resources and setting up resource links.
Note
Broker is used only to construct resources, the assignment and unassignment is done via ExecutionPipelineResource attached to InputFuResource.

Implements ResourceBroker.

Definition at line 240 of file ExecutionPipelineBroker.cc.

241  {
242  return false;
243 }

◆ isExecutionPipelineBroker()

bool ExecutionPipelineBroker::isExecutionPipelineBroker ( ) const
overridevirtual

Reimplemented from ResourceBroker.

Definition at line 378 of file ExecutionPipelineBroker.cc.

378  {
379  return true;
380 }

◆ isLoopBypass()

bool ExecutionPipelineBroker::isLoopBypass ( const MoveNode node) const
private

Definition at line 399 of file ExecutionPipelineBroker.cc.

399  {
400 
401  if (ddg_ == NULL || !ddg_->hasNode(node)) {
402  return false;
403  }
404  auto inEdges = ddg_->operationInEdges(node);
405  for (auto e : inEdges) {
406  if (e->isBackEdge()) {
407  return true;
408  }
409  }
410  return false;
411 }

References ddg_, BoostGraph< GraphNode, GraphEdge >::hasNode(), and DataDependenceGraph::operationInEdges().

Referenced by latestFromDestination(), and latestFromSource().

Here is the call graph for this function:

◆ isMoveTrigger()

bool ExecutionPipelineBroker::isMoveTrigger ( const MoveNode node) const
private

Definition at line 664 of file ExecutionPipelineBroker.cc.

664  {
665  if (!node.isDestinationOperation()) {
666  return false;
667  }
668 
669  for (unsigned int j = 0; j < node.destinationOperationCount(); j++) {
670 // const HWOperation* hwop = NULL;
671 
672  // Test other inputs to the operation.
673  ProgramOperation& destOp = node.destinationOperation(j);
674 
675  for (int i = 0; i < destOp.inputMoveCount(); i++) {
676  const MoveNode* tempNode = &destOp.inputMove(i);
677  if (tempNode->isScheduled()) {
678  if (tempNode->move().isTriggering()) {
679  if (tempNode != &node) {
680  return false;
681  break;
682  } else {
683  return true;
684  }
685  }
686  auto fu = &tempNode->move().destination().functionUnit();
687  auto triggeringPort = fu->triggerPort();
688  auto hwop = fu->operation(
689  node.destinationOperation().operation().name());
690  auto port = hwop->port(
691  node.move().destination().operationIndex());
692  if (port == triggeringPort) {
693  return true;
694  } else {
695  return false;
696  }
697  }
698  }
699  }
700  return false;
701 }

References TTAProgram::Move::destination(), MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), TTAProgram::Terminal::functionUnit(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), MoveNode::isScheduled(), TTAProgram::Move::isTriggering(), MoveNode::move(), Operation::name(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), and TTAMachine::FunctionUnit::triggerPort().

Referenced by earliestFromDestination().

Here is the call graph for this function:

◆ latestCycle()

int ExecutionPipelineBroker::latestCycle ( int  cycle,
const MoveNode node,
const TTAMachine::Bus bus,
const TTAMachine::FunctionUnit srcFU,
const TTAMachine::FunctionUnit dstFU,
int  immWriteCycle,
const TTAMachine::ImmediateUnit immu,
int  immRegIndex 
) const
overridevirtual

Return the latest cycle, starting from given cycle, where a resource of the type managed by this broker can be assigned to the given node.

Parameters
cycleCycle.
nodeNode.
srcFUif not null, srcFu that has to be used.
dstFUif not null, dstFU that has to be used.
immWriteCycleif not -1 and src is imm, write cycle of limm.
Returns
The latest cycle, starting from given cycle backwards, where a resource of the type managed by this broker can be assigned to the given node. Considers source and destination terminals independently and compares the results. Returns -1 if no assignment is possible.

Implements ResourceBroker.

Definition at line 193 of file ExecutionPipelineBroker.cc.

199  {
200  int src = latestFromSource(cycle,node, srcFU);
201  if (src == -1) {
202  return -1;
203  }
204  int dst = latestFromDestination(src, node, dstFU);
205  return dst;
206 }

References latestFromDestination(), and latestFromSource().

Referenced by SimpleBrokerDirector::latestCycle().

Here is the call graph for this function:

◆ latestFromDestination()

int ExecutionPipelineBroker::latestFromDestination ( int  cycle,
const MoveNode node,
const TTAMachine::FunctionUnit dstUnit 
) const
private

Returns latest cycle, starting from given parameter and going towards zero, in which the node can be scheduled. Taking into account destination terminal of Move (operand write).

Parameters
cycleStarting cycle for tests
nodeMoveNode to find latest cycle for
Returns
The latest cycle in which the MoveNode can be scheduled, -1 if scheduling is not possible, 'cycle' if destination is not FUPort

Definition at line 538 of file ExecutionPipelineBroker.cc.

540  {
541 
542  // TODO: this not do full reuslt overwrite another tests.
543  // It is however handled in canassign().
544  // Doing it here would make scheduling faster.
545  int latest = cycle;
546  for (unsigned int j = 0; j < node.destinationOperationCount(); j++) {
547  ProgramOperation& destOp = node.destinationOperation(j);
548  for (int i = 0; i < destOp.inputMoveCount(); i++) {
549  const MoveNode* tempNode = &destOp.inputMove(i);
550  if (tempNode->isScheduled() && tempNode != &node) {
551  if (tempNode->move().isTriggering()) {
552  latest = std::min(tempNode->cycle(), latest);
553  }
554  }
555  }
556 
557  for (int i = 0; i < destOp.outputMoveCount(); i++) {
558  const MoveNode* tempNode = &destOp.outputMove(i);
559  if (tempNode->isScheduled() && tempNode != &node) {
560  const TTAMachine::FunctionUnit* fu =
561  &node.move().destination().functionUnit();
562  if (dstUnit != NULL && dstUnit != fu) {
563  return -1;
564  }
565  const TTAMachine::HWOperation& hwop =
566  *fu->operation(
567  destOp.operation().name());
568  const int outputIndex =
569  (tempNode->isSourceOperation() &&
570  &tempNode->sourceOperation() == &destOp)
571  ?
572  tempNode->move().source().operationIndex() :
573  destOp.outputIndexFromGuardOfMove(*tempNode);
574 
575  int tempCycle = tempNode->cycle();
576  if (isLoopBypass(*tempNode)) {
577  tempCycle += initiationInterval_;
578  }
579 
580  latest = std::min(latest,
581  tempCycle - hwop.latency(outputIndex));
582  }
583  }
584  }
585 
586  return latest;
587 }

References MoveNode::cycle(), TTAProgram::Move::destination(), MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), TTAProgram::Terminal::functionUnit(), ResourceBroker::initiationInterval_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), isLoopBypass(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAProgram::Move::isTriggering(), TTAMachine::HWOperation::latency(), MoveNode::move(), Operation::name(), TTAMachine::FunctionUnit::operation(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), ProgramOperation::outputIndexFromGuardOfMove(), ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), TTAProgram::Move::source(), and MoveNode::sourceOperation().

Referenced by latestCycle().

Here is the call graph for this function:

◆ latestFromSource()

int ExecutionPipelineBroker::latestFromSource ( int  cycle,
const MoveNode node,
const TTAMachine::FunctionUnit srcFU 
) const
private

Returns latest cycle, starting from given parameter and going towards zero, in which the node can be scheduled. Taking into account source terminal of Move (result read).

Parameters
cycleStarting cycle for tests
nodeMoveNode to find latest cycle for
Returns
The latest cycle in which the MoveNode can be scheduled, -1 if scheduling is not possible, 'cycle' if source is not FUPort

Definition at line 425 of file ExecutionPipelineBroker.cc.

427  {
428 
429  if (!node.isSourceOperation()) {
430  return cycle;
431  }
432  // kludge for looop bypass.
433  ProgramOperation& sourceOp = node.sourceOperation();
434  if (isLoopBypass(node)) {
435  cycle+=initiationInterval_;
436  }
437  const MoveNode* triggerNode = NULL;
438  const MoveNode* lastOperandNode = NULL;
439  const MoveNode* lastResultNode = NULL;
440  int minCycle = -1;
441  // Source is result read, we test all operands
442  for (int i = 0; i < sourceOp.inputMoveCount(); i++) {
443  const MoveNode* tempNode = &sourceOp.inputMove(i);
444  if (tempNode->isScheduled() && tempNode != &node) {
445  minCycle = std::max(tempNode->cycle(), minCycle);
446  lastOperandNode = tempNode;
447  if (tempNode->move().isTriggering()) {
448  triggerNode = tempNode;
449  }
450  }
451  }
452  // Source is result read, we test all results
453  for (int i = 0; i < sourceOp.outputMoveCount(); i++) {
454  const MoveNode* tempNode = &sourceOp.outputMove(i);
455  if (tempNode->isScheduled() && tempNode != &node) {
456  int tempCycle = tempNode->cycle();
457  if (isLoopBypass(*tempNode)) {
458  tempCycle += initiationInterval_;
459  }
460  minCycle = std::max(tempCycle, minCycle);
461  lastResultNode = tempNode;
462  }
463  }
464 
465  if (minCycle == -1) {
466  return cycle;
467  }
468  if (minCycle > cycle && lastResultNode == NULL) {
469  // Some operand is already later then where we started to backtrack.
470  debugLogRM("returning -1");
471  return -1;
472  }
473  if (triggerNode != NULL) {
474 
475  if (minCycle >= node.earliestResultReadCycle()
476  && lastResultNode == NULL) {
477  // If we do have minCycle from operands, this is valid test,
478  // otherwise it is not.
479  throw InvalidData(__FILE__, __LINE__, __func__,
480  "Some operand move is written after the result move "
481  "is ready! " + node.toString());
482  }
483  if (node.earliestResultReadCycle() > cycle) {
484  // Result is available later then where we started to backtrack
485  debugLogRM("returning -1");
486  return -1;
487  } else {
488  minCycle = node.earliestResultReadCycle();
489  }
490  }
491  // minCycle has latest of operand writes or earliest result read cycle
492  // find next read of same FU with different PO
493  assert(lastOperandNode != NULL || lastResultNode != NULL);
494  const TTAMachine::FunctionUnit* fu;
495  if (lastOperandNode != NULL) {
496  fu = &lastOperandNode->move().destination().functionUnit();
497  } else {
498  if (lastResultNode->isSourceOperation()) {
499  fu = &lastResultNode->move().source().functionUnit();
500  } else {
501  assert(lastResultNode->isGuardOperation());
502  fu = lastResultNode->guardOperation().fuFromOutMove(*lastResultNode);
503  }
504  }
505 
506  if (srcFU != NULL && fu != srcFU) {
507  return -1;
508  }
509  HWOperation& hwop = *fu->operation(sourceOp.operation().name());
510  const TTAMachine::Port& port =
511  *hwop.port(node.move().source().operationIndex());
512  SchedulingResource& res = *resourceOf(*fu);
514  static_cast<ExecutionPipelineResource*>(&res);
515  int triggerCycle = triggerNode != NULL && triggerNode->isScheduled() ?
516  triggerNode->cycle() :
517  INT_MAX;
518  // last available cycle is one lower then next write
519 
520  int nextResult = ep->nextResultCycle(
521  port, minCycle, node, triggerNode, triggerCycle);
522  if (cycle < nextResult || nextResult < minCycle) {
523  return cycle;
524  }
525  return nextResult-1;
526 }

References __func__, assert, MoveNode::cycle(), debugLogRM, TTAProgram::Move::destination(), MoveNode::earliestResultReadCycle(), ProgramOperation::fuFromOutMove(), TTAProgram::Terminal::functionUnit(), MoveNode::guardOperation(), ResourceBroker::initiationInterval_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isGuardOperation(), isLoopBypass(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAProgram::Move::isTriggering(), MoveNode::move(), Operation::name(), ExecutionPipelineResource::nextResultCycle(), TTAMachine::FunctionUnit::operation(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), TTAMachine::HWOperation::port(), ResourceBroker::resourceOf(), TTAProgram::Move::source(), MoveNode::sourceOperation(), and MoveNode::toString().

Referenced by latestCycle().

Here is the call graph for this function:

◆ longestLatency()

virtual int ExecutionPipelineBroker::longestLatency ( ) const
inlinevirtual

Definition at line 88 of file ExecutionPipelineBroker.hh.

88 { return longestLatency_; }

References longestLatency_.

Referenced by SimpleBrokerDirector::latestCycle().

◆ setDDG()

void ExecutionPipelineBroker::setDDG ( const DataDependenceGraph ddg)

Definition at line 806 of file ExecutionPipelineBroker.cc.

806  {
807  for (ResourceMap::iterator i = resMap_.begin(); i != resMap_.end(); i++) {
808  (static_cast<ExecutionPipelineResource*>(i->second))->setDDG(ddg);
809  }
810  ddg_ = ddg;
811 }

References ddg_, and ResourceBroker::resMap_.

Referenced by SimpleBrokerDirector::setDDG().

◆ setInitiationInterval()

void ExecutionPipelineBroker::setInitiationInterval ( unsigned int  ii)
overridevirtual

Set initiation interval, if ii = 0 then initiation interval is not used.

Parameters
iiinitiation interval

Reimplemented from ResourceBroker.

Definition at line 388 of file ExecutionPipelineBroker.cc.

389 {
390  initiationInterval_ = ii;
391 
392  // change ii for broker's resources also
393  for (FUPipelineMap::iterator i = fuPipelineMap_.begin();
394  i != fuPipelineMap_.end(); ++i) {
395  i->first->setInitiationInterval(ii);
396  }
397 }

References fuPipelineMap_, and ResourceBroker::initiationInterval_.

◆ setMaxCycle()

void ExecutionPipelineBroker::setMaxCycle ( unsigned int  maxCycle)
overridevirtual

Reimplemented from ResourceBroker.

Definition at line 74 of file ExecutionPipelineBroker.cc.

74  {
75  // change ii for broker's resources also
76  for (FUPipelineMap::iterator i = fuPipelineMap_.begin();
77  i != fuPipelineMap_.end(); ++i) {
78  i->first->setMaxCycle(maxCycle);
79  }
80 }

References fuPipelineMap_.

Referenced by SimpleBrokerDirector::setMaxCycle().

◆ setupResourceLinks()

void ExecutionPipelineBroker::setupResourceLinks ( const ResourceMapper mapper)
overridevirtual

Complete resource initialisation by creating the references to other resources due to a dependency or a relation. Use the given resource mapper to lookup dependent and related resources using machine parts as keys.

Parameters
mapperResource mapper.

Implements ResourceBroker.

Definition at line 291 of file ExecutionPipelineBroker.cc.

291  {
292 
293  setResourceMapper(mapper);
294 
295  for (ResourceMap::iterator resIter = resMap_.begin();
296  resIter != resMap_.end(); resIter++) {
297 
298  const FunctionUnit* fuOriginal =
299  dynamic_cast<const FunctionUnit*>((*resIter).first);
300  if (fuOriginal == NULL){
301  throw InvalidData(
302  __FILE__, __LINE__, __func__,
303  "ExecutionPipelineBroker has something "
304  "else then FU registered!");
305  }
306 
307  // resMap_ is local for broker, so it can only contain fu->epResource
308  SchedulingResource* epResource = (*resIter).second;
309 
310  const FunctionUnit* fu = NULL;
311 
312  try {
313  fu = MapTools::valueForKey<const FunctionUnit*>(
314  fuPipelineMap_, epResource);
315  } catch (const Exception& e) {
316  std::string msg = "Pipeline resource \'";
317  msg += epResource->name();
318  msg += "\' not found";
319  abortWithError(msg);
320  }
321 
322  for (int i = 0; i < fu->portCount(); i++) {
323  BaseFUPort* port = fu->port(i);
324  if (port->isTriggering()) {
325  if (port->outputSocket() != NULL) {
326  try {
327  SchedulingResource& relatedRes =
328  mapper.resourceOf(*port->outputSocket());
329  epResource->addToRelatedGroup(0, relatedRes);
330  } catch (const KeyNotFound& e) {
331  std::string msg = "ExecutionPipelineBroker: finding ";
332  msg += " resource for Socket ";
333  msg += " failed with error: ";
334  msg += e.errorMessageStack();
335  msg += " for resource " + epResource->name();
336  throw KeyNotFound(
337  __FILE__, __LINE__, __func__, msg);
338  }
339 
340  } else {
341  try {
342  SchedulingResource& relatedRes =
343  mapper.resourceOf(*port->inputSocket());
344  epResource->addToRelatedGroup(0, relatedRes);
345  } catch (const KeyNotFound& e) {
346  std::string msg = "ExecutionPipelineBroker: finding ";
347  msg += " resource for Socket ";
348  msg += " failed with error: ";
349  msg += e.errorMessageStack();
350  msg += " for resource " + epResource->name();
351  throw KeyNotFound(
352  __FILE__, __LINE__, __func__, msg);
353  }
354  }
355  }
356  }
357  }
358 }

References __func__, abortWithError, SchedulingResource::addToRelatedGroup(), Exception::errorMessageStack(), fuPipelineMap_, TTAMachine::Port::inputSocket(), TTAMachine::BaseFUPort::isTriggering(), SchedulingResource::name(), TTAMachine::Port::outputSocket(), TTAMachine::FunctionUnit::port(), TTAMachine::Unit::portCount(), ResourceBroker::resMap_, ResourceMapper::resourceOf(), and ResourceBroker::setResourceMapper().

Here is the call graph for this function:

◆ unassign()

void ExecutionPipelineBroker::unassign ( MoveNode node)
overridevirtual

Free the resource type managed by this broker and unassign it from given node.

If this broker is not applicable to the given node, or the node is not assigned a resource of the managed type, this method does nothing.

Parameters
nodeNode.

Implements ResourceBroker.

Definition at line 118 of file ExecutionPipelineBroker.cc.

118  {
119  abortWithError("Not implemented.");
120 }

References abortWithError.

Member Data Documentation

◆ ddg_

const DataDependenceGraph* ExecutionPipelineBroker::ddg_
private

Definition at line 111 of file ExecutionPipelineBroker.hh.

Referenced by isLoopBypass(), and setDDG().

◆ fuPipelineMap_

FUPipelineMap ExecutionPipelineBroker::fuPipelineMap_
private

FU's and their corresponding pipeline resources.

Definition at line 108 of file ExecutionPipelineBroker.hh.

Referenced by buildResources(), ExecutionPipelineBroker(), setInitiationInterval(), setMaxCycle(), and setupResourceLinks().

◆ longestLatency_

int ExecutionPipelineBroker::longestLatency_
private

Longest latency of all operations of all the FUs.

Definition at line 110 of file ExecutionPipelineBroker.hh.

Referenced by buildResources(), and longestLatency().


The documentation for this class was generated from the following files:
ExecutionPipelineResource
Definition: ExecutionPipelineResource.hh:64
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
ProgramOperation::outputIndexFromGuardOfMove
int outputIndexFromGuardOfMove(const MoveNode &node) const
Definition: ProgramOperation.cc:256
TTAProgram::Move::isTriggering
bool isTriggering() const
Definition: Move.cc:284
TTAMachine::Port::inputSocket
virtual Socket * inputSocket() const
Definition: Port.cc:261
ExecutionPipelineBroker::longestLatency_
int longestLatency_
Longest latency of all operations of all the FUs.
Definition: ExecutionPipelineBroker.hh:110
ResourceBroker::initiationInterval_
unsigned int initiationInterval_
Definition: ResourceBroker.hh:158
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
TTAMachine::HWOperation
Definition: HWOperation.hh:52
ResourceBroker::resMap_
ResourceMap resMap_
Definition: ResourceBroker.hh:165
MoveNode::isDestinationOperation
bool isDestinationOperation() const
TTAMachine::FunctionUnit::triggerPort
virtual BaseFUPort * triggerPort() const
Definition: FunctionUnit.cc:267
ExecutionPipelineBroker::latestFromDestination
int latestFromDestination(int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const
Definition: ExecutionPipelineBroker.cc:538
TTAMachine::BaseFUPort
Definition: BaseFUPort.hh:44
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
ExecutionPipelineBroker::earliestFromSource
int earliestFromSource(int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const
Definition: ExecutionPipelineBroker.cc:600
ProgramOperation::fuFromOutMove
const TTAMachine::FunctionUnit * fuFromOutMove(const MoveNode &outputNode) const
Definition: ProgramOperation.cc:844
ProgramOperation
Definition: ProgramOperation.hh:70
MoveNode
Definition: MoveNode.hh:65
TTAMachine::FunctionUnit::port
virtual BaseFUPort * port(const std::string &name) const
Definition: FunctionUnit.cc:145
ResourceMapper::resourceOf
SchedulingResource & resourceOf(const TTAMachine::MachinePart &mp, int index=0) const
Definition: ResourceMapper.cc:96
TTAMachine::Machine::Navigator::count
int count() const
ResourceBroker::addResource
void addResource(const TTAMachine::MachinePart &mp, SchedulingResource *res)
Definition: ResourceBroker.cc:265
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
TTAMachine::FunctionUnit::maxLatency
virtual int maxLatency() const
Definition: FunctionUnit.cc:443
ExecutionPipelineBroker::ddg_
const DataDependenceGraph * ddg_
Definition: ExecutionPipelineBroker.hh:111
debugLogRM
#define debugLogRM(__X)
Definition: ResourceManager.hh:123
MoveNode::sourceOperation
ProgramOperation & sourceOperation() const
Definition: MoveNode.cc:453
assert
#define assert(condition)
Definition: Application.hh:86
TTAMachine::FunctionUnit
Definition: FunctionUnit.hh:55
TTAMachine::HWOperation::port
virtual FUPort * port(int operand) const
Definition: HWOperation.cc:320
ResourceBroker::setResourceMapper
void setResourceMapper(const ResourceMapper &mapper)
Definition: ResourceBroker.cc:224
MoveNode::isGuardOperation
bool isGuardOperation() const
Definition: MoveNode.cc:181
DataDependenceGraph::operationInEdges
EdgeSet operationInEdges(const MoveNode &node) const
Definition: DataDependenceGraph.cc:5913
MoveNode::earliestResultReadCycle
int earliestResultReadCycle() const
Definition: MoveNode.cc:652
TTAMachine::Machine::controlUnit
virtual ControlUnit * controlUnit() const
Definition: Machine.cc:345
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
SchedulingResource::addToRelatedGroup
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
Definition: SchedulingResource.cc:82
MoveNode::cycle
int cycle() const
Definition: MoveNode.cc:421
InvalidData
Definition: Exception.hh:149
ExecutionPipelineResource::resultNotOverWritten
bool resultNotOverWritten(int resultReadCycle, int resultReadyCycle, const MoveNode &node, const TTAMachine::Port &port, const MoveNode *trigger, int triggerCycle) const
Definition: ExecutionPipelineResource.cc:2048
TTAMachine::ControlUnit
Definition: ControlUnit.hh:50
ExecutionPipelineBroker::isLoopBypass
bool isLoopBypass(const MoveNode &node) const
Definition: ExecutionPipelineBroker.cc:399
SchedulingResource
Definition: SchedulingResource.hh:52
TTAMachine::Port
Definition: Port.hh:54
ExecutionPipelineBroker::isMoveTrigger
bool isMoveTrigger(const MoveNode &node) const
Definition: ExecutionPipelineBroker.cc:664
__func__
#define __func__
Definition: Application.hh:67
TTAMachine::Machine::functionUnitNavigator
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition: Machine.cc:380
ExecutionPipelineBroker::latestFromSource
int latestFromSource(int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const
Definition: ExecutionPipelineBroker.cc:425
ExecutionPipelineBroker::fuPipelineMap_
FUPipelineMap fuPipelineMap_
FU's and their corresponding pipeline resources.
Definition: ExecutionPipelineBroker.hh:108
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
ResourceBroker::resourceOf
SchedulingResource * resourceOf(const TTAMachine::MachinePart &mp) const
MoveNode::isSourceOperation
bool isSourceOperation() const
Definition: MoveNode.cc:168
Exception
Definition: Exception.hh:54
MoveNode::destinationOperationCount
unsigned int destinationOperationCount() const
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
TTAMachine::BaseFUPort::isTriggering
virtual bool isTriggering() const =0
BoostGraph::hasNode
bool hasNode(const Node &) const
TTAMachine::Unit::portCount
virtual int portCount() const
Definition: Unit.cc:135
ProgramOperation::outputMoveCount
int outputMoveCount() const
Definition: ProgramOperation.cc:610
TTAProgram::Terminal::functionUnit
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition: Terminal.cc:251
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
MoveNode::move
TTAProgram::Move & move()
ExecutionPipelineResource::nextResultCycle
int nextResultCycle(const TTAMachine::Port &port, int cycle, const MoveNode &node, const MoveNode *trigger=NULL, int triggerCycle=INT_MAX) const
Definition: ExecutionPipelineResource.cc:1602
TTAMachine::Port::outputSocket
virtual Socket * outputSocket() const
Definition: Port.cc:281
ResourceBroker::ResourceBroker
ResourceBroker(std::string, unsigned int initiationInterval=0)
Definition: ResourceBroker.cc:49
MoveNode::isScheduled
bool isScheduled() const
Definition: MoveNode.cc:409
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAMachine::Machine::Navigator::item
ComponentType * item(int index) const
KeyNotFound
Definition: Exception.hh:285
TTAMachine::FunctionUnit::operation
virtual HWOperation * operation(const std::string &name) const
Definition: FunctionUnit.cc:363
SchedulingResource::name
virtual const std::string & name() const
TTAMachine::HWOperation::latency
int latency() const
Definition: HWOperation.cc:216
ExecutionPipelineBroker::earliestFromDestination
int earliestFromDestination(int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const
Definition: ExecutionPipelineBroker.cc:719
ProgramOperation::outputMove
MoveNode & outputMove(int index) const
Definition: ProgramOperation.cc:632
TTAMachine::Machine::Navigator
Definition: Machine.hh:186
ExecutionPipelineResource::highestKnownCycle
int highestKnownCycle() const
Definition: ExecutionPipelineResource.cc:1479
ProgramOperation::outputIndexOfMove
int outputIndexOfMove(const MoveNode &mn) const
Definition: ProgramOperation.cc:886
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
MoveNode::guardOperation
ProgramOperation & guardOperation() const
Definition: MoveNode.cc:479