OpenASIP 2.2
Loading...
Searching...
No Matches
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.
 

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.
 
int longestLatency_
 Longest latency of all operations of all the FUs.
 
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}
const DataDependenceGraph * ddg_
FUPipelineMap fuPipelineMap_
FU's and their corresponding pipeline resources.
int longestLatency_
Longest latency of all operations of all the FUs.

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}
#define abortWithError(message)

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 =
263
264 ResourceBroker::addResource(*fu, epResource);
265 fuPipelineMap_.insert(
266 pair<SchedulingResource*, const FunctionUnit*>(epResource, fu));
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}
void addResource(const TTAMachine::MachinePart &mp, SchedulingResource *res)
unsigned int initiationInterval_
virtual int maxLatency() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345

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}
#define debugLogRM(__X)
int earliestFromSource(int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const
int earliestFromDestination(int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const

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}
bool isMoveTrigger(const MoveNode &node) const
unsigned int destinationOperationCount() const
int cycle() const
Definition MoveNode.cc:421
bool isDestinationOperation() const
TTAProgram::Move & move()
bool isScheduled() const
Definition MoveNode.cc:409
ProgramOperation & destinationOperation(unsigned int index=0) const
virtual TCEString name() const
Definition Operation.cc:93
int outputMoveCount() const
const Operation & operation() const
int inputMoveCount() const
MoveNode & inputMove(int index) const
const TTAMachine::FunctionUnit * fuFromOutMove(const MoveNode &outputNode) const
MoveNode & outputMove(int index) const
int outputIndexOfMove(const MoveNode &mn) const
virtual HWOperation * operation(const std::string &name) const
bool isTriggering() const
Definition Move.cc:284
Terminal & destination() const
Definition Move.cc:323
virtual const TTAMachine::FunctionUnit & functionUnit() const
Definition Terminal.cc:251

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(), ProgramOperation::operation(), TTAMachine::FunctionUnit::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}
#define assert(condition)
bool resultNotOverWritten(int resultReadCycle, int resultReadyCycle, const MoveNode &node, const TTAMachine::Port &port, const MoveNode *trigger, int triggerCycle) const
int earliestResultReadCycle() const
Definition MoveNode.cc:652
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
bool isSourceOperation() const
Definition MoveNode.cc:168
SchedulingResource * resourceOf(const TTAMachine::MachinePart &mp) const
virtual FUPort * port(int operand) const
Terminal & source() const
Definition Move.cc:302
virtual int operationIndex() const
Definition Terminal.cc:364
virtual bool isFUPort() const
Definition Terminal.cc:118

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(), ProgramOperation::operation(), TTAMachine::FunctionUnit::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}
ResourceMap resMap_

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}
bool hasNode(const Node &) const
EdgeSet operationInEdges(const MoveNode &node) const

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(
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}
virtual BaseFUPort * triggerPort() const

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}
int latestFromDestination(int, const MoveNode &, const TTAMachine::FunctionUnit *dstFU) const
int latestFromSource(int, const MoveNode &, const TTAMachine::FunctionUnit *srcFU) const

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}
bool isLoopBypass(const MoveNode &node) const
int outputIndexFromGuardOfMove(const MoveNode &node) const

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(), ProgramOperation::operation(), TTAMachine::FunctionUnit::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}
#define __func__
int nextResultCycle(const TTAMachine::Port &port, int cycle, const MoveNode &node, const MoveNode *trigger=NULL, int triggerCycle=INT_MAX) const
bool isGuardOperation() const
Definition MoveNode.cc:181
std::string toString() const
Definition MoveNode.cc:576
ProgramOperation & guardOperation() const
Definition MoveNode.cc:479

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(), ProgramOperation::operation(), TTAMachine::FunctionUnit::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{
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 {
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}
std::string errorMessageStack(bool messagesOnly=false) const
Definition Exception.cc:138
static KeyType keyForValue(const MapType &aMap, const ValueType &aValue)
void setResourceMapper(const ResourceMapper &mapper)
SchedulingResource & resourceOf(const TTAMachine::MachinePart &mp, int index=0) const
virtual void addToRelatedGroup(const int group, SchedulingResource &resource)
virtual const std::string & name() const
virtual bool isTriggering() const =0
virtual BaseFUPort * port(const std::string &name) const
virtual Socket * outputSocket() const
Definition Port.cc:281
virtual Socket * inputSocket() const
Definition Port.cc:261
virtual int portCount() const
Definition Unit.cc:135

References __func__, abortWithError, SchedulingResource::addToRelatedGroup(), Exception::errorMessageStack(), fuPipelineMap_, TTAMachine::Port::inputSocket(), TTAMachine::BaseFUPort::isTriggering(), MapTools::keyForValue(), 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: