LLVM: lib/CodeGen/ScoreboardHazardRecognizer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
18#include "llvm/Config/llvm-config.h"
24#include
25
26using namespace llvm;
27
28#define DEBUG_TYPE DebugType
29
32 const char *ParentDebugType)
33 : DebugType(ParentDebugType), ItinData(II), DAG(SchedDAG) {
34 (void)DebugType;
35
36
37
38 unsigned ScoreboardDepth = 1;
39 if (ItinData && !ItinData->isEmpty()) {
40 for (unsigned idx = 0; ; ++idx) {
41 if (ItinData->isEndMarker(idx))
42 break;
43
44 const InstrStage *IS = ItinData->beginStage(idx);
45 const InstrStage *E = ItinData->endStage(idx);
46 unsigned CurCycle = 0;
47 unsigned ItinDepth = 0;
48 for (; IS != E; ++IS) {
49 unsigned StageDepth = CurCycle + IS->getCycles();
50 if (ItinDepth < StageDepth) ItinDepth = StageDepth;
51 CurCycle += IS->getNextCycles();
52 }
53
54
55 while (ItinDepth > ScoreboardDepth) {
56 ScoreboardDepth *= 2;
57
58
59
60 MaxLookAhead = ScoreboardDepth;
61 }
62 }
63 }
64
65 ReservedScoreboard.reset(ScoreboardDepth);
66 RequiredScoreboard.reset(ScoreboardDepth);
67
68
69 if (!isEnabled())
70 LLVM_DEBUG(dbgs() << "Disabled scoreboard hazard recognizer\n");
71 else {
72
73 IssueWidth = ItinData->SchedModel.IssueWidth;
74 LLVM_DEBUG(dbgs() << "Using scoreboard hazard recognizer: Depth = "
75 << ScoreboardDepth << '\n');
76 }
77}
78
80 IssueCount = 0;
81 RequiredScoreboard.reset();
82 ReservedScoreboard.reset();
83}
84
85#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
86LLVM_DUMP_METHOD void ScoreboardHazardRecognizer::Scoreboard::dump() const {
87 dbgs() << "Scoreboard:\n";
88
89 unsigned last = Depth - 1;
90 while ((last > 0) && ((*this)[last] == 0))
91 last--;
92
93 for (unsigned i = 0; i <= last; i++) {
95 dbgs() << "\t";
96 for (int j = std::numeric_limitsInstrStage::FuncUnits::digits - 1;
97 j >= 0; j--)
98 dbgs() << ((FUs & (1ULL << j)) ? '1' : '0');
99 dbgs() << '\n';
100 }
101}
102#endif
103
105 if (IssueWidth == 0)
106 return false;
107
108 return IssueCount == IssueWidth;
109}
110
113 if (!ItinData || ItinData->isEmpty())
115
116
117 int cycle = Stalls;
118
119
120
121
124
126 }
127 unsigned idx = MCID->getSchedClass();
128 for (const InstrStage *IS = ItinData->beginStage(idx),
129 *E = ItinData->endStage(idx); IS != E; ++IS) {
130
131
132
133 for (unsigned int i = 0; i < IS->getCycles(); ++i) {
134 int StageCycle = cycle + (int)i;
135 if (StageCycle < 0)
136 continue;
137
138 if (StageCycle >= (int)RequiredScoreboard.getDepth()) {
139 assert((StageCycle - Stalls) < (int)RequiredScoreboard.getDepth() &&
140 "Scoreboard depth exceeded!");
141
142 break;
143 }
144
146 switch (IS->getReservationKind()) {
148
149 freeUnits &= ~ReservedScoreboard[StageCycle];
150 [[fallthrough]];
152
153 freeUnits &= ~RequiredScoreboard[StageCycle];
154 break;
155 }
156
157 if (!freeUnits) {
158 LLVM_DEBUG(dbgs() << "*** Hazard in cycle +" << StageCycle << ", ");
161 }
162 }
163
164
165 cycle += IS->getNextCycles();
166 }
167
169}
170
172 if (!ItinData || ItinData->isEmpty())
173 return;
174
175
176
178 assert(MCID && "The scheduler must filter non-machineinstrs");
179 if (DAG->TII->isZeroCost(MCID->Opcode))
180 return;
181
182 ++IssueCount;
183
184 unsigned cycle = 0;
185
186 unsigned idx = MCID->getSchedClass();
187 for (const InstrStage *IS = ItinData->beginStage(idx),
188 *E = ItinData->endStage(idx); IS != E; ++IS) {
189
190
191
192 for (unsigned int i = 0; i < IS->getCycles(); ++i) {
193 assert(((cycle + i) < RequiredScoreboard.getDepth()) &&
194 "Scoreboard depth exceeded!");
195
197 switch (IS->getReservationKind()) {
199
200 freeUnits &= ~ReservedScoreboard[cycle + i];
201 [[fallthrough]];
203
204 freeUnits &= ~RequiredScoreboard[cycle + i];
205 break;
206 }
207
208
210 do {
211 freeUnit = freeUnits;
212 freeUnits = freeUnit & (freeUnit - 1);
213 } while (freeUnits);
214
216 RequiredScoreboard[cycle + i] |= freeUnit;
217 else
218 ReservedScoreboard[cycle + i] |= freeUnit;
219 }
220
221
222 cycle += IS->getNextCycles();
223 }
224
225 LLVM_DEBUG(ReservedScoreboard.dump());
226 LLVM_DEBUG(RequiredScoreboard.dump());
227}
228
230 IssueCount = 0;
231 ReservedScoreboard[0] = 0; ReservedScoreboard.advance();
232 RequiredScoreboard[0] = 0; RequiredScoreboard.advance();
233}
234
236 IssueCount = 0;
237 ReservedScoreboard[ReservedScoreboard.getDepth()-1] = 0;
238 ReservedScoreboard.recede();
239 RequiredScoreboard[RequiredScoreboard.getDepth()-1] = 0;
240 RequiredScoreboard.recede();
241}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
uint64_t IntrinsicInst * II
Itinerary data supplied by a subtarget to be used by a target.
Describe properties that are true of each instruction in the target description file.
Scheduling unit. This is a node in the scheduling DAG.
void Reset() override
Reset - This callback is invoked when a new block of instructions is about to be schedule.
Definition ScoreboardHazardRecognizer.cpp:79
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
Definition ScoreboardHazardRecognizer.cpp:171
void RecedeCycle() override
RecedeCycle - This callback is invoked whenever the next bottom-up instruction to be scheduled cannot...
Definition ScoreboardHazardRecognizer.cpp:235
HazardType getHazardType(SUnit *SU, int Stalls) override
getHazardType - Return the hazard type of emitting this node.
Definition ScoreboardHazardRecognizer.cpp:112
ScoreboardHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG, const char *ParentDebugType="")
Definition ScoreboardHazardRecognizer.cpp:30
bool atIssueLimit() const override
atIssueLimit - Return true if no more instructions may be issued in this cycle.
Definition ScoreboardHazardRecognizer.cpp:104
void AdvanceCycle() override
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
Definition ScoreboardHazardRecognizer.cpp:229
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
These values represent a non-pipelined step in the execution of an instruction.
uint64_t FuncUnits
Bitmask representing a set of functional units.