• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "list_scheduler.h"
17 
18 namespace maplebe {
19 uint32 ListScheduler::lastSchedInsnId = 0;
20 
DoListScheduling()21 void ListScheduler::DoListScheduling()
22 {
23     Init();
24 
25     if (doDelayHeuristics) {
26         /* Compute delay priority of all candidates */
27         ComputeDelayPriority();
28     }
29 
30     if (LIST_SCHEDULE_DUMP || isUnitTest) {
31         LogInfo::MapleLogger() << "##  --- schedule bb_" << curCDGNode->GetBB()->GetId() << " ---\n\n";
32         if (doDelayHeuristics) {
33             DumpDelay();
34         }
35         LogInfo::MapleLogger() << "    >>  dependencies resolved: ";
36     }
37 
38     // Push depNodes whose dependencies resolved into waitingQueue
39     CandidateToWaitingQueue();
40 
41     ComputeEStart(currCycle);
42 
43     // Iterate until the instructions in the current BB are scheduled
44     while (scheduledNodeNum < curCDGNode->GetInsnNum()) {
45         UpdateInfoBeforeSelectNode();
46 
47         if (LIST_SCHEDULE_DUMP || isUnitTest) {
48             LogInfo::MapleLogger() << "\n\n '' current cycle: " << currCycle << "\n\n";
49             DumpWaitingQueue();
50         }
51 
52         // Push depNodes whose resources are free from waitingQueue into readyList
53         WaitingQueueToReadyList();
54 
55         if (LIST_SCHEDULE_DUMP || isUnitTest) {
56             LogInfo::MapleLogger() << "    >>  After waitingQueue to readyList: {";
57             DumpReadyList();
58         }
59 
60         // If there are no ready insns, stall until one is ready
61         if (readyList.empty()) {
62             advancedCycle = 1;
63             continue;
64         }
65 
66         CalculateMostUsedUnitKindCount();
67 
68         if (!doDelayHeuristics) {
69             // Update LStart
70             ComputeLStart();
71             if (LIST_SCHEDULE_DUMP || isUnitTest) {
72                 DumpEStartLStartOfAllNodes();
73             }
74         }
75 
76         // Sort the readyList by priority from highest to lowest
77         SortReadyList();
78 
79         if (LIST_SCHEDULE_DUMP || isUnitTest) {
80             LogInfo::MapleLogger() << "    >>  ReadyList after sort: {";
81             DumpReadyList();
82         }
83 
84         // Select the ready node with the highest priority
85         DepNode *schedNode = *readyList.begin();
86         CHECK_FATAL(schedNode != nullptr, "select readyNode failed");
87         if (LIST_SCHEDULE_DUMP || isUnitTest) {
88             LogInfo::MapleLogger() << "    >>  Select node: insn_" << schedNode->GetInsn()->GetId() << "\n\n";
89         }
90 
91         if (schedNode->GetInsn()->GetBB()->GetId() == curCDGNode->GetBB()->GetId()) {
92             scheduledNodeNum++;
93         }
94         UpdateInfoAfterSelectNode(*schedNode);
95     }
96     commonSchedInfo = nullptr;
97 }
98 
Init()99 void ListScheduler::Init()
100 {
101     DEBUG_ASSERT(region != nullptr, "invalid region");
102     DEBUG_ASSERT(curCDGNode != nullptr, "invalid cdgNode");
103     DEBUG_ASSERT(commonSchedInfo != nullptr, "invalid common scheduling info");
104 
105     mad = Globals::GetInstance()->GetMAD();
106 
107     waitingQueue.clear();
108     readyList.clear();
109 
110     mad->ReleaseAllUnits();
111     currCycle = 0;
112     advancedCycle = 0;
113     scheduledNodeNum = 0;
114 
115     MapleVector<DepNode *> &candidates = commonSchedInfo->GetCandidates();
116     // Set the initial earliest time of all nodes to 0
117     for (auto *depNode : candidates) {
118         depNode->SetEStart(0);
119     }
120 
121     lastSchedInsnId = 0;
122 }
123 
CandidateToWaitingQueue()124 void ListScheduler::CandidateToWaitingQueue()
125 {
126     MapleVector<DepNode *> &candidates = commonSchedInfo->GetCandidates();
127     auto candiIter = candidates.begin();
128     while (candiIter != candidates.end()) {
129         DepNode *candiNode = *candiIter;
130         // dependencies resolved
131         if (candiNode->GetValidPredsSize() == 0) {
132             if (LIST_SCHEDULE_DUMP || isUnitTest) {
133                 LogInfo::MapleLogger() << "insn_" << candiNode->GetInsn()->GetId() << ", ";
134             }
135             (void)waitingQueue.emplace_back(candiNode);
136             candiNode->SetState(kWaiting);
137             candiIter = commonSchedInfo->EraseIterFromCandidates(candiIter);
138         } else {
139             ++candiIter;
140         }
141     }
142 }
143 
WaitingQueueToReadyList()144 void ListScheduler::WaitingQueueToReadyList()
145 {
146     auto waitingIter = waitingQueue.begin();
147     while (waitingIter != waitingQueue.end()) {
148         DepNode *waitingNode = *waitingIter;
149         // Just check whether the current cycle is free, because
150         // the rightmost bit of occupyTable always indicates curCycle
151         if (((cgFunc.IsAfterRegAlloc() && waitingNode->IsResourceIdle()) || !cgFunc.IsAfterRegAlloc()) &&
152             waitingNode->GetEStart() <= currCycle) {
153             (void)readyList.emplace_back(waitingNode);
154             waitingNode->SetState(kReady);
155             waitingIter = EraseIterFromWaitingQueue(waitingIter);
156         } else {
157             ++waitingIter;
158         }
159     }
160 }
161 
162 static uint32 kMaxUnitIdx = 0;
163 // Sort by priority in descending order, which use LStart as algorithm of computing priority,
164 // that is the first node in list has the highest priority
CriticalPathRankScheduleInsns(const DepNode * node1,const DepNode * node2)165 bool ListScheduler::CriticalPathRankScheduleInsns(const DepNode *node1, const DepNode *node2)
166 {
167     // p as an acronym for priority
168     CompareLStart compareLStart;
169     int p1 = compareLStart(*node1, *node2);
170     if (p1 != 0) {
171         return p1 > 0;
172     }
173 
174     CompareCost compareCost;
175     int p2 = compareCost(*node1, *node2);
176     if (p2 != 0) {
177         return p2 > 0;
178     }
179 
180     CompareEStart compareEStart;
181     int p3 = compareEStart(*node1, *node2);
182     if (p3 != 0) {
183         return p3 > 0;
184     }
185 
186     CompareSuccNodeSize compareSuccNodeSize;
187     int p4 = compareSuccNodeSize(*node1, *node2);
188     if (p4 != 0) {
189         return p4 > 0;
190     }
191 
192     CompareUnitKindNum compareUnitKindNum(kMaxUnitIdx);
193     int p5 = compareUnitKindNum(*node1, *node2);
194     if (p5 != 0) {
195         return p5 > 0;
196     }
197 
198     CompareSlotType compareSlotType;
199     int p6 = compareSlotType(*node1, *node2);
200     if (p6 != 0) {
201         return p6 > 0;
202     }
203 
204     CompareInsnID compareInsnId;
205     int p7 = compareInsnId(*node1, *node2);
206     if (p7 != 0) {
207         return p7 > 0;
208     }
209 
210     // default
211     return true;
212 }
213 
UpdateInfoBeforeSelectNode()214 void ListScheduler::UpdateInfoBeforeSelectNode()
215 {
216     while (advancedCycle > 0) {
217         currCycle++;
218         // Update the occupation of cpu units
219         mad->AdvanceOneCycleForAll();
220         advancedCycle--;
221     }
222     // Fall back to the waitingQueue if the depNode in readyList has resources conflict
223     UpdateNodesInReadyList();
224 }
225 
SortReadyList()226 void ListScheduler::SortReadyList()
227 {
228     // Use default rank rules
229     if (rankScheduleInsns == nullptr) {
230         if (doDelayHeuristics) {
231             std::sort(readyList.begin(), readyList.end(), DelayRankScheduleInsns);
232         } else {
233             std::sort(readyList.begin(), readyList.end(), CriticalPathRankScheduleInsns);
234         }
235     } else {
236         // Use custom rank rules
237         std::sort(readyList.begin(), readyList.end(), rankScheduleInsns);
238     }
239 }
240 
UpdateEStart(DepNode & schedNode)241 void ListScheduler::UpdateEStart(DepNode &schedNode)
242 {
243     std::vector<DepNode *> traversalList;
244     (void)traversalList.emplace_back(&schedNode);
245 
246     while (!traversalList.empty()) {
247         DepNode *curNode = traversalList.front();
248         traversalList.erase(traversalList.begin());
249 
250         for (auto succLink : curNode->GetSuccs()) {
251             DepNode &succNode = succLink->GetTo();
252             DEBUG_ASSERT(succNode.GetState() != kScheduled, "invalid state of depNode");
253             succNode.SetEStart(std::max(succNode.GetEStart(), schedNode.GetSchedCycle() + succLink->GetLatency()));
254             maxEStart = std::max(maxEStart, succNode.GetEStart());
255             if (!succNode.GetSuccs().empty() &&
256                 std::find(traversalList.begin(), traversalList.end(), &succNode) == traversalList.end()) {
257                 (void)traversalList.emplace_back(&succNode);
258             }
259         }
260     }
261 }
262 
UpdateInfoAfterSelectNode(DepNode & schedNode)263 void ListScheduler::UpdateInfoAfterSelectNode(DepNode &schedNode)
264 {
265     schedNode.SetState(kScheduled);
266     schedNode.SetSchedCycle(currCycle);
267     if (cgFunc.IsAfterRegAlloc()) {
268         schedNode.OccupyRequiredUnits();
269     }
270     schedNode.SetEStart(currCycle);
271     commonSchedInfo->AddSchedResults(&schedNode);
272     lastSchedInsnId = schedNode.GetInsn()->GetId();
273     lastSchedNode = &schedNode;
274     EraseNodeFromReadyList(&schedNode);
275     UpdateAdvanceCycle(schedNode);
276 
277     if (LIST_SCHEDULE_DUMP || isUnitTest) {
278         LogInfo::MapleLogger() << "    >>  dependencies resolved: {";
279     }
280     for (auto succLink : schedNode.GetSuccs()) {
281         DepNode &succNode = succLink->GetTo();
282         succNode.DecreaseValidPredsSize();
283         // Push depNodes whose dependencies resolved from candidates into waitingQueue
284         if (succNode.GetValidPredsSize() == 0 && succNode.GetState() == kCandidate) {
285             if (LIST_SCHEDULE_DUMP || isUnitTest) {
286                 LogInfo::MapleLogger() << "insn_" << succNode.GetInsn()->GetId() << ", ";
287             }
288             (void)waitingQueue.emplace_back(&succNode);
289             commonSchedInfo->EraseNodeFromCandidates(&succNode);
290             succNode.SetState(kWaiting);
291         }
292     }
293 
294     UpdateEStart(schedNode);
295 
296     if (LIST_SCHEDULE_DUMP || isUnitTest) {
297         LogInfo::MapleLogger() << "}\n\n";
298         DumpScheduledResult();
299         LogInfo::MapleLogger() << "'' issue insn_" << schedNode.GetInsn()->GetId() << " [ ";
300         schedNode.GetInsn()->Dump();
301         LogInfo::MapleLogger() << " ] "
302                                << " at cycle " << currCycle << "\n\n";
303     }
304 
305     // Add comment
306     Insn *schedInsn = schedNode.GetInsn();
307     DEBUG_ASSERT(schedInsn != nullptr, "get schedInsn from schedNode failed");
308     Reservation *res = schedNode.GetReservation();
309     DEBUG_ASSERT(res != nullptr, "get reservation of insn failed");
310     schedInsn->AppendComment(std::string("run on cycle: ")
311                                  .append(std::to_string(schedNode.GetSchedCycle()))
312                                  .append("; ")
313                                  .append(std::string("cost: "))
314                                  .append(std::to_string(res->GetLatency()))
315                                  .append("; "));
316     schedInsn->AppendComment(std::string("from bb: ").append(std::to_string(schedInsn->GetBB()->GetId())));
317 }
318 
UpdateNodesInReadyList()319 void ListScheduler::UpdateNodesInReadyList()
320 {
321     auto readyIter = readyList.begin();
322     while (readyIter != readyList.end()) {
323         DepNode *readyNode = *readyIter;
324         CHECK_NULL_FATAL(lastSchedNode);
325         // In globalSchedule before RA, we do not consider resource conflict in pipeline
326         if ((cgFunc.IsAfterRegAlloc() && !readyNode->IsResourceIdle()) || readyNode->GetEStart() > currCycle) {
327             if (LIST_SCHEDULE_DUMP || isUnitTest) {
328                 LogInfo::MapleLogger() << "    >>  ReadyList -> WaitingQueue: insn_" << readyNode->GetInsn()->GetId()
329                                        << " (resource conflict)\n\n";
330             }
331             (void)waitingQueue.emplace_back(readyNode);
332             readyNode->SetState(kWaiting);
333             readyIter = EraseIterFromReadyList(readyIter);
334         } else {
335             ++readyIter;
336         }
337     }
338 }
339 
UpdateAdvanceCycle(const DepNode & schedNode)340 void ListScheduler::UpdateAdvanceCycle(const DepNode &schedNode)
341 {
342     switch (schedNode.GetInsn()->GetLatencyType()) {
343         case kLtClinit:
344             advancedCycle = kClinitAdvanceCycle;
345             break;
346         case kLtAdrpLdr:
347             advancedCycle = kAdrpLdrAdvanceCycle;
348             break;
349         case kLtClinitTail:
350             advancedCycle = kClinitTailAdvanceCycle;
351             break;
352         default:
353             break;
354     }
355 
356     if (advancedCycle == 0 && mad->IsFullIssued()) {
357         advancedCycle = 1;
358     }
359 }
360 
361 // Compute the delay of the depNode by postorder, which is calculated only once before scheduling,
362 // and the delay of the leaf node is initially set to 0 or execTime
ComputeDelayPriority()363 void ListScheduler::ComputeDelayPriority()
364 {
365     std::vector<DepNode *> traversalList;
366     MapleVector<DepNode *> &candidates = commonSchedInfo->GetCandidates();
367     for (auto *depNode : candidates) {
368         if (depNode->GetSuccs().empty()) {  // Leaf node
369             depNode->SetDelay(static_cast<uint32>(depNode->GetReservation()->GetLatency()));
370             (void)traversalList.emplace_back(depNode);
371         } else {
372             depNode->SetDelay(0);
373         }
374     }
375 
376     // Compute delay from leaf node to root node
377     while (!traversalList.empty()) {
378         DepNode *depNode = traversalList.front();
379         traversalList.erase(traversalList.begin());
380 
381         for (const auto *predLink : depNode->GetPreds()) {
382             DepNode &predNode = predLink->GetFrom();
383             // Consider the cumulative effect of nodes on the critical path
384             predNode.SetDelay(std::max(predLink->GetLatency() + depNode->GetDelay(), predNode.GetDelay()));
385             maxDelay = std::max(maxDelay, predNode.GetDelay());
386             predNode.DecreaseValidSuccsSize();
387             if (predNode.GetValidSuccsSize() == 0) {
388                 (void)traversalList.emplace_back(&predNode);
389             }
390         }
391     }
392 }
393 
InitInfoBeforeCompEStart(uint32 cycle,std::vector<DepNode * > & traversalList)394 void ListScheduler::InitInfoBeforeCompEStart(uint32 cycle, std::vector<DepNode *> &traversalList)
395 {
396     for (CDGNode *cdgNode : region->GetRegionNodes()) {
397         for (auto *depNode : cdgNode->GetAllDataNodes()) {
398             depNode->SetTopoPredsSize(static_cast<uint32>(depNode->GetPreds().size()));
399             if (depNode->GetState() != kScheduled) {
400                 depNode->SetEStart(cycle);
401             }
402             if (depNode->GetTopoPredsSize() == 0) {
403                 (void)traversalList.emplace_back(depNode);
404             }
405         }
406     }
407 }
408 
409 // Compute the earliest start cycle of the instruction.
410 // Regardless of whether the LStart heuristic is used, EStart always needs to be calculated,
411 // which indicates the cycles required for an insn to wait because of the resource conflict.
ComputeEStart(uint32 cycle)412 void ListScheduler::ComputeEStart(uint32 cycle)
413 {
414     std::vector<DepNode *> traversalList;
415     InitInfoBeforeCompEStart(cycle, traversalList);
416 
417     // Compute the eStart of each depNode in the topology sequence
418     while (!traversalList.empty()) {
419         DepNode *depNode = traversalList.front();
420         traversalList.erase(traversalList.begin());
421 
422         for (const auto *succLink : depNode->GetSuccs()) {
423             DepNode &succNode = succLink->GetTo();
424             succNode.DecreaseTopoPredsSize();
425 
426             if (succNode.GetState() != kScheduled) {
427                 succNode.SetEStart(std::max(depNode->GetEStart() + succLink->GetLatency(), succNode.GetEStart()));
428             }
429             maxEStart = std::max(succNode.GetEStart(), maxEStart);
430 
431             if (succNode.GetTopoPredsSize() == 0) {
432                 (void)traversalList.emplace_back(&succNode);
433             }
434         }
435     }
436     if (maxEStart < cycle) {
437         maxEStart = cycle;
438     }
439 }
440 
InitInfoBeforeCompLStart(std::vector<DepNode * > & traversalList)441 void ListScheduler::InitInfoBeforeCompLStart(std::vector<DepNode *> &traversalList)
442 {
443     for (CDGNode *cdgNode : region->GetRegionNodes()) {
444         for (auto *depNode : cdgNode->GetAllDataNodes()) {
445             if (depNode->GetState() != kScheduled) {
446                 depNode->SetLStart(maxEStart);
447             }
448             depNode->SetValidSuccsSize(static_cast<uint32>(depNode->GetSuccs().size()));
449             if (depNode->GetSuccs().empty()) {
450                 (void)traversalList.emplace_back(depNode);
451             }
452         }
453     }
454 }
455 
456 // Compute the latest start cycle of the instruction, which
457 // is dynamically recalculated based on the current maxEStart during scheduling.
ComputeLStart()458 void ListScheduler::ComputeLStart()
459 {
460     maxLStart = maxEStart;
461 
462     MapleVector<DepNode *> &candidates = commonSchedInfo->GetCandidates();
463     if (candidates.empty() && waitingQueue.empty()) {
464         return;
465     }
466 
467     // Push leaf nodes into traversalList
468     std::vector<DepNode *> traversalList;
469     InitInfoBeforeCompLStart(traversalList);
470 
471     // Compute the lStart of all nodes in the topology sequence
472     while (!traversalList.empty()) {
473         DepNode *depNode = traversalList.front();
474         traversalList.erase(traversalList.begin());
475 
476         for (const auto predLink : depNode->GetPreds()) {
477             DepNode &predNode = predLink->GetFrom();
478 
479             if (predNode.GetState() != kScheduled) {
480                 predNode.SetLStart(std::min(depNode->GetLStart() - predLink->GetLatency(), predNode.GetLStart()));
481             }
482             maxLStart = std::max(maxLStart, predNode.GetLStart());
483 
484             predNode.DecreaseValidSuccsSize();
485             if (predNode.GetValidSuccsSize() == 0) {
486                 traversalList.emplace_back(&predNode);
487             }
488         }
489     }
490 }
491 
492 // Calculate the most used unitKind index
CalculateMostUsedUnitKindCount()493 void ListScheduler::CalculateMostUsedUnitKindCount()
494 {
495     std::array<uint32, kUnitKindLast> unitKindCount = {0};
496     for (auto *depNode : readyList) {
497         CountUnitKind(*depNode, unitKindCount);
498     }
499 
500     uint32 maxCount = 0;
501     kMaxUnitIdx = 0;
502     for (uint32 i = 1; i < kUnitKindLast; ++i) {
503         if (maxCount < unitKindCount[i]) {
504             maxCount = unitKindCount[i];
505             kMaxUnitIdx = i;
506         }
507     }
508 }
509 
510 // The index of unitKindCount is unitKind, the element of unitKindCount is count of the unitKind
CountUnitKind(const DepNode & depNode,std::array<uint32,kUnitKindLast> & unitKindCount) const511 void ListScheduler::CountUnitKind(const DepNode &depNode, std::array<uint32, kUnitKindLast> &unitKindCount) const
512 {
513     uint32 unitKind = depNode.GetUnitKind();
514     auto index = static_cast<uint32>(__builtin_ffs(static_cast<int>(unitKind)));
515     while (index != 0) {
516         DEBUG_ASSERT(index < kUnitKindLast, "invalid unitKind index");
517         ++unitKindCount[index];
518         unitKind &= ~(1u << (index - 1u));
519         index = static_cast<uint32>(__builtin_ffs(static_cast<int>(unitKind)));
520     }
521 }
522 
DumpWaitingQueue() const523 void ListScheduler::DumpWaitingQueue() const
524 {
525     LogInfo::MapleLogger() << "    >>  waitingQueue: {";
526     for (uint32 i = 0; i < waitingQueue.size(); ++i) {
527         Insn *waitInsn = waitingQueue[i]->GetInsn();
528         DEBUG_ASSERT(waitInsn != nullptr, "get insn from depNode failed");
529         LogInfo::MapleLogger() << "insn_" << waitInsn->GetId();
530         CHECK_FATAL(waitingQueue.size() > 0, "must not be zero");
531         if (i != waitingQueue.size() - 1) {
532             LogInfo::MapleLogger() << ", ";
533         }
534     }
535     LogInfo::MapleLogger() << "}\n\n";
536 }
537 
DumpReadyList() const538 void ListScheduler::DumpReadyList() const
539 {
540     for (uint32 i = 0; i < readyList.size(); ++i) {
541         Insn *readyInsn = readyList[i]->GetInsn();
542         DEBUG_ASSERT(readyInsn != nullptr, "get insn from depNode failed");
543         if (doDelayHeuristics) {
544             LogInfo::MapleLogger() << "insn_" << readyInsn->GetId() << "(Delay = " << readyList[i]->GetDelay() << ")";
545         } else {
546             LogInfo::MapleLogger() << "insn_" << readyInsn->GetId() << "(EStart = " << readyList[i]->GetEStart()
547                                    << ", LStart = " << readyList[i]->GetLStart() << ")";
548         }
549         CHECK_FATAL(readyList.size() > 0, "must not be zero");
550         if (i != readyList.size() - 1) {
551             LogInfo::MapleLogger() << ", ";
552         }
553     }
554     LogInfo::MapleLogger() << "}\n\n";
555 }
556 
DumpScheduledResult() const557 void ListScheduler::DumpScheduledResult() const
558 {
559     LogInfo::MapleLogger() << "    >>  scheduledResult: {";
560     for (uint32 i = 0; i < commonSchedInfo->GetSchedResultsSize(); ++i) {
561         Insn *schedInsn = commonSchedInfo->GetSchedResults()[i]->GetInsn();
562         DEBUG_ASSERT(schedInsn != nullptr, "get insn from depNode failed");
563         LogInfo::MapleLogger() << "insn_" << schedInsn->GetId();
564         CHECK_FATAL(commonSchedInfo->GetSchedResultsSize() > 0, "must not be zero");
565         if (i != commonSchedInfo->GetSchedResultsSize() - 1) {
566             LogInfo::MapleLogger() << ", ";
567         }
568     }
569     LogInfo::MapleLogger() << "}\n\n";
570 }
571 
DumpDelay() const572 void ListScheduler::DumpDelay() const
573 {
574     BB *curBB = curCDGNode->GetBB();
575     DEBUG_ASSERT(curBB != nullptr, "get bb from cdgNode failed");
576     LogInfo::MapleLogger() << "        >> Delay priority of readyList in bb_" << curBB->GetId() << "\n";
577     LogInfo::MapleLogger() << "     --------------------------------------------------------\n";
578     (void)LogInfo::MapleLogger().fill(' ');
579     LogInfo::MapleLogger() << "      " << std::setiosflags(std::ios::left) << std::setw(kNumEight) << "insn"
580                            << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right)
581                            << std::setw(kNumFour) << "bb" << std::resetiosflags(std::ios::right)
582                            << std::setiosflags(std::ios::right) << std::setw(kNumTen) << "predDepSize"
583                            << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
584                            << std::setw(kNumTen) << "delay" << std::resetiosflags(std::ios::right)
585                            << std::setiosflags(std::ios::right) << std::setw(kNumEight) << "cost"
586                            << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
587                            << std::setw(kNumFifteen) << "reservation" << std::resetiosflags(std::ios::right) << "\n";
588     LogInfo::MapleLogger() << "     --------------------------------------------------------\n";
589     for (auto depNode : commonSchedInfo->GetCandidates()) {
590         Insn *insn = depNode->GetInsn();
591         ASSERT_NOT_NULL(insn);
592         uint32 predSize = depNode->GetValidPredsSize();
593         uint32 delay = depNode->GetDelay();
594         ASSERT_NOT_NULL(mad);
595         ASSERT_NOT_NULL(mad->FindReservation(*insn));
596         int latency = mad->FindReservation(*insn)->GetLatency();
597         LogInfo::MapleLogger() << "      " << std::setiosflags(std::ios::left) << std::setw(kNumEight) << insn->GetId()
598                                << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right)
599                                << std::setw(kNumFour) << curBB->GetId() << std::resetiosflags(std::ios::right)
600                                << std::setiosflags(std::ios::right) << std::setw(kNumTen) << predSize
601                                << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
602                                << std::setw(kNumTen) << delay << std::resetiosflags(std::ios::right)
603                                << std::setiosflags(std::ios::right) << std::setw(kNumEight) << latency
604                                << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
605                                << std::setw(kNumFifteen);
606         DumpReservation(*depNode);
607         LogInfo::MapleLogger() << std::resetiosflags(std::ios::right) << "\n";
608     }
609     LogInfo::MapleLogger() << "     --------------------------------------------------------\n\n";
610 }
611 
DumpEStartLStartOfAllNodes()612 void ListScheduler::DumpEStartLStartOfAllNodes()
613 {
614     BB *curBB = curCDGNode->GetBB();
615     DEBUG_ASSERT(curBB != nullptr, "get bb from cdgNode failed");
616     LogInfo::MapleLogger() << "    >> max EStart: " << maxEStart << "\n\n";
617     LogInfo::MapleLogger() << "              >> CP priority of readyList in bb_" << curBB->GetId() << "\n";
618     LogInfo::MapleLogger() << "     --------------------------------------------------------------------------\n";
619     (void)LogInfo::MapleLogger().fill(' ');
620     LogInfo::MapleLogger() << "      " << std::setiosflags(std::ios::left) << std::setw(kNumEight) << "insn"
621                            << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right)
622                            << std::setw(kNumFour) << "bb" << std::resetiosflags(std::ios::right)
623                            << std::setiosflags(std::ios::right) << std::setw(kNumEight) << "state"
624                            << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
625                            << std::setw(kNumTwelve) << "predDepSize" << std::resetiosflags(std::ios::right)
626                            << std::setiosflags(std::ios::right) << std::setw(kNumTen) << "EStart"
627                            << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
628                            << std::setw(kNumTen) << "LStart" << std::resetiosflags(std::ios::right)
629                            << std::setiosflags(std::ios::right) << std::setw(kNumEight) << "cost"
630                            << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
631                            << std::setw(kNumFifteen) << "reservation" << std::resetiosflags(std::ios::right) << "\n";
632     LogInfo::MapleLogger() << "     --------------------------------------------------------------------------\n";
633     DumpDepNodeInfo(*curBB, commonSchedInfo->GetCandidates(), "candi");
634     DumpDepNodeInfo(*curBB, waitingQueue, "wait");
635     DumpDepNodeInfo(*curBB, readyList, "ready");
636     LogInfo::MapleLogger() << "     --------------------------------------------------------------------------\n\n";
637 }
638 
DumpDepNodeInfo(const BB & curBB,MapleVector<DepNode * > & nodes,const std::string state) const639 void ListScheduler::DumpDepNodeInfo(const BB &curBB, MapleVector<DepNode *> &nodes, const std::string state) const
640 {
641     for (auto depNode : nodes) {
642         Insn *insn = depNode->GetInsn();
643         DEBUG_ASSERT(insn != nullptr, "get insn from depNode failed");
644         uint32 predSize = depNode->GetValidPredsSize();
645         uint32 eStart = depNode->GetEStart();
646         uint32 lStart = depNode->GetLStart();
647         ASSERT_NOT_NULL(mad->FindReservation(*insn));
648         int latency = mad->FindReservation(*insn)->GetLatency();
649         (void)LogInfo::MapleLogger().fill(' ');
650         LogInfo::MapleLogger() << "      " << std::setiosflags(std::ios::left) << std::setw(kNumEight) << insn->GetId()
651                                << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right)
652                                << std::setw(kNumFour) << curBB.GetId() << std::resetiosflags(std::ios::right)
653                                << std::setiosflags(std::ios::right) << std::setw(kNumEight) << state
654                                << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
655                                << std::setw(kNumTwelve) << predSize << std::resetiosflags(std::ios::right)
656                                << std::setiosflags(std::ios::right) << std::setw(kNumTen) << eStart
657                                << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
658                                << std::setw(kNumTen) << lStart << std::resetiosflags(std::ios::right)
659                                << std::setiosflags(std::ios::right) << std::setw(kNumEight) << latency
660                                << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::right)
661                                << std::setw(kNumFour) << " ";
662         DumpReservation(*depNode);
663         LogInfo::MapleLogger() << std::resetiosflags(std::ios::right) << "\n";
664     }
665 }
666 
DumpReservation(const DepNode & depNode) const667 void ListScheduler::DumpReservation(const DepNode &depNode) const
668 {
669     for (uint32 i = 0; i < depNode.GetUnitNum(); ++i) {
670         UnitId unitId = depNode.GetUnitByIndex(i)->GetUnitId();
671         switch (unitId) {
672             case kUnitIdSlot0:
673                 LogInfo::MapleLogger() << "slot0";
674                 break;
675             case kUnitIdSlot1:
676                 LogInfo::MapleLogger() << "slot1";
677                 break;
678             case kUnitIdAgen:
679                 LogInfo::MapleLogger() << "agen";
680                 break;
681             case kUnitIdHazard:
682                 LogInfo::MapleLogger() << "hazard";
683                 break;
684             case kUnitIdCrypto:
685                 LogInfo::MapleLogger() << "crypto";
686                 break;
687             case kUnitIdMul:
688                 LogInfo::MapleLogger() << "mul";
689                 break;
690             case kUnitIdDiv:
691                 LogInfo::MapleLogger() << "div";
692                 break;
693             case kUnitIdBranch:
694                 LogInfo::MapleLogger() << "branch";
695                 break;
696             case kUnitIdStAgu:
697                 LogInfo::MapleLogger() << "stAgu";
698                 break;
699             case kUnitIdLdAgu:
700                 LogInfo::MapleLogger() << "ldAgu";
701                 break;
702             case kUnitIdFpAluLo:
703                 LogInfo::MapleLogger() << "fpAluLo";
704                 break;
705             case kUnitIdFpAluHi:
706                 LogInfo::MapleLogger() << "fpAluHi";
707                 break;
708             case kUnitIdFpMulLo:
709                 LogInfo::MapleLogger() << "fpMulLo";
710                 break;
711             case kUnitIdFpMulHi:
712                 LogInfo::MapleLogger() << "fpMulHi";
713                 break;
714             case kUnitIdFpDivLo:
715                 LogInfo::MapleLogger() << "fpDivLo";
716                 break;
717             case kUnitIdFpDivHi:
718                 LogInfo::MapleLogger() << "fpDivHi";
719                 break;
720             case kUnitIdSlotS:
721                 LogInfo::MapleLogger() << "slot0 | slot1";
722                 break;
723             case kUnitIdFpAluS:
724                 LogInfo::MapleLogger() << "fpAluLo | fpAluHi";
725                 break;
726             case kUnitIdFpMulS:
727                 LogInfo::MapleLogger() << "fpMulLo | fpMulHi";
728                 break;
729             case kUnitIdFpDivS:
730                 LogInfo::MapleLogger() << "fpDivLo | fpDivHi";
731                 break;
732             case kUnitIdSlotD:
733                 LogInfo::MapleLogger() << "slot0 & slot1";
734                 break;
735             case kUnitIdFpAluD:
736                 LogInfo::MapleLogger() << "fpAluLo & fpAluHi";
737                 break;
738             case kUnitIdFpMulD:
739                 LogInfo::MapleLogger() << "fpMulLo & fpMulHi";
740                 break;
741             case kUnitIdFpDivD:
742                 LogInfo::MapleLogger() << "fpMulLo & fpMulHi";
743                 break;
744             case kUnitIdSlotSHazard:
745                 LogInfo::MapleLogger() << "(slot0 | slot1) & hazard";
746                 break;
747             case kUnitIdSlotSMul:
748                 LogInfo::MapleLogger() << "(slot0 | slot1) & mul";
749                 break;
750             case kUnitIdSlotSBranch:
751                 LogInfo::MapleLogger() << "(slot0 | slot1) & branch";
752                 break;
753             case kUnitIdSlotSAgen:
754                 LogInfo::MapleLogger() << "(slot0 | slot1) & agen";
755                 break;
756             case kUnitIdSlotDAgen:
757                 LogInfo::MapleLogger() << "slot0 & slot1 & agen";
758                 break;
759             case kUnitIdSlot0LdAgu:
760                 LogInfo::MapleLogger() << "slot0 & ldAgu";
761                 break;
762             case kUnitIdSlot0StAgu:
763                 LogInfo::MapleLogger() << "slot0 & stAgu";
764                 break;
765             default:
766                 LogInfo::MapleLogger() << "unknown";
767                 break;
768         }
769         if (i != depNode.GetUnitNum() - 1) {
770             LogInfo::MapleLogger() << ", ";
771         }
772     }
773 }
774 }  // namespace maplebe
775