OpenASIP 2.2
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
BF2ScheduleFront Class Reference

#include <BF2ScheduleFront.hh>

Inheritance diagram for BF2ScheduleFront:
Inheritance graph
Collaboration diagram for BF2ScheduleFront:
Collaboration graph

Public Types

typedef BF2Scheduler::MoveNodeMap MoveNodeMap
 

Public Member Functions

 BF2ScheduleFront (BF2Scheduler &sched, MoveNode &mn, int lc)
 
virtual bool operator() () override
 
void undoOnlyMe () override
 
MoveNodefindInducingBypassSource (MoveNode &mn)
 
void bypassed (MoveNode &src, MoveNode &dst)
 
void undidBypass (MoveNode &, MoveNode &dst)
 
void mightBeReady (MoveNode &n) override
 
void deletingNode (MoveNode *deletedNode)
 
void appendBypassSources (MoveNodeMap &map)
 
- Public Member Functions inherited from BFOptimization
 BFOptimization (BF2Scheduler &sched)
 
virtual bool isFinishFront ()
 
- Public Member Functions inherited from Reversible
virtual void undo ()
 
virtual ~Reversible ()
 
void deleteChildren (std::stack< Reversible * > &children)
 
int id ()
 
 Reversible ()
 

Static Public Member Functions

static int prefResultCycle (const MoveNode &mn)
 
- Static Public Member Functions inherited from BFOptimization
static void clearPrologMoves ()
 
static MoveNodegetSisterTrigger (const MoveNode &mn, const TTAMachine::Machine &mach)
 

Public Attributes

DataDependenceGraph::NodeSet illegalBypassSources_
 
DataDependenceGraph::NodeSet illegalOperandShares_
 

Protected Member Functions

DataDependenceGraph::NodeSet allNodesOfSameOperation (MoveNode &mn)
 
int scheduleMove (MoveNode &move, BF2Scheduler::SchedulingLimits limits, bool allowEarlyBypass=true, bool allowLateBypass=true, bool allowEarlySharing=true)
 
bool scheduleFrontFromMove (MoveNode &mn)
 
void requeueOtherMovesOfSameOp (MoveNode &mn)
 
bool tryToScheduleMoveOuter (MoveNode &mn, int &latestCycle)
 
BF2Scheduler::SchedulingLimits getPreferredLimits (const MoveNode &mn)
 
MoveNodegetMoveNodeFromFrontBU ()
 
void printFront (const TCEString &prefix)
 
void clearSchedulingFront ()
 
int latestScheduledOfFrontCycle ()
 
- Protected Member Functions inherited from BFOptimization
DataDependenceGraphddg ()
 
DataDependenceGraphrootDDG ()
 
const DataDependenceGraphddg () const
 
DataDependenceGraphprologDDG ()
 
SimpleResourceManagerrm () const
 
SimpleResourceManagerprologRM () const
 
BUMoveNodeSelectorselector ()
 
const TTAMachine::MachinetargetMachine () const
 
unsigned int ii () const
 
MoveNodeDuplicatorduplicator () const
 
virtual bool assign (int cycle, MoveNode &, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU_=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1, bool ignoreGuardWriteCycle=false)
 
virtual void unassign (MoveNode &mn, bool disposePrologCopy=true)
 
virtual int rmEC (int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)
 
virtual int rmLC (int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1)
 
virtual bool canAssign (int cycle, MoveNode &mn, const TTAMachine::Bus *bus=nullptr, const TTAMachine::FunctionUnit *srcFU=nullptr, const TTAMachine::FunctionUnit *dstFU=nullptr, const TTAMachine::Bus *prologBus=nullptr, int immWriteCycle=-1, int prologImmWriteCycle=-1, const TTAMachine::ImmediateUnit *immu=nullptr, int immRegIndex=-1, bool ignoreGWN=false)
 
bool putAlsoToPrologEpilog (int cycle, MoveNode &mn)
 
void setPrologSrcFUAnno (MoveNode &prologMN, MoveNode &loopMN)
 
void setPrologDstFUAnno (MoveNode &prologMN, MoveNode &loopMN)
 
void setJumpGuard (MoveNode &mn)
 
void unsetJumpGuard (MoveNode &mn)
 
bool needJumpGuard (const MoveNode &mn, int cycle)
 
int jumpGuardAvailableCycle (const MoveNode &mn)
 
bool canBeSpeculated (const Operation &op)
 
bool canBeSpeculated (const MoveNode &mn)
 
bool usePrologMove (const MoveNode &mn)
 
bool canBeScheduled (const MoveNode &mn)
 
const TTAMachine::RegisterFileRFReadPortCountPreventsScheduling (const MoveNode &mn)
 
bool immCountPreventsScheduling (const MoveNode &mn)
 
- Protected Member Functions inherited from Reversible
bool runPreChild (Reversible *preChild)
 
bool runPostChild (Reversible *preChild)
 
bool runChild (std::stack< Reversible * > &children, Reversible *child)
 
bool runChild (Reversible *child, bool pre)
 
void undoAndRemovePreChildren ()
 
void undoAndRemovePostChildren ()
 
void undoAndRemoveChildren (std::stack< Reversible * > &children)
 

Private Types

typedef std::map< MoveNode *, int, MoveNode::ComparatorPathLengthCache
 

Private Member Functions

bool tryRevertEarlierBypass (MoveNode &mn)
 
MoveNodefindInducingBypassSourceFromOperation (ProgramOperation &po, const DataDependenceGraph::NodeSet &processedNodes, DataDependenceGraph::NodeSet &queue)
 

Private Attributes

MoveNodeMap bypassSources_
 
