Skip to content

Commit f9f91b0

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 492f82f commit f9f91b0

File tree

16 files changed

+943
-356
lines changed

16 files changed

+943
-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
@@ -177,6 +177,9 @@ LLVM_ABI extern char &MachineSchedulerID;
177177
/// PostMachineScheduler - This pass schedules machine instructions postRA.
178178
LLVM_ABI extern char &PostMachineSchedulerID;
179179

180+
/// SSAMachineScheduler - This pass schedules machine instructions in SSA.
181+
LLVM_ABI extern char &SSAMachineSchedulerID;
182+
180183
/// SpillPlacement analysis. Suggest optimal placement of spill code between
181184
/// basic blocks.
182185
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
@@ -292,6 +292,7 @@ LLVM_ABI void initializeReplaceWithVeclibLegacyPass(PassRegistry &);
292292
LLVM_ABI void initializeResetMachineFunctionPass(PassRegistry &);
293293
LLVM_ABI void initializeSCEVAAWrapperPassPass(PassRegistry &);
294294
LLVM_ABI void initializeSROALegacyPassPass(PassRegistry &);
295+
LLVM_ABI void initializeSSAMachineSchedulerPass(PassRegistry &);
295296
LLVM_ABI void initializeSafeStackLegacyPassPass(PassRegistry &);
296297
LLVM_ABI void initializeSafepointIRVerifierPass(PassRegistry &);
297298
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("ssa-machine-scheduler", 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
@@ -123,6 +123,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
123123
initializeRemoveLoadsIntoFakeUsesLegacyPass(Registry);
124124
initializeRemoveRedundantDebugValuesLegacyPass(Registry);
125125
initializeRenameIndependentSubregsLegacyPass(Registry);
126+
initializeSSAMachineSchedulerPass(Registry);
126127
initializeSafeStackLegacyPassPass(Registry);
127128
initializeSelectOptimizePass(Registry);
128129
initializeShadowStackGCLoweringPass(Registry);

llvm/lib/CodeGen/MachineScheduler.cpp

Lines changed: 176 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,33 @@ class MachineSchedulerImpl : public MachineSchedulerBase {
346346
ScheduleDAGInstrs *createMachineScheduler();
347347
};
348348

349+
/// Impl class for SSAMachineScheduler.
350+
class SSAMachineSchedulerImpl : public MachineSchedulerBase {
351+
// These are only for using MF.verify()
352+
// remove when verify supports passing in all analyses
353+
MachineFunctionPass *P = nullptr;
354+
MachineFunctionAnalysisManager *MFAM = nullptr;
355+
356+
public:
357+
struct RequiredAnalyses {
358+
MachineLoopInfo &MLI;
359+
MachineDominatorTree &MDT;
360+
AAResults &AA;
361+
LiveIntervals &LIS;
362+
};
363+
364+
SSAMachineSchedulerImpl() {}
365+
// Migration only
366+
void setLegacyPass(MachineFunctionPass *P) { this->P = P; }
367+
void setMFAM(MachineFunctionAnalysisManager *MFAM) { this->MFAM = MFAM; }
368+
369+
bool run(MachineFunction &MF, const TargetMachine &TM,
370+
const RequiredAnalyses &Analyses);
371+
372+
protected:
373+
ScheduleDAGInstrs *createMachineScheduler();
374+
};
375+
349376
/// Impl class for PostMachineScheduler.
350377
class PostMachineSchedulerImpl : public MachineSchedulerBase {
351378
// These are only for using MF.verify()
@@ -376,6 +403,7 @@ class PostMachineSchedulerImpl : public MachineSchedulerBase {
376403
using impl_detail::MachineSchedulerBase;
377404
using impl_detail::MachineSchedulerImpl;
378405
using impl_detail::PostMachineSchedulerImpl;
406+
using impl_detail::SSAMachineSchedulerImpl;
379407

380408
namespace {
381409
/// MachineScheduler runs after coalescing and before register allocation.
@@ -390,6 +418,18 @@ class MachineSchedulerLegacy : public MachineFunctionPass {
390418
static char ID; // Class identification, replacement for typeinfo
391419
};
392420

421+
/// SSAMachineScheduler runs before PHI elimination.
422+
class SSAMachineScheduler : public MachineFunctionPass {
423+
SSAMachineSchedulerImpl Impl;
424+
425+
public:
426+
SSAMachineScheduler();
427+
void getAnalysisUsage(AnalysisUsage &AU) const override;
428+
bool runOnMachineFunction(MachineFunction &) override;
429+
430+
static char ID; // Class identification, replacement for typeinfo
431+
};
432+
393433
/// PostMachineScheduler runs after shortly before code emission.
394434
class PostMachineSchedulerLegacy : public MachineFunctionPass {
395435
PostMachineSchedulerImpl Impl;
@@ -435,6 +475,35 @@ void MachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
435475
MachineFunctionPass::getAnalysisUsage(AU);
436476
}
437477

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

440509
char &llvm::PostMachineSchedulerID = PostMachineSchedulerLegacy::ID;
@@ -486,6 +555,11 @@ static cl::opt<bool> EnableMachineSched(
486555
cl::desc("Enable the machine instruction scheduling pass."), cl::init(true),
487556
cl::Hidden);
488557

558+
static cl::opt<bool> EnableSSAMachineSched(
559+
"enable-ssa-misched",
560+
cl::desc("Enable the machine instruction scheduling pass in SSA."),
561+
cl::init(false), cl::Hidden);
562+
489563
static cl::opt<bool> EnablePostRAMachineSched(
490564
"enable-post-misched",
491565
cl::desc("Enable the post-ra machine instruction scheduling pass."),
@@ -582,6 +656,53 @@ bool MachineSchedulerImpl::run(MachineFunction &Func, const TargetMachine &TM,
582656
return true;
583657
}
584658

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

788+
bool SSAMachineScheduler::runOnMachineFunction(MachineFunction &MF) {
789+
if (skipFunction(MF.getFunction()))
790+
return false;
791+
792+
if (EnableSSAMachineSched.getNumOccurrences()) {
793+
if (!EnableSSAMachineSched)
794+
return false;
795+
} else if (!MF.getSubtarget().enableSSAMachineScheduler()) {
796+
return false;
797+
}
798+
799+
auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
800+
auto &MDT = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
801+
auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
802+
auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
803+
auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
804+
Impl.setLegacyPass(this);
805+
return Impl.run(MF, TM, {MLI, MDT, AA, LIS});
806+
}
807+
667808
MachineSchedulerPass::MachineSchedulerPass(const TargetMachine *TM)
668809
: Impl(std::make_unique<MachineSchedulerImpl>()), TM(TM) {}
669810
MachineSchedulerPass::~MachineSchedulerPass() = default;
670811
MachineSchedulerPass::MachineSchedulerPass(MachineSchedulerPass &&Other) =
671812
default;
672813

814+
SSAMachineSchedulerPass::SSAMachineSchedulerPass(const TargetMachine *TM)
815+
: Impl(std::make_unique<SSAMachineSchedulerImpl>()), TM(TM) {}
816+
SSAMachineSchedulerPass::SSAMachineSchedulerPass(
817+
SSAMachineSchedulerPass &&Other) = default;
818+
SSAMachineSchedulerPass::~SSAMachineSchedulerPass() = default;
819+
673820
PostMachineSchedulerPass::PostMachineSchedulerPass(const TargetMachine *TM)
674821
: Impl(std::make_unique<PostMachineSchedulerImpl>()), TM(TM) {}
675822
PostMachineSchedulerPass::PostMachineSchedulerPass(
@@ -704,6 +851,33 @@ MachineSchedulerPass::run(MachineFunction &MF,
704851
.preserve<LiveIntervalsAnalysis>();
705852
}
706853

854+
PreservedAnalyses
855+
SSAMachineSchedulerPass::run(MachineFunction &MF,
856+
MachineFunctionAnalysisManager &MFAM) {
857+
if (EnableSSAMachineSched.getNumOccurrences()) {
858+
if (!EnableSSAMachineSched)
859+
return PreservedAnalyses::all();
860+
} else if (!MF.getSubtarget().enableSSAMachineScheduler()) {
861+
LLVM_DEBUG(dbgs() << "Subtarget disables ssa-MI-sched.\n");
862+
return PreservedAnalyses::all();
863+
}
864+
865+
auto &MLI = MFAM.getResult<MachineLoopAnalysis>(MF);
866+
auto &MDT = MFAM.getResult<MachineDominatorTreeAnalysis>(MF);
867+
auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
868+
.getManager();
869+
auto &AA = FAM.getResult<AAManager>(MF.getFunction());
870+
auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
871+
Impl->setMFAM(&MFAM);
872+
bool Changed = Impl->run(MF, *TM, {MLI, MDT, AA, LIS});
873+
if (!Changed)
874+
return PreservedAnalyses::all();
875+
876+
PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
877+
PA.preserveSet<CFGAnalyses>();
878+
return PA;
879+
}
880+
707881
bool PostMachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) {
708882
if (skipFunction(MF.getFunction()))
709883
return false;
@@ -760,11 +934,10 @@ PostMachineSchedulerPass::run(MachineFunction &MF,
760934
/// the boundary, but there would be no benefit to postRA scheduling across
761935
/// calls this late anyway.
762936
static bool isSchedBoundary(MachineBasicBlock::iterator MI,
763-
MachineBasicBlock *MBB,
764-
MachineFunction *MF,
937+
MachineBasicBlock *MBB, MachineFunction *MF,
765938
const TargetInstrInfo *TII) {
766939
return MI->isCall() || TII->isSchedulingBoundary(*MI, MBB, *MF) ||
767-
MI->isFakeUse();
940+
MI->isFakeUse() || MI->isPHI();
768941
}
769942

770943
using MBBRegionsVector = SmallVector<SchedRegion, 16>;

llvm/lib/CodeGen/TargetPassConfig.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,12 @@ void TargetPassConfig::addOptimizedRegAlloc() {
14871487
addPass(&UnreachableMachineBlockElimID);
14881488
addPass(&LiveVariablesID);
14891489

1490+
// Run SSA machine scheduler runs just before PHI elimination.
1491+
if (EnableSSAMachineScheduler) {
1492+
addPass(&LiveIntervalsID);
1493+
addPass(&SSAMachineSchedulerID);
1494+
}
1495+
14901496
// Edge splitting is smarter with machine loop info.
14911497
addPass(&MachineLoopInfoID);
14921498
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)