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