DataDependenceGraph::NodeSet schedulingFront_
 
DataDependenceGraph::NodeSet nodesToNotify_
 
MoveNodemn_
 
int lc_
 
PathLengthCache pathLengthCache_
 

Additional Inherited Members

- Protected Attributes inherited from BFOptimization
BF2Schedulersched_
 
- Protected Attributes inherited from Reversible
std::stack< Reversible * > preChildren_
 
std::stack< Reversible * > postChildren_
 
- Static Protected Attributes inherited from BFOptimization
static std::map< MoveNode *, MoveNode *, MoveNode::ComparatorprologMoves_
 

Detailed Description

Definition at line 50 of file BF2ScheduleFront.hh.

Member Typedef Documentation

◆ MoveNodeMap

Definition at line 82 of file BF2ScheduleFront.hh.

◆ PathLengthCache

Definition at line 132 of file BF2ScheduleFront.hh.

Constructor & Destructor Documentation

◆ BF2ScheduleFront()

BF2ScheduleFront::BF2ScheduleFront ( BF2Scheduler sched,
MoveNode mn,
int  lc 
)
inline

Definition at line 53 of file BF2ScheduleFront.hh.

Member Function Documentation

◆ allNodesOfSameOperation()

DataDependenceGraph::NodeSet BF2ScheduleFront::allNodesOfSameOperation ( MoveNode mn)
protected

Definition at line 514 of file BF2ScheduleFront.cc.

514 {
515
518 queue.insert(&mn);
519
520 while (!queue.empty()) {
521 MoveNode* mn = *queue.begin();
522 nodes.insert(mn);
523 queue.erase(mn);
524 if (mn->isSourceOperation()) {
526 mn->sourceOperation(), nodes, queue);
527 }
528
529 if (mn->isGuardOperation()) {
531 mn->guardOperation(), nodes, queue);
532 }
533
534 for (unsigned int i = 0; i < mn->destinationOperationCount(); i++) {
536 mn->destinationOperation(i), nodes, queue);
537 }
538
540 if (ddg().hasNode(*mn)) {
541 MoveNode* bypassSrc =
542 ddg().onlyRegisterRawSource(*mn, false, false);
543 if (bypassSrc != NULL) {
544 if (nodes.find(bypassSrc) == nodes.end()) {
545 queue.insert(bypassSrc);
546 }
547 } else {
548#ifdef DEBUG_BUBBLEFISH_SCHEDULER
549 std::cerr << "Warning:Cannot find src for forced bypass. "
550 << " Inst. scheduler may fail/deadlock" <<std::endl;
551#endif
552 }
553 }
554 }
555
557 if (ddg().hasNode(*mn)) {
558 DataDependenceGraph::NodeSet rrDestinations =
559 ddg().onlyRegisterRawDestinations(*mn, false, false);
560 for (auto n : rrDestinations) {
561 if (nodes.find(n) == nodes.end()) {
562 queue.insert(n);
563 }
564 }
565 }
566 }
567 }
568 return nodes;
569}
static bool isSourceUniversalReg(const MoveNode &mn)
static bool isDestinationUniversalReg(const MoveNode &mn)
DataDependenceGraph & ddg()
static void queueOperation(ProgramOperation &po, const DataDependenceGraph::NodeSet &nodes, DataDependenceGraph::NodeSet &queue)
NodeSet onlyRegisterRawDestinations(const MoveNode &mn, bool allowGuardEdges=false, bool allowBackEdges=false) const
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
std::set< GraphNode *, typename GraphNode::Comparator > NodeSet
Definition Graph.hh:53
unsigned int destinationOperationCount() const
bool isGuardOperation() const
Definition MoveNode.cc:181
ProgramOperation & sourceOperation() const
Definition MoveNode.cc:453
ProgramOperation & guardOperation() const
Definition MoveNode.cc:479
bool isSourceOperation() const
Definition MoveNode.cc:168
ProgramOperation & destinationOperation(unsigned int index=0) const

References BFOptimization::ddg(), MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), MoveNode::guardOperation(), BF2Scheduler::isDestinationUniversalReg(), MoveNode::isGuardOperation(), MoveNode::isSourceOperation(), BF2Scheduler::isSourceUniversalReg(), DataDependenceGraph::onlyRegisterRawDestinations(), DataDependenceGraph::onlyRegisterRawSource(), BUMoveNodeSelector::queueOperation(), and MoveNode::sourceOperation().

Referenced by requeueOtherMovesOfSameOp().

Here is the call graph for this function:

◆ appendBypassSources()

void BF2ScheduleFront::appendBypassSources ( MoveNodeMap map)

Definition at line 705 of file BF2ScheduleFront.cc.

705 {
707}
static void append(const ContainerType &src, ContainerType &dest)
MoveNodeMap bypassSources_

References AssocTools::append(), and bypassSources_.

Referenced by BF2Scheduler::bypassNodes().

Here is the call graph for this function:

◆ bypassed()

void BF2ScheduleFront::bypassed ( MoveNode src,
MoveNode dst 
)
inline

Definition at line 63 of file BF2ScheduleFront.hh.

63 {
64 bypassSources_[&dst] = &src;
65 }

References bypassSources_.

Referenced by BFEarlyBypass::operator()().

◆ clearSchedulingFront()

void BF2ScheduleFront::clearSchedulingFront ( )
protected

Definition at line 595 of file BF2ScheduleFront.cc.

595 {
596 for (auto node : schedulingFront_) {
597 node->setIsInFrontier(false);
598 }
599 schedulingFront_.clear();
600}
DataDependenceGraph::NodeSet schedulingFront_

References schedulingFront_.

