Skip to content
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ add_llvm_target(RISCVCodeGen
RISCVISelDAGToDAG.cpp
RISCVISelLowering.cpp
RISCVLandingPadSetup.cpp
RISCVLoadStoreOptimizer.cpp
RISCVMachineFunctionInfo.cpp
RISCVMergeBaseOffset.cpp
RISCVOptWInstrs.cpp
Expand Down
36 changes: 36 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2750,6 +2750,42 @@ MachineInstr *RISCVInstrInfo::emitLdStWithAddr(MachineInstr &MemI,
.setMIFlags(MemI.getFlags());
}

// TODO: At the moment, MIPS introduced paring of instructions operating with
// word or double word. This should be extended with more instructions when more
// vendors support load/store pairing.
bool RISCVInstrInfo::isPairableLdStInstOpc(unsigned Opc) {
switch (Opc) {
default:
return false;
case RISCV::SW:
case RISCV::SD:
case RISCV::LD:
case RISCV::LW:
return true;
}
}

bool RISCVInstrInfo::isLdStSafeToPair(const MachineInstr &LdSt,
const TargetRegisterInfo *TRI) {
// If this is a volatile load/store, don't mess with it.
if (LdSt.hasOrderedMemoryRef() || LdSt.getNumExplicitOperands() != 3)
return false;

if (LdSt.getOperand(1).isFI())
return true;

assert(LdSt.getOperand(1).isReg() && "Expected a reg operand.");
// Can't cluster if the instruction modifies the base register
// or it is update form. e.g. ld x5,8(x5)
if (LdSt.modifiesRegister(LdSt.getOperand(1).getReg(), TRI))
return false;

if (!LdSt.getOperand(2).isImm())
return false;

return true;
}

bool RISCVInstrInfo::getMemOperandsWithOffsetWidth(
const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps,
int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width,
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ class RISCVInstrInfo : public RISCVGenInstrInfo {

bool isHighLatencyDef(int Opc) const override;

/// Return true if pairing the given load or store may be paired with another.
static bool isPairableLdStInstOpc(unsigned Opc);

static bool isLdStSafeToPair(const MachineInstr &LdSt,
const TargetRegisterInfo *TRI);

protected:
const RISCVSubtarget &STI;

Expand Down
Loading