Skip to content

Commit e0b6488

Browse files
lucas-ramijrbyrnes
authored andcommitted
[MachineScheduler] Optional scheduling of single-MI regions (llvm#129704)
Following 15e295d the machine scheduler no longer filters-out single-MI regions when emitting regions to schedule. While this has no functional impact at the moment, it generally has a negative compile-time impact (see llvm#128739). Since all targets but AMDGPU do not care for this behavior, this introduces an off-by-default flag to `ScheduleDAGInstrs` to control whether such regions are going to be scheduled, effectively reverting 15e295d for all targets but AMDGPU (currently the only target enabling this flag). Change-Id: Ib38f9b7e8d2bb1073cb43ed7e58eaf251ffdce48
1 parent c1748ab commit e0b6488

File tree

5 files changed

+73
-57
lines changed

5 files changed

+73
-57
lines changed

llvm/include/llvm/CodeGen/ScheduleDAGInstrs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ namespace llvm {
124124
/// rescheduling).
125125
bool RemoveKillFlags;
126126

127+
/// True if regions with a single MI should be scheduled.
128+
bool ScheduleSingleMIRegions = false;
129+
127130
/// The standard DAG builder does not normally include terminators as DAG
128131
/// nodes because it does not create the necessary dependencies to prevent
129132
/// reordering. A specialized scheduler can override
@@ -288,6 +291,11 @@ namespace llvm {
288291
return Topo.IsReachable(SU, TargetSU);
289292
}
290293

294+
/// Whether regions with a single MI should be scheduled.
295+
bool shouldScheduleSingleMIRegions() const {
296+
return ScheduleSingleMIRegions;
297+
}
298+
291299
/// Returns an iterator to the top of the current scheduling region.
292300
MachineBasicBlock::iterator begin() const { return RegionBegin; }
293301

llvm/lib/CodeGen/MachineScheduler.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler,
618618

619619
MBBRegionsVector MBBRegions;
620620
getSchedRegions(&*MBB, MBBRegions, Scheduler.doMBBSchedRegionsTopDown());
621+
bool ScheduleSingleMI = Scheduler.shouldScheduleSingleMIRegions();
621622
for (const SchedRegion &R : MBBRegions) {
622623
MachineBasicBlock::iterator I = R.RegionBegin;
623624
MachineBasicBlock::iterator RegionEnd = R.RegionEnd;
@@ -627,8 +628,9 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler,
627628
// it. Perhaps it still needs to be bundled.
628629
Scheduler.enterRegion(&*MBB, I, RegionEnd, NumRegionInstrs);
629630

630-
// Skip empty scheduling regions (0 or 1 schedulable instructions).
631-
if (I == RegionEnd || I == std::prev(RegionEnd)) {
631+
// Skip empty scheduling regions and, conditionally, regions with a single
632+
// MI.
633+
if (I == RegionEnd || (!ScheduleSingleMI && I == std::prev(RegionEnd))) {
632634
// Close the current region. Bundle the terminator if needed.
633635
// This invalidates 'RegionEnd' and 'I'.
634636
Scheduler.exitRegion();

llvm/lib/Target/AMDGPU/GCNSchedStrategy.cpp

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,10 @@ GCNScheduleDAGMILive::GCNScheduleDAGMILive(
765765
StartingOccupancy(MFI.getOccupancy()), MinOccupancy(StartingOccupancy),
766766
RegionLiveOuts(this, /*IsLiveOut=*/true) {
767767

768+
// We want regions with a single MI to be scheduled so that we can reason
769+
// about them correctly during scheduling stages that move MIs between regions
770+
// (e.g., rematerialization).
771+
ScheduleSingleMIRegions = true;
768772
LLVM_DEBUG(dbgs() << "Starting occupancy is " << StartingOccupancy << ".\n");
769773
if (RelaxedOcc) {
770774
MinOccupancy = std::min(MFI.getMinAllowedOccupancy(), StartingOccupancy);
@@ -1098,6 +1102,13 @@ bool PreRARematStage::initGCNSchedStage() {
10981102
DAG.Regions.size() == 1 || !canIncreaseOccupancyOrReduceSpill())
10991103
return false;
11001104

1105+
// Map all MIs to their parent region.
1106+
for (unsigned I = 0, E = DAG.Regions.size(); I < E; ++I) {
1107+
RegionBoundaries Region = DAG.Regions[I];
1108+
for (auto MI = Region.first; MI != Region.second; ++MI)
1109+
MIRegion.insert({&*MI, I});
1110+
}
1111+
11011112
// Rematerialize identified instructions and update scheduler's state.
11021113
rematerialize();
11031114
if (GCNTrackers)
@@ -1831,7 +1842,7 @@ bool PreRARematStage::canIncreaseOccupancyOrReduceSpill() {
18311842
// Cache set of registers that are going to be rematerialized.
18321843
DenseSet<unsigned> RematRegs;
18331844

1834-
// identify rematerializable instructions in the function.
1845+
// Identify rematerializable instructions in the function.
18351846
for (unsigned I = 0, E = DAG.Regions.size(); I != E; ++I) {
18361847
auto Region = DAG.Regions[I];
18371848
for (auto MI = Region.first; MI != Region.second; ++MI) {
@@ -1941,6 +1952,8 @@ void PreRARematStage::rematerialize() {
19411952
MachineBasicBlock::iterator InsertPos = Remat.InsertPos;
19421953
Register Reg = DefMI->getOperand(0).getReg();
19431954
unsigned SubReg = DefMI->getOperand(0).getSubReg();
1955+
unsigned DefRegion = MIRegion.at(DefMI);
1956+
19441957
// Rematerialize DefMI to its use block.
19451958
TII->reMaterialize(*InsertPos->getParent(), InsertPos, Reg, SubReg, *DefMI,
19461959
*DAG.TRI);
@@ -1952,8 +1965,12 @@ void PreRARematStage::rematerialize() {
19521965
// Update region boundaries in regions we sinked from (remove defining MI)
19531966
// and to (insert MI rematerialized in use block). Only then we can erase
19541967
// the original MI.
1955-
DAG.updateRegionBoundaries(DAG.Regions, DefMI, nullptr);
1956-
DAG.updateRegionBoundaries(DAG.Regions, InsertPos, Remat.RematMI);
1968+
DAG.updateRegionBoundaries(DAG.Regions[DefRegion], DefMI, nullptr);
1969+
auto UseRegion = MIRegion.find(Remat.UseMI);
1970+
if (UseRegion != MIRegion.end()) {
1971+
DAG.updateRegionBoundaries(DAG.Regions[UseRegion->second], InsertPos,
1972+
Remat.RematMI);
1973+
}
19571974
DefMI->eraseFromParent();
19581975
DAG.LIS->RemoveMachineInstrFromMaps(*DefMI);
19591976

@@ -2008,8 +2025,8 @@ void PreRARematStage::rematerialize() {
20082025
}
20092026
// RP in the region from which the instruction was rematerialized may or may
20102027
// not decrease.
2011-
ImpactedRegions.insert({Remat.DefRegion, DAG.Pressure[Remat.DefRegion]});
2012-
RecomputeRP.insert(Remat.DefRegion);
2028+
ImpactedRegions.insert({DefRegion, DAG.Pressure[DefRegion]});
2029+
RecomputeRP.insert(DefRegion);
20132030

20142031
// Update the register's live interval manually. This is aligned with the
20152032
// instruction collection phase in that it assumes a single def and use
@@ -2150,7 +2167,8 @@ void PreRARematStage::finalizeGCNSchedStage() {
21502167
// Rollback the rematerializations.
21512168
for (auto &Remat : Remats) {
21522169
MachineInstr &RematMI = *Remat.RematMI;
2153-
MachineBasicBlock *MBB = getRegionMBB(MF, DAG.Regions[Remat.DefRegion]);
2170+
unsigned DefRegion = MIRegion.at(DefMI);
2171+
MachineBasicBlock *MBB = getRegionMBB(MF, DAG.Regions[DefRegion]);
21542172
MachineBasicBlock::iterator InsertPos(MBB->end());
21552173

21562174
Register Reg = RematMI.getOperand(0).getReg();
@@ -2164,6 +2182,13 @@ void PreRARematStage::finalizeGCNSchedStage() {
21642182
NewMI->getOperand(0).setSubReg(SubReg);
21652183
DAG.LIS->InsertMachineInstrInMaps(*NewMI);
21662184

2185+
auto UseRegion = MIRegion.find(Remat.UseMI);
2186+
if (UseRegion != MIRegion.end()) {
2187+
DAG.updateRegionBoundaries(DAG.Regions[UseRegion->second], RematMI,
2188+
nullptr);
2189+
}
2190+
DAG.updateRegionBoundaries(DAG.Regions[DefRegion], InsertPos, NewMI);
2191+
21672192
// Erase rematerialized MI.
21682193
DAG.updateRegionBoundaries(DAG.Regions, RematMI, nullptr);
21692194
RematMI.eraseFromParent();
@@ -2187,49 +2212,25 @@ void PreRARematStage::finalizeGCNSchedStage() {
21872212
}
21882213

21892214
void GCNScheduleDAGMILive::updateRegionBoundaries(
2190-
SmallVectorImpl<RegionBoundaries> &RegionBoundaries,
2191-
MachineBasicBlock::iterator MI, MachineInstr *NewMI) {
2192-
unsigned I = 0, E = RegionBoundaries.size();
2193-
// Search for first region of the block where MI is located. We may encounter
2194-
// an empty region if all instructions from an initially non-empty region were
2195-
// removed.
2196-
while (I != E && RegionBoundaries[I].first != RegionBoundaries[I].second &&
2197-
MI->getParent() != RegionBoundaries[I].first->getParent())
2198-
++I;
2199-
2200-
for (; I != E; ++I) {
2201-
auto &Bounds = RegionBoundaries[I];
2202-
assert(MI != Bounds.second && "cannot insert at region end");
2203-
assert(!NewMI || NewMI != Bounds.second && "cannot remove at region end");
2204-
2205-
// We may encounter an empty region if all of the region' instructions were
2206-
// previously removed.
2207-
if (Bounds.first == Bounds.second) {
2208-
if (MI->getParent()->end() != Bounds.second)
2209-
return;
2210-
continue;
2211-
}
2212-
if (MI->getParent() != Bounds.first->getParent())
2213-
return;
2214-
2215-
// We only care for modifications at the beginning of the region since the
2216-
// upper region boundary is exclusive.
2217-
if (MI != Bounds.first)
2218-
continue;
2219-
if (!NewMI) {
2220-
// This is an MI removal, which may leave the region empty; in such cases
2221-
// set both boundaries to the removed instruction's MBB's end.
2222-
MachineBasicBlock::iterator NextMI = std::next(MI);
2223-
if (NextMI != Bounds.second)
2224-
Bounds.first = NextMI;
2225-
else
2226-
Bounds.first = Bounds.second;
2227-
} else {
2228-
// This is an MI insertion at the beggining of the region.
2229-
Bounds.first = NewMI;
2230-
}
2215+
RegionBoundaries &RegionBounds, MachineBasicBlock::iterator MI,
2216+
MachineInstr *NewMI) {
2217+
assert(!NewMI ||
2218+
NewMI != RegionBounds.second && "cannot remove at region end");
2219+
2220+
if (RegionBounds.first == RegionBounds.second) {
2221+
assert(NewMI && "cannot remove from an empty region");
2222+
RegionBounds.first = NewMI;
22312223
return;
22322224
}
2225+
2226+
// We only care for modifications at the beginning of a non-empty region since
2227+
// the upper region boundary is exclusive.
2228+
if (MI != RegionBounds.first)
2229+
return;
2230+
if (!NewMI)
2231+
RegionBounds.first = std::next(MI); // Removal
2232+
else
2233+
RegionBounds.first = NewMI; // Insertion
22332234
}
22342235

22352236
static bool hasIGLPInstrs(ScheduleDAGInstrs *DAG) {

llvm/lib/Target/AMDGPU/GCNSchedStrategy.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,10 @@ class GCNScheduleDAGMILive final : public ScheduleDAGMILive {
295295
/// If necessary, updates a region's boundaries following insertion ( \p NewMI
296296
/// != nullptr) or removal ( \p NewMI == nullptr) of a \p MI in the region.
297297
/// For an MI removal, this must be called before the MI is actually erased
298-
/// from its parent MBB. If a region is left empty by a removal, both
299-
/// boundaries are set to the last removed MI's MBB's end.
300-
void
301-
updateRegionBoundaries(SmallVectorImpl<RegionBoundaries> &RegionBoundaries,
302-
MachineBasicBlock::iterator MI, MachineInstr *NewMI);
298+
/// from its parent MBB.
299+
void updateRegionBoundaries(RegionBoundaries &RegionBounds,
300+
MachineBasicBlock::iterator MI,
301+
MachineInstr *NewMI);
303302

304303
void runSchedStages();
305304

@@ -463,8 +462,6 @@ class PreRARematStage : public GCNSchedStage {
463462
/// Set of regions in which the rematerializable instruction's defined
464463
/// register is a live-in.
465464
SmallDenseSet<unsigned, 4> LiveInRegions;
466-
/// Region containing the rematerializable instruction.
467-
unsigned DefRegion;
468465

469466
/// The position at which to insert the remat.
470467
MachineBasicBlock::iterator InsertPos;
@@ -611,6 +608,12 @@ class PreRARematStage : public GCNSchedStage {
611608

612609
RematInstructions Remats;
613610

611+
RematInstruction(MachineInstr *UseMI) : UseMI(UseMI) {}
612+
};
613+
614+
/// Maps all MIs to their parent region. MI terminators are considered to be
615+
/// outside the region they delimitate, and as such are not stored in the map.
616+
DenseMap<MachineInstr *, unsigned> MIRegion;
614617
/// Collect regions whose live-ins or register pressure will change due to
615618
/// rematerializations.
616619
DenseMap<unsigned, GCNRegPressure> ImpactedRegions;

llvm/test/CodeGen/ARM/misched-branch-targets.mir

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# RUN: llc -o - -run-pass=machine-scheduler -misched=shuffle %s | FileCheck %s
2+
# RUN: llc -o - -passes=machine-scheduler -misched=shuffle %s | FileCheck %s
23
# RUN: llc -o - -run-pass=postmisched %s | FileCheck %s
4+
# RUN: llc -o - -passes=postmisched %s | FileCheck %s
35

46
# REQUIRES: asserts
57
# -misched=shuffle is only available with assertions enabled
@@ -145,7 +147,7 @@ body: |
145147

146148
# CHECK-LABEL: name: foo_setjmp
147149
# CHECK: body:
148-
# CHECK: tBL 14 /* CC::al */, $noreg, @setjmp, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0
150+
# CHECK: tBL 14 /* CC::al */, $noreg, @setjmp, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit-def $sp, implicit-def $r0
149151
# CHECK-NEXT: t2BTI
150152

151153
---

0 commit comments

Comments
 (0)