Referenced by scheduleFrontFromMove(), and undoOnlyMe().

◆ deletingNode()

void BF2ScheduleFront::deletingNode ( MoveNode deletedNode)
inline

Definition at line 78 of file BF2ScheduleFront.hh.

78 {
79 nodesToNotify_.erase(deletedNode);
80 }
DataDependenceGraph::NodeSet nodesToNotify_

References nodesToNotify_.

Referenced by BF2Scheduler::deletingNode().

◆ findInducingBypassSource()

MoveNode * BF2ScheduleFront::findInducingBypassSource ( MoveNode mn)

Definition at line 603 of file BF2ScheduleFront.cc.

603 {
605 DataDependenceGraph::NodeSet processedNodes;
606 queue.insert(&mn);
607
608 while (!queue.empty()) {
609 MoveNode* mn = *queue.begin();
610 processedNodes.insert(mn);
611 queue.erase(mn);
612
614 for (auto i : bypassSources_) {
615 if (i.second == mn) {
616 return mn;
617 }
618 }
619 }
620
621 if (mn->isSourceOperation()) {
622 MoveNode *result =
624 mn->sourceOperation(), processedNodes, queue);
625 if (result != NULL) {
626 return result;
627 }
628 }
629
630 for (unsigned int i = 0; i < mn->destinationOperationCount(); i++) {
631 MoveNode *result =
633 mn->destinationOperation(i), processedNodes, queue);
634 if (result != NULL) {
635 return result;
636 }
637 }
638 }
639 return NULL;
640}
MoveNode * findInducingBypassSourceFromOperation(ProgramOperation &po, const DataDependenceGraph::NodeSet &processedNodes, DataDependenceGraph::NodeSet &queue)
BF2Scheduler & sched_

References bypassSources_, MoveNode::destinationOperation(), MoveNode::destinationOperationCount(), findInducingBypassSourceFromOperation(), BF2Scheduler::isDestinationUniversalReg(), MoveNode::isSourceOperation(), BFOptimization::sched_, and MoveNode::sourceOperation().

Referenced by tryRevertEarlierBypass().

Here is the call graph for this function:

◆ findInducingBypassSourceFromOperation()

MoveNode * BF2ScheduleFront::findInducingBypassSourceFromOperation ( ProgramOperation po,
const DataDependenceGraph::NodeSet processedNodes,
DataDependenceGraph::NodeSet queue 
)
private

Definition at line 642 of file BF2ScheduleFront.cc.

645 {
646 for (int j = 0; j < po.inputMoveCount(); j++) {
647 MoveNode& inputMove = po.inputMove(j);
648 // only add if not already added
649 if (processedNodes.find(&inputMove) == processedNodes.end()) {
650 queue.insert(&inputMove);
651 }
652 }
653
654 for (int j = 0; j < po.outputMoveCount(); j++) {
655 MoveNode& outputMove = po.outputMove(j);
656 // only add if not already added
657 if (processedNodes.find(&outputMove) == processedNodes.end()) {
658 if (!sched_.isDestinationUniversalReg(outputMove)) {
659 for (auto i : bypassSources_) {
660 if (i.second == &outputMove) {
661 return &outputMove;
662 }
663 }
664 }
665 queue.insert(&outputMove);
666 }
667 }
668 return NULL;
669}
int outputMoveCount() const
int inputMoveCount() const
MoveNode & inputMove(int index) const
MoveNode & outputMove(int index) const

References bypassSources_, ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), BF2Scheduler::isDestinationUniversalReg(), ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), and BFOptimization::sched_.

Referenced by findInducingBypassSource().

Here is the call graph for this function:

◆ getMoveNodeFromFrontBU()

MoveNode * BF2ScheduleFront::getMoveNodeFromFrontBU ( )
protected

Definition at line 339 of file BF2ScheduleFront.cc.

339 {
340#ifdef DEBUG_BUBBLEFISH_SCHEDULER
341 std::cerr << "\tGetting moveNode from front" << std::endl;
342#endif
343 int sd = -2;
344 MoveNode* selectedMN = NULL;
345 for (auto mn: schedulingFront_) {
346
347 if (mn->isScheduled() || sched_.isDeadResult(*mn)) {
348 continue;
349 }
350
351 int cursd;
352 auto j = pathLengthCache_.find(mn);
353 if (j != pathLengthCache_.end()) {
354 cursd = j->second;
355 } else {
356 cursd = ddg().maxSourceDistance(*mn);
357 pathLengthCache_[mn] = cursd;
358 }
359
360 // weight more last moves of unready ops
361 if (mn->isDestinationOperation()) {
362 if (mn->isLastUnscheduledMoveOfDstOp()) {
363 cursd += 10000;
364 }
365 }
366
367 if (cursd > sd &&
369 selectedMN = mn;
370 sd = cursd;
371 }
372 }
373
374 if (selectedMN != NULL && !sched_.isPreLoopSharedOperand(*selectedMN)) {
375#ifdef DEBUG_BUBBLEFISH_SCHEDULER
376 std::cerr << "\t\tSelected:" << selectedMN->toString() << std::endl;
377#endif
378 MoveNode* trigger = getSisterTrigger(*selectedMN, targetMachine());
379 if (trigger != NULL && !trigger->isScheduled() &&
380 !sched_.hasUnscheduledSuccessors(*trigger)) {
381#ifdef DEBUG_BUBBLEFISH_SCHEDULER
382 std::cerr << "\t\tReturning trigger instead:"
383 << trigger->toString() << std::endl;
384#endif
385
386 BFSwapOperands* bfswo = new BFSwapOperands(sched_, *trigger);
387 if (runPreChild(bfswo)) {
388 return bfswo->switchedMNs().second;
389 } else {
390 return trigger;
391 }
392 }
393 }
394 if (selectedMN != NULL) {
395#ifdef DEBUG_BUBBLEFISH_SCHEDULER
396 std::cerr << "\tSelected MN: " << selectedMN->toString() << std::endl;
397#endif
398 } else {
399#ifdef DEBUG_BUBBLEFISH_SCHEDULER
400 std::cerr << "Front empty, returning NULL" << std::endl;
401#endif
402 }
403 return selectedMN;
404}
PathLengthCache pathLengthCache_
bool isDeadResult(MoveNode &mn) const
TTAMachine::FUPort * isPreLoopSharedOperand(MoveNode &mn) const
bool hasUnscheduledSuccessors(MoveNode &mn) const
static MoveNode * getSisterTrigger(const MoveNode &mn, const TTAMachine::Machine &mach)
const TTAMachine::Machine & targetMachine() const
std::pair< MoveNode *, MoveNode * > switchedMNs()
int maxSourceDistance(const GraphNode &node) const
std::string toString() const
Definition MoveNode.cc:576
bool isScheduled() const
Definition MoveNode.cc:409
bool runPreChild(Reversible *preChild)

