[llvm-branch-commits] [RISCV] Port LoadStoreOpt to NewPM (PR #235511)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Oct 25 12:05:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-risc-v
Author: Aiden Grossman (boomanaiden154)
<details>
<summary>Changes</summary>
Standard NewPM pass portign. Also mark in the LegacyPM this pass
preserves the CFG.
---
Full diff: https://github.com/llvm/llvm-project/pull/235511.diff
4 Files Affected:
- (modified) llvm/lib/Target/RISCV/RISCV.h (+9-2)
- (modified) llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp (+66-32)
- (modified) llvm/lib/Target/RISCV/RISCVPassRegistry.def (+1)
- (modified) llvm/lib/Target/RISCV/RISCVTargetMachine.cpp (+2-2)
``````````diff
diff --git a/llvm/lib/Target/RISCV/RISCV.h b/llvm/lib/Target/RISCV/RISCV.h
index 96f4e23f2fafd..36924db70283d 100644
--- a/llvm/lib/Target/RISCV/RISCV.h
+++ b/llvm/lib/Target/RISCV/RISCV.h
@@ -256,8 +256,15 @@ class RISCVPushPopOptPass : public OptionalPassInfoMixin<RISCVPushPopOptPass> {
FunctionPass *createRISCVPushPopOptLegacyPass();
void initializeRISCVPushPopOptLegacyPass(PassRegistry &);
-FunctionPass *createRISCVLoadStoreOptPass();
-void initializeRISCVLoadStoreOptPass(PassRegistry &);
+class RISCVLoadStoreOptPass
+ : public OptionalPassInfoMixin<RISCVLoadStoreOptPass> {
+public:
+ PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+};
+
+FunctionPass *createRISCVLoadStoreOptLegacyPass();
+void initializeRISCVLoadStoreOptLegacyPass(PassRegistry &);
FunctionPass *createRISCVPreAllocZilsdOptPass();
void initializeRISCVPreAllocZilsdOptPass(PassRegistry &);
diff --git a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
index 9efe85d27c6c0..92cd393ca6add 100644
--- a/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
+++ b/llvm/lib/Target/RISCV/RISCVLoadStoreOptimizer.cpp
@@ -29,7 +29,10 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/IR/Analysis.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetOptions.h"
@@ -44,23 +47,27 @@ STATISTIC(NumSD2SW, "Number of SD instructions split back to SW");
namespace {
-struct RISCVLoadStoreOpt : public MachineFunctionPass {
+class RISCVLoadStoreOptLegacy : public MachineFunctionPass {
+public:
static char ID;
bool runOnMachineFunction(MachineFunction &Fn) override;
- RISCVLoadStoreOpt() : MachineFunctionPass(ID) {}
+ RISCVLoadStoreOptLegacy() : MachineFunctionPass(ID) {}
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().setNoVRegs();
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesCFG();
AU.addRequired<AAResultsWrapperPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
StringRef getPassName() const override { return RISCV_LOAD_STORE_OPT_NAME; }
+};
+class RISCVLoadStoreOptImpl {
// Find and pair load/store instructions.
bool tryToPairLdStInst(MachineBasicBlock::iterator &MBBI);
@@ -92,35 +99,37 @@ struct RISCVLoadStoreOpt : public MachineFunctionPass {
void splitLdSdIntoTwo(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI, bool IsLoad);
-private:
AliasAnalysis *AA;
MachineRegisterInfo *MRI;
const RISCVInstrInfo *TII;
const RISCVRegisterInfo *TRI;
const RISCVSubtarget *STI = nullptr;
LiveRegUnits ModifiedRegUnits, UsedRegUnits;
+
+public:
+ bool runOnMachineFunction(MachineFunction &MF,
+ function_ref<AliasAnalysis *()> GetAA);
};
} // end anonymous namespace
-char RISCVLoadStoreOpt::ID = 0;
-INITIALIZE_PASS(RISCVLoadStoreOpt, DEBUG_TYPE, RISCV_LOAD_STORE_OPT_NAME, false,
- false)
+char RISCVLoadStoreOptLegacy::ID = 0;
+INITIALIZE_PASS(RISCVLoadStoreOptLegacy, DEBUG_TYPE, RISCV_LOAD_STORE_OPT_NAME,
+ false, false)
-bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
- if (skipFunction(Fn.getFunction()))
- return false;
+bool RISCVLoadStoreOptImpl::runOnMachineFunction(
+ MachineFunction &MF, function_ref<AliasAnalysis *()> GetAA) {
bool MadeChange = false;
- STI = &Fn.getSubtarget<RISCVSubtarget>();
+ STI = &MF.getSubtarget<RISCVSubtarget>();
TII = STI->getInstrInfo();
TRI = STI->getRegisterInfo();
- MRI = &Fn.getRegInfo();
- AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ MRI = &MF.getRegInfo();
+ AA = GetAA();
ModifiedRegUnits.init(*TRI);
UsedRegUnits.init(*TRI);
if (STI->useMIPSLoadStorePairs() || STI->hasVendorXqcilsm()) {
- for (MachineBasicBlock &MBB : Fn) {
+ for (MachineBasicBlock &MBB : MF) {
LLVM_DEBUG(dbgs() << "MBB: " << MBB.getName() << "\n");
for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
@@ -135,7 +144,7 @@ bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
}
if (!STI->is64Bit() && STI->hasStdExtZilsd()) {
- for (auto &MBB : Fn) {
+ for (auto &MBB : MF) {
for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E;) {
if (fixInvalidRegPairOp(MBB, MBBI)) {
MadeChange = true;
@@ -152,7 +161,8 @@ bool RISCVLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
// Find loads and stores that can be merged into a single load or store pair
// instruction.
-bool RISCVLoadStoreOpt::tryToPairLdStInst(MachineBasicBlock::iterator &MBBI) {
+bool RISCVLoadStoreOptImpl::tryToPairLdStInst(
+ MachineBasicBlock::iterator &MBBI) {
MachineInstr &MI = *MBBI;
// If this is volatile, it is not a candidate.
@@ -189,7 +199,7 @@ static bool isMemOpAligned(MachineInstr &MI, Align RequiredAlignment) {
// For now this only handles consecutive loads and stores traversing the basic
// block top-down.
// TODO: Traverse the basic block bottom-up as well.
-bool RISCVLoadStoreOpt::tryConvertToXqcilsmMultiLdSt(
+bool RISCVLoadStoreOptImpl::tryConvertToXqcilsmMultiLdSt(
MachineBasicBlock::iterator &FirstIt) {
MachineInstr &FirstMI = *FirstIt;
MachineFunction *MF = FirstMI.getMF();
@@ -374,7 +384,7 @@ bool RISCVLoadStoreOpt::tryConvertToXqcilsmMultiLdSt(
return true;
}
-bool RISCVLoadStoreOpt::tryConvertToXqcilsmLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToXqcilsmLdStPair(
MachineFunction *MF, MachineBasicBlock::iterator First,
MachineBasicBlock::iterator Second) {
unsigned Opc = First->getOpcode();
@@ -475,7 +485,7 @@ bool RISCVLoadStoreOpt::tryConvertToXqcilsmLdStPair(
return true;
}
-bool RISCVLoadStoreOpt::tryConvertToMIPSLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToMIPSLdStPair(
MachineFunction *MF, MachineBasicBlock::iterator First,
MachineBasicBlock::iterator Second) {
// Try converting to SWP/LWP/LDP/SDP.
@@ -535,7 +545,7 @@ bool RISCVLoadStoreOpt::tryConvertToMIPSLdStPair(
// appropriate paired opcode, verifies that the memory operand is properly
// aligned, and checks that the offset is valid. If all conditions are met, it
// builds and inserts the paired instruction.
-bool RISCVLoadStoreOpt::tryConvertToLdStPair(
+bool RISCVLoadStoreOptImpl::tryConvertToLdStPair(
MachineBasicBlock::iterator First, MachineBasicBlock::iterator Second) {
MachineFunction *MF = First->getMF();
@@ -564,8 +574,8 @@ static bool mayAlias(MachineInstr &MIa,
// This requires more sophisticated checks for aliasing, register
// liveness, and potential scheduling hazards.
MachineBasicBlock::iterator
-RISCVLoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
- bool &MergeForward) {
+RISCVLoadStoreOptImpl::findMatchingInsn(MachineBasicBlock::iterator I,
+ bool &MergeForward) {
MachineBasicBlock::iterator E = I->getParent()->end();
MachineBasicBlock::iterator MBBI = I;
MachineInstr &FirstMI = *I;
@@ -677,9 +687,9 @@ RISCVLoadStoreOpt::findMatchingInsn(MachineBasicBlock::iterator I,
}
MachineBasicBlock::iterator
-RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
- MachineBasicBlock::iterator Paired,
- bool MergeForward) {
+RISCVLoadStoreOptImpl::mergePairedInsns(MachineBasicBlock::iterator I,
+ MachineBasicBlock::iterator Paired,
+ bool MergeForward) {
MachineBasicBlock::iterator E = I->getParent()->end();
MachineBasicBlock::iterator NextI = next_nodbg(I, E);
// If NextI is the second of the two instructions to be merged, skip one
@@ -763,7 +773,8 @@ RISCVLoadStoreOpt::mergePairedInsns(MachineBasicBlock::iterator I,
// Post reg-alloc zilsd pass implementation
//===----------------------------------------------------------------------===//
-bool RISCVLoadStoreOpt::isValidZilsdRegPair(Register First, Register Second) {
+bool RISCVLoadStoreOptImpl::isValidZilsdRegPair(Register First,
+ Register Second) {
// Special case: First register can not be zero unless both registers are
// zeros.
// Spec says: LD instructions with destination x0 are processed as any other
@@ -781,9 +792,9 @@ bool RISCVLoadStoreOpt::isValidZilsdRegPair(Register First, Register Second) {
return (FirstNum % 2 == 0) && (SecondNum == FirstNum + 1);
}
-void RISCVLoadStoreOpt::splitLdSdIntoTwo(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI,
- bool IsLoad) {
+void RISCVLoadStoreOptImpl::splitLdSdIntoTwo(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator &MBBI,
+ bool IsLoad) {
MachineInstr *MI = &*MBBI;
DebugLoc DL = MI->getDebugLoc();
@@ -877,8 +888,8 @@ void RISCVLoadStoreOpt::splitLdSdIntoTwo(MachineBasicBlock &MBB,
MBBI = MBB.erase(MBBI);
}
-bool RISCVLoadStoreOpt::fixInvalidRegPairOp(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator &MBBI) {
+bool RISCVLoadStoreOptImpl::fixInvalidRegPairOp(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) {
MachineInstr *MI = &*MBBI;
unsigned Opcode = MI->getOpcode();
@@ -936,6 +947,29 @@ bool RISCVLoadStoreOpt::fixInvalidRegPairOp(MachineBasicBlock &MBB,
}
// Returns an instance of the Load / Store Optimization pass.
-FunctionPass *llvm::createRISCVLoadStoreOptPass() {
- return new RISCVLoadStoreOpt();
+FunctionPass *llvm::createRISCVLoadStoreOptLegacyPass() {
+ return new RISCVLoadStoreOptLegacy();
+}
+
+bool RISCVLoadStoreOptLegacy::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
+ RISCVLoadStoreOptImpl Impl;
+ return Impl.runOnMachineFunction(MF, [&]() {
+ return &getAnalysis<AAResultsWrapperPass>().getAAResults();
+ });
+}
+
+PreservedAnalyses
+RISCVLoadStoreOptPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ RISCVLoadStoreOptImpl Impl;
+ bool Changed = Impl.runOnMachineFunction(MF, [&]() {
+ return &MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+ .getManager()
+ .getResult<AAManager>(MF.getFunction());
+ });
+ return Changed ? getMachineFunctionPassPreservedAnalyses()
+ .preserveSet<CFGAnalyses>()
+ : PreservedAnalyses::all();
}
diff --git a/llvm/lib/Target/RISCV/RISCVPassRegistry.def b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
index c909234e4004c..905c3fe29c771 100644
--- a/llvm/lib/Target/RISCV/RISCVPassRegistry.def
+++ b/llvm/lib/Target/RISCV/RISCVPassRegistry.def
@@ -52,6 +52,7 @@ MACHINE_FUNCTION_PASS("riscv-insert-vsetvli", RISCVInsertVSETVLIPass())
MACHINE_FUNCTION_PASS("riscv-insert-write-vxrm", RISCVInsertWriteVXRMPass())
MACHINE_FUNCTION_PASS("riscv-isel", RISCVISelDAGToDAGPass(*this, getOptLevel()))
MACHINE_FUNCTION_PASS("riscv-late-branch-opt", RISCVLateBranchOptPass())
+MACHINE_FUNCTION_PASS("riscv-load-store-opt", RISCVLoadStoreOptPass())
MACHINE_FUNCTION_PASS("riscv-lpad-setup", RISCVLandingPadSetupPass())
MACHINE_FUNCTION_PASS("riscv-make-compressible", RISCVMakeCompressiblePass())
MACHINE_FUNCTION_PASS("riscv-merge-base-offset", RISCVMergeBaseOffsetPass())
diff --git a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
index eda36ce5e0521..aa91c3de66061 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetMachine.cpp
@@ -76,7 +76,7 @@ extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
initializeRISCVMoveMergeLegacyPass(*PR);
initializeRISCVPushPopOptLegacyPass(*PR);
initializeRISCVIndirectBranchTrackingLegacyPass(*PR);
- initializeRISCVLoadStoreOptPass(*PR);
+ initializeRISCVLoadStoreOptLegacyPass(*PR);
initializeRISCVPreAllocZilsdOptPass(*PR);
initializeRISCVExpandPseudoAtomicsLegacyPass(*PR);
initializeRISCVRedundantCopyEliminationLegacyPass(*PR);
@@ -491,7 +491,7 @@ void RISCVPassConfig::addPreSched2() {
// Emit KCFI checks for indirect calls.
addPass(createKCFIPass());
if (TM->getOptLevel() != CodeGenOptLevel::None)
- addPass(createRISCVLoadStoreOptPass());
+ addPass(createRISCVLoadStoreOptLegacyPass());
}
void RISCVPassConfig::addPreEmitPass() {
``````````
</details>
https://github.com/llvm/llvm-project/pull/235511
More information about the llvm-branch-commits
mailing list