Skip to content

Commit e79bd5a

Browse files
perlfuKonstantina Mitropoulou
andcommitted
[MachineScheduler] Add support for scheduling while in SSA
Allow targets to add an MachineScheduler before PHI elimination, i.e. in SSA mode. Add initial support in AMDGPU backend for using SSA Machine Scheduler instead of normal Machine Scheduler. (This behaviour is disabled by default.) Also add basic "kick the tyres" demonstrator tests. This change is intended to support the introduction of a pre-RA spilling pass which runs prior to PHI elimination. Machine scheduler has a significant impact on register pressure and as such is best run before this new spilling pass. Co-authored-by: Konstantina Mitropoulou <[email protected]>
1 parent 9630b32 commit e79bd5a

File tree

16 files changed

+945
-356
lines changed

16 files changed

+945
-356
lines changed

llvm/include/llvm/CodeGen/MachineScheduler.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ namespace impl_detail {
103103
// FIXME: Remove these declarations once RegisterClassInfo is queryable as an
104104
// analysis.
105105
class MachineSchedulerImpl;
106+
class SSAMachineSchedulerImpl;
106107
class PostMachineSchedulerImpl;
107108
} // namespace impl_detail
108109

@@ -1464,6 +1465,20 @@ class MachineSchedulerPass : public PassInfoMixin<MachineSchedulerPass> {
14641465
MachineFunctionAnalysisManager &MFAM);
14651466
};
14661467

1468+
class SSAMachineSchedulerPass : public PassInfoMixin<SSAMachineSchedulerPass> {
1469+
// FIXME: Remove this member once RegisterClassInfo is queryable as an
1470+
// analysis.
1471+
std::unique_ptr<impl_detail::SSAMachineSchedulerImpl> Impl;
1472+
const TargetMachine *TM;
1473+
1474+
public:
1475+
SSAMachineSchedulerPass(const TargetMachine *TM);
1476+
SSAMachineSchedulerPass(SSAMachineSchedulerPass &&Other);
1477+
~SSAMachineSchedulerPass();
1478+
PreservedAnalyses run(MachineFunction &MF,
1479+
MachineFunctionAnalysisManager &MFAM);
1480+
};
1481+
14671482
class PostMachineSchedulerPass
14681483
: public PassInfoMixin<PostMachineSchedulerPass> {
14691484
// FIXME: Remove this member once RegisterClassInfo is queryable as an

llvm/include/llvm/CodeGen/Passes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ LLVM_ABI extern char &MachineSchedulerID;
165165
/// PostMachineScheduler - This pass schedules machine instructions postRA.
166166
LLVM_ABI extern char &PostMachineSchedulerID;
167167

168+
/// SSAMachineScheduler - This pass schedules machine instructions in SSA.
169+
LLVM_ABI extern char &SSAMachineSchedulerID;
170+
168171
/// SpillPlacement analysis. Suggest optimal placement of spill code between
169172
/// basic blocks.
170173
LLVM_ABI extern char &SpillPlacementID;

llvm/include/llvm/CodeGen/TargetPassConfig.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
135135
/// replace a copy.
136136
bool EnableSinkAndFold = false;
137137

138+
/// Enable insertion of SSAMachineScheduler pass, this triggers early
139+
/// computation of live intervals.
140+
bool EnableSSAMachineScheduler = false;
141+
138142
/// Require processing of functions such that callees are generated before
139143
/// callers.
140144
bool RequireCodeGenSCCOrder = false;
@@ -205,6 +209,13 @@ class LLVM_ABI TargetPassConfig : public ImmutablePass {
205209
setOpt(RequireCodeGenSCCOrder, Enable);
206210
}
207211

212+
bool getEnableSSAMachineScheduler() const {
213+
return EnableSSAMachineScheduler;
214+
}
215+
void setEnableSSAMachineScheduler(bool Enable) {
216+
setOpt(EnableSSAMachineScheduler, Enable);
217+
}
218+
208219
/// Allow the target to override a specific pass without overriding the pass
209220
/// pipeline. When passes are added to the standard pipeline at the
210221
/// point where StandardID is expected, add TargetID in its place.

llvm/include/llvm/CodeGen/TargetSubtargetInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ class LLVM_ABI TargetSubtargetInfo : public MCSubtargetInfo {
220220
/// allocation.
221221
virtual bool enablePostRAMachineScheduler() const;
222222

223+
/// True if the subtarget should run a machine scheduler before PHI
224+
/// elimination.
225+
virtual bool enableSSAMachineScheduler() const;
226+
223227
/// True if the subtarget should run the atomic expansion pass.
224228
virtual bool enableAtomicExpand() const;
225229

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ LLVM_ABI void initializeReplaceWithVeclibLegacyPass(PassRegistry &);
289289
LLVM_ABI void initializeResetMachineFunctionPass(PassRegistry &);
290290
LLVM_ABI void initializeSCEVAAWrapperPassPass(PassRegistry &);
291291
LLVM_ABI void initializeSROALegacyPassPass(PassRegistry &);
292+
LLVM_ABI void initializeSSAMachineSchedulerPass(PassRegistry &);
292293
LLVM_ABI void initializeSafeStackLegacyPassPass(PassRegistry &);
293294
LLVM_ABI void initializeSafepointIRVerifierPass(PassRegistry &);
294295
LLVM_ABI void initializeSelectOptimizePass(PassRegistry &);

llvm/include/llvm/Passes/MachinePassRegistry.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass())
122122
MACHINE_FUNCTION_PASS("machine-latecleanup", MachineLateInstrsCleanupPass())
123123
MACHINE_FUNCTION_PASS("machine-sanmd", MachineSanitizerBinaryMetadataPass())
124124
MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass(TM))
125+
MACHINE_FUNCTION_PASS("ssamisched", SSAMachineSchedulerPass(TM))
125126
MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass())
126127
MACHINE_FUNCTION_PASS("no-op-machine-function", NoOpMachineFunctionPass())
127128
MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass())

