[llvm] [BPF] Support Jump Table (PR #149715)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 22 22:33:40 PDT 2025
yonghong-song wrote:
> > Two observations for test case with two jump tables ([link](https://gist.github.com/eddyz87/ff1b9895df194cd8934d2a8728e5ffd7)).
> > ### Jump table element size
> > Array indices are computed for element size of 8:
> > ```
> > r3 = (s32)r2
> > r3 <<= 3
> > r2 = BPF.JT.0.0 ll
> > r2 += r3
> > ```
[...]
> > ### Leftover globals
> > Global variables for arrays `jt1` and `jt2` are emitted:
> > ```
> > .L__const.foo.jt1:
> > .quad .Ltmp0
> > .quad .Ltmp1
> > .size .L__const.foo.jt1, 16
> >
> > .type .L__const.foo.jt2, at object # @__const.foo.jt2
> > .p2align 3, 0x0
> > ```
> > We should probably clean these (at-least if there are no references to these symbols in the final code).
Fixed the element size issue. The element size is 8 now.
For cleaning up globals like __const.foo.jt{1,2}. I tried to remove them during finalization like below:
```
diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
index 03f7d8d035dd..b1a24ec9a788 100644
--- a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
+++ b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
@@ -133,6 +133,39 @@ void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
EmitToStreamer(*OutStreamer, TmpInst);
}
+bool BPFAsmPrinter::doFinalization(Module &M) {
+ // Remove computed goto globals like
+ // @__const.foo.jt1 = private unnamed_addr constant [2 x ptr]
+ // [ptr blockaddress(@foo, %l1), ptr blockaddress(@foo, %l2)], align 8
+ // These globals have been replaced with a jumptable label.
+
+ std::vector<GlobalVariable *> Targets;
+ for (GlobalVariable &Global : M.globals()) {
+ if (Global.getLinkage() != GlobalValue::PrivateLinkage)
+ continue;
+ if (!Global.isConstant() || !Global.hasInitializer())
+ continue;
+
+ Constant *CV = dyn_cast<Constant>(Global.getInitializer());
+ if (!CV)
+ continue;
+ ConstantArray *CA = dyn_cast<ConstantArray>(CV);
+ if (!CA)
+ continue;
+
+ for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
+ if (!dyn_cast<BlockAddress>(CA->getOperand(i)))
+ continue;
+ }
+ Targets.push_back(&Global);
+ }
+
+ for (GlobalVariable *GV : Targets)
+ GV->eraseFromParent();
+
+ return AsmPrinter::doFinalization(M);
+}
+
MCSymbol *BPFAsmPrinter::getJTPublicSymbol(unsigned JTI) {
SmallString<60> Name;
raw_svector_ostream(Name)
diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.h b/llvm/lib/Target/BPF/BPFAsmPrinter.h
index 2e6e8a7d491f..e5731bd8e3b4 100644
--- a/llvm/lib/Target/BPF/BPFAsmPrinter.h
+++ b/llvm/lib/Target/BPF/BPFAsmPrinter.h
@@ -29,6 +29,7 @@ public:
const char *ExtraCode, raw_ostream &O) override;
void emitInstruction(const MachineInstr *MI) override;
+ bool doFinalization(Module &M) override;
MCSymbol *getJTPublicSymbol(unsigned JTI);
MCSymbol *lowerBlockAddress(const BlockAddress *BA);
MCSymbol *lowerGlobalValue(const GlobalValue *GVal);
```
But unfortunately, I hit a build failure with the above
```
While deleting: ptr %__const.foo.jt1
Use still stuck around after Def is destroyed: %arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.fo
o.jt1, i64 0, i64 %idxprom
Uses remain when a value is destroyed!
UNREACHABLE executed at /home/yhs/work/yhs/llvm-project/llvm/lib/IR/Value.cpp:102!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, p
reprocessed source, and associated run script.
...
```
Clearly even at this stage, the llvm itself still kept lots of references and won't be able to remove them easily.
The good news are these symbols with name '.L_const.foo.jt{0,1}' and won't show up in the symbol table. The only side effect is it takes some space in .rodata section and I think it should be fine.
https://github.com/llvm/llvm-project/pull/149715
More information about the llvm-commits
mailing list