Skip to content

Commit cfcb8a2

Browse files
committed
[RISCV] fix RISCVPushPopOptimizer pass
RISCVPushPopOptimizer pass didn't suggest that CFI instructions can be inserted between cm.pop and ret and couldn't apply optimization in these cases. The patch fix it and allows the pass to remove CFI instructions and combine cm.pop and ret into the one instruction: cm.popret or cm.popretz.
1 parent cf30e8e commit cfcb8a2

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

llvm/lib/Target/RISCV/RISCVPushPopOptimizer.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,26 @@ char RISCVPushPopOpt::ID = 0;
4545
INITIALIZE_PASS(RISCVPushPopOpt, "riscv-push-pop-opt", RISCV_PUSH_POP_OPT_NAME,
4646
false, false)
4747

48+
template <typename IterT>
49+
static IterT nextNoDebugNoCFIInst(const IterT It, const IterT End) {
50+
return std::find_if_not(std::next(It), End, [](const auto &Inst) {
51+
return Inst.isDebugInstr() || Inst.isCFIInstruction() ||
52+
Inst.isPseudoProbe();
53+
});
54+
}
55+
56+
static void eraseCFIInst(const MachineBasicBlock::iterator Begin,
57+
const MachineBasicBlock::iterator End) {
58+
for (const auto &Inst :
59+
llvm::make_early_inc_range(llvm::make_range(Begin, End)))
60+
if (Inst.isCFIInstruction())
61+
Inst.eraseFromParent();
62+
}
63+
4864
// Check if POP instruction was inserted into the MBB and return iterator to it.
4965
static MachineBasicBlock::iterator containsPop(MachineBasicBlock &MBB) {
5066
for (MachineBasicBlock::iterator MBBI = MBB.begin(); MBBI != MBB.end();
51-
MBBI = next_nodbg(MBBI, MBB.end()))
67+
MBBI = nextNoDebugNoCFIInst(MBBI, MBB.end()))
5268
if (MBBI->getOpcode() == RISCV::CM_POP)
5369
return MBBI;
5470

@@ -76,6 +92,9 @@ bool RISCVPushPopOpt::usePopRet(MachineBasicBlock::iterator &MBBI,
7692
for (unsigned i = FirstNonDeclaredOp; i < MBBI->getNumOperands(); ++i)
7793
PopRetBuilder.add(MBBI->getOperand(i));
7894

95+
// Remove CFI instructions, they are not needed for cm.popret and cm.popretz
96+
eraseCFIInst(MBBI, NextI);
97+
7998
MBBI->eraseFromParent();
8099
NextI->eraseFromParent();
81100
return true;
@@ -92,8 +111,8 @@ bool RISCVPushPopOpt::adjustRetVal(MachineBasicBlock::iterator &MBBI) {
92111
// Since POP instruction is in Epilogue no normal instructions will follow
93112
// after it. Therefore search only previous ones to find the return value.
94113
for (MachineBasicBlock::reverse_iterator I =
95-
next_nodbg(MBBI.getReverse(), RE);
96-
I != RE; I = next_nodbg(I, RE)) {
114+
nextNoDebugNoCFIInst(MBBI.getReverse(), RE);
115+
I != RE; I = nextNoDebugNoCFIInst(I, RE)) {
97116
MachineInstr &MI = *I;
98117
if (auto OperandPair = TII->isCopyInstrImpl(MI)) {
99118
Register DestReg = OperandPair->Destination->getReg();
@@ -138,7 +157,7 @@ bool RISCVPushPopOpt::runOnMachineFunction(MachineFunction &Fn) {
138157
bool Modified = false;
139158
for (auto &MBB : Fn) {
140159
MachineBasicBlock::iterator MBBI = containsPop(MBB);
141-
MachineBasicBlock::iterator NextI = next_nodbg(MBBI, MBB.end());
160+
MachineBasicBlock::iterator NextI = nextNoDebugNoCFIInst(MBBI, MBB.end());
142161
if (MBBI != MBB.end() && NextI != MBB.end() &&
143162
NextI->getOpcode() == RISCV::PseudoRET)
144163
Modified |= usePopRet(MBBI, NextI, adjustRetVal(MBBI));

0 commit comments

Comments
 (0)