Skip to content

Commit 83c308f

Browse files
authored
[AMDGPU][Scheduler] Consistent occupancy calculation during rematerialization (#149224)
The `RPTarget`'s way of determining whether VGPRs are beneficial to save and whether the target has been reached w.r.t. VGPR usage currently assumes, if `CombinedVGPRSavings` is true, that free slots in one VGPR RC can always be used for the other. Implicitly, this makes the rematerialization stage (only current user of `RPTarget`) follow a different occupancy calculation than the "regular one" that the scheduler uses, one that assumes that ArchVGPR/AGPR usage can be balanced perfectly and at no cost, which is untrue in general. This ultimately yields suboptimal rematerialization decisions that require cross-VGPR-RC copies unnecessarily. This fixes that, making the `RPTarget`'s internal model of occupancy consistent with the regular one. The `CombinedVGPRSavings` flag is removed, and a form of cross-VGPR-RC saving implemented only for unified RFs, which is where it makes the most sense. Only when the amount of free VGPRs in a given VGPR RC (ArchVPGR or AGPR) is lower than the excess VGPR usage in the other VGPR RC does the `RPTarget` consider that a pressure reduction in the former will be beneficial to the latter.
1 parent ab7281d commit 83c308f

File tree

6 files changed

+214
-303
lines changed

6 files changed

+214
-303
lines changed

llvm/lib/Target/AMDGPU/GCNRegPressure.cpp

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -368,46 +368,45 @@ static LaneBitmask findUseBetween(unsigned Reg, LaneBitmask LastUseMask,
368368
////////////////////////////////////////////////////////////////////////////////
369369
// GCNRPTarget
370370

371-
GCNRPTarget::GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP,
372-
bool CombineVGPRSavings)
373-
: RP(RP), CombineVGPRSavings(CombineVGPRSavings) {
371+
GCNRPTarget::GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP)
372+
: GCNRPTarget(RP, MF) {
374373
const Function &F = MF.getFunction();
375374
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
376-
setRegLimits(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F), MF);
375+
setTarget(ST.getMaxNumSGPRs(F), ST.getMaxNumVGPRs(F));
377376
}
378377

379378
GCNRPTarget::GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs,
380-
const MachineFunction &MF, const GCNRegPressure &RP,
381-
bool CombineVGPRSavings)
382-
: RP(RP), CombineVGPRSavings(CombineVGPRSavings) {
383-
setRegLimits(NumSGPRs, NumVGPRs, MF);
379+
const MachineFunction &MF, const GCNRegPressure &RP)
380+
: GCNRPTarget(RP, MF) {
381+
setTarget(NumSGPRs, NumVGPRs);
384382
}
385383

386384
GCNRPTarget::GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
387-
const GCNRegPressure &RP, bool CombineVGPRSavings)
388-
: RP(RP), CombineVGPRSavings(CombineVGPRSavings) {
385+
const GCNRegPressure &RP)
386+
: GCNRPTarget(RP, MF) {
389387
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
390388
unsigned DynamicVGPRBlockSize =
391389
MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
392-
setRegLimits(ST.getMaxNumSGPRs(Occupancy, /*Addressable=*/false),
393-
ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize), MF);
390+
setTarget(ST.getMaxNumSGPRs(Occupancy, /*Addressable=*/false),
391+
ST.getMaxNumVGPRs(Occupancy, DynamicVGPRBlockSize));
394392
}
395393

396-
void GCNRPTarget::setRegLimits(unsigned NumSGPRs, unsigned NumVGPRs,
397-
const MachineFunction &MF) {
394+
void GCNRPTarget::setTarget(unsigned NumSGPRs, unsigned NumVGPRs) {
398395
const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
399-
unsigned DynamicVGPRBlockSize =
400-
MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
401396
MaxSGPRs = std::min(ST.getAddressableNumSGPRs(), NumSGPRs);
402397
MaxVGPRs = std::min(ST.getAddressableNumArchVGPRs(), NumVGPRs);
403-
MaxUnifiedVGPRs =
404-
ST.hasGFX90AInsts()
405-
? std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs)
406-
: 0;
398+
if (UnifiedRF) {
399+
unsigned DynamicVGPRBlockSize =
400+
MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
401+
MaxUnifiedVGPRs =
402+
std::min(ST.getAddressableNumVGPRs(DynamicVGPRBlockSize), NumVGPRs);
403+
} else {
404+
MaxUnifiedVGPRs = 0;
405+
}
407406
}
408407

