Skip to content

Commit 30e6a3b

Browse files
committed
[AIEX] Better organization for RegionEndEdges code
1 parent 567215c commit 30e6a3b

1 file changed

Lines changed: 108 additions & 75 deletions

File tree

llvm/lib/Target/AIE/AIEBaseSubtarget.cpp

Lines changed: 108 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -356,27 +356,17 @@ class RegionEndEdges : public ScheduleDAGMutation {
356356
class EmitFixedSUnits : public ScheduleDAGMutation {
357357
AAResults *AA;
358358

359-
public:
360-
EmitFixedSUnits(AAResults *AA) : AA(AA) {}
361-
362-
void apply(ScheduleDAGInstrs *DAG) override {
363-
AIEPostRASchedStrategy *Scheduler =
364-
static_cast<AIEScheduleDAGMI *>(DAG)->getSchedImpl();
365-
auto *TII = static_cast<const AIEBaseInstrInfo *>(DAG->TII);
366-
auto *ItinData = DAG->MF.getSubtarget().getInstrItineraryData();
367-
const TargetRegisterInfo *TRI = DAG->MF.getSubtarget().getRegisterInfo();
368-
const BlockState &BS =
369-
Scheduler->getInterBlock().getBlockState(DAG->getBB());
370-
const Region &CurRegion = BS.getCurrentRegion();
371-
AIERegMemEventTracker RET{ItinData, TRI, TII, AA};
372-
359+
private:
360+
void createFixedSUDAGNodes(ScheduleDAGInstrs *DAG,
361+
AIEPostRASchedStrategy *Scheduler,
362+
const Region &CurRegion) {
373363
// First, create SUnits for all "fixed" instructions
374364
// Those will be chained from/to the EntrySU/ExitSU to ensure they are
375365
// placed in the correct cycle. The scheduler will enforce that these fixed
376366
// SUnits get placed exactly at their depth (for the Top zone) or height
377367
// (for the Bot zone).
378368
SUnit *Pred = &DAG->EntrySU;
379-
// We itarate over BUNDLEs or standalone instructions.
369+
// We iterate over BUNDLEs or standalone instructions.
380370
for (MachineInstr &MI : CurRegion.top_fixed_instrs()) {
381371
SUnit &FixedSU = Scheduler->addFixedSUnit(MI, /*IsTop=*/true);
382372
SDep Dep(Pred, SDep::Artificial);
@@ -394,89 +384,105 @@ class EmitFixedSUnits : public ScheduleDAGMutation {
394384
Succ = &FixedSU;
395385
}
396386
DAG->makeMaps();
387+
}
388+
389+
void establishSafeFreeSUToPrologueDistances(
390+
ScheduleDAGInstrs *DAG, AIEPostRASchedStrategy *Scheduler,
391+
const TargetRegisterInfo *TRI, const AIEBaseInstrInfo *TII,
392+
const InstrItineraryData *ItinData) {
393+
394+
MachineBasicBlock *LoopSucc = nullptr;
395+
for (MachineBasicBlock *Succ : DAG->getBB()->successors()) {
396+
const BlockState &SuccBS = Scheduler->getInterBlock().getBlockState(Succ);
397+
if (SuccBS.Kind == BlockType::Loop && SuccBS.isPipelined()) {
398+
LoopSucc = Succ;
399+
break;
400+
}
401+
}
402+
403+
if (!LoopSucc)
404+
return;
405+
406+
const BlockState &LoopBS =
407+
Scheduler->getInterBlock().getBlockState(LoopSucc);
408+
409+
const BlockState &BS =
410+
Scheduler->getInterBlock().getBlockState(DAG->getBB());
411+
412+
const Region &CurRegion = BS.getCurrentRegion();
397413

398414
ArrayRef<AIE::MachineBundle> BotFixedBundles =
399415
CurRegion.getBotFixedBundles();
400-
ArrayRef<AIE::MachineBundle> TopFixedBundles =
401-
CurRegion.getTopFixedBundles();
402416

403-
// Handle bot-fixed instructions (prologue) with backward tracking
404-
// Only handle prologues (preheader blocks), not epilogues here
405-
if (!BotFixedBundles.empty() && BS.Kind != BlockType::Epilogue) {
406-
AIERegMemEventTracker BackwardRET{ItinData, TRI, TII, AA};
407-
408-
// Track bot-fixed bundles backward (this sets BotFixedRegionSize)
409-
BackwardRET.computeUseDefBackward(BotFixedBundles,
410-
/*InSeparateRegion=*/false);
411-
412-
// Find the loop successor - must exist if we have bot-fixed bundles in a
413-
// prologue
414-
MachineBasicBlock *LoopSucc = nullptr;
415-
for (MachineBasicBlock *Succ : DAG->getBB()->successors()) {
416-
const BlockState &SuccBS =
417-
Scheduler->getInterBlock().getBlockState(Succ);
418-
if (SuccBS.Kind == BlockType::Loop && SuccBS.isPipelined()) {
419-
LoopSucc = Succ;
420-
break;
421-
}
422-
}
423-
assert(LoopSucc &&
424-
"Bot-fixed bundles present but no pipelined loop successor found");
425-
426-
const BlockState &LoopBS =
427-
Scheduler->getInterBlock().getBlockState(LoopSucc);
428-
ArrayRef<AIE::MachineBundle> LoopTimedBundles = LoopBS.getTop().Bundles;
429-
BackwardRET.computeUseDefBackward(LoopTimedBundles,
430-
/*InSeparateRegion=*/true);
431-
432-
// Create dependencies from free instructions to ExitSU
433-
// Side-effect instructions are now handled automatically by
434-
// getSafeOperandsDistanceFromEnd()
435-
auto IsNonBotFixedSU = [Scheduler](const SUnit &SU) {
436-
return !Scheduler->isFixedSU(SU, /*IsTop*/ false);
437-
};
417+
ArrayRef<AIE::MachineBundle> LoopTimedBundles = LoopBS.getTop().Bundles;
438418

439-
for (SUnit &SU : make_filter_range(DAG->SUnits, IsNonBotFixedSU)) {
440-
const MachineInstr &MI = *SU.getInstr();
441-
if (const unsigned Latency =
442-
BackwardRET.getSafeOperandsDistanceFromBottom(MI)) {
443-
LLVM_DEBUG(dbgs()
444-
<< "Prologue: SU(" << SU.NodeNum << ") needs latency "
445-
<< Latency << " to ExitSU: " << MI);
446-
LLVM_DEBUG(dbgs() << " Adding new edge\n");
447-
SDep Dep(&SU, SDep::Artificial);
448-
Dep.setLatency(Latency);
449-
DAG->ExitSU.addPred(Dep, /*Required=*/true);
450-
}
419+
AIERegMemEventTracker BackwardRET{ItinData, TRI, TII, AA};
420+
421+
// Track bot-fixed bundles backward (this sets BotFixedRegionSize)
422+
BackwardRET.computeUseDefBackward(BotFixedBundles,
423+
/*InSeparateRegion=*/false);
424+
425+
BackwardRET.computeUseDefBackward(LoopTimedBundles,
426+
/*InSeparateRegion=*/true);
427+
428+
// Create dependencies from free instructions to ExitSU
429+
// Side-effect instructions are now handled automatically by
430+
// getSafeOperandsDistanceFromEnd()
431+
auto IsNonBotFixedSU = [Scheduler](const SUnit &SU) {
432+
return !Scheduler->isFixedSU(SU, /*IsTop*/ false);
433+
};
434+
435+
for (SUnit &SU : make_filter_range(DAG->SUnits, IsNonBotFixedSU)) {
436+
const MachineInstr &MI = *SU.getInstr();
437+
if (const unsigned Latency =
438+
BackwardRET.getSafeOperandsDistanceFromBottom(MI)) {
439+
LLVM_DEBUG(dbgs() << "Prologue: SU(" << SU.NodeNum << ") needs latency "
440+
<< Latency << " to ExitSU: " << MI);
441+
LLVM_DEBUG(dbgs() << " Adding new edge\n");
442+
SDep Dep(&SU, SDep::Artificial);
443+
Dep.setLatency(Latency);
444+
DAG->ExitSU.addPred(Dep, /*Required=*/true);
451445
}
452446
}
447+
}
448+
449+
void establishSafeFreeSUToEpilogueDistances(
450+
ScheduleDAGInstrs *DAG, AIEPostRASchedStrategy *Scheduler,
451+
const TargetRegisterInfo *TRI, const AIEBaseInstrInfo *TII,
452+
const InstrItineraryData *ItinData) {
453+
454+
const BlockState &BS =
455+
Scheduler->getInterBlock().getBlockState(DAG->getBB());
453456

454-
// We only need to focus on top-fixed instructions when there is an Epilogue
455-
// block.
456457
if (BS.Kind != BlockType::Epilogue)
457458
return;
458459

459460
MachineBasicBlock *Loop = AIELoopUtils::getLoopPredecessor(*DAG->getBB());
460-
assert(Loop);
461461
const BlockState &LBS = Scheduler->getInterBlock().getBlockState(Loop);
462-
assert(LBS.Kind == BlockType::Loop);
463462

464-
if (!LBS.isPipelined()) {
465-
assert(CurRegion.getTopFixedBundles().empty());
463+
if (!LBS.isPipelined())
466464
return;
467-
}
465+
466+
const Region &CurRegion = BS.getCurrentRegion();
467+
468+
ArrayRef<AIE::MachineBundle> TopFixedBundles =
469+
CurRegion.getTopFixedBundles();
468470

469471
ArrayRef<AIE::MachineBundle> LoopTimedBundles = LBS.getTop().Bundles;
470472

471-
RET.computeUseDefForward(TopFixedBundles, /*InSeparateRegion=*/false);
473+
AIERegMemEventTracker ForwardRET{ItinData, TRI, TII, AA};
474+
475+
ForwardRET.computeUseDefForward(TopFixedBundles,
476+
/*InSeparateRegion=*/false);
472477
// It is more cost-effective to reuse the RET to establish individual safety
473478
// margins between the pipelined loop and the free instructions. This
474479
// approach allows us to manage all dependencies related to EntrySU in one
475480
// centralized location. While it is possible to implement this as a
476481
// separate mutator, doing so could be costly, as it would prevent the
477482
// creation of multiple edges from EntrySU to each free instruction that
478483
// depends on both timed regions (TopFixed and LoopTimed).
479-
RET.computeUseDefForward(LoopTimedBundles, /*InSeparateRegion=*/true);
484+
ForwardRET.computeUseDefForward(LoopTimedBundles,
485+
/*InSeparateRegion=*/true);
480486

481487
auto IsNonTopFixedSU = [Scheduler](const SUnit &SU) {
482488
return !Scheduler->isFixedSU(SU, /*IsTop*/ true);
@@ -486,17 +492,22 @@ class EmitFixedSUnits : public ScheduleDAGMutation {
486492
// account the def/use cycle of each operand.
487493
for (SUnit &SU : make_filter_range(DAG->SUnits, IsNonTopFixedSU)) {
488494
const MachineInstr &MI = *SU.getInstr();
489-
if (const unsigned Latency = RET.getSafeOperandsDistanceFromTop(MI)) {
495+
if (const unsigned Latency =
496+
ForwardRET.getSafeOperandsDistanceFromTop(MI)) {
490497
SDep Dep(&DAG->EntrySU, SDep::Artificial);
491498
Dep.setLatency(Latency);
492499
SU.addPred(Dep, /*Required=*/true);
493500
}
494501
}
502+
}
503+
504+
void establishSafeFixedSUToExitSUDistances(
505+
ScheduleDAGInstrs *DAG, AIEPostRASchedStrategy *Scheduler,
506+
const AIEBaseInstrInfo *TII, const InstrItineraryData *ItinData) {
495507

496508
auto IsTopFixedSU = [Scheduler](const SUnit &SU) {
497509
return Scheduler->isFixedSU(SU, true);
498510
};
499-
500511
// TODO: this is pessimistic, we can handle this in RegionEndEdges after
501512
// a mutation reordering.
502513
// Establish dependencies to ExitSU for each top-fixed sched. unit by taking
@@ -509,6 +520,28 @@ class EmitFixedSUnits : public ScheduleDAGMutation {
509520
DAG->ExitSU.addPred(Dep, /*Required=*/true);
510521
}
511522
}
523+
524+
public:
525+
EmitFixedSUnits(AAResults *AA) : AA(AA) {}
526+
527+
void apply(ScheduleDAGInstrs *DAG) override {
528+
AIEPostRASchedStrategy *Scheduler =
529+
static_cast<AIEScheduleDAGMI *>(DAG)->getSchedImpl();
530+
auto *TII = static_cast<const AIEBaseInstrInfo *>(DAG->TII);
531+
auto *ItinData = DAG->MF.getSubtarget().getInstrItineraryData();
532+
const TargetRegisterInfo *TRI = DAG->MF.getSubtarget().getRegisterInfo();
533+
const BlockState &BS =
534+
Scheduler->getInterBlock().getBlockState(DAG->getBB());
535+
const Region &CurRegion = BS.getCurrentRegion();
536+
537+
createFixedSUDAGNodes(DAG, Scheduler, CurRegion);
538+
539+
establishSafeFreeSUToPrologueDistances(DAG, Scheduler, TRI, TII, ItinData);
540+
541+
establishSafeFreeSUToEpilogueDistances(DAG, Scheduler, TRI, TII, ItinData);
542+
543+
establishSafeFixedSUToExitSUDistances(DAG, Scheduler, TII, ItinData);
544+
}
512545
};
513546

514547
/// Collect all "weak" edges in a separate vector. This allows modifying

0 commit comments

Comments
 (0)