diff options
Diffstat (limited to 'llvm/lib/CodeGen/MachineScheduler.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MachineScheduler.cpp | 332 |
1 files changed, 232 insertions, 100 deletions
diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index 393530f..df90077 100644 --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -58,6 +58,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/GraphWriter.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -215,69 +216,85 @@ MachineSchedContext::~MachineSchedContext() { namespace { -/// Base class for a machine scheduler class that can run at any point. -class MachineSchedulerBase : public MachineSchedContext, - public MachineFunctionPass { +/// Base class for the machine scheduler classes. +class MachineSchedulerBase : public MachineSchedContext { +protected: + void scheduleRegions(ScheduleDAGInstrs &Scheduler, bool FixKillFlags); +}; + +/// Impl class for MachineScheduler. +class MachineSchedulerImpl : public MachineSchedulerBase { + MachineFunctionPass *P = nullptr; + MachineFunctionAnalysisManager *MFAM = nullptr; + public: - MachineSchedulerBase(char &ID): MachineFunctionPass(ID) {} + MachineSchedulerImpl(MachineFunction &Func, MachineFunctionPass *P); + MachineSchedulerImpl(MachineFunction &Func, + MachineFunctionAnalysisManager &MFAM, + const TargetMachine *TargetM); + bool run(); + +protected: + ScheduleDAGInstrs *createMachineScheduler(); +}; - void print(raw_ostream &O, const Module* = nullptr) const override; +/// Impl class for PostMachineScheduler. +class PostMachineSchedulerImpl : public MachineSchedulerBase { + MachineFunctionPass *P = nullptr; + MachineFunctionAnalysisManager *MFAM = nullptr; + +public: + PostMachineSchedulerImpl(MachineFunction &Func, MachineFunctionPass *P); + PostMachineSchedulerImpl(MachineFunction &Func, + MachineFunctionAnalysisManager &MFAM, + const TargetMachine *TargetM); + bool run(); protected: - void scheduleRegions(ScheduleDAGInstrs &Scheduler, bool FixKillFlags); + ScheduleDAGInstrs *createPostMachineScheduler(); }; /// MachineScheduler runs after coalescing and before register allocation. -class MachineScheduler : public MachineSchedulerBase { +class MachineSchedulerLegacy : public MachineFunctionPass { public: - MachineScheduler(); - + MachineSchedulerLegacy(); void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnMachineFunction(MachineFunction&) override; static char ID; // Class identification, replacement for typeinfo - -protected: - ScheduleDAGInstrs *createMachineScheduler(); }; /// PostMachineScheduler runs after shortly before code emission. -class PostMachineScheduler : public MachineSchedulerBase { +class PostMachineSchedulerLegacy : public MachineFunctionPass { public: - PostMachineScheduler(); - + PostMachineSchedulerLegacy(); void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnMachineFunction(MachineFunction&) override; static char ID; // Class identification, replacement for typeinfo - -protected: - ScheduleDAGInstrs *createPostMachineScheduler(); }; } // end anonymous namespace -char MachineScheduler::ID = 0; +char MachineSchedulerLegacy::ID = 0; -char &llvm::MachineSchedulerID = MachineScheduler::ID; +char &llvm::MachineSchedulerID = MachineSchedulerLegacy::ID; -INITIALIZE_PASS_BEGIN(MachineScheduler, DEBUG_TYPE, +INITIALIZE_PASS_BEGIN(MachineSchedulerLegacy, DEBUG_TYPE, "Machine Instruction Scheduler", false, false) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass) INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass) -INITIALIZE_PASS_END(MachineScheduler, DEBUG_TYPE, +INITIALIZE_PASS_END(MachineSchedulerLegacy, DEBUG_TYPE, "Machine Instruction Scheduler", false, false) -MachineScheduler::MachineScheduler() : MachineSchedulerBase(ID) { - initializeMachineSchedulerPass(*PassRegistry::getPassRegistry()); +MachineSchedulerLegacy::MachineSchedulerLegacy() : MachineFunctionPass(ID) { + initializeMachineSchedulerLegacyPass(*PassRegistry::getPassRegistry()); } -void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { +void MachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<MachineDominatorTreeWrapperPass>(); AU.addRequired<MachineLoopInfoWrapperPass>(); @@ -290,23 +307,24 @@ void MachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } -char PostMachineScheduler::ID = 0; +char PostMachineSchedulerLegacy::ID = 0; -char &llvm::PostMachineSchedulerID = PostMachineScheduler::ID; +char &llvm::PostMachineSchedulerID = PostMachineSchedulerLegacy::ID; -INITIALIZE_PASS_BEGIN(PostMachineScheduler, "postmisched", +INITIALIZE_PASS_BEGIN(PostMachineSchedulerLegacy, "postmisched", "PostRA Machine Instruction Scheduler", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) -INITIALIZE_PASS_END(PostMachineScheduler, "postmisched", +INITIALIZE_PASS_END(PostMachineSchedulerLegacy, "postmisched", "PostRA Machine Instruction Scheduler", false, false) -PostMachineScheduler::PostMachineScheduler() : MachineSchedulerBase(ID) { - initializePostMachineSchedulerPass(*PassRegistry::getPassRegistry()); +PostMachineSchedulerLegacy::PostMachineSchedulerLegacy() + : MachineFunctionPass(ID) { + initializePostMachineSchedulerLegacyPass(*PassRegistry::getPassRegistry()); } -void PostMachineScheduler::getAnalysisUsage(AnalysisUsage &AU) const { +void PostMachineSchedulerLegacy::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired<MachineDominatorTreeWrapperPass>(); AU.addRequired<MachineLoopInfoWrapperPass>(); @@ -385,15 +403,40 @@ nextIfDebug(MachineBasicBlock::iterator I, .getNonConstIterator(); } +MachineSchedulerImpl::MachineSchedulerImpl(MachineFunction &Func, + MachineFunctionPass *P) + : P(P) { + MF = &Func; + MLI = &P->getAnalysis<MachineLoopInfoWrapperPass>().getLI(); + MDT = &P->getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); + TM = &P->getAnalysis<TargetPassConfig>().getTM<TargetMachine>(); + AA = &P->getAnalysis<AAResultsWrapperPass>().getAAResults(); + LIS = &P->getAnalysis<LiveIntervalsWrapperPass>().getLIS(); +} + +MachineSchedulerImpl::MachineSchedulerImpl(MachineFunction &Func, + MachineFunctionAnalysisManager &MFAM, + const TargetMachine *TargetM) + : MFAM(&MFAM) { + MF = &Func; + TM = TargetM; + MLI = &MFAM.getResult<MachineLoopAnalysis>(Func); + MDT = &MFAM.getResult<MachineDominatorTreeAnalysis>(Func); + auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(Func) + .getManager(); + AA = &FAM.getResult<AAManager>(Func.getFunction()); + LIS = &MFAM.getResult<LiveIntervalsAnalysis>(Func); +} + /// Instantiate a ScheduleDAGInstrs that will be owned by the caller. -ScheduleDAGInstrs *MachineScheduler::createMachineScheduler() { +ScheduleDAGInstrs *MachineSchedulerImpl::createMachineScheduler() { // Select the scheduler, or set the default. MachineSchedRegistry::ScheduleDAGCtor Ctor = MachineSchedOpt; if (Ctor != useDefaultMachineSched) return Ctor(this); // Get the default scheduler set by the target for this function. - ScheduleDAGInstrs *Scheduler = PassConfig->createMachineScheduler(this); + ScheduleDAGInstrs *Scheduler = TM->createMachineScheduler(this); if (Scheduler) return Scheduler; @@ -401,12 +444,60 @@ ScheduleDAGInstrs *MachineScheduler::createMachineScheduler() { return createGenericSchedLive(this); } +bool MachineSchedulerImpl::run() { + if (VerifyScheduling) { + LLVM_DEBUG(LIS->dump()); + const char *MSchedBanner = "Before machine scheduling."; + if (P) + MF->verify(P, MSchedBanner, &errs()); + else + MF->verify(*MFAM, MSchedBanner, &errs()); + } + RegClassInfo->runOnMachineFunction(*MF); + + // Instantiate the selected scheduler for this target, function, and + // optimization level. + std::unique_ptr<ScheduleDAGInstrs> Scheduler(createMachineScheduler()); + scheduleRegions(*Scheduler, false); + + LLVM_DEBUG(LIS->dump()); + if (VerifyScheduling) { + const char *MSchedBanner = "After machine scheduling."; + if (P) + MF->verify(P, MSchedBanner, &errs()); + else + MF->verify(*MFAM, MSchedBanner, &errs()); + } + return true; +} + +PostMachineSchedulerImpl::PostMachineSchedulerImpl(MachineFunction &Func, + MachineFunctionPass *P) + : P(P) { + MF = &Func; + MLI = &P->getAnalysis<MachineLoopInfoWrapperPass>().getLI(); + TM = &P->getAnalysis<TargetPassConfig>().getTM<TargetMachine>(); + AA = &P->getAnalysis<AAResultsWrapperPass>().getAAResults(); +} + +PostMachineSchedulerImpl::PostMachineSchedulerImpl( + MachineFunction &Func, MachineFunctionAnalysisManager &MFAM, + const TargetMachine *TargetM) + : MFAM(&MFAM) { + MF = &Func; + TM = TargetM; + MLI = &MFAM.getResult<MachineLoopAnalysis>(Func); + auto &FAM = MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(Func) + .getManager(); + AA = &FAM.getResult<AAManager>(Func.getFunction()); +} + /// Instantiate a ScheduleDAGInstrs for PostRA scheduling that will be owned by /// the caller. We don't have a command line option to override the postRA /// scheduler. The Target must configure it. -ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() { +ScheduleDAGInstrs *PostMachineSchedulerImpl::createPostMachineScheduler() { // Get the postRA scheduler set by the target for this function. - ScheduleDAGInstrs *Scheduler = PassConfig->createPostMachineScheduler(this); + ScheduleDAGInstrs *Scheduler = TM->createPostMachineScheduler(this); if (Scheduler) return Scheduler; @@ -414,6 +505,30 @@ ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() { return createGenericSchedPostRA(this); } +bool PostMachineSchedulerImpl::run() { + if (VerifyScheduling) { + const char *PostMSchedBanner = "Before post machine scheduling."; + if (P) + MF->verify(P, PostMSchedBanner, &errs()); + else + MF->verify(*MFAM, PostMSchedBanner, &errs()); + } + + // Instantiate the selected scheduler for this target, function, and + // optimization level. + std::unique_ptr<ScheduleDAGInstrs> Scheduler(createPostMachineScheduler()); + scheduleRegions(*Scheduler, true); + + if (VerifyScheduling) { + const char *PostMSchedBanner = "After post machine scheduling."; + if (P) + MF->verify(P, PostMSchedBanner, &errs()); + else + MF->verify(*MFAM, PostMSchedBanner, &errs()); + } + return true; +} + /// Top-level MachineScheduler pass driver. /// /// Visit blocks in function order. Divide each block into scheduling regions @@ -430,74 +545,84 @@ ScheduleDAGInstrs *PostMachineScheduler::createPostMachineScheduler() { /// ScheduleDAGInstrs whenever adding or removing instructions. A much simpler /// design would be to split blocks at scheduling boundaries, but LLVM has a /// general bias against block splitting purely for implementation simplicity. -bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) { - if (skipFunction(mf.getFunction())) +bool MachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(MF.getFunction())) return false; if (EnableMachineSched.getNumOccurrences()) { if (!EnableMachineSched) return false; - } else if (!mf.getSubtarget().enableMachineScheduler()) + } else if (!MF.getSubtarget().enableMachineScheduler()) { return false; + } - LLVM_DEBUG(dbgs() << "Before MISched:\n"; mf.print(dbgs())); - - // Initialize the context of the pass. - MF = &mf; - MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI(); - MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); - PassConfig = &getAnalysis<TargetPassConfig>(); - AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); + LLVM_DEBUG(dbgs() << "Before MISched:\n"; MF.print(dbgs())); - LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS(); + MachineSchedulerImpl Impl(MF, this); + return Impl.run(); +} - if (VerifyScheduling) { - LLVM_DEBUG(LIS->dump()); - MF->verify(this, "Before machine scheduling.", &errs()); +PreservedAnalyses +MachineSchedulerPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + if (EnableMachineSched.getNumOccurrences()) { + if (!EnableMachineSched) + return PreservedAnalyses::all(); + } else if (!MF.getSubtarget().enableMachineScheduler()) { + return PreservedAnalyses::all(); } - RegClassInfo->runOnMachineFunction(*MF); - // Instantiate the selected scheduler for this target, function, and - // optimization level. - std::unique_ptr<ScheduleDAGInstrs> Scheduler(createMachineScheduler()); - scheduleRegions(*Scheduler, false); + LLVM_DEBUG(dbgs() << "Before MISched:\n"; MF.print(dbgs())); - LLVM_DEBUG(LIS->dump()); - if (VerifyScheduling) - MF->verify(this, "After machine scheduling.", &errs()); - return true; + MachineSchedulerImpl Impl(MF, MFAM, TM); + bool Changed = Impl.run(); + if (!Changed) + return PreservedAnalyses::all(); + + PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet<CFGAnalyses>(); + PA.preserve<SlotIndexesAnalysis>(); + PA.preserve<LiveIntervalsAnalysis>(); + return PA; } -bool PostMachineScheduler::runOnMachineFunction(MachineFunction &mf) { - if (skipFunction(mf.getFunction())) +bool PostMachineSchedulerLegacy::runOnMachineFunction(MachineFunction &MF) { + if (skipFunction(MF.getFunction())) return false; if (EnablePostRAMachineSched.getNumOccurrences()) { if (!EnablePostRAMachineSched) return false; - } else if (!mf.getSubtarget().enablePostRAMachineScheduler()) { + } else if (!MF.getSubtarget().enablePostRAMachineScheduler()) { LLVM_DEBUG(dbgs() << "Subtarget disables post-MI-sched.\n"); return false; } - LLVM_DEBUG(dbgs() << "Before post-MI-sched:\n"; mf.print(dbgs())); + LLVM_DEBUG(dbgs() << "Before post-MI-sched:\n"; MF.print(dbgs())); - // Initialize the context of the pass. - MF = &mf; - MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI(); - PassConfig = &getAnalysis<TargetPassConfig>(); - AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); + PostMachineSchedulerImpl Impl(MF, this); + return Impl.run(); +} - if (VerifyScheduling) - MF->verify(this, "Before post machine scheduling.", &errs()); +PreservedAnalyses +PostMachineSchedulerPass::run(MachineFunction &MF, + MachineFunctionAnalysisManager &MFAM) { + if (EnablePostRAMachineSched.getNumOccurrences()) { + if (!EnablePostRAMachineSched) + return PreservedAnalyses::all(); + } else if (!MF.getSubtarget().enablePostRAMachineScheduler()) { + LLVM_DEBUG(dbgs() << "Subtarget disables post-MI-sched.\n"); + return PreservedAnalyses::all(); + } + LLVM_DEBUG(dbgs() << "Before post-MI-sched:\n"; MF.print(dbgs())); - // Instantiate the selected scheduler for this target, function, and - // optimization level. - std::unique_ptr<ScheduleDAGInstrs> Scheduler(createPostMachineScheduler()); - scheduleRegions(*Scheduler, true); + PostMachineSchedulerImpl Impl(MF, MFAM, TM); + bool Changed = Impl.run(); + if (!Changed) + return PreservedAnalyses::all(); - if (VerifyScheduling) - MF->verify(this, "After post machine scheduling.", &errs()); - return true; + PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses(); + PA.preserveSet<CFGAnalyses>(); + return PA; } /// Return true of the given instruction should not be included in a scheduling @@ -662,10 +787,6 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler, Scheduler.finalizeSchedule(); } -void MachineSchedulerBase::print(raw_ostream &O, const Module* m) const { - // unimplemented -} - #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void ReadyQueue::dump() const { dbgs() << "Queue " << Name << ": "; @@ -1293,9 +1414,9 @@ void ScheduleDAGMILive::initRegPressure() { updatePressureDiffs(LiveUses); } - LLVM_DEBUG(dbgs() << "Top Pressure:\n"; + LLVM_DEBUG(dbgs() << "Top Pressure: "; dumpRegSetPressure(TopRPTracker.getRegSetPressureAtPos(), TRI); - dbgs() << "Bottom Pressure:\n"; + dbgs() << "Bottom Pressure: "; dumpRegSetPressure(BotRPTracker.getRegSetPressureAtPos(), TRI);); assert((BotRPTracker.getPos() == RegionEnd || @@ -1316,11 +1437,14 @@ void ScheduleDAGMILive::initRegPressure() { RegionCriticalPSets.push_back(PressureChange(i)); } } - LLVM_DEBUG(dbgs() << "Excess PSets: "; - for (const PressureChange &RCPS - : RegionCriticalPSets) dbgs() - << TRI->getRegPressureSetName(RCPS.getPSet()) << " "; - dbgs() << "\n"); + LLVM_DEBUG({ + if (RegionCriticalPSets.size() > 0) { + dbgs() << "Excess PSets: "; + for (const PressureChange &RCPS : RegionCriticalPSets) + dbgs() << TRI->getRegPressureSetName(RCPS.getPSet()) << " "; + dbgs() << "\n"; + } + }); } void ScheduleDAGMILive:: @@ -1374,10 +1498,14 @@ void ScheduleDAGMILive::updatePressureDiffs(ArrayRef<VRegMaskOrUnit> LiveUses) { PressureDiff &PDiff = getPressureDiff(&SU); PDiff.addPressureChange(Reg, Decrement, &MRI); - LLVM_DEBUG(dbgs() << " UpdateRegP: SU(" << SU.NodeNum << ") " - << printReg(Reg, TRI) << ':' - << PrintLaneMask(P.LaneMask) << ' ' << *SU.getInstr(); - dbgs() << " to "; PDiff.dump(*TRI);); + if (llvm::any_of(PDiff, [](const PressureChange &Change) { + return Change.isValid(); + })) + LLVM_DEBUG(dbgs() + << " UpdateRegPressure: SU(" << SU.NodeNum << ") " + << printReg(Reg, TRI) << ':' + << PrintLaneMask(P.LaneMask) << ' ' << *SU.getInstr(); + dbgs() << " to "; PDiff.dump(*TRI);); } } else { assert(P.LaneMask.any()); @@ -1409,9 +1537,13 @@ void ScheduleDAGMILive::updatePressureDiffs(ArrayRef<VRegMaskOrUnit> LiveUses) { if (LRQ.valueIn() == VNI) { PressureDiff &PDiff = getPressureDiff(SU); PDiff.addPressureChange(Reg, true, &MRI); - LLVM_DEBUG(dbgs() << " UpdateRegP: SU(" << SU->NodeNum << ") " - << *SU->getInstr(); - dbgs() << " to "; PDiff.dump(*TRI);); + if (llvm::any_of(PDiff, [](const PressureChange &Change) { + return Change.isValid(); + })) + LLVM_DEBUG(dbgs() << " UpdateRegPressure: SU(" << SU->NodeNum + << ") " << *SU->getInstr(); + dbgs() << " to "; + PDiff.dump(*TRI);); } } } @@ -1671,7 +1803,7 @@ void ScheduleDAGMILive::scheduleMI(SUnit *SU, bool IsTopNode) { TopRPTracker.advance(RegOpers); assert(TopRPTracker.getPos() == CurrentTop && "out of sync"); - LLVM_DEBUG(dbgs() << "Top Pressure:\n"; dumpRegSetPressure( + LLVM_DEBUG(dbgs() << "Top Pressure: "; dumpRegSetPressure( TopRPTracker.getRegSetPressureAtPos(), TRI);); updateScheduledPressure(SU, TopRPTracker.getPressure().MaxSetPressure); @@ -1709,7 +1841,7 @@ void ScheduleDAGMILive::scheduleMI(SUnit *SU, bool IsTopNode) { SmallVector<VRegMaskOrUnit, 8> LiveUses; BotRPTracker.recede(RegOpers, &LiveUses); assert(BotRPTracker.getPos() == CurrentBottom && "out of sync"); - LLVM_DEBUG(dbgs() << "Bottom Pressure:\n"; dumpRegSetPressure( + LLVM_DEBUG(dbgs() << "Bottom Pressure: "; dumpRegSetPressure( BotRPTracker.getRegSetPressureAtPos(), TRI);); updateScheduledPressure(SU, BotRPTracker.getPressure().MaxSetPressure); |