409-
bool GCNRPTarget::isSaveBeneficial(Register Reg,
410-
const MachineRegisterInfo &MRI) const {
408+
bool GCNRPTarget::isSaveBeneficial(Register Reg) const {
409+
const MachineRegisterInfo &MRI = MF.getRegInfo();
411410
const TargetRegisterClass *RC = MRI.getRegClass(Reg);
412411
const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
413412
const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(TRI);
@@ -416,16 +415,19 @@ bool GCNRPTarget::isSaveBeneficial(Register Reg,
416415
return RP.getSGPRNum() > MaxSGPRs;
417416
unsigned NumVGPRs =
418417
SRI->isAGPRClass(RC) ? RP.getAGPRNum() : RP.getArchVGPRNum();
419-
return isVGPRBankSaveBeneficial(NumVGPRs);
418+
// The addressable limit must always be respected.
419+
if (NumVGPRs > MaxVGPRs)
420+
return true;
421+
// For unified RFs, combined VGPR usage limit must be respected as well.
422+
return UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs;
420423
}
421424

422425
bool GCNRPTarget::satisfied() const {
423-
if (RP.getSGPRNum() > MaxSGPRs)
426+
if (RP.getSGPRNum() > MaxSGPRs || RP.getVGPRNum(false) > MaxVGPRs)
424427
return false;
425-
if (RP.getVGPRNum(false) > MaxVGPRs &&
426-
(!CombineVGPRSavings || !satisifiesVGPRBanksTarget()))
428+
if (UnifiedRF && RP.getVGPRNum(true) > MaxUnifiedVGPRs)
427429
return false;
428-
return satisfiesUnifiedTarget();
430+
return true;
429431
}
430432

431433
///////////////////////////////////////////////////////////////////////////////

llvm/lib/Target/AMDGPU/GCNRegPressure.h

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -186,28 +186,30 @@ class GCNRPTarget {
186186
/// Sets up the target such that the register pressure starting at \p RP does
187187
/// not show register spilling on function \p MF (w.r.t. the function's
188188
/// mininum target occupancy).
189-
GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP,
190-
bool CombineVGPRSavings = false);
189+
GCNRPTarget(const MachineFunction &MF, const GCNRegPressure &RP);
191190

192191
/// Sets up the target such that the register pressure starting at \p RP does
193192
/// not use more than \p NumSGPRs SGPRs and \p NumVGPRs VGPRs on function \p
194193
/// MF.
195194
GCNRPTarget(unsigned NumSGPRs, unsigned NumVGPRs, const MachineFunction &MF,
196-
const GCNRegPressure &RP, bool CombineVGPRSavings = false);
195+
const GCNRegPressure &RP);
197196

198197
/// Sets up the target such that the register pressure starting at \p RP does
199198
/// not prevent achieving an occupancy of at least \p Occupancy on function
200199
/// \p MF.
201200
GCNRPTarget(unsigned Occupancy, const MachineFunction &MF,
202-
const GCNRegPressure &RP, bool CombineVGPRSavings = false);
201+
const GCNRegPressure &RP);
202+
203+
/// Changes the target (same semantics as constructor).
204+
void setTarget(unsigned NumSGPRs, unsigned NumVGPRs);
203205

204206
const GCNRegPressure &getCurrentRP() const { return RP; }
205207

206208
void setRP(const GCNRegPressure &NewRP) { RP = NewRP; }
207209