References BFOptimization::ddg(), BFOptimization::getSisterTrigger(), BF2Scheduler::hasUnscheduledSuccessors(), BF2Scheduler::isDeadResult(), BF2Scheduler::isPreLoopSharedOperand(), MoveNode::isScheduled(), BoostGraph< GraphNode, GraphEdge >::maxSourceDistance(), pathLengthCache_, Reversible::runPreChild(), BFOptimization::sched_, schedulingFront_, BFSwapOperands::switchedMNs(), BFOptimization::targetMachine(), and MoveNode::toString().

Referenced by operator()(), and scheduleFrontFromMove().

Here is the call graph for this function:

◆ getPreferredLimits()

BF2Scheduler::SchedulingLimits BF2ScheduleFront::getPreferredLimits ( const MoveNode mn)
protected

Definition at line 441 of file BF2ScheduleFront.cc.

442 {
444 int prefCycle = prefResultCycle(mn);
445
446 if (prefCycle != INT_MAX) {
447#ifdef DEBUG_BUBBLEFISH_SCHEDULER
448 std::cerr << "Schedulong TOP-DOWN(TD)" << mn.toString() << std::endl;
449 std::cerr << "Setting earl. limit to pref:" << prefCycle << std::endl;
450#endif
451 limits.earliestCycle = prefCycle;
453 }
454 if (mn.move().isControlFlowMove() &&
455 getSisterTrigger(mn, targetMachine()) == &mn) {
456 prefCycle = lc_- targetMachine().controlUnit()->delaySlots();
457#ifdef DEBUG_BUBBLEFISH_SCHEDULER
458 std::cerr << "Control flow move requires exact cycle: "
459 << prefCycle << std::endl;
460#endif
461 limits.earliestCycle = limits.latestCycle = prefCycle;
463 }
464 return limits;
465}
static int prefResultCycle(const MoveNode &mn)
TTAProgram::Move & move()
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345
bool isControlFlowMove() const
Definition Move.cc:233
SchedulingDirection direction

References TTAMachine::Machine::controlUnit(), TTAMachine::ControlUnit::delaySlots(), BF2Scheduler::SchedulingLimits::direction, BF2Scheduler::SchedulingLimits::earliestCycle, BF2Scheduler::EXACTCYCLE, BFOptimization::getSisterTrigger(), TTAProgram::Move::isControlFlowMove(), BF2Scheduler::SchedulingLimits::latestCycle, lc_, MoveNode::move(), prefResultCycle(), BFOptimization::targetMachine(), BF2Scheduler::TOPDOWN, and MoveNode::toString().

Referenced by tryToScheduleMoveOuter().

Here is the call graph for this function:

◆ latestScheduledOfFrontCycle()

int BF2ScheduleFront::latestScheduledOfFrontCycle ( )
protected

Definition at line 327 of file BF2ScheduleFront.cc.

327 {
328 int lc = -1;
329 for (auto mn : schedulingFront_) {
330 if (mn->isScheduled() && mn->cycle() > lc) {
331 lc = mn->cycle();
332 }
333 }
334 return lc;
335}

References schedulingFront_.

Referenced by tryToScheduleMoveOuter().

◆ mightBeReady()

void BF2ScheduleFront::mightBeReady ( MoveNode n)
overridevirtual

Reimplemented from BFOptimization.

Definition at line 701 of file BF2ScheduleFront.cc.

701 {
702 nodesToNotify_.insert(&n);
703}

References nodesToNotify_.

Referenced by BFOptimization::mightBeReady(), and BFRenameLiveRange::notifySelector().

◆ operator()()

bool BF2ScheduleFront::operator() ( )
overridevirtual

This performs the operation. Returns true if success, false if fail.

Implements Reversible.

Definition at line 61 of file BF2ScheduleFront.cc.

61 {
62
63#ifdef DEBUG_BUBBLEFISH_SCHEDULER
64 std::cerr << std::endl << "Got: " << mn_.toString()
65 << " to schedule(1)" << std::endl;
66#endif
69 assert(mn2 != NULL);
70
71 bool ok = scheduleFrontFromMove(*mn2);
72 // Do not waste memory by keeping it in the stack of performed
73 // operations.
74 // Not needed anymore. Can calculate again for next front.
75 // Consider sharing between different fronts if still too slow.
76 pathLengthCache_.clear();
77 return ok;
78}
#define assert(condition)
MoveNode * getMoveNodeFromFrontBU()
bool scheduleFrontFromMove(MoveNode &mn)
void requeueOtherMovesOfSameOp(MoveNode &mn)

