Skip to content

Commit 26525f2

Browse files
committed
Address review feedback
Aditionally fixes bug where MIRegion would only be filled after collecting rematerializable instructions, however the collection phase depends on MIRegion to determine whether the user of an MI is located in a different region from that MI. This does not break any test.
1 parent 0cb4897 commit 26525f2

File tree

2 files changed

+27
-31
lines changed

2 files changed

+27
-31
lines changed

llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,16 +1102,23 @@ bool PreRARematStage::initGCNSchedStage() {
11021102
assert(!S.hasNextStage());
11031103

11041104
if (!GCNSchedStage::initGCNSchedStage() || DAG.RegionsWithMinOcc.none() ||
1105-
DAG.Regions.size() == 1 || !canIncreaseOccupancyOrReduceSpill())
1105+
DAG.Regions.size() == 1)
11061106
return false;
11071107

1108-
// Map all MIs to their parent region.
1109-
for (unsigned I = 0, E = DAG.Regions.size(); I < E; ++I) {
1108+
// Before performing any IR modification record the parent region of each MI
1109+
// and the parent MBB of each region.
1110+
const unsigned NumRegions = DAG.Regions.size();
1111+
RegionBB.reserve(NumRegions);
1112+
for (unsigned I = 0; I < NumRegions; ++I) {
11101113
RegionBoundaries Region = DAG.Regions[I];
11111114
for (auto MI = Region.first; MI != Region.second; ++MI)
11121115
MIRegion.insert({&*MI, I});
1116+
RegionBB.push_back(Region.first->getParent());
11131117
}
11141118

1119+
if (!canIncreaseOccupancyOrReduceSpill())
1120+
return false;
1121+
11151122
// Rematerialize identified instructions and update scheduler's state.
11161123
rematerialize();
11171124
if (GCNTrackers)
@@ -1844,8 +1851,11 @@ bool ExcessRP::saveAGPRs(unsigned NumRegs) {
18441851
bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18451852
const SIRegisterInfo *SRI = static_cast<const SIRegisterInfo *>(DAG.TRI);
18461853

1847-
REMAT_DEBUG(dbgs() << "Collecting rematerializable instructions in "
1848-
<< MF.getFunction().getName() << '\n');
1854+
REMAT_DEBUG({
1855+
dbgs() << "Collecting rematerializable instructions in ";
1856+
MF.getFunction().printAsOperand(dbgs(), false);
1857+
dbgs() << '\n';
1858+
});
18491859

18501860
// Maps optimizable regions (i.e., regions at minimum and VGPR-limited
18511861
// occupancy, or regions with VGPR spilling) to a model of their excess RP.
@@ -1962,17 +1972,18 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
19621972

19631973
// We only support rematerializing virtual VGPRs with one definition.
19641974
Register Reg = DefMI.getOperand(0).getReg();
1965-
if (!Reg.isVirtual() || !DAG.LIS->hasInterval(Reg) ||
1966-
!SRI->isVGPRClass(DAG.MRI.getRegClass(Reg)) ||
1975+
if (!Reg.isVirtual() || !SRI->isVGPRClass(DAG.MRI.getRegClass(Reg)) ||
19671976
!DAG.MRI.hasOneDef(Reg))
19681977
continue;
19691978

19701979
// We only care to rematerialize the instruction if it has a single
1971-
// non-debug user in a different block. The using MI may not belong to a
1980+
// non-debug user in a different region. The using MI may not belong to a
19721981
// region if it is a lone region terminator.
19731982
MachineInstr *UseMI = DAG.MRI.getOneNonDBGUser(Reg);
1983+
if (!UseMI)
1984+
continue;
19741985
auto UseRegion = MIRegion.find(UseMI);
1975-
if (!UseMI || (UseRegion != MIRegion.end() && UseRegion->second == I))
1986+
if (UseRegion != MIRegion.end() && UseRegion->second == I)
19761987
continue;
19771988

19781989
// Do not rematerialize an instruction if it uses or is used by an
@@ -2109,8 +2120,7 @@ void PreRARematStage::rematerialize() {
21092120
if (LI.hasSubRanges() && MO.getSubReg())
21102121
LM = DAG.TRI->getSubRegIndexLaneMask(MO.getSubReg());
21112122

2112-
assert(RegionLiveIns.contains(UseReg));
2113-
LaneBitmask LiveInMask = RegionLiveIns[UseReg];
2123+
LaneBitmask LiveInMask = RegionLiveIns.at(UseReg);
21142124
LaneBitmask UncoveredLanes = LM & ~(LiveInMask & LM);
21152125
// If this register has lanes not covered by the LiveIns, be sure they
21162126
// do not map to any subrange. ref:
@@ -2197,21 +2207,6 @@ bool PreRARematStage::isTriviallyReMaterializable(const MachineInstr &MI) {
21972207
return true;
21982208
}
21992209

2200-
/// Identifies the parent MBB of a \p Region. For an empty region, this runs in
2201-
/// linear time in the number of MBBs in \p MF; otherwise it runs in constant
2202-
/// time.
2203-
static MachineBasicBlock *getRegionMBB(MachineFunction &MF,
2204-
RegionBoundaries &Region) {
2205-
if (Region.first != Region.second)
2206-
return Region.first->getParent();
2207-
// The boundaries of an empty region may not point to a valid MI from which we
2208-
// can get the parent MBB, so we have to iterate over all the MF's MBBs.
2209-
for (MachineBasicBlock &MBB : MF)
2210-
if (MBB.end() == Region.second)
2211-
return &MBB;
2212-
llvm_unreachable("region's parent MBB cannot be identified");
2213-
}
2214-
22152210
void PreRARematStage::finalizeGCNSchedStage() {
22162211
// We consider that reducing spilling is always beneficial so we never
22172212
// rollback rematerializations in such cases. It's also possible that
@@ -2222,16 +2217,15 @@ void PreRARematStage::finalizeGCNSchedStage() {
22222217
if (!IncreaseOccupancy || MaxOcc >= TargetOcc)
22232218
return;
22242219

2225-
REMAT_DEBUG(dbgs() << "Rollbacking all rematerializations\n");
2226-
const auto *TII =
2227-
static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
2220+
REMAT_DEBUG(dbgs() << "Rolling back all rematerializations\n");
2221+
const SIInstrInfo *TII = MF.getSubtarget<GCNSubtarget>().getInstrInfo();
22282222

22292223
// Rollback the rematerializations.
22302224
for (const auto &[DefMI, Remat] : Rematerializations) {
22312225
MachineInstr &RematMI = *Remat.RematMI;
22322226
unsigned DefRegion = MIRegion.at(DefMI);
22332227
MachineBasicBlock::iterator InsertPos(DAG.Regions[DefRegion].second);
2234-
MachineBasicBlock *MBB = getRegionMBB(MF, DAG.Regions[DefRegion]);
2228+
MachineBasicBlock *MBB = RegionBB[DefRegion];
22352229
Register Reg = RematMI.getOperand(0).getReg();
22362230
unsigned SubReg = RematMI.getOperand(0).getSubReg();
22372231

llvm/lib/Target/AMDGPU/GCNSchedStrategy.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,11 @@ class PreRARematStage : public GCNSchedStage {
466466
/// Maps all MIs to their parent region. MI terminators are considered to be
467467
/// outside the region they delimitate, and as such are not stored in the map.
468468
DenseMap<MachineInstr *, unsigned> MIRegion;
469+
/// Parent MBB to each region, in region order.
470+
SmallVector<MachineBasicBlock *> RegionBB;
469471
/// Collects instructions to rematerialize.
470472
MapVector<MachineInstr *, RematInstruction> Rematerializations;
471-
/// Collect regions whose live-ins or register pressure will change due to
473+
/// Collects regions whose live-ins or register pressure will change due to
472474
/// rematerializations.
473475
DenseMap<unsigned, GCNRegPressure> ImpactedRegions;
474476
/// In case we need to rollback rematerializations, save lane masks for all

0 commit comments

Comments
 (0)