@@ -988,7 +988,6 @@ void GCNScheduleDAGMILive::runSchedStages() {
988988 ->reset (MRI, RegionLiveOuts.getLiveRegsForRegionIdx (
989989 Stage->getRegionIdx ()));
990990 }
991-
992991 ScheduleDAGMILive::schedule ();
993992 Stage->finalizeGCNRegion ();
994993 }
@@ -1818,7 +1817,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18181817 auto NumRegs = SIRegisterInfo::getNumCoveredRegs (Mask);
18191818 unsigned I = OptIt->getFirst ();
18201819 unsigned &Excess = OptIt->getSecond ();
1821- if (NumRegs >= Excess)
1820+ if (NumRegs >= Excess)
18221821 OptRegions.erase (I);
18231822 else
18241823 Excess -= NumRegs;
@@ -1854,41 +1853,32 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18541853 if (!UseMI || DefMI.getParent () == UseMI->getParent ())
18551854 continue ;
18561855
1857- // Do not rematerialize an instruction if it uses or is used by an
1858- // instruction that we have designated for rematerialization.
1859- // FIXME: Allow for rematerialization chains: this requires 1. updating
1860- // remat points to account for uses that are rematerialized, and 2. either
1861- // rematerializing the candidates in careful ordering, or deferring the
1862- // MBB RP walk until the entire chain has been rematerialized.
1863- if (Rematerializations.contains (UseMI) ||
1864- llvm::any_of (DefMI.operands (), [&RematRegs](MachineOperand &MO) {
1865- return MO.isReg () && RematRegs.contains (MO.getReg ());
1866- }))
1867- continue ;
1868-
18691856 // Do not rematerialize an instruction it it uses registers that aren't
18701857 // available at its use. This ensures that we are not extending any live
18711858 // range while rematerializing.
18721859 SlotIndex DefIdx = DAG.LIS ->getInstructionIndex (DefMI);
18731860 SlotIndex UseIdx = DAG.LIS ->getInstructionIndex (*UseMI).getRegSlot (true );
1861+
18741862 if (!allUsesAvailableAt (&DefMI, DefIdx, UseIdx))
18751863 continue ;
18761864
18771865 REMAT_DEBUG (dbgs () << " Region " << I << " : remat instruction " << DefMI);
1878- RematInstruction &Remat =
1879- Rematerializations.try_emplace (&DefMI, I, UseMI).first ->second ;
1866+ RematInstruction &Temp = *Remats.insert ({&DefMI, I, UseMI});
18801867
18811868 bool RematUseful = false ;
18821869 if (auto It = OptRegions.find (I); It != OptRegions.end ()) {
18831870 // Optimistically consider that moving the instruction out of its
18841871 // defining region will reduce RP in the latter; this assumes that
18851872 // maximum RP in the region is reached somewhere between the defining
18861873 // instruction and the end of the region.
1874+ // Since we only remat instructions with one use, we can assume that we
1875+ // adding a new remat instead of merely updating the remat position.
18871876 REMAT_DEBUG (dbgs () << " Defining region is optimizable\n " );
18881877 RematUseful = true ;
18891878 LaneBitmask Mask = DAG.RegionLiveOuts .getLiveRegsForRegionIdx (I)[Reg];
1890- if (ReduceRPInRegion (It, Mask))
1891- return true ;
1879+ if (ReduceRPInRegion (It, Mask)) {
1880+ return Remats.resolveInsertPos (&DAG.MRI , DAG.LIS );
1881+ }
18921882 }
18931883
18941884 for (unsigned LIRegion = 0 ; LIRegion != E; ++LIRegion) {
@@ -1897,7 +1887,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18971887 auto It = DAG.LiveIns [LIRegion].find (Reg);
18981888 if (It == DAG.LiveIns [LIRegion].end () || It->second .none ())
18991889 continue ;
1900- Remat .LiveInRegions .insert (LIRegion);
1890+ Temp .LiveInRegions .insert (LIRegion);
19011891
19021892 // Account for the reduction in RP due to the rematerialization in an
19031893 // optimizable region in which the defined register is a live-in. This
@@ -1909,14 +1899,13 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
19091899 REMAT_DEBUG (dbgs () << " Live-in in region " << LIRegion << ' \n ' );
19101900 RematUseful = true ;
19111901 if (ReduceRPInRegion (It, DAG.LiveIns [LIRegion][Reg]))
1912- return true ;
1902+ return Remats. resolveInsertPos (&DAG. MRI , DAG. LIS ) ;
19131903 }
19141904 }
19151905
19161906 // If the instruction is not a live-in or live-out in any optimizable
19171907 // region then there is no point in rematerializing it.
19181908 if (!RematUseful) {
1919- Rematerializations.pop_back ();
19201909 REMAT_DEBUG (dbgs () << " No impact, not rematerializing instruction\n " );
19211910 } else {
19221911 RematRegs.insert (Reg);
@@ -1927,11 +1916,11 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
19271916 if (IncreaseOccupancy) {
19281917 // We were trying to increase occupancy but failed, abort the stage.
19291918 REMAT_DEBUG (dbgs () << " Cannot increase occupancy\n " );
1930- Rematerializations .clear ();
1919+ Remats .clear ();
19311920 return false ;
19321921 }
19331922 REMAT_DEBUG (dbgs () << " Can reduce but not eliminate spilling\n " );
1934- return !Rematerializations .empty ();
1923+ return !Remats .empty () && Remats. resolveInsertPos (&DAG. MRI , DAG. LIS );
19351924}
19361925
19371926void PreRARematStage::rematerialize () {
@@ -1943,19 +1932,23 @@ void PreRARematStage::rematerialize() {
19431932 DenseSet<unsigned > RecomputeRP;
19441933 SlotIndexes *Slots = DAG.LIS ->getSlotIndexes ();
19451934
1935+ // Remat the dependencies last
1936+ Remats.sort (&DAG.MRI );
1937+
19461938 // Rematerialize all instructions.
1947- for (auto &[DefMI, Remat] : Rematerializations) {
1948- MachineBasicBlock::iterator InsertPos (Remat.UseMI );
1939+ for (auto &Remat : Remats) {
1940+ MachineInstr *DefMI = Remat.DefMI ;
1941+ MachineBasicBlock::iterator InsertPos = Remat.InsertPos ;
19491942 Register Reg = DefMI->getOperand (0 ).getReg ();
19501943 unsigned SubReg = DefMI->getOperand (0 ).getSubReg ();
1951-
19521944 // Rematerialize DefMI to its use block.
19531945 TII->reMaterialize (*InsertPos->getParent (), InsertPos, Reg, SubReg, *DefMI,
19541946 *DAG.TRI );
19551947 Remat.RematMI = &*std::prev (InsertPos);
19561948 Remat.RematMI ->getOperand (0 ).setSubReg (SubReg);
19571949 DAG.LIS ->InsertMachineInstrInMaps (*Remat.RematMI );
19581950
1951+
19591952 // Update region boundaries in regions we sinked from (remove defining MI)
19601953 // and to (insert MI rematerialized in use block). Only then we can erase
19611954 // the original MI.
@@ -2054,6 +2047,20 @@ void PreRARematStage::rematerialize() {
20542047 UpdateLiveRange (SubRange);
20552048 }
20562049 }
2050+ for (auto &Remat : reverse (Remats)) {
2051+ if (Remat.HasDependency ) {
2052+ for (auto &ROp : Remat.RematMI ->operands ()) {
2053+ if (!ROp.isReg () || !ROp.getReg () || !ROp.readsReg ())
2054+ continue ;
2055+ auto UseReg = ROp.getReg ();
2056+ if (!UseReg.isVirtual ())
2057+ continue ;
2058+
2059+ DAG.LIS ->removeInterval (UseReg);
2060+ DAG.LIS ->createAndComputeVirtRegInterval (UseReg);
2061+ }
2062+ }
2063+ }
20572064
20582065 // All regions impacted by at least one rematerialization must be rescheduled.
20592066 // Maximum pressure must also be recomputed for all regions where it changed
@@ -2066,6 +2073,7 @@ void PreRARematStage::rematerialize() {
20662073 continue ;
20672074
20682075 GCNRegPressure RP;
2076+
20692077 if (IsEmptyRegion) {
20702078 RP = getRegPressure (DAG.MRI , DAG.LiveIns [I]);
20712079 } else {
@@ -2140,10 +2148,11 @@ void PreRARematStage::finalizeGCNSchedStage() {
21402148 static_cast <const SIInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
21412149
21422150 // Rollback the rematerializations.
2143- for (const auto &[_, Remat] : Rematerializations ) {
2151+ for (auto &Remat : Remats ) {
21442152 MachineInstr &RematMI = *Remat.RematMI ;
2145- MachineBasicBlock::iterator InsertPos (DAG.Regions [Remat.DefRegion ].second );
21462153 MachineBasicBlock *MBB = getRegionMBB (MF, DAG.Regions [Remat.DefRegion ]);
2154+ MachineBasicBlock::iterator InsertPos (MBB->end ());
2155+
21472156 Register Reg = RematMI.getOperand (0 ).getReg ();
21482157 unsigned SubReg = RematMI.getOperand (0 ).getSubReg ();
21492158
@@ -2156,6 +2165,7 @@ void PreRARematStage::finalizeGCNSchedStage() {
21562165 DAG.LIS ->InsertMachineInstrInMaps (*NewMI);
21572166
21582167 // Erase rematerialized MI.
2168+ DAG.updateRegionBoundaries (DAG.Regions , RematMI, nullptr );
21592169 RematMI.eraseFromParent ();
21602170 DAG.LIS ->RemoveMachineInstrFromMaps (RematMI);
21612171
@@ -2166,6 +2176,7 @@ void PreRARematStage::finalizeGCNSchedStage() {
21662176 // Re-add the register as a live-in in all regions it used to be one in.
21672177 for (unsigned LIRegion : Remat.LiveInRegions )
21682178 DAG.LiveIns [LIRegion].insert ({Reg, RegMasks.at ({LIRegion, Reg})});
2179+
21692180 }
21702181
21712182 // Reset RP in all impacted regions.
0 commit comments