comparison lib/Target/SystemZ/SystemZMachineScheduler.cpp @ 121:803732b1fca8

LLVM 5.0
author kono
date Fri, 27 Oct 2017 17:07:41 +0900
parents 1172e4bd9c6f
children 3a76565eade5
comparison
equal deleted inserted replaced
120:1172e4bd9c6f 121:803732b1fca8
9 // 9 //
10 // -------------------------- Post RA scheduling ---------------------------- // 10 // -------------------------- Post RA scheduling ---------------------------- //
11 // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into 11 // SystemZPostRASchedStrategy is a scheduling strategy which is plugged into
12 // the MachineScheduler. It has a sorted Available set of SUs and a pickNode() 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 13 // implementation that looks to optimize decoder grouping and balance the
14 // usage of processor resources. 14 // usage of processor resources. Scheduler states are saved for the end
15 // region of each MBB, so that a successor block can learn from it.
15 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
16 17
17 #include "SystemZMachineScheduler.h" 18 #include "SystemZMachineScheduler.h"
18 19
19 using namespace llvm; 20 using namespace llvm;
20 21
21 #define DEBUG_TYPE "misched" 22 #define DEBUG_TYPE "machine-scheduler"
22 23
23 #ifndef NDEBUG 24 #ifndef NDEBUG
24 // Print the set of SUs 25 // Print the set of SUs
25 void SystemZPostRASchedStrategy::SUSet:: 26 void SystemZPostRASchedStrategy::SUSet::
26 dump(SystemZHazardRecognizer &HazardRec) { 27 dump(SystemZHazardRecognizer &HazardRec) const {
27 dbgs() << "{"; 28 dbgs() << "{";
28 for (auto &SU : *this) { 29 for (auto &SU : *this) {
29 HazardRec.dumpSU(SU, dbgs()); 30 HazardRec.dumpSU(SU, dbgs());
30 if (SU != *rbegin()) 31 if (SU != *rbegin())
31 dbgs() << ", "; 32 dbgs() << ", ";
32 } 33 }
33 dbgs() << "}\n"; 34 dbgs() << "}\n";
34 } 35 }
35 #endif 36 #endif
36 37
38 // Try to find a single predecessor that would be interesting for the
39 // scheduler in the top-most region of MBB.
40 static MachineBasicBlock *getSingleSchedPred(MachineBasicBlock *MBB,
41 const MachineLoop *Loop) {
42 MachineBasicBlock *PredMBB = nullptr;
43 if (MBB->pred_size() == 1)
44 PredMBB = *MBB->pred_begin();
45
46 // The loop header has two predecessors, return the latch, but not for a
47 // single block loop.
48 if (MBB->pred_size() == 2 && Loop != nullptr && Loop->getHeader() == MBB) {
49 for (auto I = MBB->pred_begin(); I != MBB->pred_end(); ++I)
50 if (Loop->contains(*I))
51 PredMBB = (*I == MBB ? nullptr : *I);
52 }
53
54 assert ((PredMBB == nullptr || !Loop || Loop->contains(PredMBB))
55 && "Loop MBB should not consider predecessor outside of loop.");
56
57 return PredMBB;
58 }
59
60 void SystemZPostRASchedStrategy::
61 advanceTo(MachineBasicBlock::iterator NextBegin) {
62 MachineBasicBlock::iterator LastEmittedMI = HazardRec->getLastEmittedMI();
63 MachineBasicBlock::iterator I =
64 ((LastEmittedMI != nullptr && LastEmittedMI->getParent() == MBB) ?
65 std::next(LastEmittedMI) : MBB->begin());
66
67 for (; I != NextBegin; ++I) {
68 if (I->isPosition() || I->isDebugValue())
69 continue;
70 HazardRec->emitInstruction(&*I);
71 }
72 }
73
74 void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) {
75 assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
76 "Entering MBB twice?");
77 DEBUG (dbgs() << "+++ Entering MBB#" << NextMBB->getNumber());
78
79 MBB = NextMBB;
80 /// Create a HazardRec for MBB, save it in SchedStates and set HazardRec to
81 /// point to it.
82 HazardRec = SchedStates[MBB] = new SystemZHazardRecognizer(TII, &SchedModel);
83 DEBUG (const MachineLoop *Loop = MLI->getLoopFor(MBB);
84 if(Loop && Loop->getHeader() == MBB)
85 dbgs() << " (Loop header)";
86 dbgs() << ":\n";);
87
88 // Try to take over the state from a single predecessor, if it has been
89 // scheduled. If this is not possible, we are done.
90 MachineBasicBlock *SinglePredMBB =
91 getSingleSchedPred(MBB, MLI->getLoopFor(MBB));
92 if (SinglePredMBB == nullptr ||
93 SchedStates.find(SinglePredMBB) == SchedStates.end())
94 return;
95
96 DEBUG (dbgs() << "+++ Continued scheduling from MBB#"
97 << SinglePredMBB->getNumber() << "\n";);
98
99 HazardRec->copyState(SchedStates[SinglePredMBB]);
100
101 // Emit incoming terminator(s). Be optimistic and assume that branch
102 // prediction will generally do "the right thing".
103 for (MachineBasicBlock::iterator I = SinglePredMBB->getFirstTerminator();
104 I != SinglePredMBB->end(); I++) {
105 DEBUG (dbgs() << "+++ Emitting incoming branch: "; I->dump(););
106 bool TakenBranch = (I->isBranch() &&
107 (TII->getBranchInfo(*I).Target->isReg() || // Relative branch
108 TII->getBranchInfo(*I).Target->getMBB() == MBB));
109 HazardRec->emitInstruction(&*I, TakenBranch);
110 if (TakenBranch)
111 break;
112 }
113 }
114
115 void SystemZPostRASchedStrategy::leaveMBB() {
116 DEBUG (dbgs() << "+++ Leaving MBB#" << MBB->getNumber() << "\n";);
117
118 // Advance to first terminator. The successor block will handle terminators
119 // dependent on CFG layout (T/NT branch etc).
120 advanceTo(MBB->getFirstTerminator());
121 }
122
37 SystemZPostRASchedStrategy:: 123 SystemZPostRASchedStrategy::
38 SystemZPostRASchedStrategy(const MachineSchedContext *C) 124 SystemZPostRASchedStrategy(const MachineSchedContext *C)
39 : DAG(nullptr), HazardRec(C) {} 125 : MLI(C->MLI),
40 126 TII(static_cast<const SystemZInstrInfo *>
41 void SystemZPostRASchedStrategy::initialize(ScheduleDAGMI *dag) { 127 (C->MF->getSubtarget().getInstrInfo())),
42 DAG = dag; 128 MBB(nullptr), HazardRec(nullptr) {
43 HazardRec.setDAG(dag); 129 const TargetSubtargetInfo *ST = &C->MF->getSubtarget();
44 HazardRec.Reset(); 130 SchedModel.init(ST->getSchedModel(), ST, TII);
131 }
132
133 SystemZPostRASchedStrategy::~SystemZPostRASchedStrategy() {
134 // Delete hazard recognizers kept around for each MBB.
135 for (auto I : SchedStates) {
136 SystemZHazardRecognizer *hazrec = I.second;
137 delete hazrec;
138 }
139 }
140
141 void SystemZPostRASchedStrategy::initPolicy(MachineBasicBlock::iterator Begin,
142 MachineBasicBlock::iterator End,
143 unsigned NumRegionInstrs) {
144 // Don't emit the terminators.
145 if (Begin->isTerminator())
146 return;
147
148 // Emit any instructions before start of region.
149 advanceTo(Begin);
45 } 150 }
46 151
47 // Pick the next node to schedule. 152 // Pick the next node to schedule.
48 SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) { 153 SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) {
49 // Only scheduling top-down. 154 // Only scheduling top-down.
53 return nullptr; 158 return nullptr;
54 159
55 // If only one choice, return it. 160 // If only one choice, return it.
56 if (Available.size() == 1) { 161 if (Available.size() == 1) {
57 DEBUG (dbgs() << "+++ Only one: "; 162 DEBUG (dbgs() << "+++ Only one: ";
58 HazardRec.dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";); 163 HazardRec->dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";);
59 return *Available.begin(); 164 return *Available.begin();
60 } 165 }
61 166
62 // All nodes that are possible to schedule are stored by in the 167 // All nodes that are possible to schedule are stored by in the
63 // Available set. 168 // Available set.
64 DEBUG(dbgs() << "+++ Available: "; Available.dump(HazardRec);); 169 DEBUG(dbgs() << "+++ Available: "; Available.dump(*HazardRec););
65 170
66 Candidate Best; 171 Candidate Best;
67 for (auto *SU : Available) { 172 for (auto *SU : Available) {
68 173
69 // SU is the next candidate to be compared against current Best. 174 // SU is the next candidate to be compared against current Best.
70 Candidate c(SU, HazardRec); 175 Candidate c(SU, *HazardRec);
71 176
72 // Remeber which SU is the best candidate. 177 // Remeber which SU is the best candidate.
73 if (Best.SU == nullptr || c < Best) { 178 if (Best.SU == nullptr || c < Best) {
74 Best = c; 179 Best = c;
75 DEBUG(dbgs() << "+++ Best sofar: "; 180 DEBUG(dbgs() << "+++ Best sofar: ";
76 HazardRec.dumpSU(Best.SU, dbgs()); 181 HazardRec->dumpSU(Best.SU, dbgs());
77 if (Best.GroupingCost != 0) 182 if (Best.GroupingCost != 0)
78 dbgs() << "\tGrouping cost:" << Best.GroupingCost; 183 dbgs() << "\tGrouping cost:" << Best.GroupingCost;
79 if (Best.ResourcesCost != 0) 184 if (Best.ResourcesCost != 0)
80 dbgs() << " Resource cost:" << Best.ResourcesCost; 185 dbgs() << " Resource cost:" << Best.ResourcesCost;
81 dbgs() << " Height:" << Best.SU->getHeight(); 186 dbgs() << " Height:" << Best.SU->getHeight();
136 void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) { 241 void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) {
137 DEBUG(dbgs() << "+++ Scheduling SU(" << SU->NodeNum << ")\n";); 242 DEBUG(dbgs() << "+++ Scheduling SU(" << SU->NodeNum << ")\n";);
138 243
139 // Remove SU from Available set and update HazardRec. 244 // Remove SU from Available set and update HazardRec.
140 Available.erase(SU); 245 Available.erase(SU);
141 HazardRec.EmitInstruction(SU); 246 HazardRec->EmitInstruction(SU);
142 } 247 }
143 248
144 void SystemZPostRASchedStrategy::releaseTopNode(SUnit *SU) { 249 void SystemZPostRASchedStrategy::releaseTopNode(SUnit *SU) {
145 // Set isScheduleHigh flag on all SUs that we want to consider first in 250 // Set isScheduleHigh flag on all SUs that we want to consider first in
146 // pickNode(). 251 // pickNode().
147 const MCSchedClassDesc *SC = DAG->getSchedClass(SU); 252 const MCSchedClassDesc *SC = HazardRec->getSchedClass(SU);
148 bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup)); 253 bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup));
149 SU->isScheduleHigh = (AffectsGrouping || SU->isUnbuffered); 254 SU->isScheduleHigh = (AffectsGrouping || SU->isUnbuffered);
150 255
151 // Put all released SUs in the Available set. 256 // Put all released SUs in the Available set.
152 Available.insert(SU); 257 Available.insert(SU);