References assert, getMoveNodeFromFrontBU(), mn_, pathLengthCache_, requeueOtherMovesOfSameOp(), scheduleFrontFromMove(), and MoveNode::toString().

Here is the call graph for this function:

◆ prefResultCycle()

int BF2ScheduleFront::prefResultCycle ( const MoveNode mn)
static

Definition at line 406 of file BF2ScheduleFront.cc.

406 {
407 int prefCycle = INT_MAX;
408 if (mn.isSourceOperation()) {
409 if (!mn.isDestinationOperation()) {
410 const ProgramOperation& sop = mn.sourceOperation();
411 for (int i = 0; i < sop.outputMoveCount(); i++) {
412 const MoveNode& outNode = sop.outputMove(i);
413 if (!outNode.isScheduled()) {
414 continue;
415 }
416
417#ifdef DEBUG_BUBBLEFISH_SCHEDULER
418 std::cerr << "\t\tOut node: " << outNode.toString()
419 << " is scheduled!" << std::endl;
420#endif
421 const TTAMachine::HWOperation& hwop =
422 *sop.hwopFromOutMove(outNode);
423 // find the OSAL id of the operand of the output being tested
424 const int outNodeOutputIndex =
425 sop.outputIndexOfMove(outNode);
426 int onLatency = hwop.latency(outNodeOutputIndex);
427 int latestTrigger = outNode.cycle() - onLatency;
428 const int myOutIndex = mn.move().source().operationIndex();
429 int myLatency = hwop.latency(myOutIndex);
430 int myPreferredCycle = latestTrigger + myLatency;
431 if (myPreferredCycle < prefCycle) {
432 prefCycle = myPreferredCycle;
433 }
434 }
435 }
436 }
437 return prefCycle;
438}
int cycle() const
Definition MoveNode.cc:421
bool isDestinationOperation() const
const TTAMachine::HWOperation * hwopFromOutMove(const MoveNode &outputNode) const
int outputIndexOfMove(const MoveNode &mn) const
Terminal & source() const
Definition Move.cc:302
virtual int operationIndex() const
Definition Terminal.cc:364

References MoveNode::cycle(), ProgramOperation::hwopFromOutMove(), MoveNode::isDestinationOperation(), MoveNode::isScheduled(), MoveNode::isSourceOperation(), TTAMachine::HWOperation::latency(), MoveNode::move(), TTAProgram::Terminal::operationIndex(), ProgramOperation::outputIndexOfMove(), ProgramOperation::outputMove(), ProgramOperation::outputMoveCount(), TTAProgram::Move::source(), MoveNode::sourceOperation(), and MoveNode::toString().

Referenced by getPreferredLimits(), and BFScheduleBU::operator()().

Here is the call graph for this function:

◆ printFront()

void BF2ScheduleFront::printFront ( const TCEString prefix)
protected

Definition at line 572 of file BF2ScheduleFront.cc.

572 {
573 for (auto node : schedulingFront_) {
574 if (sched_.isDeadResult(*node)) {
575 std::cerr << "DEAD ";
576 }
577 std::cerr << prefix << node->toString() << std::endl;
578 }
579}

References BF2Scheduler::isDeadResult(), BFOptimization::sched_, and schedulingFront_.

Referenced by scheduleFrontFromMove(), and undoOnlyMe().

Here is the call graph for this function:

◆ requeueOtherMovesOfSameOp()

void BF2ScheduleFront::requeueOtherMovesOfSameOp ( MoveNode mn)
protected

Definition at line 502 of file BF2ScheduleFront.cc.

502 {
505 for (auto mn : moves) {
506 if (!mn->isFinalized()) { // && !sched_.isPreLoopSharedOperand(*mn)) {
507 mn->setIsInFrontier(true);
508 schedulingFront_.insert(mn);
509 }
510 }
511}
DataDependenceGraph::NodeSet allNodesOfSameOperation(MoveNode &mn)
void setIsInFrontier(bool inFrontier=true)
bool isFinalized() const

References allNodesOfSameOperation(), MoveNode::isFinalized(), schedulingFront_, and MoveNode::setIsInFrontier().

Referenced by operator()(), and scheduleFrontFromMove().

Here is the call graph for this function:

◆ scheduleFrontFromMove()

bool BF2ScheduleFront::scheduleFrontFromMove ( MoveNode mn)
protected

Definition at line 81 of file BF2ScheduleFront.cc.