llvm/lib/CodeGen/CodeGen.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
120120
initializeRemoveLoadsIntoFakeUsesLegacyPass(Registry);
121121
initializeRemoveRedundantDebugValuesLegacyPass(Registry);
122122
initializeRenameIndependentSubregsLegacyPass(Registry);
123+
initializeSSAMachineSchedulerPass(Registry);
123124
initializeSafeStackLegacyPassPass(Registry);
124125
initializeSelectOptimizePass(Registry);
125126
initializeShadowStackGCLoweringPass(Registry);

llvm/lib/CodeGen/MachineScheduler.cpp

Lines changed: 178 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,33 @@ class MachineSchedulerImpl : public MachineSchedulerBase {
350350
ScheduleDAGInstrs *createMachineScheduler();
351351
};
352352

353+
/// Impl class for SSAMachineScheduler.
354+
class SSAMachineSchedulerImpl : public MachineSchedulerBase {
355+
// These are only for using MF.verify()
356+
// remove when verify supports passing in all analyses
357+
MachineFunctionPass *P = nullptr;
358+
MachineFunctionAnalysisManager *MFAM = nullptr;
359+
360+
public:
361+
struct RequiredAnalyses {
362+
MachineLoopInfo &MLI;
363+
MachineDominatorTree &MDT;
364+
AAResults &AA;
365+
LiveIntervals &LIS;
366+
};
367+
368+
SSAMachineSchedulerImpl() {}
369+
// Migration only
370+
void setLegacyPass(MachineFunctionPass *P) { this->P = P; }
371+
void setMFAM(MachineFunctionAnalysisManager *MFAM) { this->MFAM = MFAM; }
372+
373+
bool run(MachineFunction &MF, const TargetMachine &TM,
374+
const RequiredAnalyses &Analyses);
375+
376+
protected:
377+
ScheduleDAGInstrs *createMachineScheduler();
378+
};
379+
353380
/// Impl class for PostMachineScheduler.
354381
class PostMachineSchedulerImpl : public MachineSchedulerBase {
355382
// These are only for using MF.verify()
@@ -380,6 +407,7 @@ class PostMachineSchedulerImpl : public MachineSchedulerBase {
380407
using impl_detail::MachineSchedulerBase;
381408
using impl_detail::MachineSchedulerImpl;
382409
using impl_detail::PostMachineSchedulerImpl;
410+
using impl_detail::SSAMachineSchedulerImpl;
383411

384412
namespace {
385413
/// MachineScheduler runs after coalescing and before register allocation.
@@ -394,6 +422,18 @@ class MachineSchedulerLegacy : public MachineFunctionPass {
394422
static char ID; // Class identification, replacement for typeinfo
395423
};
396424

425+
/// SSAMachineScheduler runs before PHI elimination.
426+
class SSAMachineScheduler : public MachineFunctionPass {
427+
SSAMachineSchedulerImpl Impl;
428+
429+
public:
430+
SSAMachineScheduler();
431+
void getAnalysisUsage(AnalysisUsage &AU) const override;
432+
bool runOnMachineFunction(MachineFunction &) override;
433+
434+
static char ID; // Class identification, replacement for typeinfo
435+
};
436+
397437
/// PostMachineScheduler runs after shortly before code emission.
398438
class PostMachineSchedulerLegacy : public MachineFunctionPass {
399439
PostMachineSchedulerImpl Impl;
@@ -439,6 +479,35 @@ void MachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
439479
MachineFunctionPass::getAnalysisUsage(AU);
440480
}
441481

482+
char SSAMachineScheduler::ID = 0;
483+
484+
char &llvm::SSAMachineSchedulerID = SSAMachineScheduler::ID;
485+
486+
INITIALIZE_PASS_BEGIN(SSAMachineScheduler, "ssamisched",
487+
"SSA Machine Instruction Scheduler", false, false)
488+
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
489+
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
490+
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
491+
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
492+
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
493+
INITIALIZE_PASS_END(SSAMachineScheduler, "ssamisched",
494+
"SSA Machine Instruction Scheduler", false, false)
495+
496+
SSAMachineScheduler::SSAMachineScheduler() : MachineFunctionPass(ID) {
497+
initializeSSAMachineSchedulerPass(*PassRegistry::getPassRegistry());
498+
}
499+
500+
void SSAMachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const {
501+
AU.setPreservesCFG();
502+
AU.addRequired<MachineDominatorTreeWrapperPass>();
503+
AU.addRequired<MachineLoopInfoWrapperPass>();
504+
AU.addRequired<AAResultsWrapperPass>();
505+
AU.addRequired<TargetPassConfig>();
506+
AU.addRequired<SlotIndexesWrapperPass>();
507+
AU.addRequired<LiveIntervalsWrapperPass>();
508+
MachineFunctionPass::getAnalysisUsage(AU);
509+
}
510+
442511
char PostMachineSchedulerLegacy::ID = 0;
443512

444513
char &llvm::PostMachineSchedulerID = PostMachineSchedulerLegacy::ID;
@@ -490,6 +559,11 @@ static cl::opt<bool> EnableMachineSched(
490559
cl::desc("Enable the machine instruction scheduling pass."), cl::init(true),
491560
cl::Hidden);
492561

562+
static cl::opt<bool> EnableSSAMachineSched(
563+
"enable-ssa-misched",
564+
cl::desc("Enable the machine instruction scheduling pass in SSA."),
565+
cl::init(false), cl::Hidden);
566+
493567
static cl::opt<bool> EnablePostRAMachineSched(
494568
"enable-post-misched",
495569
cl::desc("Enable the post-ra machine instruction scheduling pass."),
@@ -586,6 +660,53 @@ bool MachineSchedulerImpl::run(MachineFunction &Func, const TargetMachine &TM,
586660
return true;
587661
}
588662

663+
/// Instantiate a ScheduleDAGInstrs that will be owned by the caller.
664+
ScheduleDAGInstrs *SSAMachineSchedulerImpl::createMachineScheduler() {
665+
// Get the default scheduler set by the target for this function.
666+
ScheduleDAGInstrs *Scheduler = TM->createMachineScheduler(this);
667+
if (Scheduler)
668+
return Scheduler;
669+
670+
// Default to GenericScheduler.
671+
return createSchedLive(this);
672+
}
673+
674+
bool SSAMachineSchedulerImpl::run(MachineFunction &Func,
675+
const TargetMachine &TM,
676+
const RequiredAnalyses &Analyses) {
677+
MF = &Func;
678+
MLI = &Analyses.MLI;
679+
MDT = &Analyses.MDT;
680+
this->TM = &TM;
681+
AA = &Analyses.AA;
682+
LIS = &Analyses.LIS;
683+
684+
if (VerifyScheduling) {
685+
LLVM_DEBUG(LIS->dump());
686+
const char *MSchedBanner = "Before machine scheduling.";
687+
if (P)
688+
MF->verify(P, MSchedBanner, &errs());
689+
else
690+
MF->verify(*MFAM, MSchedBanner, &errs());
691+
}
692+
RegClassInfo->runOnMachineFunction(*MF);
693+
694+
// Instantiate the selected scheduler for this target, function, and
695+
// optimization level.
696+
std::unique_ptr<ScheduleDAGInstrs> Scheduler(createMachineScheduler());
697+
scheduleRegions(*Scheduler, false);
698+
699+
LLVM_DEBUG(LIS->dump());
700+
if (VerifyScheduling) {
701+
const char *MSchedBanner = "After machine scheduling.";
702+
if (P)
703+
MF->verify(P, MSchedBanner, &errs());
704+
else
705+
MF->verify(*MFAM, MSchedBanner, &errs());
706+
}
707+
return true;
708+
}
709+
589710
/// Instantiate a ScheduleDAGInstrs for PostRA scheduling that will be owned by
590711
/// the caller. We don't have a command line option to override the postRA
591712
/// scheduler. The Target must configure it.
@@ -668,12 +789,40 @@ bool MachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
668789
return Impl.run(MF, TM, {MLI, MDT, AA, LIS});
669790
}
670791

792+
bool SSAMachineScheduler::runOnMachineFunction(MachineFunction &MF) {
793+
if (skipFunction(MF.getFunction()))
794+
return false;
795+
796+
if (EnableSSAMachineSched.getNumOccurrences()) {
797+
if (!EnableSSAMachineSched)
798+
return false;
799+
} else if (!MF.getSubtarget().enableSSAMachineScheduler()) {
800+
return false;
801+
}
802+
803+
LLVM_DEBUG(dbgs() << "Before ssa-MI-sched:\n"; MF.print(dbgs()));
804+
805+
auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
806+
auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
807+
auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
808+
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
809+
auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
810+
Impl.setLegacyPass(this);
811+
return Impl.run(MF, TM, {MLI, MDT, AA, LIS});
812+
}
813+
671814
MachineSchedulerPass::MachineSchedulerPass(const TargetMachine *TM)
672815
: Impl(std::make_unique<MachineSchedulerImpl>()), TM(TM) {}
673816
MachineSchedulerPass::~MachineSchedulerPass() = default;
674817
MachineSchedulerPass::MachineSchedulerPass(MachineSchedulerPass &&Other) =
675818
default;
676819

820+
SSAMachineSchedulerPass::SSAMachineSchedulerPass(const TargetMachine *TM)
821+
: Impl(std::make_unique<SSAMachineSchedulerImpl>()), TM(TM) {}
822+
SSAMachineSchedulerPass::SSAMachineSchedulerPass(
823+
SSAMachineSchedulerPass &&Other) = default;
824+
SSAMachineSchedulerPass::~SSAMachineSchedulerPass() = default;
825+
677826
PostMachineSchedulerPass::PostMachineSchedulerPass(const TargetMachine *TM)
678827
: Impl(std::make_unique<PostMachineSchedulerImpl>()), TM(TM) {}
679828
PostMachineSchedulerPass::PostMachineSchedulerPass(
@@ -708,6 +857,33 @@ MachineSchedulerPass::run(MachineFunction &MF,
708857
.preserve<LiveIntervalsAnalysis>();
709858
}
710859

860+
PreservedAnalyses
861+
SSAMachineSchedulerPass::run(MachineFunction &MF,
862+
MachineFunctionAnalysisManager &MFAM) {
863+
if (EnableSSAMachineSched.getNumOccurrences()) {
864+
if (!EnableSSAMachineSched)
865+
return PreservedAnalyses::all();
866+
} else if (!MF.getSubtarget().enableSSAMachineScheduler()) {
867+
LLVM_DEBUG(dbgs() << "Subtarget disables ssa-MI-sched.\n");
868+
return PreservedAnalyses::all();
869+
}
870+
LLVM_DEBUG(dbgs() << "Before ssa-MI-sched:\n"; MF.print(dbgs()));
871+
auto &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
872+
auto &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
873+
auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
874+
.getManager();
875+
auto &AA = FAM.getResult<AAManager>(MF.getFunction());
876+
auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
877+
Impl->setMFAM(&MFAM);
878+
bool Changed = Impl->run(MF, *TM, {MLI, MDT, AA, LIS});
879+
if (!Changed)
880+
return PreservedAnalyses::all();
881+
882+
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
883+
PA.preserveSet<CFGAnalyses>();
884+
return PA;
885+
}
886+
711887
bool PostMachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
712888
if (skipFunction(MF.getFunction()))
713889
return false;
@@ -764,11 +940,10 @@ PostMachineSchedulerPass::run(MachineFunction &MF,
764940
/// the boundary, but there would be no benefit to postRA scheduling across
765941
/// calls this late anyway.
766942
static bool isSchedBoundary(MachineBasicBlock::iterator MI,
767-
MachineBasicBlock *MBB,
768-
MachineFunction *MF,
943+
MachineBasicBlock *MBB, MachineFunction *MF,
769944
const TargetInstrInfo *TII) {
770945
return MI->isCall() || TII->isSchedulingBoundary(*MI, MBB, *MF) ||
771-
MI->isFakeUse();
946+
MI->isFakeUse() || MI->isPHI();
772947
}
773948

774949
using MBBRegionsVector = SmallVector<SchedRegion, 16>;

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,12 @@ void TargetPassConfig::addOptimizedRegAlloc() {
14791479
addPass(&UnreachableMachineBlockElimID);
14801480
addPass(&LiveVariablesID);
14811481

1482+
// Run SSA machine scheduler runs just before PHI elimination.
1483+
if (EnableSSAMachineScheduler) {
1484+
addPass(&LiveIntervalsID);
1485+
addPass(&SSAMachineSchedulerID);
1486+
}
1487+
14821488
// Edge splitting is smarter with machine loop info.
14831489
addPass(&MachineLoopInfoID);
14841490
addPass(&PHIEliminationID);

llvm/lib/CodeGen/TargetSubtargetInfo.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ bool TargetSubtargetInfo::enablePostRAMachineScheduler() const {
5454
return enableMachineScheduler() && enablePostRAScheduler();
5555
}
5656

57+
bool TargetSubtargetInfo::enableSSAMachineScheduler() const { return false; }
58+
5759
bool TargetSubtargetInfo::useAA() const {
5860
return false;
5961
}

0 commit comments

Comments
 (0)