@@ -1698,7 +1698,7 @@ struct ExcessRP {
1698
1698
unsigned ArchVGPRs = 0 ;
1699
1699
// / Number of excess AGPRs.
1700
1700
unsigned AGPRs = 0 ;
1701
- // / For unified register files, number of excess VGPRs.
1701
+ // / For unified register files, number of excess VGPRs. 0 otherwise.
1702
1702
unsigned VGPRs = 0 ;
1703
1703
// / For unified register files with AGPR usage, number of excess ArchVGPRs to
1704
1704
// / save before we are able to save a whole allocation granule.
@@ -1707,29 +1707,26 @@ struct ExcessRP {
1707
1707
bool HasAGPRs = false ;
1708
1708
// / Whether the subtarget has a unified RF.
1709
1709
bool UnifiedRF;
1710
+ // / Whether we consider that ArchVGPRs can be spilled to AGPRs and the other
1711
+ // / way around.
1712
+ bool AllowVGPRToVGPRSpill;
1710
1713
1711
1714
// / Constructs the excess RP model; determines the excess pressure w.r.t. a
1712
1715
// / maximum number of allowed SGPRs/VGPRs.
1713
1716
ExcessRP (const GCNSubtarget &ST, const GCNRegPressure &RP, unsigned MaxSGPRs,
1714
- unsigned MaxVGPRs);
1717
+ unsigned MaxVGPRs, bool AllowVGPRToVGPRSpill );
1715
1718
1716
1719
// / Accounts for \p NumRegs saved SGPRs in the model. Returns whether saving
1717
1720
// / these SGPRs helped reduce excess pressure.
1718
1721
bool saveSGPRs (unsigned NumRegs) { return saveRegs (SGPRs, NumRegs); }
1719
1722
1720
- // / Accounts for \p NumRegs saved ArchVGPRs in the model. If \p
1721
- // / UseArchVGPRForAGPRSpill is true, saved ArchVGPRs are used to save excess
1722
- // / AGPRs once excess ArchVGPR pressure has been eliminated. Returns whether
1723
- // / saving these ArchVGPRs helped reduce excess pressure.
1724
- bool saveArchVGPRs (unsigned NumRegs, bool UseArchVGPRForAGPRSpill);
1723
+ // / Accounts for \p NumRegs saved ArchVGPRs in the model. Returns whether
1724
+ // / saving these ArchGPRs helped reduce excess pressure.
1725
+ bool saveArchVGPRs (unsigned NumRegs);
1725
1726
1726
1727
// / Accounts for \p NumRegs saved AGPRs in the model. Returns whether saving
1727
1728
// / these AGPRs helped reduce excess pressure.
1728
- bool saveAGPRs (unsigned NumRegs) {
1729
- return saveRegs (AGPRs, NumRegs) ||
1730
- (UnifiedRF && saveRegs (VGPRs, NumRegs)) ||
1731
- saveRegs (ArchVGPRs, NumRegs);
1732
- }
1729
+ bool saveAGPRs (unsigned NumRegs);
1733
1730
1734
1731
// / Returns whether there is any excess register pressure.
1735
1732
operator bool () const { return SGPRs || ArchVGPRs || AGPRs || VGPRs; }
@@ -1755,8 +1752,10 @@ struct ExcessRP {
1755
1752
} // namespace
1756
1753
1757
1754
ExcessRP::ExcessRP (const GCNSubtarget &ST, const GCNRegPressure &RP,
1758
- unsigned MaxSGPRs, unsigned MaxVGPRs)
1759
- : UnifiedRF(ST.hasGFX90AInsts()) {
1755
+ unsigned MaxSGPRs, unsigned MaxVGPRs,
1756
+ bool AllowVGPRToVGPRSpill)
1757
+ : UnifiedRF(ST.hasGFX90AInsts()),
1758
+ AllowVGPRToVGPRSpill(AllowVGPRToVGPRSpill) {
1760
1759
// Compute excess SGPR pressure.
1761
1760
unsigned NumSGPRs = RP.getSGPRNum ();
1762
1761
if (NumSGPRs > MaxSGPRs)
@@ -1801,15 +1800,15 @@ ExcessRP::ExcessRP(const GCNSubtarget &ST, const GCNRegPressure &RP,
1801
1800
}
1802
1801
}
1803
1802
1804
- bool ExcessRP::saveArchVGPRs (unsigned NumRegs, bool UseArchVGPRForAGPRSpill ) {
1803
+ bool ExcessRP::saveArchVGPRs (unsigned NumRegs) {
1805
1804
bool Progress = saveRegs (ArchVGPRs, NumRegs);
1806
1805
if (!NumRegs)
1807
1806
return Progress;
1808
1807
1809
1808
if (!UnifiedRF) {
1810
- if (UseArchVGPRForAGPRSpill )
1809
+ if (AllowVGPRToVGPRSpill )
1811
1810
Progress |= saveRegs (AGPRs, NumRegs);
1812
- } else if (HasAGPRs && (VGPRs || (UseArchVGPRForAGPRSpill && AGPRs))) {
1811
+ } else if (HasAGPRs && (VGPRs || (AllowVGPRToVGPRSpill && AGPRs))) {
1813
1812
// There is progress as long as there are VGPRs left to save, even if the
1814
1813
// save induced by this particular call does not cross an ArchVGPR alignment
1815
1814
// barrier.
@@ -1836,13 +1835,21 @@ bool ExcessRP::saveArchVGPRs(unsigned NumRegs, bool UseArchVGPRForAGPRSpill) {
1836
1835
// Prioritize saving generic VGPRs, then AGPRs if we allow AGPR-to-ArchVGPR
1837
1836
// spilling and have some free ArchVGPR slots.
1838
1837
saveRegs (VGPRs, NumSavedRegs);
1839
- if (UseArchVGPRForAGPRSpill )
1838
+ if (AllowVGPRToVGPRSpill )
1840
1839
saveRegs (AGPRs, NumSavedRegs);
1841
1840
} else {
1842
1841
// No AGPR usage in the region i.e., no allocation granule to worry about.
1843
1842
Progress |= saveRegs (VGPRs, NumRegs);
1844
1843
}
1844
+ return Progress;
1845
+ }
1845
1846
1847
+ bool ExcessRP::saveAGPRs (unsigned NumRegs) {
1848
+ bool Progress = saveRegs (AGPRs, NumRegs);
1849
+ if (UnifiedRF)
1850
+ Progress |= saveRegs (VGPRs, NumRegs);
1851
+ if (AllowVGPRToVGPRSpill)
1852
+ Progress |= saveRegs (ArchVGPRs, NumRegs);
1846
1853
return Progress;
1847
1854
}
1848
1855
@@ -1873,15 +1880,22 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
1873
1880
// one in the whole function.
1874
1881
for (unsigned I = 0 , E = DAG.Regions .size (); I != E; ++I) {
1875
1882
GCNRegPressure &RP = DAG.Pressure [I];
1876
- ExcessRP Excess (ST, RP, MaxSGPRsNoSpill, MaxVGPRsNoSpill);
1883
+ // We allow saved VGPRs of one category (ArchVGPR or AGPR) to be considered
1884
+ // as free spill slots for the other category only when we are just trying
1885
+ // to eliminate spilling. At this point we err on the conservative side and
1886
+ // do not increase register-to-register spilling for the sake of increasing
1887
+ // occupancy.
1888
+ ExcessRP Excess (ST, RP, MaxSGPRsNoSpill, MaxVGPRsNoSpill,
1889
+ /* AllowVGPRToVGPRSpill=*/ true );
1877
1890
if (Excess && IncreaseOccupancy) {
1878
1891
// There is spilling in the region and we were so far trying to increase
1879
1892
// occupancy. Strop trying that and focus on reducing spilling.
1880
1893
IncreaseOccupancy = false ;
1881
1894
OptRegions.clear ();
1882
1895
} else if (IncreaseOccupancy) {
1883
1896
// There is no spilling in the region, try to increase occupancy.
1884
- Excess = ExcessRP (ST, RP, MaxSGPRsIncOcc, MaxVGPRsIncOcc);
1897
+ Excess = ExcessRP (ST, RP, MaxSGPRsIncOcc, MaxVGPRsIncOcc,
1898
+ /* AllowVGPRToVGPRSpill=*/ false );
1885
1899
}
1886
1900
if (Excess)
1887
1901
OptRegions.insert ({I, Excess});
@@ -1916,19 +1930,12 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
1916
1930
bool &Progress) -> bool {
1917
1931
ExcessRP &Excess = OptIt->getSecond ();
1918
1932
unsigned NumRegs = SIRegisterInfo::getNumCoveredRegs (Mask);
1919
- if (SRI->isSGPRClass (RC)) {
1933
+ if (SRI->isSGPRClass (RC))
1920
1934
Progress |= Excess.saveSGPRs (NumRegs);
1921
- } else if (SRI->isAGPRClass (RC)) {
1935
+ else if (SRI->isAGPRClass (RC))
1922
1936
Progress |= Excess.saveAGPRs (NumRegs);
1923
- } else {
1924
- // We allow saved ArchVGPRs to be considered as free spill slots for AGPRs
1925
- // only when we are just trying to eliminate spilling to memory. At this
1926
- // point we err on the conservative side and do not increase
1927
- // register-to-register spilling for the sake of increasing occupancy.
1928
- Progress |=
1929
- Excess.saveArchVGPRs (NumRegs,
1930
- /* UseArchVGPRForAGPRSpill=*/ !IncreaseOccupancy);
1931
- }
1937
+ else
1938
+ Progress |= Excess.saveArchVGPRs (NumRegs);
1932
1939
if (!Excess)
1933
1940
OptRegions.erase (OptIt->getFirst ());
1934
1941
return OptRegions.empty ();
0 commit comments