@@ -284,22 +284,30 @@ void GCNHazardRecognizer::processBundle() {
284
284
CurrCycleInstr = nullptr ;
285
285
}
286
286
287
- void GCNHazardRecognizer::reverseProcessBundle () {
287
+ void GCNHazardRecognizer::processBundleBottomUp () {
288
+ // Step through each instruction in the bundle in bottom-up order.
288
289
MachineBasicBlock::instr_iterator MI =
289
290
std::next (CurrCycleInstr->getIterator ());
290
291
MachineBasicBlock::instr_iterator E =
291
292
CurrCycleInstr->getParent ()->instr_end ();
292
293
294
+ // Evict stale entries to maintain a fixed lookahead window.
295
+ // TODO: Hazard detection is not yet implemented. This scheduling
296
+ // is intended for GFX11 and newer.
293
297
for (; MI != E && MI->isInsideBundle (); ++MI) {
294
298
CurrCycleInstr = &*MI;
295
- for (unsigned I = 0 , E = MaxLookAhead - 1 ; I < E; ++I) {
296
- if (!EmittedInstrs.empty ())
297
- EmittedInstrs.pop_back ();
298
- }
299
+
300
+ // Remove up to (MaxLookAhead - 1) oldest entries.
301
+ for (unsigned I = 0 , E = MaxLookAhead - 1 ; I < E && !EmittedInstrs.empty ();
302
+ ++I)
303
+ EmittedInstrs.pop_back ();
299
304
300
305
EmittedInstrs.push_back (CurrCycleInstr);
306
+
307
+ // Keep only the most recent MaxLookAhead entries
301
308
EmittedInstrs.resize (MaxLookAhead);
302
309
}
310
+
303
311
CurrCycleInstr = nullptr ;
304
312
}
305
313
@@ -442,14 +450,16 @@ void GCNHazardRecognizer::AdvanceCycle() {
442
450
}
443
451
444
452
void GCNHazardRecognizer::RecedeCycle () {
453
+ // If no instruction was issued this cycle, pop the oldest placeholder.
445
454
if (!CurrCycleInstr) {
446
455
if (!EmittedInstrs.empty ())
447
456
EmittedInstrs.pop_back ();
448
457
return ;
449
458
}
450
459
460
+ // If this is a bundle header, handle the entire bundle here.
451
461
if (CurrCycleInstr->isBundle ()) {
452
- reverseProcessBundle ();
462
+ processBundleBottomUp ();
453
463
return ;
454
464
}
455
465
@@ -459,14 +469,21 @@ void GCNHazardRecognizer::RecedeCycle() {
459
469
return ;
460
470
}
461
471
472
+ // Add current instruction to the emitted list.
462
473
EmittedInstrs.push_back (CurrCycleInstr);
463
- for (unsigned i = 1 , e = std::min (NumWaitStates, getMaxLookAhead ()); i < e;
464
- ++i) {
474
+
475
+ // Model remaining wait states by removing older placeholders.
476
+ for (unsigned I = 1 , E = std::min (NumWaitStates, getMaxLookAhead ()); I < E;
477
+ ++I) {
465
478
if (!EmittedInstrs.empty ())
466
479
EmittedInstrs.pop_back ();
467
480
}
468
481
482
+ // getMaxLookahead() is the largest number of wait states we will ever need
483
+ // to insert, so there is no point in keeping track of more than that many
484
+ // wait states.
469
485
EmittedInstrs.resize (getMaxLookAhead ());
486
+
470
487
CurrCycleInstr = nullptr ;
471
488
}
472
489
0 commit comments