81 {
82 MoveNode* mn2 = &mn;
83 int latest = lc_;
84#ifdef DEBUG_BUBBLEFISH_SCHEDULER
85 std::cerr << "ScheduleFrontFromMove called: " <<mn.toString()<< std::endl;
86#endif
87 while (mn2 != NULL) {
88 if (mn2->move().isControlFlowMove()) {
89 latest = std::min(
90 latest,
91 lc_- targetMachine().controlUnit()->delaySlots());
92 }
93
94 if (!tryToScheduleMoveOuter(*mn2, latest)) {
95#ifdef DEBUG_BUBBLEFISH_SCHEDULER
96 std::cerr << "TryToScheduleMoveOuter " << mn2->toString() <<
97 " failed!, latest now" << latest << std::endl;
98#endif
99 undo();
100 int smallestRMCycle = rm().smallestCycle();
101 if (smallestRMCycle == INT_MAX) {
102 smallestRMCycle = lc_;
103 }
104#ifdef DEBUG_BUBBLEFISH_SCHEDULER
105 std::cerr << "Latest after outer fail: " << latest << std::endl;
106 std::cerr << "smallest rm cycle: " << smallestRMCycle <<
107 " max latency+1: " << targetMachine().maximumLatency()+1
108 << std::endl;
109#endif
110 if (latest < 0 || latest <
111 (smallestRMCycle - (targetMachine().maximumLatency()+1))) {
112 if (Application::verboseLevel() > 1 ||
113 rm().initiationInterval() == 0) {
114 std::cerr << "Retry to too early cycle. cannot schedule: "
115 << mn2->toString()
116 << std::endl;
117 ddg().writeToDotFile("fail.dot");
118 }
119 return false;
120 } else {
121#ifdef DEBUG_BUBBLEFISH_SCHEDULER
122 std::cerr << "OK or retry at earlier cycle.." << std::endl;
123#endif
124 }
125 }
126#ifdef DEBUG_BUBBLEFISH_SCHEDULER
127 std::cerr << "TryToScheduleMoveOuter ok: " << mn2->toString() <<std::endl;
128#endif
132 }
133#ifdef DEBUG_BUBBLEFISH_SCHEDULER
134 std::cerr << "Schedulingfront scheduled ok!: " << this << std::endl;
135 printFront("\t");
136#endif
137 for (auto i : schedulingFront_) {
138 if (!i->isScheduled()) {
139 if (!sched_.isDeadResult(*i) &&
141 std::cerr << "Front Has unscheduled move: "
142 << (*i).toString() << std::endl;
143 ddg().writeToDotFile("front_unscheduled_move.dot");
144 assert(0);
145 }
146 } else {
147#ifdef DEBUG_BUBBLEFISH_SCHEDULER
148 std::cerr << "\tNotifying scheduled: " << (*i).toString()
149 << std::endl;
150#endif
152
153 }
154 }
155
156 for (auto n: nodesToNotify_) {
157 if (!sched_.isDeadResult(*n) && !n->isScheduled()) {
158#ifdef DEBUG_BUBBLEFISH_SCHEDULER
159 std::cerr << "\tMight be ready: " << n->toString() << std::endl;
160#endif
162 }
163 }
165 return true;
166}
static int verboseLevel()
bool tryToScheduleMoveOuter(MoveNode &mn, int &latestCycle)
void printFront(const TCEString &prefix)
BUMoveNodeSelector & selector()
SimpleResourceManager & rm() const
virtual void notifyScheduled(MoveNode &node)
virtual void mightBeReady(MoveNode &node)
virtual void writeToDotFile(const TCEString &fileName) const
virtual void undo()
Definition Reversible.cc:69
virtual int smallestCycle() const override
int maximumLatency() const
Definition Machine.cc:1023

References assert, clearSchedulingFront(), BFOptimization::ddg(), getMoveNodeFromFrontBU(), TTAProgram::Move::isControlFlowMove(), BF2Scheduler::isDeadResult(), BF2Scheduler::isPreLoopSharedOperand(), lc_, TTAMachine::Machine::maximumLatency(), BUMoveNodeSelector::mightBeReady(), MoveNode::move(), nodesToNotify_, BUMoveNodeSelector::notifyScheduled(), printFront(), requeueOtherMovesOfSameOp(), BFOptimization::rm(), BFOptimization::sched_, schedulingFront_, BFOptimization::selector(), SimpleResourceManager::smallestCycle(), BFOptimization::targetMachine(), MoveNode::toString(), tryToScheduleMoveOuter(), Reversible::undo(), Application::verboseLevel(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by operator()().

Here is the call graph for this function:

◆ scheduleMove()

int BF2ScheduleFront::scheduleMove ( MoveNode move,
BF2Scheduler::SchedulingLimits  limits,
bool  allowEarlyBypass = true,
bool  allowLateBypass = true,
bool  allowEarlySharing = true 
)
protected

Definition at line 468 of file BF2ScheduleFront.cc.

471 {
472
473 BFOptimization* sched;
474 switch (limits.direction) {
477 sched = new BFScheduleBU(
478 sched_, mn, limits.latestCycle, allowEarlyBypass,
479 allowLateBypass, allowEarlySharing);
480 break;
481 } else {
482 std::cerr << "Is pre loop shared oper, sch to prolog instead: " <<
483 mn.toString() << std::endl;
484 assert(false);
485 break;
486 }
488 sched = new BFScheduleTD(
489 sched_, mn, limits.earliestCycle, allowLateBypass);
490 break;
492 assert(limits.earliestCycle == limits.latestCycle);
493 sched = new BFScheduleExact(
494 sched_,mn,limits.earliestCycle);
495 break;
496 default:
497 return -1;
498 }
499 return runPreChild(sched) ? 1 : -1;
500}

References assert, BF2Scheduler::BOTTOMUP, BF2Scheduler::SchedulingLimits::direction, BF2Scheduler::SchedulingLimits::earliestCycle, BF2Scheduler::EXACTCYCLE, BF2Scheduler::isPreLoopSharedOperand(), BF2Scheduler::SchedulingLimits::latestCycle, Reversible::runPreChild(), BFOptimization::sched_, BF2Scheduler::TOPDOWN, and MoveNode::toString().

Referenced by tryToScheduleMoveOuter().

Here is the call graph for this function:

◆ tryRevertEarlierBypass()

bool BF2ScheduleFront::tryRevertEarlierBypass ( MoveNode mn)
private

Definition at line 671 of file BF2ScheduleFront.cc.

