18010b631SJonas Paulsson //-- SystemZMachineScheduler.cpp - SystemZ Scheduler Interface -*- C++ -*---==// 28010b631SJonas Paulsson // 38010b631SJonas Paulsson // The LLVM Compiler Infrastructure 48010b631SJonas Paulsson // 58010b631SJonas Paulsson // This file is distributed under the University of Illinois Open Source 68010b631SJonas Paulsson // License. See LICENSE.TXT for details. 78010b631SJonas Paulsson // 88010b631SJonas Paulsson //===----------------------------------------------------------------------===// 98010b631SJonas Paulsson // 108010b631SJonas Paulsson // -------------------------- Post RA scheduling ---------------------------- // 118010b631SJonas Paulsson // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into 128010b631SJonas Paulsson // the MachineScheduler. It has a sorted Available set of SUs and a pickNode() 138010b631SJonas Paulsson // implementation that looks to optimize decoder grouping and balance the 148010b631SJonas Paulsson // usage of processor resources. 158010b631SJonas Paulsson //===----------------------------------------------------------------------===// 168010b631SJonas Paulsson 178010b631SJonas Paulsson #include "SystemZMachineScheduler.h" 188010b631SJonas Paulsson 198010b631SJonas Paulsson using namespace llvm; 208010b631SJonas Paulsson 21*0cd23f56SEvandro Menezes #define DEBUG_TYPE "machine-scheduler" 228010b631SJonas Paulsson 238010b631SJonas Paulsson #ifndef NDEBUG 248010b631SJonas Paulsson // Print the set of SUs 258010b631SJonas Paulsson void SystemZPostRASchedStrategy::SUSet:: 266da25f4fSRafael Espindola dump(SystemZHazardRecognizer &HazardRec) const { 278010b631SJonas Paulsson dbgs() << "{"; 288010b631SJonas Paulsson for (auto &SU : *this) { 298010b631SJonas Paulsson HazardRec.dumpSU(SU, dbgs()); 308010b631SJonas Paulsson if (SU != *rbegin()) 318010b631SJonas Paulsson dbgs() << ", "; 328010b631SJonas Paulsson } 338010b631SJonas Paulsson dbgs() << "}\n"; 348010b631SJonas Paulsson } 358010b631SJonas Paulsson #endif 368010b631SJonas Paulsson 378010b631SJonas Paulsson SystemZPostRASchedStrategy:: 388010b631SJonas Paulsson SystemZPostRASchedStrategy(const MachineSchedContext *C) 398010b631SJonas Paulsson : DAG(nullptr), HazardRec(C) {} 408010b631SJonas Paulsson 418010b631SJonas Paulsson void SystemZPostRASchedStrategy::initialize(ScheduleDAGMI *dag) { 428010b631SJonas Paulsson DAG = dag; 438010b631SJonas Paulsson HazardRec.setDAG(dag); 448010b631SJonas Paulsson HazardRec.Reset(); 458010b631SJonas Paulsson } 468010b631SJonas Paulsson 478010b631SJonas Paulsson // Pick the next node to schedule. 488010b631SJonas Paulsson SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) { 498010b631SJonas Paulsson // Only scheduling top-down. 508010b631SJonas Paulsson IsTopNode = true; 518010b631SJonas Paulsson 528010b631SJonas Paulsson if (Available.empty()) 538010b631SJonas Paulsson return nullptr; 548010b631SJonas Paulsson 558010b631SJonas Paulsson // If only one choice, return it. 568010b631SJonas Paulsson if (Available.size() == 1) { 578010b631SJonas Paulsson DEBUG (dbgs() << "+++ Only one: "; 588010b631SJonas Paulsson HazardRec.dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";); 598010b631SJonas Paulsson return *Available.begin(); 608010b631SJonas Paulsson } 618010b631SJonas Paulsson 628010b631SJonas Paulsson // All nodes that are possible to schedule are stored by in the 638010b631SJonas Paulsson // Available set. 648010b631SJonas Paulsson DEBUG(dbgs() << "+++ Available: "; Available.dump(HazardRec);); 658010b631SJonas Paulsson 668010b631SJonas Paulsson Candidate Best; 678010b631SJonas Paulsson for (auto *SU : Available) { 688010b631SJonas Paulsson 698010b631SJonas Paulsson // SU is the next candidate to be compared against current Best. 708010b631SJonas Paulsson Candidate c(SU, HazardRec); 718010b631SJonas Paulsson 728010b631SJonas Paulsson // Remeber which SU is the best candidate. 738010b631SJonas Paulsson if (Best.SU == nullptr || c < Best) { 748010b631SJonas Paulsson Best = c; 758010b631SJonas Paulsson DEBUG(dbgs() << "+++ Best sofar: "; 768010b631SJonas Paulsson HazardRec.dumpSU(Best.SU, dbgs()); 778010b631SJonas Paulsson if (Best.GroupingCost != 0) 788010b631SJonas Paulsson dbgs() << "\tGrouping cost:" << Best.GroupingCost; 798010b631SJonas Paulsson if (Best.ResourcesCost != 0) 808010b631SJonas Paulsson dbgs() << " Resource cost:" << Best.ResourcesCost; 818010b631SJonas Paulsson dbgs() << " Height:" << Best.SU->getHeight(); 828010b631SJonas Paulsson dbgs() << "\n";); 838010b631SJonas Paulsson } 848010b631SJonas Paulsson 858010b631SJonas Paulsson // Once we know we have seen all SUs that affect grouping or use unbuffered 868010b631SJonas Paulsson // resources, we can stop iterating if Best looks good. 878010b631SJonas Paulsson if (!SU->isScheduleHigh && Best.noCost()) 888010b631SJonas Paulsson break; 898010b631SJonas Paulsson } 908010b631SJonas Paulsson 918010b631SJonas Paulsson assert (Best.SU != nullptr); 928010b631SJonas Paulsson return Best.SU; 938010b631SJonas Paulsson } 948010b631SJonas Paulsson 958010b631SJonas Paulsson SystemZPostRASchedStrategy::Candidate:: 968010b631SJonas Paulsson Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec) : Candidate() { 978010b631SJonas Paulsson SU = SU_; 988010b631SJonas Paulsson 998010b631SJonas Paulsson // Check the grouping cost. For a node that must begin / end a 1008010b631SJonas Paulsson // group, it is positive if it would do so prematurely, or negative 1018010b631SJonas Paulsson // if it would fit naturally into the schedule. 1028010b631SJonas Paulsson GroupingCost = HazardRec.groupingCost(SU); 1038010b631SJonas Paulsson 1048010b631SJonas Paulsson // Check the resources cost for this SU. 1058010b631SJonas Paulsson ResourcesCost = HazardRec.resourcesCost(SU); 1068010b631SJonas Paulsson } 1078010b631SJonas Paulsson 1088010b631SJonas Paulsson bool SystemZPostRASchedStrategy::Candidate:: 1098010b631SJonas Paulsson operator<(const Candidate &other) { 1108010b631SJonas Paulsson 1118010b631SJonas Paulsson // Check decoder grouping. 1128010b631SJonas Paulsson if (GroupingCost < other.GroupingCost) 1138010b631SJonas Paulsson return true; 1148010b631SJonas Paulsson if (GroupingCost > other.GroupingCost) 1158010b631SJonas Paulsson return false; 1168010b631SJonas Paulsson 1178010b631SJonas Paulsson // Compare the use of resources. 1188010b631SJonas Paulsson if (ResourcesCost < other.ResourcesCost) 1198010b631SJonas Paulsson return true; 1208010b631SJonas Paulsson if (ResourcesCost > other.ResourcesCost) 1218010b631SJonas Paulsson return false; 1228010b631SJonas Paulsson 1238010b631SJonas Paulsson // Higher SU is otherwise generally better. 1248010b631SJonas Paulsson if (SU->getHeight() > other.SU->getHeight()) 1258010b631SJonas Paulsson return true; 1268010b631SJonas Paulsson if (SU->getHeight() < other.SU->getHeight()) 1278010b631SJonas Paulsson return false; 1288010b631SJonas Paulsson 1298010b631SJonas Paulsson // If all same, fall back to original order. 1308010b631SJonas Paulsson if (SU->NodeNum < other.SU->NodeNum) 1318010b631SJonas Paulsson return true; 1328010b631SJonas Paulsson 1338010b631SJonas Paulsson return false; 1348010b631SJonas Paulsson } 1358010b631SJonas Paulsson 1368010b631SJonas Paulsson void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) { 1378010b631SJonas Paulsson DEBUG(dbgs() << "+++ Scheduling SU(" << SU->NodeNum << ")\n";); 1388010b631SJonas Paulsson 1398010b631SJonas Paulsson // Remove SU from Available set and update HazardRec. 1408010b631SJonas Paulsson Available.erase(SU); 1418010b631SJonas Paulsson HazardRec.EmitInstruction(SU); 1428010b631SJonas Paulsson } 1438010b631SJonas Paulsson 1448010b631SJonas Paulsson void SystemZPostRASchedStrategy::releaseTopNode(SUnit *SU) { 1458010b631SJonas Paulsson // Set isScheduleHigh flag on all SUs that we want to consider first in 1468010b631SJonas Paulsson // pickNode(). 1478010b631SJonas Paulsson const MCSchedClassDesc *SC = DAG->getSchedClass(SU); 1488010b631SJonas Paulsson bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup)); 1498010b631SJonas Paulsson SU->isScheduleHigh = (AffectsGrouping || SU->isUnbuffered); 1508010b631SJonas Paulsson 1518010b631SJonas Paulsson // Put all released SUs in the Available set. 1528010b631SJonas Paulsson Available.insert(SU); 1538010b631SJonas Paulsson } 154