1212// ===----------------------------------------------------------------------===//
1313
1414#include " GCNIterativeScheduler.h"
15+ #include " AMDGPUIGroupLP.h"
1516#include " GCNSchedStrategy.h"
1617#include " SIMachineFunctionInfo.h"
1718
@@ -118,21 +119,42 @@ void GCNIterativeScheduler::printSchedRP(raw_ostream &OS,
118119}
119120#endif
120121
122+ void GCNIterativeScheduler::swapIGLPMutations (const Region &R, bool IsReentry) {
123+ bool HasIGLPInstrs = false ;
124+ const SIInstrInfo *SII = static_cast <const SIInstrInfo *>(TII);
125+ for (MachineBasicBlock::iterator I = R.Begin ; I != R.End ; I++) {
126+ if (SII->isIGLPMutationOnly (I->getOpcode ())) {
127+ HasIGLPInstrs = true ;
128+ break ;
129+ }
130+ }
131+
132+ if (HasIGLPInstrs) {
133+ SavedMutations.clear ();
134+ SavedMutations.swap (Mutations);
135+ auto SchedPhase = IsReentry ? AMDGPU::SchedulingPhase::PreRAReentry
136+ : AMDGPU::SchedulingPhase::Initial;
137+
138+ addMutation (createIGroupLPDAGMutation (SchedPhase));
139+ }
140+ }
141+
121142// DAG builder helper
122143class GCNIterativeScheduler ::BuildDAG {
123144 GCNIterativeScheduler &Sch;
124145 SmallVector<SUnit *, 8 > TopRoots;
125146
126147 SmallVector<SUnit*, 8 > BotRoots;
127148public:
128- BuildDAG (const Region &R, GCNIterativeScheduler &_Sch)
129- : Sch(_Sch) {
149+ BuildDAG (const Region &R, GCNIterativeScheduler &_Sch, bool IsReentry = false )
150+ : Sch(_Sch) {
130151 auto *BB = R.Begin ->getParent ();
131152 Sch.BaseClass ::startBlock (BB);
132153 Sch.BaseClass ::enterRegion (BB, R.Begin , R.End , R.NumRegionInstrs );
133-
154+ Sch. swapIGLPMutations (R, IsReentry);
134155 Sch.buildSchedGraph (Sch.AA , nullptr , nullptr , nullptr ,
135156 /* TrackLaneMask*/ true );
157+ Sch.postProcessDAG ();
136158 Sch.Topo .InitDAGTopologicalSorting ();
137159 Sch.findRootsAndBiasEdges (TopRoots, BotRoots);
138160 }
@@ -432,13 +454,15 @@ unsigned GCNIterativeScheduler::tryMaximizeOccupancy(unsigned TargetOcc) {
432454
433455 auto NewOcc = TargetOcc;
434456 for (auto *R : Regions) {
457+ // Always build the DAG to add mutations
458+ BuildDAG DAG (*R, *this );
459+
435460 if (R->MaxPressure .getOccupancy (ST) >= NewOcc)
436- break ;
461+ continue ;
437462
438463 LLVM_DEBUG (printRegion (dbgs (), R->Begin , R->End , LIS, 3 );
439464 printLivenessInfo (dbgs (), R->Begin , R->End , LIS));
440465
441- BuildDAG DAG (*R, *this );
442466 const auto MinSchedule = makeMinRegSchedule (DAG.getTopRoots (), *this );
443467 const auto MaxRP = getSchedulePressure (*R, MinSchedule);
444468 LLVM_DEBUG (dbgs () << " Occupancy improvement attempt:\n " ;
@@ -469,8 +493,11 @@ void GCNIterativeScheduler::scheduleLegacyMaxOccupancy(
469493 sortRegionsByPressure (TgtOcc);
470494 auto Occ = Regions.front ()->MaxPressure .getOccupancy (ST);
471495
472- if (TryMaximizeOccupancy && Occ < TgtOcc)
496+ bool IsReentry = false ;
497+ if (TryMaximizeOccupancy && Occ < TgtOcc) {
473498 Occ = tryMaximizeOccupancy (TgtOcc);
499+ IsReentry = true ;
500+ }
474501
475502 // This is really weird but for some magic scheduling regions twice
476503 // gives performance improvement
@@ -489,7 +516,8 @@ void GCNIterativeScheduler::scheduleLegacyMaxOccupancy(
489516 LStrgy.setTargetOccupancy (I == 0 ? 0 : TgtOcc);
490517 for (auto *R : Regions) {
491518 OverrideLegacyStrategy Ovr (*R, LStrgy, *this );
492-
519+ IsReentry |= I > 0 ;
520+ swapIGLPMutations (*R, IsReentry);
493521 Ovr.schedule ();
494522 const auto RP = getRegionPressure (*R);
495523 LLVM_DEBUG (printSchedRP (dbgs (), R->MaxPressure , RP));
@@ -556,8 +584,11 @@ void GCNIterativeScheduler::scheduleILP(
556584 sortRegionsByPressure (TgtOcc);
557585 auto Occ = Regions.front ()->MaxPressure .getOccupancy (ST);
558586
559- if (TryMaximizeOccupancy && Occ < TgtOcc)
587+ bool IsReentry = false ;
588+ if (TryMaximizeOccupancy && Occ < TgtOcc) {
560589 Occ = tryMaximizeOccupancy (TgtOcc);
590+ IsReentry = true ;
591+ }
561592
562593 TgtOcc = std::min (Occ, TgtOcc);
563594 LLVM_DEBUG (dbgs () << " Scheduling using default scheduler, "
@@ -566,7 +597,7 @@ void GCNIterativeScheduler::scheduleILP(
566597
567598 unsigned FinalOccupancy = std::min (Occ, MFI->getOccupancy ());
568599 for (auto *R : Regions) {
569- BuildDAG DAG (*R, *this );
600+ BuildDAG DAG (*R, *this , IsReentry );
570601 const auto ILPSchedule = makeGCNILPScheduler (DAG.getBottomRoots (), *this );
571602
572603 const auto RP = getSchedulePressure (*R, ILPSchedule);
0 commit comments