671 {
672
673 MoveNode* inducingBypass = findInducingBypassSource(mn);
674 while (inducingBypass != NULL &&
675 sched_.isDestinationUniversalReg(*inducingBypass)) {
676 for (auto i : bypassSources_) {
677 if (i.second == inducingBypass) {
678 inducingBypass = findInducingBypassSource(*(i.first));
679 break;
680 }
681 }
682 }
683 if (inducingBypass == NULL) {
684 return false;
685 } else {
686#ifdef DEBUG_BUBBLEFISH_SCHEDULER
687 std::cerr << "\t\tMaking illegal bypas of src: "
688 << inducingBypass->toString() << std::endl;
689#endif
690 if (illegalBypassSources_.count(inducingBypass)) {
691#ifdef DEBUG_BUBBLEFISH_SCHEDULER
692 std::cerr << "\t\tIs already illegal bypass! " << std::endl;
693#endif
694 return false;
695 }
696 illegalBypassSources_.insert(inducingBypass);
697 return true;
698 }
699}
DataDependenceGraph::NodeSet illegalBypassSources_
MoveNode * findInducingBypassSource(MoveNode &mn)

References bypassSources_, findInducingBypassSource(), illegalBypassSources_, BF2Scheduler::isDestinationUniversalReg(), BFOptimization::sched_, and MoveNode::toString().

Referenced by tryToScheduleMoveOuter().

Here is the call graph for this function:

◆ tryToScheduleMoveOuter()

bool BF2ScheduleFront::tryToScheduleMoveOuter ( MoveNode mn,
int &  latestCycle 
)
protected

Definition at line 170 of file BF2ScheduleFront.cc.

170 {
171#ifdef DEBUG_BUBBLEFISH_SCHEDULER
172 std::cerr << std::endl << "\tGot: " << mn.toString() << " to schedule(2)"
173 << std::endl;
174#endif
175 while(true) {
177 assert(prologRM() != NULL);
178#ifdef DEBUG_BUBBLEFISH_SCHEDULER
179 std::cerr << "\tShould scheudule pre-opshare to prefix: "
180 << mn.toString() << std::endl;
181#endif
182 BFOptimization* sbu = new BFDropPreShared(sched_, mn);
183 bool ok = runPreChild(sbu);
184 if (!ok) {
185 int lcFront = latestScheduledOfFrontCycle();
186 if (lcFront != -1 && lcFront <= latestCycle) {
187 latestCycle = lcFront -1;
188 } else{
189 latestCycle--;
190 }
191 return false;
192 } else {
193 return true;
194 }
195 }
196
197 // Kill (result) moves that write to values that are
198 // never used(even when not bypassing).
199 if (mn.isDestinationVariable()) {
200 BFOptimization* dre = new BFDREEarly(sched_, mn);
201 if (runPreChild(dre)) {
202 return true;
203 }
204 }
205
207 if (limits.direction == BF2Scheduler::EXACTCYCLE &&
208 latestCycle < limits.latestCycle) {
209 latestCycle = INT_MIN;
210#ifdef DEBUG_BUBBLEFISH_SCHEDULER
211 std::cerr << "\tlatestCycle later than exact limit. failing."
212 << std::endl;
213#endif
214 return false;
215 }
216
217 limits.latestCycle = std::min(limits.latestCycle, latestCycle);
218#ifdef DEBUG_BUBBLEFISH_SCHEDULER
219 std::cerr << "\tFirst all optimizations on" << std::endl;
220#endif
221 int schedRes = scheduleMove(mn, limits, true, true, true);
222 if (schedRes >= 0) {
223#ifdef DEBUG_BUBBLEFISH_SCHEDULER
224 std::cerr << "\tScheduling of: " << mn.toString() << " ok "
225 << std::endl;
226#endif
227 return true;
228 }
229
230 if (limits.direction == BF2Scheduler::TOPDOWN) {
232 limits.earliestCycle = 0;
233#ifdef DEBUG_BUBBLEFISH_SCHEDULER
234 std::cerr << "\tTOPDOWN failed, trying bottomup" << std::endl;
235#endif
236 if (scheduleMove(mn, limits) >= 0) {
237#ifdef DEBUG_BUBBLEFISH_SCHEDULER
238 std::cerr << "\ttopdown back to bottomup ok" << std::endl;
239#endif
240 return true;
241 }
242 }
243#ifdef DEBUG_BUBBLEFISH_SCHEDULER
244 std::cerr << "\tTrying without early sharing" << std::endl;
245#endif
246 // disable early sharing;
247 if (scheduleMove(mn, limits, true, true, false) >=0) {
248 return true;
249 }
250
251
252#ifdef DEBUG_BUBBLEFISH_SCHEDULER
253 std::cerr << "\tTrying without early BP" << std::endl;
254#endif
255 // disable early bypass;
256 if (scheduleMove(mn, limits, false, true) >=0) {
257#ifdef DEBUG_BUBBLEFISH_SCHEDULER
258 std::cerr << "\tok without early BP" << std::endl;
259#endif
260 return true;
261 }
262
263#ifdef DEBUG_BUBBLEFISH_SCHEDULER
264 std::cerr << "\tTrying without early BP and without early sharing"
265 << std::endl;
266#endif
267 if (scheduleMove(mn, limits, false, true, false) >= 0) {
268 return true;
269 }
270
271 if (tryRevertEarlierBypass(mn)) {
272#ifdef DEBUG_BUBBLEFISH_SCHEDULER
273 std::cerr << "\tTrying to Revert earlier bypass.."
274 << std::endl;
275#endif
276 // do not make cycle go earlier, but forbid some bypass.
277 return false;
278 }
279
280#ifdef DEBUG_BUBBLEFISH_SCHEDULER
281 std::cerr << "\tTrying without late BP" << std::endl;
282#endif
283 // disable late bypass
284 if (scheduleMove(mn, limits, true, false) >=0) {
285#ifdef DEBUG_BUBBLEFISH_SCHEDULER
286 std::cerr << "\tok without late BP" << std::endl;
287#endif
288 return true;
289 }
290#ifdef DEBUG_BUBBLEFISH_SCHEDULER
291 std::cerr << "\tTrying without any BP" << std::endl;
292#endif
293 // disable both bypasses
294 if (scheduleMove(mn, limits, false, false) >=0) {
295#ifdef DEBUG_BUBBLEFISH_SCHEDULER
296 std::cerr << "\tok without any BP" << std::endl;
297#endif
298 return true;
299 }
300
301 if (mn.destinationOperationCount() > 1) {
302#ifdef DEBUG_BUBBLEFISH_SCHEDULER
303 std::cerr << "forbidding operand share: " << mn.toString()
304 << std::endl;
305#endif
306 illegalOperandShares_.insert(&mn);
307 return true;
308 }
309
310#ifdef DEBUG_BUBBLEFISH_SCHEDULER
311 std::cerr << "\tScheduleMove failing, need to tr earlier cycle"
312 << std::endl;
313#endif
314
315 int lcFront = latestScheduledOfFrontCycle();
316 if (lcFront != -1 && lcFront <= latestCycle) {
317 latestCycle = lcFront -1;
318 } else{
319 latestCycle--;
320 }
321 return false;
322 }
323 std::cerr << "end of schduleMoveOuter, should not be here!" << std::endl;
324 return true;
325}
DataDependenceGraph::NodeSet illegalOperandShares_
bool tryRevertEarlierBypass(MoveNode &mn)
int scheduleMove(MoveNode &move, BF2Scheduler::SchedulingLimits limits, bool allowEarlyBypass=true, bool allowLateBypass=true, bool allowEarlySharing=true)
BF2Scheduler::SchedulingLimits getPreferredLimits(const MoveNode &mn)
SimpleResourceManager * prologRM() const
bool isDestinationVariable() const
Definition MoveNode.cc:264

