Go to the documentation of this file.
63 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
65 <<
" to schedule(1)" << std::endl;
84 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
85 std::cerr <<
"ScheduleFrontFromMove called: " <<mn.
toString()<< std::endl;
95 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
96 std::cerr <<
"TryToScheduleMoveOuter " << mn2->
toString() <<
97 " failed!, latest now" << latest << std::endl;
101 if (smallestRMCycle == INT_MAX) {
102 smallestRMCycle =
lc_;
104 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
105 std::cerr <<
"Latest after outer fail: " << latest << std::endl;
106 std::cerr <<
"smallest rm cycle: " << smallestRMCycle <<
110 if (latest < 0 || latest <
113 rm().initiationInterval() == 0) {
114 std::cerr <<
"Retry to too early cycle. cannot schedule: "
121 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
122 std::cerr <<
"OK or retry at earlier cycle.." << std::endl;
126 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
127 std::cerr <<
"TryToScheduleMoveOuter ok: " << mn2->
toString() <<std::endl;
133 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
134 std::cerr <<
"Schedulingfront scheduled ok!: " <<
this << std::endl;
138 if (!i->isScheduled()) {
141 std::cerr <<
"Front Has unscheduled move: "
142 << (*i).toString() << std::endl;
147 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
148 std::cerr <<
"\tNotifying scheduled: " << (*i).toString()
158 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
159 std::cerr <<
"\tMight be ready: " << n->toString() << std::endl;
171 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
172 std::cerr << std::endl <<
"\tGot: " << mn.
toString() <<
" to schedule(2)"
178 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
179 std::cerr <<
"\tShould scheudule pre-opshare to prefix: "
186 if (lcFront != -1 && lcFront <= latestCycle) {
187 latestCycle = lcFront -1;
209 latestCycle = INT_MIN;
210 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
211 std::cerr <<
"\tlatestCycle later than exact limit. failing."
218 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
219 std::cerr <<
"\tFirst all optimizations on" << std::endl;
221 int schedRes =
scheduleMove(mn, limits,
true,
true,
true);
223 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
224 std::cerr <<
"\tScheduling of: " << mn.
toString() <<
" ok "
233 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
234 std::cerr <<
"\tTOPDOWN failed, trying bottomup" << std::endl;
237 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
238 std::cerr <<
"\ttopdown back to bottomup ok" << std::endl;
243 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
244 std::cerr <<
"\tTrying without early sharing" << std::endl;
252 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
253 std::cerr <<
"\tTrying without early BP" << std::endl;
257 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
258 std::cerr <<
"\tok without early BP" << std::endl;
263 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
264 std::cerr <<
"\tTrying without early BP and without early sharing"
267 if (
scheduleMove(mn, limits,
false,
true,
false) >= 0) {
272 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
273 std::cerr <<
"\tTrying to Revert earlier bypass.."
280 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
281 std::cerr <<
"\tTrying without late BP" << std::endl;
285 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
286 std::cerr <<
"\tok without late BP" << std::endl;
290 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
291 std::cerr <<
"\tTrying without any BP" << std::endl;
295 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
296 std::cerr <<
"\tok without any BP" << std::endl;
302 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
303 std::cerr <<
"forbidding operand share: " << mn.
toString()
310 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
311 std::cerr <<
"\tScheduleMove failing, need to tr earlier cycle"
316 if (lcFront != -1 && lcFront <= latestCycle) {
317 latestCycle = lcFront -1;
323 std::cerr <<
"end of schduleMoveOuter, should not be here!" << std::endl;
330 if (mn->isScheduled() && mn->cycle() > lc) {
340 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
341 std::cerr <<
"\tGetting moveNode from front" << std::endl;
361 if (mn->isDestinationOperation()) {
362 if (mn->isLastUnscheduledMoveOfDstOp()) {
375 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
376 std::cerr <<
"\t\tSelected:" << selectedMN->
toString() << std::endl;
381 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
382 std::cerr <<
"\t\tReturning trigger instead:"
383 << trigger->
toString() << std::endl;
394 if (selectedMN != NULL) {
395 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
396 std::cerr <<
"\tSelected MN: " << selectedMN->
toString() << std::endl;
399 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
400 std::cerr <<
"Front empty, returning NULL" << std::endl;
407 int prefCycle = INT_MAX;
417 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
418 std::cerr <<
"\t\tOut node: " << outNode.
toString()
419 <<
" is scheduled!" << std::endl;
424 const int outNodeOutputIndex =
426 int onLatency = hwop.
latency(outNodeOutputIndex);
427 int latestTrigger = outNode.
cycle() - onLatency;
429 int myLatency = hwop.
latency(myOutIndex);
430 int myPreferredCycle = latestTrigger + myLatency;
431 if (myPreferredCycle < prefCycle) {
432 prefCycle = myPreferredCycle;
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;
457 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
458 std::cerr <<
"Control flow move requires exact cycle: "
459 << prefCycle << std::endl;
471 bool allowEarlyBypass,
bool allowLateBypass,
bool allowEarlySharing) {
479 allowLateBypass, allowEarlySharing);
482 std::cerr <<
"Is pre loop shared oper, sch to prolog instead: " <<
505 for (
auto mn : moves) {
520 while (!queue.empty()) {
540 if (
ddg().hasNode(*mn)) {
543 if (bypassSrc != NULL) {
544 if (nodes.find(bypassSrc) == nodes.end()) {
545 queue.insert(bypassSrc);
548 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
549 std::cerr <<
"Warning:Cannot find src for forced bypass. "
550 <<
" Inst. scheduler may fail/deadlock" <<std::endl;
557 if (
ddg().hasNode(*mn)) {
560 for (
auto n : rrDestinations) {
561 if (nodes.find(n) == nodes.end()) {
575 std::cerr <<
"DEAD ";
577 std::cerr << prefix << node->toString() << std::endl;
583 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
584 std::cerr <<
"should undo front. printing front:" << std::endl;
589 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
590 std::cerr <<
"should have cleared. printing front:" << std::endl;
597 node->setIsInFrontier(
false);
608 while (!queue.empty()) {
610 processedNodes.insert(mn);
615 if (i.second == mn) {
625 if (result != NULL) {
634 if (result != NULL) {
649 if (processedNodes.find(&inputMove) == processedNodes.end()) {
650 queue.insert(&inputMove);
657 if (processedNodes.find(&outputMove) == processedNodes.end()) {
660 if (i.second == &outputMove) {
665 queue.insert(&outputMove);
674 while (inducingBypass != NULL &&
677 if (i.second == inducingBypass) {
683 if (inducingBypass == NULL) {
686 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
687 std::cerr <<
"\t\tMaking illegal bypas of src: "
688 << inducingBypass->
toString() << std::endl;
691 #ifdef DEBUG_BUBBLEFISH_SCHEDULER
692 std::cerr <<
"\t\tIs already illegal bypass! " << std::endl;
int maximumLatency() const
MoveNodeMap bypassSources_
bool scheduleFrontFromMove(MoveNode &mn)
SchedulingDirection direction
BF2Scheduler::MoveNodeMap MoveNodeMap
DataDependenceGraph::NodeSet illegalBypassSources_
bool isDestinationVariable() const
std::string toString() const
int maxSourceDistance(const GraphNode &node) const
bool hasUnscheduledSuccessors(MoveNode &mn) const
bool isDestinationOperation() const
static bool isDestinationUniversalReg(const MoveNode &mn)
std::set< MoveNode *, typename MoveNode ::Comparator > NodeSet
virtual int smallestCycle() const override
bool isDeadResult(MoveNode &mn) const
BF2Scheduler::SchedulingLimits getPreferredLimits(const MoveNode &mn)
static MoveNode * getSisterTrigger(const MoveNode &mn, const TTAMachine::Machine &mach)
virtual void mightBeReady(MoveNode &node)
static int verboseLevel()
MoveNode * onlyRegisterRawSource(const MoveNode &mn, int allowGuardEdges=2, int backEdges=0) const
const TTAMachine::Machine & targetMachine() const
void undoOnlyMe() override
DataDependenceGraph::NodeSet schedulingFront_
void appendBypassSources(MoveNodeMap &map)
NodeSet onlyRegisterRawDestinations(const MoveNode &mn, bool allowGuardEdges=false, bool allowBackEdges=false) const
PathLengthCache pathLengthCache_
ProgramOperation & sourceOperation() const
#define assert(condition)
TTAMachine::FUPort * isPreLoopSharedOperand(MoveNode &mn) const
bool isGuardOperation() const
virtual ControlUnit * controlUnit() const
virtual int operationIndex() const
int latestScheduledOfFrontCycle()
SimpleResourceManager * prologRM() const
bool isControlFlowMove() const
void requeueOtherMovesOfSameOp(MoveNode &mn)
static bool isSourceUniversalReg(const MoveNode &mn)
void mightBeReady(MoveNode &n) override
bool tryRevertEarlierBypass(MoveNode &mn)
int scheduleMove(MoveNode &move, BF2Scheduler::SchedulingLimits limits, bool allowEarlyBypass=true, bool allowLateBypass=true, bool allowEarlySharing=true)
DataDependenceGraph::NodeSet nodesToNotify_
const TTAMachine::HWOperation * hwopFromOutMove(const MoveNode &outputNode) const
bool isSourceOperation() const
virtual bool operator()() override
DataDependenceGraph & ddg()
MoveNode * findInducingBypassSource(MoveNode &mn)
unsigned int destinationOperationCount() const
SimpleResourceManager & rm() const
bool tryToScheduleMoveOuter(MoveNode &mn, int &latestCycle)
int inputMoveCount() const
static int prefResultCycle(const MoveNode &mn)
virtual void writeToDotFile(const TCEString &fileName) const
MoveNode * findInducingBypassSourceFromOperation(ProgramOperation &po, const DataDependenceGraph::NodeSet &processedNodes, DataDependenceGraph::NodeSet &queue)
int outputMoveCount() const
ProgramOperation & destinationOperation(unsigned int index=0) const
TTAProgram::Move & move()
static void queueOperation(ProgramOperation &po, const DataDependenceGraph::NodeSet &nodes, DataDependenceGraph::NodeSet &queue)
DataDependenceGraph::NodeSet allNodesOfSameOperation(MoveNode &mn)
void printFront(const TCEString &prefix)
std::pair< MoveNode *, MoveNode * > switchedMNs()
bool runPreChild(Reversible *preChild)
DataDependenceGraph::NodeSet illegalOperandShares_
virtual void notifyScheduled(MoveNode &node)
BUMoveNodeSelector & selector()
Terminal & source() const
void clearSchedulingFront()
void setIsInFrontier(bool inFrontier=true)
MoveNode & outputMove(int index) const
MoveNode * getMoveNodeFromFrontBU()
int outputIndexOfMove(const MoveNode &mn) const
MoveNode & inputMove(int index) const
ProgramOperation & guardOperation() const