1*8010b631SJonas Paulsson //==-- SystemZMachineScheduler.h - SystemZ Scheduler Interface -*- C++ -*---==//
2*8010b631SJonas Paulsson //
3*8010b631SJonas Paulsson //                     The LLVM Compiler Infrastructure
4*8010b631SJonas Paulsson //
5*8010b631SJonas Paulsson // This file is distributed under the University of Illinois Open Source
6*8010b631SJonas Paulsson // License. See LICENSE.TXT for details.
7*8010b631SJonas Paulsson //
8*8010b631SJonas Paulsson //===----------------------------------------------------------------------===//
9*8010b631SJonas Paulsson //
10*8010b631SJonas Paulsson // -------------------------- Post RA scheduling ---------------------------- //
11*8010b631SJonas Paulsson // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into
12*8010b631SJonas Paulsson // the MachineScheduler. It has a sorted Available set of SUs and a pickNode()
13*8010b631SJonas Paulsson // implementation that looks to optimize decoder grouping and balance the
14*8010b631SJonas Paulsson // usage of processor resources.
15*8010b631SJonas Paulsson //===----------------------------------------------------------------------===//
16*8010b631SJonas Paulsson 
17*8010b631SJonas Paulsson #include "SystemZInstrInfo.h"
18*8010b631SJonas Paulsson #include "SystemZHazardRecognizer.h"
19*8010b631SJonas Paulsson #include "llvm/CodeGen/MachineScheduler.h"
20*8010b631SJonas Paulsson #include "llvm/Support/Debug.h"
21*8010b631SJonas Paulsson 
22*8010b631SJonas Paulsson #ifndef LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
23*8010b631SJonas Paulsson #define LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H
24*8010b631SJonas Paulsson 
25*8010b631SJonas Paulsson using namespace llvm;
26*8010b631SJonas Paulsson 
27*8010b631SJonas Paulsson namespace llvm {
28*8010b631SJonas Paulsson 
29*8010b631SJonas Paulsson /// A MachineSchedStrategy implementation for SystemZ post RA scheduling.
30*8010b631SJonas Paulsson class SystemZPostRASchedStrategy : public MachineSchedStrategy {
31*8010b631SJonas Paulsson     ScheduleDAGMI *DAG;
32*8010b631SJonas Paulsson 
33*8010b631SJonas Paulsson   /// A candidate during instruction evaluation.
34*8010b631SJonas Paulsson   struct Candidate {
35*8010b631SJonas Paulsson     SUnit *SU;
36*8010b631SJonas Paulsson 
37*8010b631SJonas Paulsson     /// The decoding cost.
38*8010b631SJonas Paulsson     int GroupingCost;
39*8010b631SJonas Paulsson 
40*8010b631SJonas Paulsson     /// The processor resources cost.
41*8010b631SJonas Paulsson     int ResourcesCost;
42*8010b631SJonas Paulsson 
43*8010b631SJonas Paulsson     Candidate() : SU(nullptr), GroupingCost(0), ResourcesCost(0) {}
44*8010b631SJonas Paulsson     Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec);
45*8010b631SJonas Paulsson 
46*8010b631SJonas Paulsson     // Compare two candidates.
47*8010b631SJonas Paulsson     bool operator<(const Candidate &other);
48*8010b631SJonas Paulsson 
49*8010b631SJonas Paulsson     // Check if this node is free of cost ("as good as any").
50*8010b631SJonas Paulsson     bool inline noCost() {
51*8010b631SJonas Paulsson       return (GroupingCost <= 0 && !ResourcesCost);
52*8010b631SJonas Paulsson     }
53*8010b631SJonas Paulsson    };
54*8010b631SJonas Paulsson 
55*8010b631SJonas Paulsson   // A sorter for the Available set that makes sure that SUs are considered
56*8010b631SJonas Paulsson   // in the best order.
57*8010b631SJonas Paulsson   struct SUSorter {
58*8010b631SJonas Paulsson     bool operator() (SUnit *lhs, SUnit *rhs) const {
59*8010b631SJonas Paulsson       if (lhs->isScheduleHigh && !rhs->isScheduleHigh)
60*8010b631SJonas Paulsson         return true;
61*8010b631SJonas Paulsson       if (!lhs->isScheduleHigh && rhs->isScheduleHigh)
62*8010b631SJonas Paulsson         return false;
63*8010b631SJonas Paulsson 
64*8010b631SJonas Paulsson       if (lhs->getHeight() > rhs->getHeight())
65*8010b631SJonas Paulsson         return true;
66*8010b631SJonas Paulsson       else if (lhs->getHeight() < rhs->getHeight())
67*8010b631SJonas Paulsson         return false;
68*8010b631SJonas Paulsson 
69*8010b631SJonas Paulsson       return (lhs->NodeNum < rhs->NodeNum);
70*8010b631SJonas Paulsson     }
71*8010b631SJonas Paulsson   };
72*8010b631SJonas Paulsson   // A set of SUs with a sorter and dump method.
73*8010b631SJonas Paulsson   struct SUSet : std::set<SUnit*, SUSorter> {
74*8010b631SJonas Paulsson     #ifndef NDEBUG
75*8010b631SJonas Paulsson     void dump(SystemZHazardRecognizer &HazardRec);
76*8010b631SJonas Paulsson     #endif
77*8010b631SJonas Paulsson   };
78*8010b631SJonas Paulsson 
79*8010b631SJonas Paulsson   /// The set of available SUs to schedule next.
80*8010b631SJonas Paulsson   SUSet Available;
81*8010b631SJonas Paulsson 
82*8010b631SJonas Paulsson   // HazardRecognizer that tracks the scheduler state for the current
83*8010b631SJonas Paulsson   // region.
84*8010b631SJonas Paulsson   SystemZHazardRecognizer HazardRec;
85*8010b631SJonas Paulsson 
86*8010b631SJonas Paulsson  public:
87*8010b631SJonas Paulsson   SystemZPostRASchedStrategy(const MachineSchedContext *C);
88*8010b631SJonas Paulsson 
89*8010b631SJonas Paulsson   /// PostRA scheduling does not track pressure.
90*8010b631SJonas Paulsson   bool shouldTrackPressure() const override { return false; }
91*8010b631SJonas Paulsson 
92*8010b631SJonas Paulsson   /// Initialize the strategy after building the DAG for a new region.
93*8010b631SJonas Paulsson   void initialize(ScheduleDAGMI *dag) override;
94*8010b631SJonas Paulsson 
95*8010b631SJonas Paulsson   /// Pick the next node to schedule, or return NULL.
96*8010b631SJonas Paulsson   SUnit *pickNode(bool &IsTopNode) override;
97*8010b631SJonas Paulsson 
98*8010b631SJonas Paulsson   /// ScheduleDAGMI has scheduled an instruction - tell HazardRec
99*8010b631SJonas Paulsson   /// about it.
100*8010b631SJonas Paulsson   void schedNode(SUnit *SU, bool IsTopNode) override;
101*8010b631SJonas Paulsson 
102*8010b631SJonas Paulsson   /// SU has had all predecessor dependencies resolved. Put it into
103*8010b631SJonas Paulsson   /// Available.
104*8010b631SJonas Paulsson   void releaseTopNode(SUnit *SU) override;
105*8010b631SJonas Paulsson 
106*8010b631SJonas Paulsson   /// Currently only scheduling top-down, so this method is empty.
107*8010b631SJonas Paulsson   void releaseBottomNode(SUnit *SU) override {};
108*8010b631SJonas Paulsson };
109*8010b631SJonas Paulsson 
110*8010b631SJonas Paulsson } // namespace llvm
111*8010b631SJonas Paulsson 
112*8010b631SJonas Paulsson #endif /* LLVM_LIB_TARGET_SYSTEMZ_SYSTEMZMACHINESCHEDULER_H */
113