13943d2b0SEugene Zelenko //==- SystemZMachineScheduler.h - SystemZ Scheduler Interface ----*- C++ -*-==// 28010b631SJonas Paulsson // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 68010b631SJonas Paulsson // 78010b631SJonas Paulsson //===----------------------------------------------------------------------===// 88010b631SJonas Paulsson // 98010b631SJonas Paulsson // -------------------------- Post RA scheduling ---------------------------- // 108010b631SJonas Paulsson // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into 118010b631SJonas Paulsson // the MachineScheduler. It has a sorted Available set of SUs and a pickNode() 128010b631SJonas Paulsson // implementation that looks to optimize decoder grouping and balance the 1357a705d9SJonas Paulsson // usage of processor resources. Scheduler states are saved for the end 1457a705d9SJonas Paulsson // region of each MBB, so that a successor block can learn from it. 158010b631SJonas Paulsson //===----------------------------------------------------------------------===// 168010b631SJonas Paulsson 178010b631SJonas Paulsson #include "SystemZHazardRecognizer.h" 188010b631SJonas Paulsson #include "llvm/CodeGen/MachineScheduler.h" 193943d2b0SEugene Zelenko #include "llvm/CodeGen/ScheduleDAG.h" 203943d2b0SEugene Zelenko #include <set> 218010b631SJonas Paulsson 228010b631SJonas Paulsson #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H 238010b631SJonas Paulsson #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H 248010b631SJonas Paulsson 258010b631SJonas Paulsson using namespace llvm; 268010b631SJonas Paulsson 278010b631SJonas Paulsson namespace llvm { 288010b631SJonas Paulsson 298010b631SJonas Paulsson /// A MachineSchedStrategy implementation for SystemZ post RA scheduling. 308010b631SJonas Paulsson class SystemZPostRASchedStrategy : public MachineSchedStrategy { 3157a705d9SJonas Paulsson 3257a705d9SJonas Paulsson const MachineLoopInfo *MLI; 3357a705d9SJonas Paulsson const SystemZInstrInfo *TII; 3457a705d9SJonas Paulsson 3557a705d9SJonas Paulsson // A SchedModel is needed before any DAG is built while advancing past 3657a705d9SJonas Paulsson // non-scheduled instructions, so it would not always be possible to call 3757a705d9SJonas Paulsson // DAG->getSchedClass(SU). 3857a705d9SJonas Paulsson TargetSchedModel SchedModel; 398010b631SJonas Paulsson 408010b631SJonas Paulsson /// A candidate during instruction evaluation. 418010b631SJonas Paulsson struct Candidate { 423943d2b0SEugene Zelenko SUnit *SU = nullptr; 438010b631SJonas Paulsson 448010b631SJonas Paulsson /// The decoding cost. 453943d2b0SEugene Zelenko int GroupingCost = 0; 468010b631SJonas Paulsson 478010b631SJonas Paulsson /// The processor resources cost. 483943d2b0SEugene Zelenko int ResourcesCost = 0; 498010b631SJonas Paulsson 503943d2b0SEugene Zelenko Candidate() = default; 518010b631SJonas Paulsson Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec); 528010b631SJonas Paulsson 538010b631SJonas Paulsson // Compare two candidates. 548010b631SJonas Paulsson bool operator<(const Candidate &other); 558010b631SJonas Paulsson 568010b631SJonas Paulsson // Check if this node is free of cost ("as good as any"). noCostCandidate573943d2b0SEugene Zelenko bool noCost() const { 588010b631SJonas Paulsson return (GroupingCost <= 0 && !ResourcesCost); 598010b631SJonas Paulsson } 6061fbcf58SJonas Paulsson 6161fbcf58SJonas Paulsson #ifndef NDEBUG dumpCostsCandidate6261fbcf58SJonas Paulsson void dumpCosts() { 6361fbcf58SJonas Paulsson if (GroupingCost != 0) 6461fbcf58SJonas Paulsson dbgs() << " Grouping cost:" << GroupingCost; 6561fbcf58SJonas Paulsson if (ResourcesCost != 0) 6661fbcf58SJonas Paulsson dbgs() << " Resource cost:" << ResourcesCost; 6761fbcf58SJonas Paulsson } 6861fbcf58SJonas Paulsson #endif 698010b631SJonas Paulsson }; 708010b631SJonas Paulsson 718010b631SJonas Paulsson // A sorter for the Available set that makes sure that SUs are considered 728010b631SJonas Paulsson // in the best order. 738010b631SJonas Paulsson struct SUSorter { operatorSUSorter748010b631SJonas Paulsson bool operator() (SUnit *lhs, SUnit *rhs) const { 758010b631SJonas Paulsson if (lhs->isScheduleHigh && !rhs->isScheduleHigh) 768010b631SJonas Paulsson return true; 778010b631SJonas Paulsson if (!lhs->isScheduleHigh && rhs->isScheduleHigh) 788010b631SJonas Paulsson return false; 798010b631SJonas Paulsson 808010b631SJonas Paulsson if (lhs->getHeight() > rhs->getHeight()) 818010b631SJonas Paulsson return true; 828010b631SJonas Paulsson else if (lhs->getHeight() < rhs->getHeight()) 838010b631SJonas Paulsson return false; 848010b631SJonas Paulsson 858010b631SJonas Paulsson return (lhs->NodeNum < rhs->NodeNum); 868010b631SJonas Paulsson } 878010b631SJonas Paulsson }; 888010b631SJonas Paulsson // A set of SUs with a sorter and dump method. 898010b631SJonas Paulsson struct SUSet : std::set<SUnit*, SUSorter> { 908010b631SJonas Paulsson #ifndef NDEBUG 91705f798bSSam Clegg void dump(SystemZHazardRecognizer &HazardRec) const; 928010b631SJonas Paulsson #endif 938010b631SJonas Paulsson }; 948010b631SJonas Paulsson 958010b631SJonas Paulsson /// The set of available SUs to schedule next. 968010b631SJonas Paulsson SUSet Available; 978010b631SJonas Paulsson 9857a705d9SJonas Paulsson /// Current MBB 9957a705d9SJonas Paulsson MachineBasicBlock *MBB; 10057a705d9SJonas Paulsson 10157a705d9SJonas Paulsson /// Maintain hazard recognizers for all blocks, so that the scheduler state 10257a705d9SJonas Paulsson /// can be maintained past BB boundaries when appropariate. 10357a705d9SJonas Paulsson typedef std::map<MachineBasicBlock*, SystemZHazardRecognizer*> MBB2HazRec; 10457a705d9SJonas Paulsson MBB2HazRec SchedStates; 10557a705d9SJonas Paulsson 10657a705d9SJonas Paulsson /// Pointer to the HazardRecognizer that tracks the scheduler state for 10757a705d9SJonas Paulsson /// the current region. 10857a705d9SJonas Paulsson SystemZHazardRecognizer *HazardRec; 10957a705d9SJonas Paulsson 11057a705d9SJonas Paulsson /// Update the scheduler state by emitting (non-scheduled) instructions 11157a705d9SJonas Paulsson /// up to, but not including, NextBegin. 11257a705d9SJonas Paulsson void advanceTo(MachineBasicBlock::iterator NextBegin); 1138010b631SJonas Paulsson 1148010b631SJonas Paulsson public: 1158010b631SJonas Paulsson SystemZPostRASchedStrategy(const MachineSchedContext *C); 11657a705d9SJonas Paulsson virtual ~SystemZPostRASchedStrategy(); 11757a705d9SJonas Paulsson 11857a705d9SJonas Paulsson /// Called for a region before scheduling. 11957a705d9SJonas Paulsson void initPolicy(MachineBasicBlock::iterator Begin, 12057a705d9SJonas Paulsson MachineBasicBlock::iterator End, 12157a705d9SJonas Paulsson unsigned NumRegionInstrs) override; 1228010b631SJonas Paulsson 1238010b631SJonas Paulsson /// PostRA scheduling does not track pressure. shouldTrackPressure()1248010b631SJonas Paulsson bool shouldTrackPressure() const override { return false; } 1258010b631SJonas Paulsson 12657a705d9SJonas Paulsson // Process scheduling regions top-down so that scheduler states can be 12757a705d9SJonas Paulsson // transferrred over scheduling boundaries. doMBBSchedRegionsTopDown()12857a705d9SJonas Paulsson bool doMBBSchedRegionsTopDown() const override { return true; } 12957a705d9SJonas Paulsson 13061fbcf58SJonas Paulsson void initialize(ScheduleDAGMI *dag) override; 13157a705d9SJonas Paulsson 13257a705d9SJonas Paulsson /// Tell the strategy that MBB is about to be processed. 13357a705d9SJonas Paulsson void enterMBB(MachineBasicBlock *NextMBB) override; 13457a705d9SJonas Paulsson 13557a705d9SJonas Paulsson /// Tell the strategy that current MBB is done. 13657a705d9SJonas Paulsson void leaveMBB() override; 1378010b631SJonas Paulsson 1388010b631SJonas Paulsson /// Pick the next node to schedule, or return NULL. 1398010b631SJonas Paulsson SUnit *pickNode(bool &IsTopNode) override; 1408010b631SJonas Paulsson 1418010b631SJonas Paulsson /// ScheduleDAGMI has scheduled an instruction - tell HazardRec 1428010b631SJonas Paulsson /// about it. 1438010b631SJonas Paulsson void schedNode(SUnit *SU, bool IsTopNode) override; 1448010b631SJonas Paulsson 1458010b631SJonas Paulsson /// SU has had all predecessor dependencies resolved. Put it into 1468010b631SJonas Paulsson /// Available. 1478010b631SJonas Paulsson void releaseTopNode(SUnit *SU) override; 1488010b631SJonas Paulsson 1498010b631SJonas Paulsson /// Currently only scheduling top-down, so this method is empty. releaseBottomNode(SUnit * SU)1508010b631SJonas Paulsson void releaseBottomNode(SUnit *SU) override {}; 1518010b631SJonas Paulsson }; 1528010b631SJonas Paulsson 1533943d2b0SEugene Zelenko } // end namespace llvm 1548010b631SJonas Paulsson 1553943d2b0SEugene Zelenko #endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H 156