References assert, BF2Scheduler::BOTTOMUP, MoveNode::destinationOperationCount(), BF2Scheduler::SchedulingLimits::direction, BF2Scheduler::SchedulingLimits::earliestCycle, BF2Scheduler::EXACTCYCLE, getPreferredLimits(), illegalOperandShares_, MoveNode::isDestinationVariable(), BF2Scheduler::isPreLoopSharedOperand(), BF2Scheduler::SchedulingLimits::latestCycle, latestScheduledOfFrontCycle(), BFOptimization::prologRM(), Reversible::runPreChild(), BFOptimization::sched_, scheduleMove(), BF2Scheduler::TOPDOWN, MoveNode::toString(), and tryRevertEarlierBypass().

Referenced by scheduleFrontFromMove().

Here is the call graph for this function:

◆ undidBypass()

void BF2ScheduleFront::undidBypass ( MoveNode ,
MoveNode dst 
)
inline

Definition at line 67 of file BF2ScheduleFront.hh.

67 {
68 bypassSources_.erase(&dst);
69 }

References bypassSources_.

Referenced by BFEarlyBypass::undoOnlyMe().

◆ undoOnlyMe()

void BF2ScheduleFront::undoOnlyMe ( )
overridevirtual

Undoes the operations done by this class but not children. This method should be overloaded by most derived classes.

Reimplemented from Reversible.

Definition at line 582 of file BF2ScheduleFront.cc.

582 {
583#ifdef DEBUG_BUBBLEFISH_SCHEDULER
584 std::cerr << "should undo front. printing front:" << std::endl;
585 printFront("\t");
586#endif
588
589#ifdef DEBUG_BUBBLEFISH_SCHEDULER
590 std::cerr << "should have cleared. printing front:" << std::endl;
591 printFront("\t");
592#endif
593}

References clearSchedulingFront(), and printFront().

Here is the call graph for this function:

Member Data Documentation

◆ bypassSources_

MoveNodeMap BF2ScheduleFront::bypassSources_
private

◆ illegalBypassSources_

DataDependenceGraph::NodeSet BF2ScheduleFront::illegalBypassSources_

Definition at line 71 of file BF2ScheduleFront.hh.

Referenced by BFEarlyBypasser::operator()(), and tryRevertEarlierBypass().

◆ illegalOperandShares_

DataDependenceGraph::NodeSet BF2ScheduleFront::illegalOperandShares_

Definition at line 72 of file BF2ScheduleFront.hh.

Referenced by BFShareOperands::operator()(), and tryToScheduleMoveOuter().

◆ lc_

int BF2ScheduleFront::lc_
private

Definition at line 130 of file BF2ScheduleFront.hh.

Referenced by getPreferredLimits(), and scheduleFrontFromMove().

◆ mn_

MoveNode& BF2ScheduleFront::mn_
private

Definition at line 129 of file BF2ScheduleFront.hh.

Referenced by operator()().

◆ nodesToNotify_

DataDependenceGraph::NodeSet BF2ScheduleFront::nodesToNotify_
private

Definition at line 127 of file BF2ScheduleFront.hh.

Referenced by deletingNode(), mightBeReady(), and scheduleFrontFromMove().

◆ pathLengthCache_

PathLengthCache BF2ScheduleFront::pathLengthCache_
private

Definition at line 133 of file BF2ScheduleFront.hh.

Referenced by getMoveNodeFromFrontBU(), and operator()().

◆ schedulingFront_

DataDependenceGraph::NodeSet BF2ScheduleFront::schedulingFront_
private

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