@@ -1086,7 +1086,8 @@ bool ClusteredLowOccStage::initGCNSchedStage() {
1086
1086
}
1087
1087
1088
1088
// / Allows to easily filter for this stage's debug output.
1089
- #define REMAT_DEBUG (X ) LLVM_DEBUG(dbgs() << " [PreRARemat] " ; X;)
1089
+ #define REMAT_PREFIX " [PreRARemat] "
1090
+ #define REMAT_DEBUG (X ) LLVM_DEBUG(dbgs() << REMAT_PREFIX; X;)
1090
1091
1091
1092
bool PreRARematStage::initGCNSchedStage () {
1092
1093
// FIXME: This pass will invalidate cached BBLiveInMap and MBBLiveIns for
@@ -1115,10 +1116,15 @@ bool PreRARematStage::initGCNSchedStage() {
1115
1116
rematerialize ();
1116
1117
if (GCNTrackers)
1117
1118
DAG.RegionLiveOuts .buildLiveRegMap ();
1118
- REMAT_DEBUG (
1119
- dbgs () << " Retrying function scheduling with new min. occupancy of "
1120
- << AchievedOcc << " from rematerializing (original was "
1121
- << DAG.MinOccupancy << " , target was " << TargetOcc << " )\n " );
1119
+ REMAT_DEBUG ({
1120
+ dbgs () << " Retrying function scheduling with new min. occupancy of "
1121
+ << AchievedOcc << " from rematerializing (original was "
1122
+ << DAG.MinOccupancy ;
1123
+ if (TargetOcc)
1124
+ dbgs () << " , target was " << *TargetOcc;
1125
+ dbgs () << " )\n " ;
1126
+ });
1127
+
1122
1128
if (AchievedOcc > DAG.MinOccupancy ) {
1123
1129
DAG.MinOccupancy = AchievedOcc;
1124
1130
SIMachineFunctionInfo &MFI = *MF.getInfo <SIMachineFunctionInfo>();
@@ -1540,8 +1546,7 @@ bool ClusteredLowOccStage::shouldRevertScheduling(unsigned WavesAfter) {
1540
1546
1541
1547
bool PreRARematStage::shouldRevertScheduling (unsigned WavesAfter) {
1542
1548
return GCNSchedStage::shouldRevertScheduling (WavesAfter) ||
1543
- mayCauseSpilling (WavesAfter) ||
1544
- (IncreaseOccupancy && WavesAfter < TargetOcc);
1549
+ mayCauseSpilling (WavesAfter) || (TargetOcc && WavesAfter < TargetOcc);
1545
1550
}
1546
1551
1547
1552
bool ILPInitialScheduleStage::shouldRevertScheduling (unsigned WavesAfter) {
@@ -1687,78 +1692,63 @@ bool PreRARematStage::allUsesAvailableAt(const MachineInstr *InstToRemat,
1687
1692
}
1688
1693
1689
1694
bool PreRARematStage::canIncreaseOccupancyOrReduceSpill () {
1690
- REMAT_DEBUG ({
1691
- dbgs () << " Collecting rematerializable instructions in " ;
1692
- MF.getFunction ().printAsOperand (dbgs (), false );
1693
- dbgs () << ' \n ' ;
1694
- });
1695
+ const Function &F = MF.getFunction ();
1695
1696
1696
1697
// Maps optimizable regions (i.e., regions at minimum and register-limited
1697
1698
// occupancy, or regions with spilling) to the target RP we would like to
1698
1699
// reach.
1699
1700
DenseMap<unsigned , GCNRPTarget> OptRegions;
1700
- const Function &F = MF.getFunction ();
1701
- unsigned DynamicVGPRBlockSize =
1702
- MF.getInfo <SIMachineFunctionInfo>()->getDynamicVGPRBlockSize ();
1703
-
1704
- std::pair<unsigned , unsigned > WavesPerEU = ST.getWavesPerEU (F);
1705
- const unsigned MaxSGPRsNoSpill = ST.getMaxNumSGPRs (F);
1706
- const unsigned MaxVGPRsNoSpill = ST.getMaxNumVGPRs (F);
1707
- const unsigned MaxSGPRsIncOcc =
1708
- ST.getMaxNumSGPRs (DAG.MinOccupancy + 1 , false );
1709
- const unsigned MaxVGPRsIncOcc =
1710
- ST.getMaxNumVGPRs (DAG.MinOccupancy + 1 , DynamicVGPRBlockSize);
1711
- IncreaseOccupancy = WavesPerEU.second > DAG.MinOccupancy ;
1712
-
1713
- // Collect optimizable regions. If there is spilling in any region we will
1714
- // just try to reduce spilling. Otherwise we will try to increase occupancy by
1715
- // one in the whole function.
1716
- for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
1717
- GCNRegPressure &RP = DAG.Pressure [I];
1718
- // We allow ArchVGPR or AGPR savings to count as savings of the other kind
1719
- // of VGPR only when trying to eliminate spilling. We cannot do this when
1720
- // trying to increase occupancy since VGPR class swaps only occur later in
1721
- // the register allocator i.e., the scheduler will not be able to reason
1722
- // about these savings and will not report an increase in the achievable
1723
- // occupancy, triggering rollbacks.
1724
- GCNRPTarget Target (MaxSGPRsNoSpill, MaxVGPRsNoSpill, MF, RP,
1725
- /* CombineVGPRSavings=*/ true );
1726
- if (!Target.satisfied () && IncreaseOccupancy) {
1727
- // There is spilling in the region and we were so far trying to increase
1728
- // occupancy. Strop trying that and focus on reducing spilling.
1729
- IncreaseOccupancy = false ;
1730
- OptRegions.clear ();
1731
- } else if (IncreaseOccupancy) {
1732
- // There is no spilling in the region, try to increase occupancy.
1733
- Target = GCNRPTarget (MaxSGPRsIncOcc, MaxVGPRsIncOcc, MF, RP,
1734
- /* CombineVGPRSavings=*/ false );
1701
+ unsigned MaxSGPRs = ST.getMaxNumSGPRs (F);
1702
+ unsigned MaxVGPRs = ST.getMaxNumVGPRs (F);
1703
+ auto ResetTargetRegions = [&]() {
1704
+ OptRegions.clear ();
1705
+ for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
1706
+ const GCNRegPressure &RP = DAG.Pressure [I];
1707
+ GCNRPTarget Target (MaxSGPRs, MaxVGPRs, MF, RP);
1708
+ if (!Target.satisfied ())
1709
+ OptRegions.insert ({I, Target});
1735
1710
}
1736
- if (!Target.satisfied ())
1737
- OptRegions.insert ({I, Target});
1738
- }
1739
- if (OptRegions.empty ())
1740
- return false ;
1711
+ };
1741
1712
1742
- #ifndef NDEBUG
1743
- if (IncreaseOccupancy) {
1744
- REMAT_DEBUG (dbgs () << " Occupancy minimal (" << DAG.MinOccupancy
1745
- << " ) in regions:\n " );
1713
+ ResetTargetRegions ();
1714
+ if (!OptRegions.empty () || DAG.MinOccupancy >= MFI.getMaxWavesPerEU ()) {
1715
+ // In addition to register usage being above addressable limits, occupancy
1716
+ // below the minimum is considered like "spilling" as well.
1717
+ TargetOcc = std::nullopt;
1746
1718
} else {
1747
- REMAT_DEBUG (dbgs () << " Spilling w.r.t. minimum target occupancy ("
1748
- << WavesPerEU.first << " ) in regions:\n " );
1749
- }
1750
- for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
1751
- if (auto OptIt = OptRegions.find (I); OptIt != OptRegions.end ())
1752
- REMAT_DEBUG (dbgs () << " [" << I << " ] " << OptIt->getSecond () << ' \n ' );
1719
+ // There is no spilling and room to improve occupancy; set up "increased
1720
+ // occupancy targets" for all regions.
1721
+ TargetOcc = DAG.MinOccupancy + 1 ;
1722
+ unsigned VGPRBlockSize =
1723
+ MF.getInfo <SIMachineFunctionInfo>()->getDynamicVGPRBlockSize ();
1724
+ MaxSGPRs = ST.getMaxNumSGPRs (*TargetOcc, false );
1725
+ MaxVGPRs = ST.getMaxNumVGPRs (*TargetOcc, VGPRBlockSize);
1726
+ ResetTargetRegions ();
1753
1727
}
1754
- #endif
1755
-
1756
- // When we are reducing spilling, the target is the minimum target number of
1757
- // waves/EU determined by the subtarget. In cases where either one of
1758
- // "amdgpu-num-sgpr" or "amdgpu-num-vgpr" are set on the function, the current
1759
- // minimum region occupancy may be higher than the latter.
1760
- TargetOcc = IncreaseOccupancy ? DAG.MinOccupancy + 1
1761
- : std::max (DAG.MinOccupancy , WavesPerEU.first );
1728
+ REMAT_DEBUG ({
1729
+ dbgs () << " Analyzing " ;
1730
+ MF.getFunction ().printAsOperand (dbgs (), false );
1731
+ dbgs () << " : " ;
1732
+ if (OptRegions.empty ()) {
1733
+ dbgs () << " no objective to achieve, occupancy is maximal at "
1734
+ << MFI.getMaxWavesPerEU ();
1735
+ } else if (!TargetOcc) {
1736
+ dbgs () << " reduce spilling (minimum target occupancy is "
1737
+ << MFI.getMinWavesPerEU () << ' )' ;
1738
+ } else {
1739
+ dbgs () << " increase occupancy from " << DAG.MinOccupancy << " to "
1740
+ << TargetOcc;
1741
+ }
1742
+ dbgs () << ' \n ' ;
1743
+ for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
1744
+ if (auto OptIt = OptRegions.find (I); OptIt != OptRegions.end ()) {
1745
+ dbgs () << REMAT_PREFIX << " [" << I << " ] " << OptIt->getSecond ()
1746
+ << ' \n ' ;
1747
+ }
1748
+ }
1749
+ });
1750
+ if (OptRegions.empty ())
1751
+ return false ;
1762
1752
1763
1753
// Accounts for a reduction in RP in an optimizable region. Returns whether we
1764
1754
// estimate that we have identified enough rematerialization opportunities to
@@ -1767,7 +1757,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
1767
1757
auto ReduceRPInRegion = [&](auto OptIt, Register Reg, LaneBitmask Mask,
1768
1758
bool &Progress) -> bool {
1769
1759
GCNRPTarget &Target = OptIt->getSecond ();
1770
- if (!Target.isSaveBeneficial (Reg, DAG. MRI ))
1760
+ if (!Target.isSaveBeneficial (Reg))
1771
1761
return false ;
1772
1762
Progress = true ;
1773
1763
Target.saveReg (Reg, Mask, DAG.MRI );
@@ -1876,7 +1866,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
1876
1866
}
1877
1867
}
1878
1868
1879
- if (IncreaseOccupancy ) {
1869
+ if (TargetOcc ) {
1880
1870
// We were trying to increase occupancy but failed, abort the stage.
1881
1871
REMAT_DEBUG (dbgs () << " Cannot increase occupancy\n " );
1882
1872
Rematerializations.clear ();
@@ -1979,7 +1969,9 @@ void PreRARematStage::rematerialize() {
1979
1969
// All regions impacted by at least one rematerialization must be rescheduled.
1980
1970
// Maximum pressure must also be recomputed for all regions where it changed
1981
1971
// non-predictably and checked against the target occupancy.
1982
- AchievedOcc = TargetOcc;
1972
+ unsigned DynamicVGPRBlockSize =
1973
+ MF.getInfo <SIMachineFunctionInfo>()->getDynamicVGPRBlockSize ();
1974
+ AchievedOcc = MFI.getMaxWavesPerEU ();
1983
1975
for (auto &[I, OriginalRP] : ImpactedRegions) {
1984
1976
bool IsEmptyRegion = DAG.Regions [I].first == DAG.Regions [I].second ;
1985
1977
RescheduleRegions[I] = !IsEmptyRegion;
@@ -2003,9 +1995,8 @@ void PreRARematStage::rematerialize() {
2003
1995
}
2004
1996
}
2005
1997
DAG.Pressure [I] = RP;
2006
- AchievedOcc = std::min (
2007
- AchievedOcc, RP.getOccupancy (ST, MF.getInfo <SIMachineFunctionInfo>()
2008
- ->getDynamicVGPRBlockSize ()));
1998
+ AchievedOcc =
1999
+ std::min (AchievedOcc, RP.getOccupancy (ST, DynamicVGPRBlockSize));
2009
2000
}
2010
2001
REMAT_DEBUG (dbgs () << " Achieved occupancy " << AchievedOcc << " \n " );
2011
2002
}
@@ -2035,7 +2026,7 @@ void PreRARematStage::finalizeGCNSchedStage() {
2035
2026
// which case we do not want to rollback either (the rescheduling was already
2036
2027
// reverted in PreRARematStage::shouldRevertScheduling in such cases).
2037
2028
unsigned MaxOcc = std::max (AchievedOcc, DAG.MinOccupancy );
2038
- if (!IncreaseOccupancy || MaxOcc >= TargetOcc)
2029
+ if (!TargetOcc || MaxOcc >= * TargetOcc)
2039
2030
return ;
2040
2031
2041
2032
REMAT_DEBUG (dbgs () << " Rolling back all rematerializations\n " );
0 commit comments