Skip to content

Commit

Permalink
filterc: Optimize jumps
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
fmaurer-rh committed Sep 11, 2023
1 parent 71dd4f9 commit eab2538
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions filterc/bpfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,36 @@ static int convert_cbpf(struct cbpf_program *cbpf_prog,
src_reg = bpf_src == BPF_X ? BPF_REG_X : 0;
}

// Only emit one jump if jump_false is next insn
if (fp->jf == 0) {
code = BPF_JMP | BPF_OP(fp->code) | bpf_src;
target = i + fp->jt + 1;
*insn++ = BPF_JMP_INSN(code, dst_reg, src_reg, imm, target);
break;
}

// Invert conditons where possible if jump_true is next insn
if (fp->jt == 0) {
switch (BPF_OP(fp->code)) {
case BPF_JEQ:
code = BPF_JMP | BPF_JNE | bpf_src;
break;
case BPF_JGT:
code = BPF_JMP | BPF_JLE | bpf_src;
break;
case BPF_JGE:
code = BPF_JMP | BPF_JLT | bpf_src;
break;
default:
goto jmp_rest;
}

target = i + fp->jf + 1;
*insn++ = BPF_JMP_INSN(code, dst_reg, src_reg, imm, target);
break;
}

jmp_rest:
/* Other jumps are mapped into two insns: Jxx and JA. */
code = BPF_JMP | BPF_OP(fp->code) | bpf_src;
target = i + fp->jt + 1;
Expand Down

0 comments on commit eab2538

Please sign in to comment.