LLVM  4.0.0
SystemZMachineScheduler.cpp
Go to the documentation of this file.
1 //-- SystemZMachineScheduler.cpp - SystemZ Scheduler Interface -*- C++ -*---==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // -------------------------- Post RA scheduling ---------------------------- //
11 // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into
12 // the MachineScheduler. It has a sorted Available set of SUs and a pickNode()
13 // implementation that looks to optimize decoder grouping and balance the
14 // usage of processor resources.
15 //===----------------------------------------------------------------------===//
16 
18 
19 using namespace llvm;
20 
21 #define DEBUG_TYPE "misched"
22 
23 #ifndef NDEBUG
24 // Print the set of SUs
26 dump(SystemZHazardRecognizer &HazardRec) {
27  dbgs() << "{";
28  for (auto &SU : *this) {
29  HazardRec.dumpSU(SU, dbgs());
30  if (SU != *rbegin())
31  dbgs() << ", ";
32  }
33  dbgs() << "}\n";
34 }
35 #endif
36 
39  : DAG(nullptr), HazardRec(C) {}
40 
42  DAG = dag;
43  HazardRec.setDAG(dag);
44  HazardRec.Reset();
45 }
46 
47 // Pick the next node to schedule.
49  // Only scheduling top-down.
50  IsTopNode = true;
51 
52  if (Available.empty())
53  return nullptr;
54 
55  // If only one choice, return it.
56  if (Available.size() == 1) {
57  DEBUG (dbgs() << "+++ Only one: ";
58  HazardRec.dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";);
59  return *Available.begin();
60  }
61 
62  // All nodes that are possible to schedule are stored by in the
63  // Available set.
64  DEBUG(dbgs() << "+++ Available: "; Available.dump(HazardRec););
65 
66  Candidate Best;
67  for (auto *SU : Available) {
68 
69  // SU is the next candidate to be compared against current Best.
70  Candidate c(SU, HazardRec);
71 
72  // Remeber which SU is the best candidate.
73  if (Best.SU == nullptr || c < Best) {
74  Best = c;
75  DEBUG(dbgs() << "+++ Best sofar: ";
76  HazardRec.dumpSU(Best.SU, dbgs());
77  if (Best.GroupingCost != 0)
78  dbgs() << "\tGrouping cost:" << Best.GroupingCost;
79  if (Best.ResourcesCost != 0)
80  dbgs() << " Resource cost:" << Best.ResourcesCost;
81  dbgs() << " Height:" << Best.SU->getHeight();
82  dbgs() << "\n";);
83  }
84 
85  // Once we know we have seen all SUs that affect grouping or use unbuffered
86  // resources, we can stop iterating if Best looks good.
87  if (!SU->isScheduleHigh && Best.noCost())
88  break;
89  }
90 
91  assert (Best.SU != nullptr);
92  return Best.SU;
93 }
94 
95 SystemZPostRASchedStrategy::Candidate::
96 Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec) : Candidate() {
97  SU = SU_;
98 
99  // Check the grouping cost. For a node that must begin / end a
100  // group, it is positive if it would do so prematurely, or negative
101  // if it would fit naturally into the schedule.
102  GroupingCost = HazardRec.groupingCost(SU);
103 
104  // Check the resources cost for this SU.
105  ResourcesCost = HazardRec.resourcesCost(SU);
106 }
107 
109 operator<(const Candidate &other) {
110 
111  // Check decoder grouping.
112  if (GroupingCost < other.GroupingCost)
113  return true;
114  if (GroupingCost > other.GroupingCost)
115  return false;
116 
117  // Compare the use of resources.
118  if (ResourcesCost < other.ResourcesCost)
119  return true;
120  if (ResourcesCost > other.ResourcesCost)
121  return false;
122 
123  // Higher SU is otherwise generally better.
124  if (SU->getHeight() > other.SU->getHeight())
125  return true;
126  if (SU->getHeight() < other.SU->getHeight())
127  return false;
128 
129  // If all same, fall back to original order.
130  if (SU->NodeNum < other.SU->NodeNum)
131  return true;
132 
133  return false;
134 }
135 
136 void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) {
137  DEBUG(dbgs() << "+++ Scheduling SU(" << SU->NodeNum << ")\n";);
138 
139  // Remove SU from Available set and update HazardRec.
140  Available.erase(SU);
141  HazardRec.EmitInstruction(SU);
142 }
143 
145  // Set isScheduleHigh flag on all SUs that we want to consider first in
146  // pickNode().
147  const MCSchedClassDesc *SC = DAG->getSchedClass(SU);
148  bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup));
149  SU->isScheduleHigh = (AffectsGrouping || SU->isUnbuffered);
150 
151  // Put all released SUs in the Available set.
152  Available.insert(SU);
153 }
void releaseTopNode(SUnit *SU) override
SU has had all predecessor dependencies resolved.
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule, or return NULL.
static void dump(StringRef Title, SpillInfo const &Spills)
Definition: CoroFrame.cpp:283
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolve and cache a resolved scheduling class for an SUnit.
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
int groupingCost(SUnit *SU) const
Return the cost of decoder grouping for SU.
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
SystemZHazardRecognizer maintains the state during scheduling.
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
void schedNode(SUnit *SU, bool IsTopNode) override
ScheduleDAGMI has scheduled an instruction - tell HazardRec about it.
bool isValid() const
Definition: MCSchedule.h:118
bool isUnbuffered
Definition: ScheduleDAG.h:290
Summarize the scheduling resources required for an instruction of a particular scheduling class...
Definition: MCSchedule.h:101
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
bool isScheduleHigh
Definition: ScheduleDAG.h:287
CHAIN = SC CHAIN, Imm128 - System call.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
SystemZPostRASchedStrategy(const MachineSchedContext *C)
reverse_iterator rbegin(StringRef path)
Get reverse begin iterator over path.
Definition: Path.cpp:309
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
unsigned NodeNum
Definition: ScheduleDAG.h:266
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:326
#define DEBUG(X)
Definition: Debug.h:100
SUnit - Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:244
void dumpSU(SUnit *SU, raw_ostream &OS) const