Skip to content

Commit 7299365

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 7299365

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

llvm/lib/Target/RISCV/RISCVPushPopOptimizer.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,28 @@ 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+
std::vector<std::reference_wrapper<llvm::MachineInstr>> CFIInstrs;
59+
std::copy_if(std::next(Begin), End, std::back_inserter(CFIInstrs),
60+
[](const auto &Inst) { return Inst.isCFIInstruction(); });
61+
62+
for (auto Inst : CFIInstrs)
63+
Inst.get().eraseFromParent();
64+
}
65+
4866
// Check if POP instruction was inserted into the MBB and return iterator to it.
4967
static MachineBasicBlock::iterator containsPop(MachineBasicBlock &MBB) {
5068
for (MachineBasicBlock::iterator MBBI = MBB.begin(); MBBI != MBB.end();
51-
MBBI = next_nodbg(MBBI, MBB.end()))
69+
MBBI = nextNoDebugNoCFIInst(MBBI, MBB.end()))
5270
if (MBBI->getOpcode() == RISCV::CM_POP)
5371
return MBBI;
5472

@@ -76,6 +94,9 @@ bool RISCVPushPopOpt::usePopRet(MachineBasicBlock::iterator &MBBI,
7694
for (unsigned i = FirstNonDeclaredOp; i < MBBI->getNumOperands(); ++i)
7795
PopRetBuilder.add(MBBI->getOperand(i));
7896

97+
// Remove CFI instructions, they are not needed for cm.popret and cm.popretz
98+
eraseCFIInst(MBBI, NextI);
99+
79100
MBBI->eraseFromParent();
80101
NextI->eraseFromParent();
81102
return true;
@@ -92,8 +113,8 @@ bool RISCVPushPopOpt::adjustRetVal(MachineBasicBlock::iterator &MBBI) {
92113
// Since POP instruction is in Epilogue no normal instructions will follow
93114
// after it. Therefore search only previous ones to find the return value.
94115
for (MachineBasicBlock::reverse_iterator I =
95-
next_nodbg(MBBI.getReverse(), RE);
96-
I != RE; I = next_nodbg(I, RE)) {
116+
nextNoDebugNoCFIInst(MBBI.getReverse(), RE);
117+
I != RE; I = nextNoDebugNoCFIInst(I, RE)) {
97118
MachineInstr &MI = *I;
98119
if (auto OperandPair = TII->isCopyInstrImpl(MI)) {
99120
Register DestReg = OperandPair->Destination->getReg();
@@ -138,7 +159,7 @@ bool RISCVPushPopOpt::runOnMachineFunction(MachineFunction &Fn) {
138159
bool Modified = false;
139160
for (auto &MBB : Fn) {
140161
MachineBasicBlock::iterator MBBI = containsPop(MBB);
141-
MachineBasicBlock::iterator NextI = next_nodbg(MBBI, MBB.end());
162+
MachineBasicBlock::iterator NextI = nextNoDebugNoCFIInst(MBBI, MBB.end());
142163
if (MBBI != MBB.end() && NextI != MBB.end() &&
143164
NextI->getOpcode() == RISCV::PseudoRET)
144165
Modified |= usePopRet(MBBI, NextI, adjustRetVal(MBBI));

0 commit comments

Comments
 (0)