Skip to content

Commit 2edbe3f

Browse files
committed
Allow AGPRs to be used as spill slots for ArchVGPRs based on flag
1 parent e40daa3 commit 2edbe3f

File tree

1 file changed

+38
-31
lines changed

1 file changed

+38
-31
lines changed

llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,7 @@ struct ExcessRP {
16981698
unsigned ArchVGPRs = 0;
16991699
/// Number of excess AGPRs.
17001700
unsigned AGPRs = 0;
1701-
/// For unified register files, number of excess VGPRs.
1701+
/// For unified register files, number of excess VGPRs. 0 otherwise.
17021702
unsigned VGPRs = 0;
17031703
/// For unified register files with AGPR usage, number of excess ArchVGPRs to
17041704
/// save before we are able to save a whole allocation granule.
@@ -1707,29 +1707,26 @@ struct ExcessRP {
17071707
bool HasAGPRs = false;
17081708
/// Whether the subtarget has a unified RF.
17091709
bool UnifiedRF;
1710+
/// Whether we consider that ArchVGPRs can be spilled to AGPRs and the other
1711+
/// way around.
1712+
bool AllowVGPRToVGPRSpill;
17101713

17111714
/// Constructs the excess RP model; determines the excess pressure w.r.t. a
17121715
/// maximum number of allowed SGPRs/VGPRs.
17131716
ExcessRP(const GCNSubtarget &ST, const GCNRegPressure &RP, unsigned MaxSGPRs,
1714-
unsigned MaxVGPRs);
1717+
unsigned MaxVGPRs, bool AllowVGPRToVGPRSpill);
17151718

17161719
/// Accounts for \p NumRegs saved SGPRs in the model. Returns whether saving
17171720
/// these SGPRs helped reduce excess pressure.
17181721
bool saveSGPRs(unsigned NumRegs) { return saveRegs(SGPRs, NumRegs); }
17191722

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);
17251726

17261727
/// Accounts for \p NumRegs saved AGPRs in the model. Returns whether saving
17271728
/// 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);
17331730

17341731
/// Returns whether there is any excess register pressure.
17351732
operator bool() const { return SGPRs || ArchVGPRs || AGPRs || VGPRs; }
@@ -1755,8 +1752,10 @@ struct ExcessRP {
17551752
} // namespace
17561753

17571754
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) {
17601759
// Compute excess SGPR pressure.
17611760
unsigned NumSGPRs = RP.getSGPRNum();
17621761
if (NumSGPRs > MaxSGPRs)
@@ -1801,15 +1800,15 @@ ExcessRP::ExcessRP(const GCNSubtarget &ST, const GCNRegPressure &RP,
18011800
}
18021801
}
18031802

1804-
bool ExcessRP::saveArchVGPRs(unsigned NumRegs, bool UseArchVGPRForAGPRSpill) {
1803+
bool ExcessRP::saveArchVGPRs(unsigned NumRegs) {
18051804
bool Progress = saveRegs(ArchVGPRs, NumRegs);
18061805
if (!NumRegs)
18071806
return Progress;
18081807

18091808
if (!UnifiedRF) {
1810-
if (UseArchVGPRForAGPRSpill)
1809+
if (AllowVGPRToVGPRSpill)
18111810
Progress |= saveRegs(AGPRs, NumRegs);
1812-
} else if (HasAGPRs && (VGPRs || (UseArchVGPRForAGPRSpill && AGPRs))) {
1811+
} else if (HasAGPRs && (VGPRs || (AllowVGPRToVGPRSpill && AGPRs))) {
18131812
// There is progress as long as there are VGPRs left to save, even if the
18141813
// save induced by this particular call does not cross an ArchVGPR alignment
18151814
// barrier.
@@ -1836,13 +1835,21 @@ bool ExcessRP::saveArchVGPRs(unsigned NumRegs, bool UseArchVGPRForAGPRSpill) {
18361835
// Prioritize saving generic VGPRs, then AGPRs if we allow AGPR-to-ArchVGPR
18371836
// spilling and have some free ArchVGPR slots.
18381837
saveRegs(VGPRs, NumSavedRegs);
1839-
if (UseArchVGPRForAGPRSpill)
1838+
if (AllowVGPRToVGPRSpill)
18401839
saveRegs(AGPRs, NumSavedRegs);
18411840
} else {
18421841
// No AGPR usage in the region i.e., no allocation granule to worry about.
18431842
Progress |= saveRegs(VGPRs, NumRegs);
18441843
}
1844+
return Progress;
1845+
}
18451846

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);
18461853
return Progress;
18471854
}
18481855

@@ -1873,15 +1880,22 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18731880
// one in the whole function.
18741881
for (unsigned I = 0, E = DAG.Regions.size(); I != E; ++I) {
18751882
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);
18771890
if (Excess && IncreaseOccupancy) {
18781891
// There is spilling in the region and we were so far trying to increase
18791892
// occupancy. Strop trying that and focus on reducing spilling.
18801893
IncreaseOccupancy = false;
18811894
OptRegions.clear();
18821895
} else if (IncreaseOccupancy) {
18831896
// 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);
18851899
}
18861900
if (Excess)
18871901
OptRegions.insert({I, Excess});
@@ -1916,19 +1930,12 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
19161930
bool &Progress) -> bool {
19171931
ExcessRP &Excess = OptIt->getSecond();
19181932
unsigned NumRegs = SIRegisterInfo::getNumCoveredRegs(Mask);
1919-
if (SRI->isSGPRClass(RC)) {
1933+
if (SRI->isSGPRClass(RC))
19201934
Progress |= Excess.saveSGPRs(NumRegs);
1921-
} else if (SRI->isAGPRClass(RC)) {
1935+
else if (SRI->isAGPRClass(RC))
19221936
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);
19321939
if (!Excess)
19331940
OptRegions.erase(OptIt->getFirst());
19341941
return OptRegions.empty();

0 commit comments

Comments
 (0)