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.

Signed-off-by: Felix Maurer <[email protected]>
  • Loading branch information
fmaurer-rh committed Oct 16, 2023
1 parent 0be7232 commit 3e8a3aa
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 3e8a3aa

Please sign in to comment.