[llvm] 8c3cb9c - [CodeGen][NPM] Port MachinePipeliner to NPM (#221676)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 9 01:07:25 PDT 2026
Author: Vikram Hegde
Date: 2026-09-09T13:37:19+05:30
New Revision: 8c3cb9c166e8f5ade26bc90a4a4cf5ec628f894f
URL: https://github.com/llvm/llvm-project/commit/8c3cb9c166e8f5ade26bc90a4a4cf5ec628f894f
DIFF: https://github.com/llvm/llvm-project/commit/8c3cb9c166e8f5ade26bc90a4a4cf5ec628f894f.diff
LOG: [CodeGen][NPM] Port MachinePipeliner to NPM (#221676)
changes of note,
1. registers the pass with AMDGPUCodeGenPassBuilder::addPreRegAlloc()
2. Changes the core MachinePipeliner::run() method to return actual
"Changed" state
Added:
Modified:
llvm/include/llvm/CodeGen/MachinePipeliner.h
llvm/include/llvm/InitializePasses.h
llvm/include/llvm/Passes/MachinePassRegistry.def
llvm/lib/CodeGen/CodeGen.cpp
llvm/lib/CodeGen/MachinePipeliner.cpp
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MachinePipeliner.h b/llvm/include/llvm/CodeGen/MachinePipeliner.h
index 7b2d1226530d3..dcf54cad0f85a 100644
--- a/llvm/include/llvm/CodeGen/MachinePipeliner.h
+++ b/llvm/include/llvm/CodeGen/MachinePipeliner.h
@@ -57,6 +57,7 @@
namespace llvm {
class AAResults;
+class LiveIntervals;
class NodeSet;
class SMSchedule;
@@ -71,52 +72,22 @@ struct MachinePipelinerPolicy {
bool ShouldLimitRegPressure = false;
};
-/// The main class in the implementation of the target independent
-/// software pipeliner pass.
-class LLVM_ABI MachinePipeliner : public MachineFunctionPass {
+class LLVM_ABI MachinePipelinerLegacy : public MachineFunctionPass {
public:
- MachineFunction *MF = nullptr;
- MachineOptimizationRemarkEmitter *ORE = nullptr;
- const MachineLoopInfo *MLI = nullptr;
- const InstrItineraryData *InstrItins = nullptr;
- const TargetInstrInfo *TII = nullptr;
- const RegisterClassInfo *RegClassInfo = nullptr;
- bool disabledByPragma = false;
- unsigned II_setByPragma = 0;
-
-#ifndef NDEBUG
- static int NumTries;
-#endif
-
- /// Cache the target analysis information about the loop.
- struct LoopInfo {
- MachineBasicBlock *TBB = nullptr;
- MachineBasicBlock *FBB = nullptr;
- SmallVector<MachineOperand, 4> BrCond;
- MachineInstr *LoopInductionVar = nullptr;
- MachineInstr *LoopCompare = nullptr;
- std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopPipelinerInfo =
- nullptr;
- };
- LoopInfo LI;
-
static char ID;
- MachinePipeliner() : MachineFunctionPass(ID) {}
+ MachinePipelinerLegacy() : MachineFunctionPass(ID) {}
bool runOnMachineFunction(MachineFunction &MF) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
-private:
- void preprocessPhiNodes(MachineBasicBlock &B);
- bool canPipelineLoop(MachineLoop &L);
- bool scheduleLoop(MachineLoop &L);
- bool swingModuloScheduler(MachineLoop &L);
- void setPragmaPipelineOptions(MachineLoop &L);
- bool runWindowScheduler(MachineLoop &L);
- bool useSwingModuloScheduler();
- bool useWindowScheduler(bool Changed);
+class LLVM_ABI MachinePipelinerPass
+ : public OptionalPassInfoMixin<MachinePipelinerPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
};
/// Represents a dependence between two instruction.
@@ -287,7 +258,7 @@ class SwingSchedulerDDG {
/// This class builds the dependence graph for the instructions in a loop,
/// and attempts to schedule the instructions using the SMS algorithm.
class LLVM_ABI SwingSchedulerDAG : public ScheduleDAGInstrs {
- MachinePipeliner &Pass;
+ MachineOptimizationRemarkEmitter *ORE;
std::unique_ptr<SwingSchedulerDDG> DDG;
@@ -391,14 +362,16 @@ class LLVM_ABI SwingSchedulerDAG : public ScheduleDAGInstrs {
};
public:
- SwingSchedulerDAG(MachinePipeliner &P, MachineLoop &L, LiveIntervals &lis,
- const RegisterClassInfo &rci, unsigned II,
- TargetInstrInfo::PipelinerLoopInfo *PLI, AliasAnalysis *AA)
- : ScheduleDAGInstrs(*P.MF, P.MLI, false), Pass(P), Loop(L), LIS(lis),
+ SwingSchedulerDAG(MachineFunction &MF, const MachineLoopInfo *MLI,
+ MachineOptimizationRemarkEmitter *ORE, MachineLoop &L,
+ LiveIntervals &lis, const RegisterClassInfo &rci,
+ unsigned II, TargetInstrInfo::PipelinerLoopInfo *PLI,
+ AliasAnalysis *AA)
+ : ScheduleDAGInstrs(MF, MLI, false), ORE(ORE), Loop(L), LIS(lis),
RegClassInfo(rci), II_setByPragma(II), LoopPipelinerInfo(PLI),
Topo(SUnits, &ExitSU), AA(AA), BAA(*AA) {
initPolicy();
- P.MF->getSubtarget().getSMSMutations(Mutations);
+ MF.getSubtarget().getSMSMutations(Mutations);
if (SwpEnableCopyToPhi)
Mutations.push_back(std::make_unique<CopyToPhiMutation>());
BAA.enableCrossIterationMode();
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1fa4565bef193..1ba2f67d27e5d 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -215,7 +215,7 @@ initializeMachineOptimizationRemarkEmitterPassPass(PassRegistry &);
LLVM_ABI void initializeMachineOutlinerPass(PassRegistry &);
LLVM_ABI void initializeStaticDataProfileInfoWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeStaticDataAnnotatorLegacyPass(PassRegistry &);
-LLVM_ABI void initializeMachinePipelinerPass(PassRegistry &);
+LLVM_ABI void initializeMachinePipelinerLegacyPass(PassRegistry &);
LLVM_ABI void initializeMachinePostDominatorTreeWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeMachineRegionInfoPassPass(PassRegistry &);
LLVM_ABI void initializeMachineRegisterClassInfoWrapperPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index 63c0fa4a65ffe..78253532a8570 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -104,6 +104,7 @@ MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass())
MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass())
MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass())
MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass())
+MACHINE_FUNCTION_PASS("pipeliner", MachinePipelinerPass())
MACHINE_FUNCTION_PASS("post-RA-hazard-rec", PostRAHazardRecognizerPass())
MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass(TM))
MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass())
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index c9f14737c392c..efa9bdc635c5f 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -102,7 +102,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeMachineModuleInfoWrapperPassPass(Registry);
initializeMachineOptimizationRemarkEmitterPassPass(Registry);
initializeMachineOutlinerPass(Registry);
- initializeMachinePipelinerPass(Registry);
+ initializeMachinePipelinerLegacyPass(Registry);
initializeMachineSanitizerBinaryMetadataLegacyPass(Registry);
initializeModuloScheduleTestPass(Registry);
initializeMachinePostDominatorTreeWrapperPassPass(Registry);
diff --git a/llvm/lib/CodeGen/MachinePipeliner.cpp b/llvm/lib/CodeGen/MachinePipeliner.cpp
index 5190a98ef714d..f33d41f25df34 100644
--- a/llvm/lib/CodeGen/MachinePipeliner.cpp
+++ b/llvm/lib/CodeGen/MachinePipeliner.cpp
@@ -56,6 +56,7 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/ModuloSchedule.h"
#include "llvm/CodeGen/Register.h"
@@ -226,19 +227,16 @@ static cl::opt<WindowSchedulingFlag> WindowSchedulingOption(
"Use window algorithm instead of SMS algorithm.")));
unsigned SwingSchedulerDAG::Circuits::MaxPaths = 5;
-char MachinePipeliner::ID = 0;
-#ifndef NDEBUG
-int MachinePipeliner::NumTries = 0;
-#endif
-char &llvm::MachinePipelinerID = MachinePipeliner::ID;
+char MachinePipelinerLegacy::ID = 0;
+char &llvm::MachinePipelinerID = MachinePipelinerLegacy::ID;
-INITIALIZE_PASS_BEGIN(MachinePipeliner, DEBUG_TYPE,
+INITIALIZE_PASS_BEGIN(MachinePipelinerLegacy, DEBUG_TYPE,
"Modulo Software Pipelining", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineRegisterClassInfoWrapperPass)
-INITIALIZE_PASS_END(MachinePipeliner, DEBUG_TYPE,
+INITIALIZE_PASS_END(MachinePipelinerLegacy, DEBUG_TYPE,
"Modulo Software Pipelining", false, false)
namespace {
@@ -357,47 +355,163 @@ class LoopCarriedOrderDepsTracker {
}
};
+/// The main class in the implementation of the target independent
+/// software pipeliner pass.
+class MachinePipelinerImpl {
+public:
+ MachineFunction *MF = nullptr;
+ MachineOptimizationRemarkEmitter *ORE = nullptr;
+ const MachineLoopInfo *MLI = nullptr;
+ const InstrItineraryData *InstrItins = nullptr;
+ const TargetInstrInfo *TII = nullptr;
+ RegisterClassInfo *RegClassInfo = nullptr;
+ LiveIntervals *LIS = nullptr;
+ AAResults *AA = nullptr;
+ const TargetMachine *TM = nullptr;
+ bool disabledByPragma = false;
+ unsigned II_setByPragma = 0;
+
+#ifndef NDEBUG
+ static int NumTries;
+#endif
+
+ /// Cache the target analysis information about the loop.
+ struct LoopInfo {
+ MachineBasicBlock *TBB = nullptr;
+ MachineBasicBlock *FBB = nullptr;
+ SmallVector<MachineOperand, 4> BrCond;
+ MachineInstr *LoopInductionVar = nullptr;
+ MachineInstr *LoopCompare = nullptr;
+ std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopPipelinerInfo =
+ nullptr;
+ };
+ LoopInfo LI;
+
+ MachinePipelinerImpl(MachineFunction &MF, const MachineLoopInfo &MLI,
+ LiveIntervals &LIS, AAResults &AA,
+ MachineOptimizationRemarkEmitter &ORE,
+ RegisterClassInfo &RegClassInfo);
+
+ /// Run the software pipeliner over all loops in the function.
+ bool run();
+
+private:
+ void preprocessPhiNodes(MachineBasicBlock &B);
+ bool canPipelineLoop(MachineLoop &L);
+ bool scheduleLoop(MachineLoop &L);
+ bool swingModuloScheduler(MachineLoop &L);
+ void setPragmaPipelineOptions(MachineLoop &L);
+ bool runWindowScheduler(MachineLoop &L);
+ bool useSwingModuloScheduler();
+ bool useWindowScheduler(bool Changed);
+};
+
} // end anonymous namespace
+#ifndef NDEBUG
+int MachinePipelinerImpl::NumTries = 0;
+#endif
+
+MachinePipelinerImpl::MachinePipelinerImpl(
+ MachineFunction &MF, const MachineLoopInfo &MLI, LiveIntervals &LIS,
+ AAResults &AA, MachineOptimizationRemarkEmitter &ORE,
+ RegisterClassInfo &RegClassInfo)
+ : MF(&MF), ORE(&ORE), MLI(&MLI), TII(MF.getSubtarget().getInstrInfo()),
+ RegClassInfo(&RegClassInfo), LIS(&LIS), AA(&AA), TM(&MF.getTarget()) {}
+
/// The "main" function for implementing Swing Modulo Scheduling.
-bool MachinePipeliner::runOnMachineFunction(MachineFunction &mf) {
- if (skipFunction(mf.getFunction()))
- return false;
+bool MachinePipelinerImpl::run() {
+ bool Changed = false;
+ for (const auto &L : *MLI)
+ Changed |= scheduleLoop(*L);
+
+ return Changed;
+}
+static bool runMachinePipeliner(
+ MachineFunction &MF, function_ref<const MachineLoopInfo &()> GetMLI,
+ function_ref<LiveIntervals &()> GetLIS, function_ref<AAResults &()> GetAA,
+ function_ref<MachineOptimizationRemarkEmitter &()> GetORE,
+ function_ref<RegisterClassInfo &()> GetRCI) {
if (!EnableSWP)
return false;
- if (mf.getFunction().getAttributes().hasFnAttr(Attribute::OptimizeForSize) &&
+ if (MF.getFunction().getAttributes().hasFnAttr(Attribute::OptimizeForSize) &&
!EnableSWPOptSize.getPosition())
return false;
- if (!mf.getSubtarget().enableMachinePipeliner())
+ if (!MF.getSubtarget().enableMachinePipeliner())
return false;
// Cannot pipeline loops without instruction itineraries if we are using
// DFA for the pipeliner.
- if (mf.getSubtarget().useDFAforSMS() &&
- (!mf.getSubtarget().getInstrItineraryData() ||
- mf.getSubtarget().getInstrItineraryData()->isEmpty()))
+ if (MF.getSubtarget().useDFAforSMS() &&
+ (!MF.getSubtarget().getInstrItineraryData() ||
+ MF.getSubtarget().getInstrItineraryData()->isEmpty()))
return false;
- MF = &mf;
- MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
- ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
- RegClassInfo = &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
- TII = MF->getSubtarget().getInstrInfo();
+ MachinePipelinerImpl MP(MF, GetMLI(), GetLIS(), GetAA(), GetORE(), GetRCI());
+ return MP.run();
+}
- for (const auto &L : *MLI)
- scheduleLoop(*L);
+bool MachinePipelinerLegacy::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
- return false;
+ return runMachinePipeliner(
+ MF,
+ [&]() -> const MachineLoopInfo & {
+ return getAnalysis<MachineLoopInfoWrapperPass>().getLI();
+ },
+ [&]() -> LiveIntervals & {
+ return getAnalysis<LiveIntervalsWrapperPass>().getLIS();
+ },
+ [&]() -> AAResults & {
+ return getAnalysis<AAResultsWrapperPass>().getAAResults();
+ },
+ [&]() -> MachineOptimizationRemarkEmitter & {
+ return getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
+ },
+ [&]() -> RegisterClassInfo & {
+ return getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
+ });
+}
+
+PreservedAnalyses
+MachinePipelinerPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ if (!runMachinePipeliner(
+ MF,
+ [&]() -> const MachineLoopInfo & {
+ return MFAM.getResult<MachineLoopAnalysis>(MF);
+ },
+ [&]() -> LiveIntervals & {
+ return MFAM.getResult<LiveIntervalsAnalysis>(MF);
+ },
+ [&]() -> AAResults & {
+ return MFAM
+ .getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+ .getManager()
+ .getResult<AAManager>(MF.getFunction());
+ },
+ [&]() -> MachineOptimizationRemarkEmitter & {
+ return MFAM.getResult<MachineOptimizationRemarkEmitterAnalysis>(MF);
+ },
+ [&]() -> RegisterClassInfo & {
+ return MFAM.getResult<MachineRegisterClassAnalysis>(MF);
+ }))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA = getMachineFunctionPassPreservedAnalyses();
+ PA.preserve<MachineRegisterClassAnalysis>();
+ return PA;
}
/// Attempt to perform the SMS algorithm on the specified loop. This function is
/// the main entry point for the algorithm. The function identifies candidate
/// loops, calculates the minimum initiation interval, and attempts to schedule
/// the loop.
-bool MachinePipeliner::scheduleLoop(MachineLoop &L) {
+bool MachinePipelinerImpl::scheduleLoop(MachineLoop &L) {
bool Changed = false;
for (const auto &InnerLoop : L)
Changed |= scheduleLoop(*InnerLoop);
@@ -436,7 +550,7 @@ bool MachinePipeliner::scheduleLoop(MachineLoop &L) {
return Changed;
}
-void MachinePipeliner::setPragmaPipelineOptions(MachineLoop &L) {
+void MachinePipelinerImpl::setPragmaPipelineOptions(MachineLoop &L) {
// Reset the pragma for the next loop in iteration.
disabledByPragma = false;
II_setByPragma = 0;
@@ -542,7 +656,7 @@ static bool hasPHICycle(const MachineBasicBlock *LoopHeader,
/// Return true if the loop can be software pipelined. The algorithm is
/// restricted to loops with a single basic block. Make sure that the
/// branch in the loop can be analyzed.
-bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
+bool MachinePipelinerImpl::canPipelineLoop(MachineLoop &L) {
if (L.getNumBlocks() != 1) {
ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
@@ -630,10 +744,9 @@ bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
return true;
}
-void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
+void MachinePipelinerImpl::preprocessPhiNodes(MachineBasicBlock &B) {
MachineRegisterInfo &MRI = MF->getRegInfo();
- SlotIndexes &Slots =
- *getAnalysis<LiveIntervalsWrapperPass>().getLIS().getSlotIndexes();
+ SlotIndexes &Slots = *LIS->getSlotIndexes();
for (MachineInstr &PI : B.phis()) {
MachineOperand &DefOp = PI.getOperand(0);
@@ -665,13 +778,11 @@ void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
/// 1. Computation and analysis of the dependence graph.
/// 2. Ordering of the nodes (instructions).
/// 3. Attempt to Schedule the loop.
-bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
+bool MachinePipelinerImpl::swingModuloScheduler(MachineLoop &L) {
assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
- AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- SwingSchedulerDAG SMS(
- *this, L, getAnalysis<LiveIntervalsWrapperPass>().getLIS(), *RegClassInfo,
- II_setByPragma, LI.LoopPipelinerInfo.get(), AA);
+ SwingSchedulerDAG SMS(*MF, MLI, ORE, L, *LIS, *RegClassInfo, II_setByPragma,
+ LI.LoopPipelinerInfo.get(), AA);
MachineBasicBlock *MBB = L.getHeader();
// The kernel should not include any terminator instructions. These
@@ -694,7 +805,7 @@ bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
return SMS.hasNewSchedule();
}
-void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
+void MachinePipelinerLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<AAResultsWrapperPass>();
AU.addPreserved<AAResultsWrapperPass>();
AU.addRequired<MachineLoopInfoWrapperPass>();
@@ -706,25 +817,24 @@ void MachinePipeliner::getAnalysisUsage(AnalysisUsage &AU) const {
MachineFunctionPass::getAnalysisUsage(AU);
}
-bool MachinePipeliner::runWindowScheduler(MachineLoop &L) {
+bool MachinePipelinerImpl::runWindowScheduler(MachineLoop &L) {
MachineSchedContext Context;
Context.MF = MF;
Context.MLI = MLI;
- Context.TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
- Context.AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
- Context.LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
- Context.RegClassInfo =
- &getAnalysis<MachineRegisterClassInfoWrapperPass>().getRCI();
+ Context.TM = TM;
+ Context.AA = AA;
+ Context.LIS = LIS;
+ Context.RegClassInfo = RegClassInfo;
WindowScheduler WS(&Context, L);
return WS.run();
}
-bool MachinePipeliner::useSwingModuloScheduler() {
+bool MachinePipelinerImpl::useSwingModuloScheduler() {
// SwingModuloScheduler does not work when WindowScheduler is forced.
return WindowSchedulingOption != WindowSchedulingFlag::WS_Force;
}
-bool MachinePipeliner::useWindowScheduler(bool Changed) {
+bool MachinePipelinerImpl::useWindowScheduler(bool Changed) {
// WindowScheduler does not work for following cases:
// 1. when it is off.
// 2. when SwingModuloScheduler is successfully scheduled.
@@ -799,7 +909,7 @@ void SwingSchedulerDAG::schedule() {
if (MII == 0) {
LLVM_DEBUG(dbgs() << "Invalid Minimal Initiation Interval: 0\n");
NumFailZeroMII++;
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "Invalid Minimal Initiation Interval: 0";
@@ -812,7 +922,7 @@ void SwingSchedulerDAG::schedule() {
LLVM_DEBUG(dbgs() << "MII > " << SwpMaxMii
<< ", we don't pipeline large loops\n");
NumFailLargeMaxMII++;
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "Minimal Initiation Interval too large: "
@@ -856,13 +966,13 @@ void SwingSchedulerDAG::schedule() {
// check for node order issues
checkValidNodeOrder(Circuits);
- SMSchedule Schedule(Pass.MF, this);
+ SMSchedule Schedule(&MF, this);
Scheduled = schedulePipeline(Schedule);
if (!Scheduled){
LLVM_DEBUG(dbgs() << "No schedule found, return\n");
NumFailNoSchedule++;
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "Unable to find schedule";
@@ -875,7 +985,7 @@ void SwingSchedulerDAG::schedule() {
if (numStages == 0) {
LLVM_DEBUG(dbgs() << "No overlapped iterations, skip.\n");
NumFailZeroStage++;
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "No need to pipeline - no overlapped iterations in schedule.";
@@ -887,7 +997,7 @@ void SwingSchedulerDAG::schedule() {
LLVM_DEBUG(dbgs() << "numStages:" << numStages << ">" << SwpMaxStages
<< " : too many stages, abort\n");
NumFailLargeMaxStage++;
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "Too many stages in schedule: "
@@ -898,7 +1008,7 @@ void SwingSchedulerDAG::schedule() {
return;
}
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemark(DEBUG_TYPE, "schedule", Loop.getStartLoc(),
Loop.getHeader())
<< "Pipelined succesfully!";
@@ -2903,7 +3013,7 @@ bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
if (scheduleFound) {
Schedule.finalizeSchedule(this);
- Pass.ORE->emit([&]() {
+ ORE->emit([&]() {
return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
<< "Schedule found with Initiation Interval: "
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 81420f2ab885d..725ce2d589a31 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -151,6 +151,7 @@
#include "llvm/CodeGen/MachineLICM.h"
#include "llvm/CodeGen/MachineLateInstrsCleanup.h"
#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/MachinePipeliner.h"
#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegionInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
index aa36e29b0bab6..f25fab4b24721 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
@@ -87,6 +87,7 @@
#include "llvm/CodeGen/MIRParser/MIParser.h"
#include "llvm/CodeGen/MachineCSE.h"
#include "llvm/CodeGen/MachineLICM.h"
+#include "llvm/CodeGen/MachinePipeliner.h"
#include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/PHIElimination.h"
#include "llvm/CodeGen/Passes.h"
@@ -2648,6 +2649,8 @@ Error AMDGPUCodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
void AMDGPUCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
if (getOptLevel() != CodeGenOptLevel::None)
addMachineFunctionPass(AMDGPUPrepareAGPRAllocPass(), PMW);
+ if (getOptLevel() >= CodeGenOptLevel::Default && EnableMachinePipeliner)
+ addMachineFunctionPass(MachinePipelinerPass(), PMW);
}
Expected<bool> AMDGPUCodeGenPassBuilder::addRegAssignAndRewriteOptimized(
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
index 1c1590eeb9822..56b37b6286da4 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-epilog-phi.mir
@@ -1,5 +1,6 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -pipeliner-force-ii=12 %s -o - | FileCheck %s
# Two independent recurrences (a sum and a product) must be carried across the stage
# boundary without being swapped: each accumulator's kernel result has to flow through
# its own epilog PHI and drain op into its own store.
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
index 7bad3042e571a..f2aae2e57fcaf 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-gen-structure.mir
@@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -pipeliner-force-ii=8 %s -o - | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -pipeliner-force-ii=8 %s -o - | FileCheck %s
# Verify the generated prolog / steady-state kernel / epilog structure of a pipelined loop.
# CHECK-LABEL: name: swp_amdgpu_pipeline_gen_structure
diff --git a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
index 9dc50350a8d6c..bb39f0339e6d8 100644
--- a/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
+++ b/llvm/test/CodeGen/AMDGPU/swp-amdgpu-pipeline-loop-carried-mem.mir
@@ -1,4 +1,5 @@
# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -run-pass=pipeliner -debug-only=pipeliner %s -filetype=null 2>&1 | FileCheck %s
+# RUN: llc -mtriple=amdgpu9.50-amd-amdhsa -passes=pipeliner -debug-only=pipeliner %s -filetype=null 2>&1 | FileCheck %s
# REQUIRES: asserts
# A loop that loads a[i] and stores a[i+1] must get a loop-carried memory dependence
# between the load and the store, so they are not reordered across iterations.
More information about the llvm-commits
mailing list