Skip to content

Commit 3e8a3aa

Browse files
committed
filterc: Optimize jumps
When one of the branches goes to the next insn, it is not necessary to emit two eBPF insns. We can either leave out the second jump if the false case is the next insn, or we can invert the condition and leave out the second jump if the true case is the next insn. Signed-off-by: Felix Maurer <[email protected]>
1 parent 0be7232 commit 3e8a3aa

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

filterc/bpfc.c

+30
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,36 @@ static int convert_cbpf(struct cbpf_program *cbpf_prog,
278278
src_reg = bpf_src == BPF_X ? BPF_REG_X : 0;
279279
}
280280

281+
// Only emit one jump if jump_false is next insn
282+
if (fp->jf == 0) {
283+
code = BPF_JMP | BPF_OP(fp->code) | bpf_src;
284+
target = i + fp->jt + 1;
285+
*insn++ = BPF_JMP_INSN(code, dst_reg, src_reg, imm, target);
286+
break;
287+
}
288+
289+
// Invert conditons where possible if jump_true is next insn
290+
if (fp->jt == 0) {
291+
switch (BPF_OP(fp->code)) {
292+
case BPF_JEQ:
293+
code = BPF_JMP | BPF_JNE | bpf_src;
294+
break;
295+
case BPF_JGT:
296+
code = BPF_JMP | BPF_JLE | bpf_src;
297+
break;
298+
case BPF_JGE:
299+
code = BPF_JMP | BPF_JLT | bpf_src;
300+
break;
301+
default:
302+
goto jmp_rest;
303+
}
304+
305+
target = i + fp->jf + 1;
306+
*insn++ = BPF_JMP_INSN(code, dst_reg, src_reg, imm, target);
307+
break;
308+
}
309+
310+
jmp_rest:
281311
/* Other jumps are mapped into two insns: Jxx and JA. */
282312
code = BPF_JMP | BPF_OP(fp->code) | bpf_src;
283313
target = i + fp->jt + 1;

0 commit comments

Comments
 (0)