Skip to content

Commit 2cd6339

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 c71b212 commit 2cd6339

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

llvm/lib/Target/RISCV/RISCVPushPopOptimizer.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,30 @@ 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+
assert(It != End);
51+
return std::find_if_not(std::next(It), End, [](const auto &Inst) {
52+
return Inst.isDebugInstr() || Inst.isCFIInstruction() ||
53+
Inst.isPseudoProbe();
54+
});
55+
}
56+
57+
static void eraseCFIInst(const MachineBasicBlock::iterator Begin,
58+
const MachineBasicBlock::iterator End) {
59+
assert(Begin != End);
60+
std::vector<std::reference_wrapper<llvm::MachineInstr>> CFIInstrs;
61+
std::copy_if(std::next(Begin), End, std::back_inserter(CFIInstrs),
62+
[](const auto &Inst) { return Inst.isCFIInstruction(); });
63+
64+
for (auto Inst : CFIInstrs)
65+
Inst.get().eraseFromParent();
66+
}
67+
4868
// Check if POP instruction was inserted into the MBB and return iterator to it.
4969
static MachineBasicBlock::iterator containsPop(MachineBasicBlock &MBB) {
5070
for (MachineBasicBlock::iterator MBBI = MBB.begin(); MBBI != MBB.end();
51-
MBBI = next_nodbg(MBBI, MBB.end()))
71+
MBBI = nextNoDebugNoCFIInst(MBBI, MBB.end()))
5272
if (MBBI->getOpcode() == RISCV::CM_POP)
5373
return MBBI;
5474

@@ -76,6 +96,10 @@ bool RISCVPushPopOpt::usePopRet(MachineBasicBlock::iterator &MBBI,
7696
for (unsigned i = FirstNonDeclaredOp; i < MBBI->getNumOperands(); ++i)
7797
PopRetBuilder.add(MBBI->getOperand(i));
7898

99+
// Remove CFI instructions, they are not needed for cm.popret and cm.popretz
100+
// anyway
101+
eraseCFIInst(MBBI, NextI);
102+
79103
MBBI->eraseFromParent();
80104
NextI->eraseFromParent();
81105
return true;
@@ -92,8 +116,8 @@ bool RISCVPushPopOpt::adjustRetVal(MachineBasicBlock::iterator &MBBI) {
92116
// Since POP instruction is in Epilogue no normal instructions will follow
93117
// after it. Therefore search only previous ones to find the return value.
94118
for (MachineBasicBlock::reverse_iterator I =
95-
next_nodbg(MBBI.getReverse(), RE);
96-
I != RE; I = next_nodbg(I, RE)) {
119+
nextNoDebugNoCFIInst(MBBI.getReverse(), RE);
120+
I != RE; I = nextNoDebugNoCFIInst(I, RE)) {
97121
MachineInstr &MI = *I;
98122
if (auto OperandPair = TII->isCopyInstrImpl(MI)) {
99123
Register DestReg = OperandPair->Destination->getReg();
@@ -138,7 +162,7 @@ bool RISCVPushPopOpt::runOnMachineFunction(MachineFunction &Fn) {
138162
bool Modified = false;
139163
for (auto &MBB : Fn) {
140164
MachineBasicBlock::iterator MBBI = containsPop(MBB);
141-
MachineBasicBlock::iterator NextI = next_nodbg(MBBI, MBB.end());
165+
MachineBasicBlock::iterator NextI = nextNoDebugNoCFIInst(MBBI, MBB.end());
142166
if (MBBI != MBB.end() && NextI != MBB.end() &&
143167
NextI->getOpcode() == RISCV::PseudoRET)
144168
Modified |= usePopRet(MBBI, NextI, adjustRetVal(MBBI));

0 commit comments

Comments
 (0)