mirror of https://gitee.com/openkylin/linux.git
bpf, x86: detect/optimize loading 0 immediates
When sometimes structs or variables need to be initialized/'memset' to 0 in an eBPF C program, the x86 BPF JIT converts this to use immediates. We can however save a couple of bytes (f.e. even up to 7 bytes on a single emmission of BPF_LD | BPF_IMM | BPF_DW) in the image by detecting such case and use xor on the dst register instead. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
23bf88078a
commit
606c88a86c
|
@ -459,6 +459,18 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
}
|
||||
|
||||
case BPF_ALU | BPF_MOV | BPF_K:
|
||||
/* optimization: if imm32 is zero, use 'xor <dst>,<dst>'
|
||||
* to save 3 bytes.
|
||||
*/
|
||||
if (imm32 == 0) {
|
||||
if (is_ereg(dst_reg))
|
||||
EMIT1(add_2mod(0x40, dst_reg, dst_reg));
|
||||
b2 = 0x31; /* xor */
|
||||
b3 = 0xC0;
|
||||
EMIT2(b2, add_2reg(b3, dst_reg, dst_reg));
|
||||
break;
|
||||
}
|
||||
|
||||
/* mov %eax, imm32 */
|
||||
if (is_ereg(dst_reg))
|
||||
EMIT1(add_1mod(0x40, dst_reg));
|
||||
|
@ -473,6 +485,20 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* optimization: if imm64 is zero, use 'xor <dst>,<dst>'
|
||||
* to save 7 bytes.
|
||||
*/
|
||||
if (insn[0].imm == 0 && insn[1].imm == 0) {
|
||||
b1 = add_2mod(0x48, dst_reg, dst_reg);
|
||||
b2 = 0x31; /* xor */
|
||||
b3 = 0xC0;
|
||||
EMIT3(b1, b2, add_2reg(b3, dst_reg, dst_reg));
|
||||
|
||||
insn++;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* movabsq %rax, imm64 */
|
||||
EMIT2(add_1mod(0x48, dst_reg), add_1reg(0xB8, dst_reg));
|
||||
EMIT(insn[0].imm, 4);
|
||||
|
|
Loading…
Reference in New Issue