[llvm] 8aae191 - [BPF] Remove 'may_goto 0' instructions (#123482)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 28 15:19:12 PST 2025
Author: yonghong-song
Date: 2025-01-28T15:19:05-08:00
New Revision: 8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd
URL: https://github.com/llvm/llvm-project/commit/8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd
DIFF: https://github.com/llvm/llvm-project/commit/8aae191cb6ad1f2dfc468975e4f5e564fea3cbfd.diff
LOG: [BPF] Remove 'may_goto 0' instructions (#123482)
Emil Tsalapatis from Meta reported such a case where 'may_goto 0' insn
is generated by clang compiler. But 'may_goto 0' insn is actually a
no-op so it makes sense to remove that in llvm. The patch is also able
to handle the following code pattern
```
...
may_goto 2
may_goto 1
may_goto 0
...
```
where three may_goto insns can all be removed.
---------
Co-authored-by: Yonghong Song <yonghong.song at linux.dev>
Added:
llvm/test/CodeGen/BPF/may_goto_1.ll
llvm/test/CodeGen/BPF/may_goto_2.ll
Modified:
llvm/lib/Target/BPF/BPFMIPeephole.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/BPF/BPFMIPeephole.cpp b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
index 2b17f2aaefe2bf..106572cdeb8401 100644
--- a/llvm/lib/Target/BPF/BPFMIPeephole.cpp
+++ b/llvm/lib/Target/BPF/BPFMIPeephole.cpp
@@ -24,6 +24,7 @@
#include "BPFInstrInfo.h"
#include "BPFTargetMachine.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -322,6 +323,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
bool eliminateRedundantMov();
bool adjustBranch();
bool insertMissingCallerSavedSpills();
+ bool removeMayGotoZero();
public:
@@ -337,6 +339,7 @@ struct BPFMIPreEmitPeephole : public MachineFunctionPass {
if (SupportGotol)
Changed = adjustBranch() || Changed;
Changed |= insertMissingCallerSavedSpills();
+ Changed |= removeMayGotoZero();
return Changed;
}
};
@@ -682,6 +685,59 @@ bool BPFMIPreEmitPeephole::insertMissingCallerSavedSpills() {
return Changed;
}
+bool BPFMIPreEmitPeephole::removeMayGotoZero() {
+ bool Changed = false;
+ MachineBasicBlock *Prev_MBB, *Curr_MBB = nullptr;
+
+ for (MachineBasicBlock &MBB : make_early_inc_range(reverse(*MF))) {
+ Prev_MBB = Curr_MBB;
+ Curr_MBB = &MBB;
+ if (Prev_MBB == nullptr || Curr_MBB->empty())
+ continue;
+
+ MachineInstr &MI = Curr_MBB->back();
+ if (MI.getOpcode() != TargetOpcode::INLINEASM_BR)
+ continue;
+
+ const char *AsmStr = MI.getOperand(0).getSymbolName();
+ SmallVector<StringRef, 4> AsmPieces;
+ SplitString(AsmStr, AsmPieces, ";\n");
+
+ // Do not support multiple insns in one inline asm.
+ if (AsmPieces.size() != 1)
+ continue;
+
+ // The asm insn must be a may_goto insn.
+ SmallVector<StringRef, 4> AsmOpPieces;
+ SplitString(AsmPieces[0], AsmOpPieces, " ");
+ if (AsmOpPieces.size() != 2 || AsmOpPieces[0] != "may_goto")
+ continue;
+ // Enforce the format of 'may_goto <label>'.
+ if (AsmOpPieces[1] != "${0:l}" && AsmOpPieces[1] != "$0")
+ continue;
+
+ // Get the may_goto branch target.
+ MachineOperand &MO = MI.getOperand(InlineAsm::MIOp_FirstOperand + 1);
+ if (!MO.isMBB() || MO.getMBB() != Prev_MBB)
+ continue;
+
+ Changed = true;
+ if (Curr_MBB->begin() == MI) {
+ // Single 'may_goto' insn in the same basic block.
+ Curr_MBB->removeSuccessor(Prev_MBB);
+ for (MachineBasicBlock *Pred : Curr_MBB->predecessors())
+ Pred->replaceSuccessor(Curr_MBB, Prev_MBB);
+ Curr_MBB->eraseFromParent();
+ Curr_MBB = Prev_MBB;
+ } else {
+ // Remove 'may_goto' insn.
+ MI.eraseFromParent();
+ }
+ }
+
+ return Changed;
+}
+
} // end default namespace
INITIALIZE_PASS(BPFMIPreEmitPeephole, "bpf-mi-pemit-peephole",
diff --git a/llvm/test/CodeGen/BPF/may_goto_1.ll b/llvm/test/CodeGen/BPF/may_goto_1.ll
new file mode 100644
index 00000000000000..a47716509c7aba
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/may_goto_1.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o - %s | llvm-objdump --no-show-raw-insn -d - | FileCheck %s
+
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+
+define dso_local noundef i32 @foo() local_unnamed_addr {
+entry:
+ callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+ to label %for.body [label %for.cond.cleanup]
+
+for.cond.cleanup: ; preds = %for.body.2, %for.body.2, %for.body.1, %for.body, %entry
+ ret i32 0
+
+for.body: ; preds = %entry
+ callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+ to label %for.body.1 [label %for.cond.cleanup]
+
+for.body.1: ; preds = %for.body
+ callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+ to label %for.body.2 [label %for.cond.cleanup]
+
+for.body.2: ; preds = %for.body.1
+ callbr void asm sideeffect "may_goto ${0:l}", "!i"()
+ to label %for.cond.cleanup [label %for.cond.cleanup]
+}
+
+; CHECK: 0: w0 = 0x0
+; CHECK-NEXT: 1: exit
diff --git a/llvm/test/CodeGen/BPF/may_goto_2.ll b/llvm/test/CodeGen/BPF/may_goto_2.ll
new file mode 100644
index 00000000000000..8f6fea5913d2ab
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/may_goto_2.ll
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=bpfel -mcpu=v3 -filetype=obj -o - %s | llvm-objdump --no-show-raw-insn -d - | FileCheck %s
+
+ at j = dso_local local_unnamed_addr global i32 0, align 4
+
+define dso_local noundef i32 @foo() local_unnamed_addr {
+entry:
+ callbr void asm sideeffect "may_goto $0", "!i"()
+ to label %for.body [label %for.cond.cleanup]
+
+for.cond.cleanup: ; preds = %for.body.2, %for.body.2, %for.body.1, %for.body, %entry
+ ret i32 0
+
+for.body: ; preds = %entry
+ callbr void asm sideeffect "may_goto $0", "!i"()
+ to label %for.body.1 [label %for.cond.cleanup]
+
+for.body.1: ; preds = %for.body
+ callbr void asm sideeffect "may_goto $0", "!i"()
+ to label %for.body.2 [label %for.cond.cleanup]
+
+for.body.2: ; preds = %for.body.1
+ callbr void asm sideeffect "may_goto $0", "!i"()
+ to label %for.cond.cleanup [label %for.cond.cleanup]
+}
+
+; CHECK: 0: w0 = 0x0
+; CHECK-NEXT: 1: exit
More information about the llvm-commits
mailing list