208210
/// Determines whether saving virtual register \p Reg will be beneficial
209211
/// towards achieving the RP target.
210-
bool isSaveBeneficial(Register Reg, const MachineRegisterInfo &MRI) const;
212+
bool isSaveBeneficial(Register Reg) const;
211213

212214
/// Saves virtual register \p Reg with lanemask \p Mask.
213215
void saveReg(Register Reg, LaneBitmask Mask, const MachineRegisterInfo &MRI) {
@@ -227,15 +229,15 @@ class GCNRPTarget {
227229
if (Target.MaxUnifiedVGPRs) {
228230
OS << ", " << Target.RP.getVGPRNum(true) << '/' << Target.MaxUnifiedVGPRs
229231
<< " VGPRs (unified)";
230-
} else if (Target.CombineVGPRSavings) {
231-
OS << ", " << Target.RP.getArchVGPRNum() + Target.RP.getAGPRNum() << '/'
232-
<< 2 * Target.MaxVGPRs << " VGPRs (combined target)";
233232
}
234233
return OS;
235234
}
236235
#endif
237236

238237
private:
238+
const MachineFunction &MF;
239+
const bool UnifiedRF;
240+
239241
/// Current register pressure.
240242
GCNRegPressure RP;
241243

@@ -246,29 +248,10 @@ class GCNRPTarget {
246248
/// Target number of overall VGPRs for subtargets with unified RFs. Always 0
247249
/// for subtargets with non-unified RFs.
248250
unsigned MaxUnifiedVGPRs;
249-
/// Whether we consider that the register allocator will be able to swap
250-
/// between ArchVGPRs and AGPRs by copying them to a super register class.
251-
/// Concretely, this allows savings in one of the VGPR banks to help toward
252-
/// savings in the other VGPR bank.
253-
bool CombineVGPRSavings;
254-
255-
inline bool satisifiesVGPRBanksTarget() const {
256-
assert(CombineVGPRSavings && "only makes sense with combined savings");
257-
return RP.getArchVGPRNum() + RP.getAGPRNum() <= 2 * MaxVGPRs;
258-
}
259-
260-
/// Always satisified when the subtarget doesn't have a unified RF.
261-
inline bool satisfiesUnifiedTarget() const {
262-
return !MaxUnifiedVGPRs || RP.getVGPRNum(true) <= MaxUnifiedVGPRs;
263-
}
264-
265-
inline bool isVGPRBankSaveBeneficial(unsigned NumVGPRs) const {
266-
return NumVGPRs > MaxVGPRs || !satisfiesUnifiedTarget() ||
267-
(CombineVGPRSavings && !satisifiesVGPRBanksTarget());
268-
}
269251

270-
void setRegLimits(unsigned MaxSGPRs, unsigned MaxVGPRs,
271-
const MachineFunction &MF);
252+
GCNRPTarget(const GCNRegPressure &RP, const MachineFunction &MF)
253+
: MF(MF), UnifiedRF(MF.getSubtarget<GCNSubtarget>().hasGFX90AInsts()),
254+
RP(RP) {}
272255
};
273256

274257
///////////////////////////////////////////////////////////////////////////////

llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp

Lines changed: 68 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ bool ClusteredLowOccStage::initGCNSchedStage() {
10861086
}
10871087

10881088
/// 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;)
10901091

10911092
bool PreRARematStage::initGCNSchedStage() {
10921093
// FIXME: This pass will invalidate cached BBLiveInMap and MBBLiveIns for
@@ -1115,10 +1116,15 @@ bool PreRARematStage::initGCNSchedStage() {
11151116
rematerialize();
11161117
if (GCNTrackers)
11171118
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+
11221128
if (AchievedOcc > DAG.MinOccupancy) {
11231129
DAG.MinOccupancy = AchievedOcc;
11241130
SIMachineFunctionInfo &MFI = *MF.getInfo<SIMachineFunctionInfo>();
@@ -1540,8 +1546,7 @@ bool ClusteredLowOccStage::shouldRevertScheduling(unsigned WavesAfter) {
15401546

15411547
bool PreRARematStage::shouldRevertScheduling(unsigned WavesAfter) {
15421548
return GCNSchedStage::shouldRevertScheduling(WavesAfter) ||
1543-
mayCauseSpilling(WavesAfter) ||
1544-
(IncreaseOccupancy && WavesAfter < TargetOcc);
1549+
mayCauseSpilling(WavesAfter) || (TargetOcc && WavesAfter < TargetOcc);
15451550
}
15461551

15471552
bool ILPInitialScheduleStage::shouldRevertScheduling(unsigned WavesAfter) {
@@ -1687,78 +1692,63 @@ bool PreRARematStage::allUsesAvailableAt(const MachineInstr *InstToRemat,
16871692
}
16881693

16891694
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();
16951696

16961697
// Maps optimizable regions (i.e., regions at minimum and register-limited
16971698
// occupancy, or regions with spilling) to the target RP we would like to
16981699
// reach.
16991700
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});
17351710
}
1736-
if (!Target.satisfied())
1737-
OptRegions.insert({I, Target});
1738-
}
1739-
if (OptRegions.empty())
1740-
return false;
1711+
};
17411712

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;
17461718
} 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();
17531727
}
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;
17621752

