1*3943d2b0SEugene Zelenko //==- SystemZMachineScheduler.h - 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 "SystemZHazardRecognizer.h"
188010b631SJonas Paulsson #include "llvm/CodeGen/MachineScheduler.h"
19*3943d2b0SEugene Zelenko #include "llvm/CodeGen/ScheduleDAG.h"
20*3943d2b0SEugene 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 {
318010b631SJonas Paulsson   ScheduleDAGMI *DAG;
328010b631SJonas Paulsson 
338010b631SJonas Paulsson   /// A candidate during instruction evaluation.
348010b631SJonas Paulsson   struct Candidate {
35*3943d2b0SEugene Zelenko     SUnit *SU = nullptr;
368010b631SJonas Paulsson 
378010b631SJonas Paulsson     /// The decoding cost.
38*3943d2b0SEugene Zelenko     int GroupingCost = 0;
398010b631SJonas Paulsson 
408010b631SJonas Paulsson     /// The processor resources cost.
41*3943d2b0SEugene Zelenko     int ResourcesCost = 0;
428010b631SJonas Paulsson 
43*3943d2b0SEugene Zelenko     Candidate() = default;
448010b631SJonas Paulsson     Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec);
458010b631SJonas Paulsson 
468010b631SJonas Paulsson     // Compare two candidates.
478010b631SJonas Paulsson     bool operator<(const Candidate &other);
488010b631SJonas Paulsson 
498010b631SJonas Paulsson     // Check if this node is free of cost ("as good as any").
50*3943d2b0SEugene Zelenko     bool noCost() const {
518010b631SJonas Paulsson       return (GroupingCost <= 0 && !ResourcesCost);
528010b631SJonas Paulsson     }
538010b631SJonas Paulsson   };
548010b631SJonas Paulsson 
558010b631SJonas Paulsson   // A sorter for the Available set that makes sure that SUs are considered
568010b631SJonas Paulsson   // in the best order.
578010b631SJonas Paulsson   struct SUSorter {
588010b631SJonas Paulsson     bool operator() (SUnit *lhs, SUnit *rhs) const {
598010b631SJonas Paulsson       if (lhs->isScheduleHigh && !rhs->isScheduleHigh)
608010b631SJonas Paulsson         return true;
618010b631SJonas Paulsson       if (!lhs->isScheduleHigh && rhs->isScheduleHigh)
628010b631SJonas Paulsson         return false;
638010b631SJonas Paulsson 
648010b631SJonas Paulsson       if (lhs->getHeight() > rhs->getHeight())
658010b631SJonas Paulsson         return true;
668010b631SJonas Paulsson       else if (lhs->getHeight() < rhs->getHeight())
678010b631SJonas Paulsson         return false;
688010b631SJonas Paulsson 
698010b631SJonas Paulsson       return (lhs->NodeNum < rhs->NodeNum);
708010b631SJonas Paulsson     }
718010b631SJonas Paulsson   };
728010b631SJonas Paulsson   // A set of SUs with a sorter and dump method.
738010b631SJonas Paulsson   struct SUSet : std::set<SUnit*, SUSorter> {
748010b631SJonas Paulsson     #ifndef NDEBUG
758010b631SJonas Paulsson     void dump(SystemZHazardRecognizer &HazardRec);
768010b631SJonas Paulsson     #endif
778010b631SJonas Paulsson   };
788010b631SJonas Paulsson 
798010b631SJonas Paulsson   /// The set of available SUs to schedule next.
808010b631SJonas Paulsson   SUSet Available;
818010b631SJonas Paulsson 
828010b631SJonas Paulsson   // HazardRecognizer that tracks the scheduler state for the current
838010b631SJonas Paulsson   // region.
848010b631SJonas Paulsson   SystemZHazardRecognizer HazardRec;
858010b631SJonas Paulsson 
868010b631SJonas Paulsson public:
878010b631SJonas Paulsson   SystemZPostRASchedStrategy(const MachineSchedContext *C);
888010b631SJonas Paulsson 
898010b631SJonas Paulsson   /// PostRA scheduling does not track pressure.
908010b631SJonas Paulsson   bool shouldTrackPressure() const override { return false; }
918010b631SJonas Paulsson 
928010b631SJonas Paulsson   /// Initialize the strategy after building the DAG for a new region.
938010b631SJonas Paulsson   void initialize(ScheduleDAGMI *dag) override;
948010b631SJonas Paulsson 
958010b631SJonas Paulsson   /// Pick the next node to schedule, or return NULL.
968010b631SJonas Paulsson   SUnit *pickNode(bool &IsTopNode) override;
978010b631SJonas Paulsson 
988010b631SJonas Paulsson   /// ScheduleDAGMI has scheduled an instruction - tell HazardRec
998010b631SJonas Paulsson   /// about it.
1008010b631SJonas Paulsson   void schedNode(SUnit *SU, bool IsTopNode) override;
1018010b631SJonas Paulsson 
1028010b631SJonas Paulsson   /// SU has had all predecessor dependencies resolved. Put it into
1038010b631SJonas Paulsson   /// Available.
1048010b631SJonas Paulsson   void releaseTopNode(SUnit *SU) override;
1058010b631SJonas Paulsson 
1068010b631SJonas Paulsson   /// Currently only scheduling top-down, so this method is empty.
1078010b631SJonas Paulsson   void releaseBottomNode(SUnit *SU) override {};
1088010b631SJonas Paulsson };
1098010b631SJonas Paulsson 
110*3943d2b0SEugene Zelenko } // end namespace llvm
1118010b631SJonas Paulsson 
112*3943d2b0SEugene Zelenko #endif // LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
113