@@ -765,6 +765,10 @@ GCNScheduleDAGMILive::GCNScheduleDAGMILive(
765765 StartingOccupancy(MFI.getOccupancy()), MinOccupancy(StartingOccupancy),
766766 RegionLiveOuts(this , /* IsLiveOut=*/ true ) {
767767
768+ // We want regions with a single MI to be scheduled so that we can reason
769+ // about them correctly during scheduling stages that move MIs between regions
770+ // (e.g., rematerialization).
771+ ScheduleSingleMIRegions = true ;
768772 LLVM_DEBUG (dbgs () << " Starting occupancy is " << StartingOccupancy << " .\n " );
769773 if (RelaxedOcc) {
770774 MinOccupancy = std::min (MFI.getMinAllowedOccupancy (), StartingOccupancy);
@@ -1098,6 +1102,13 @@ bool PreRARematStage::initGCNSchedStage() {
10981102 DAG.Regions .size () == 1 || !canIncreaseOccupancyOrReduceSpill ())
10991103 return false ;
11001104
1105+ // Map all MIs to their parent region.
1106+ for (unsigned I = 0 , E = DAG.Regions .size (); I < E; ++I) {
1107+ RegionBoundaries Region = DAG.Regions [I];
1108+ for (auto MI = Region.first ; MI != Region.second ; ++MI)
1109+ MIRegion.insert ({&*MI, I});
1110+ }
1111+
11011112 // Rematerialize identified instructions and update scheduler's state.
11021113 rematerialize ();
11031114 if (GCNTrackers)
@@ -1831,7 +1842,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18311842 // Cache set of registers that are going to be rematerialized.
18321843 DenseSet<unsigned > RematRegs;
18331844
1834- // identify rematerializable instructions in the function.
1845+ // Identify rematerializable instructions in the function.
18351846 for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
18361847 auto Region = DAG.Regions [I];
18371848 for (auto MI = Region.first ; MI != Region.second ; ++MI) {
@@ -1941,6 +1952,8 @@ void PreRARematStage::rematerialize() {
19411952 MachineBasicBlock::iterator InsertPos = Remat.InsertPos ;
19421953 Register Reg = DefMI->getOperand (0 ).getReg ();
19431954 unsigned SubReg = DefMI->getOperand (0 ).getSubReg ();
1955+ unsigned DefRegion = MIRegion.at (DefMI);
1956+
19441957 // Rematerialize DefMI to its use block.
19451958 TII->reMaterialize (*InsertPos->getParent (), InsertPos, Reg, SubReg, *DefMI,
19461959 *DAG.TRI );
@@ -1952,8 +1965,12 @@ void PreRARematStage::rematerialize() {
19521965 // Update region boundaries in regions we sinked from (remove defining MI)
19531966 // and to (insert MI rematerialized in use block). Only then we can erase
19541967 // the original MI.
1955- DAG.updateRegionBoundaries (DAG.Regions , DefMI, nullptr );
1956- DAG.updateRegionBoundaries (DAG.Regions , InsertPos, Remat.RematMI );
1968+ DAG.updateRegionBoundaries (DAG.Regions [DefRegion], DefMI, nullptr );
1969+ auto UseRegion = MIRegion.find (Remat.UseMI );
1970+ if (UseRegion != MIRegion.end ()) {
1971+ DAG.updateRegionBoundaries (DAG.Regions [UseRegion->second ], InsertPos,
1972+ Remat.RematMI );
1973+ }
19571974 DefMI->eraseFromParent ();
19581975 DAG.LIS ->RemoveMachineInstrFromMaps (*DefMI);
19591976
@@ -2008,8 +2025,8 @@ void PreRARematStage::rematerialize() {
20082025 }
20092026 // RP in the region from which the instruction was rematerialized may or may
20102027 // not decrease.
2011- ImpactedRegions.insert ({Remat. DefRegion , DAG.Pressure [Remat. DefRegion ]});
2012- RecomputeRP.insert (Remat. DefRegion );
2028+ ImpactedRegions.insert ({DefRegion, DAG.Pressure [DefRegion]});
2029+ RecomputeRP.insert (DefRegion);
20132030
20142031 // Update the register's live interval manually. This is aligned with the
20152032 // instruction collection phase in that it assumes a single def and use
@@ -2150,7 +2167,8 @@ void PreRARematStage::finalizeGCNSchedStage() {
21502167 // Rollback the rematerializations.
21512168 for (auto &Remat : Remats) {
21522169 MachineInstr &RematMI = *Remat.RematMI ;
2153- MachineBasicBlock *MBB = getRegionMBB (MF, DAG.Regions [Remat.DefRegion ]);
2170+ unsigned DefRegion = MIRegion.at (DefMI);
2171+ MachineBasicBlock *MBB = getRegionMBB (MF, DAG.Regions [DefRegion]);
21542172 MachineBasicBlock::iterator InsertPos (MBB->end ());
21552173
21562174 Register Reg = RematMI.getOperand (0 ).getReg ();
@@ -2164,6 +2182,13 @@ void PreRARematStage::finalizeGCNSchedStage() {
21642182 NewMI->getOperand (0 ).setSubReg (SubReg);
21652183 DAG.LIS ->InsertMachineInstrInMaps (*NewMI);
21662184
2185+ auto UseRegion = MIRegion.find (Remat.UseMI );
2186+ if (UseRegion != MIRegion.end ()) {
2187+ DAG.updateRegionBoundaries (DAG.Regions [UseRegion->second ], RematMI,
2188+ nullptr );
2189+ }
2190+ DAG.updateRegionBoundaries (DAG.Regions [DefRegion], InsertPos, NewMI);
2191+
21672192 // Erase rematerialized MI.
21682193 DAG.updateRegionBoundaries (DAG.Regions , RematMI, nullptr );
21692194 RematMI.eraseFromParent ();
@@ -2187,49 +2212,25 @@ void PreRARematStage::finalizeGCNSchedStage() {
21872212}
21882213
21892214void GCNScheduleDAGMILive::updateRegionBoundaries (
2190- SmallVectorImpl<RegionBoundaries> &RegionBoundaries,
2191- MachineBasicBlock::iterator MI, MachineInstr *NewMI) {
2192- unsigned I = 0 , E = RegionBoundaries.size ();
2193- // Search for first region of the block where MI is located. We may encounter
2194- // an empty region if all instructions from an initially non-empty region were
2195- // removed.
2196- while (I != E && RegionBoundaries[I].first != RegionBoundaries[I].second &&
2197- MI->getParent () != RegionBoundaries[I].first ->getParent ())
2198- ++I;
2199-
2200- for (; I != E; ++I) {
2201- auto &Bounds = RegionBoundaries[I];
2202- assert (MI != Bounds.second && " cannot insert at region end" );
2203- assert (!NewMI || NewMI != Bounds.second && " cannot remove at region end" );
2204-
2205- // We may encounter an empty region if all of the region' instructions were
2206- // previously removed.
2207- if (Bounds.first == Bounds.second ) {
2208- if (MI->getParent ()->end () != Bounds.second )
2209- return ;
2210- continue ;
2211- }
2212- if (MI->getParent () != Bounds.first ->getParent ())
2213- return ;
2214-
2215- // We only care for modifications at the beginning of the region since the
2216- // upper region boundary is exclusive.
2217- if (MI != Bounds.first )
2218- continue ;
2219- if (!NewMI) {
2220- // This is an MI removal, which may leave the region empty; in such cases
2221- // set both boundaries to the removed instruction's MBB's end.
2222- MachineBasicBlock::iterator NextMI = std::next (MI);
2223- if (NextMI != Bounds.second )
2224- Bounds.first = NextMI;
2225- else
2226- Bounds.first = Bounds.second ;
2227- } else {
2228- // This is an MI insertion at the beggining of the region.
2229- Bounds.first = NewMI;
2230- }
2215+ RegionBoundaries &RegionBounds, MachineBasicBlock::iterator MI,
2216+ MachineInstr *NewMI) {
2217+ assert (!NewMI ||
2218+ NewMI != RegionBounds.second && " cannot remove at region end" );
2219+
2220+ if (RegionBounds.first == RegionBounds.second ) {
2221+ assert (NewMI && " cannot remove from an empty region" );
2222+ RegionBounds.first = NewMI;
22312223 return ;
22322224 }
2225+
2226+ // We only care for modifications at the beginning of a non-empty region since
2227+ // the upper region boundary is exclusive.
2228+ if (MI != RegionBounds.first )
2229+ return ;
2230+ if (!NewMI)
2231+ RegionBounds.first = std::next (MI); // Removal
2232+ else
2233+ RegionBounds.first = NewMI; // Insertion
22332234}
22342235
22352236static bool hasIGLPInstrs (ScheduleDAGInstrs *DAG) {
0 commit comments