17631753
// Accounts for a reduction in RP in an optimizable region. Returns whether we
17641754
// estimate that we have identified enough rematerialization opportunities to
@@ -1767,7 +1757,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
17671757
auto ReduceRPInRegion = [&](auto OptIt, Register Reg, LaneBitmask Mask,
17681758
bool &Progress) -> bool {
17691759
GCNRPTarget &Target = OptIt->getSecond();
1770-
if (!Target.isSaveBeneficial(Reg, DAG.MRI))
1760+
if (!Target.isSaveBeneficial(Reg))
17711761
return false;
17721762
Progress = true;
17731763
Target.saveReg(Reg, Mask, DAG.MRI);
@@ -1876,7 +1866,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18761866
}
18771867
}
18781868

1879-
if (IncreaseOccupancy) {
1869+
if (TargetOcc) {
18801870
// We were trying to increase occupancy but failed, abort the stage.
18811871
REMAT_DEBUG(dbgs() << "Cannot increase occupancy\n");
18821872
Rematerializations.clear();
@@ -1979,7 +1969,9 @@ void PreRARematStage::rematerialize() {
19791969
// All regions impacted by at least one rematerialization must be rescheduled.
19801970
// Maximum pressure must also be recomputed for all regions where it changed
19811971
// non-predictably and checked against the target occupancy.
1982-
AchievedOcc = TargetOcc;
1972+
unsigned DynamicVGPRBlockSize =
1973+
MF.getInfo<SIMachineFunctionInfo>()->getDynamicVGPRBlockSize();
1974+
AchievedOcc = MFI.getMaxWavesPerEU();
19831975
for (auto &[I, OriginalRP] : ImpactedRegions) {
19841976
bool IsEmptyRegion = DAG.Regions[I].first == DAG.Regions[I].second;
19851977
RescheduleRegions[I] = !IsEmptyRegion;
@@ -2003,9 +1995,8 @@ void PreRARematStage::rematerialize() {
20031995
}
20041996
}
20051997
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));
20092000
}
20102001
REMAT_DEBUG(dbgs() << "Achieved occupancy " << AchievedOcc << "\n");
20112002
}
@@ -2035,7 +2026,7 @@ void PreRARematStage::finalizeGCNSchedStage() {
20352026
// which case we do not want to rollback either (the rescheduling was already
20362027
// reverted in PreRARematStage::shouldRevertScheduling in such cases).
20372028
unsigned MaxOcc = std::max(AchievedOcc, DAG.MinOccupancy);
2038-
if (!IncreaseOccupancy || MaxOcc >= TargetOcc)
2029+
if (!TargetOcc || MaxOcc >= *TargetOcc)
20392030
return;
20402031

20412032
REMAT_DEBUG(dbgs() << "Rolling back all rematerializations\n");

0 commit comments

Comments
 (0)