Skip to content

Commit 61120d2

Browse files
committed
[RISCV] Generate MIPS load/store pair instructions
Introduce RISCVLoadStoreOptimizer MIR Pass that will do the optimization. It bundles loads and stores that operate on consecutive memory locations to take the advantage of hardware load/store bonding. This is part of MIPS extensions for the p8700 CPU.
1 parent 0cb7636 commit 61120d2

File tree

9 files changed

+941
-1
lines changed

9 files changed

+941
-1
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ add_llvm_target(RISCVCodeGen
4848
RISCVISelLowering.cpp
4949
RISCVLandingPadSetup.cpp
5050
RISCVMachineFunctionInfo.cpp
51+
RISCVLoadStoreOptimizer.cpp
5152
RISCVMergeBaseOffset.cpp
5253
RISCVOptWInstrs.cpp
5354
RISCVPostRAExpandPseudoInsts.cpp

llvm/lib/Target/RISCV/RISCVInstrInfo.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,6 +2738,46 @@ MachineInstr *RISCVInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
27382738
.setMIFlags(MemI.getFlags());
27392739
}
27402740

2741+
bool RISCVInstrInfo::isPairableLdStInstOpc(unsigned Opc) {
2742+
switch (Opc) {
2743+
default:
2744+
return false;
2745+
case RISCV::SH:
2746+
case RISCV::LH:
2747+
case RISCV::LHU:
2748+
case RISCV::SW:
2749+
case RISCV::FSW:
2750+
case RISCV::LW:
2751+
case RISCV::FLW:
2752+
case RISCV::SD:
2753+
case RISCV::FSD:
2754+
case RISCV::LD:
2755+
case RISCV::FLD:
2756+
return true;
2757+
}
2758+
}
2759+
2760+
bool RISCVInstrInfo::isLdStSafeToPair(const MachineInstr &LdSt,
2761+
const TargetRegisterInfo *TRI) {
2762+
// If this is a volatile load/store, don't mess with it.
2763+
if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
2764+
return false;
2765+
2766+
if (LdSt.getOperand(1).isFI())
2767+
return true;
2768+
2769+
assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
2770+
// Can't cluster if the instruction modifies the base register
2771+
// or it is update form. e.g. ld x5,8(x5)
2772+
if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
2773+
return false;
2774+
2775+
if (!LdSt.getOperand(2).isImm())
2776+
return false;
2777+
2778+
return true;
2779+
}
2780+
27412781
bool RISCVInstrInfo::getMemOperandsWithOffsetWidth(
27422782
const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
27432783
int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,

llvm/lib/Target/RISCV/RISCVInstrInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {
300300
std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
301301
analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override;
302302

303+
/// Return true if pairing the given load or store may be paired with another.
304+
static bool isPairableLdStInstOpc(unsigned Opc);
305+
306+
static bool isLdStSafeToPair(const MachineInstr &LdSt,
307+
const TargetRegisterInfo *TRI);
308+
303309
protected:
304310
const RISCVSubtarget &STI;
305311

0 commit comments

Comments
 (0)