Skip to content

Commit 7bdc97b

Browse files
Jakub Kicinskiborkmann
authored andcommitted
nfp: bpf: optimize comparisons to negative constants
Comparison instruction requires a subtraction. If the constant is negative we are more likely to fit it into a NFP instruction directly if we change the sign and use addition. Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent 61dd8f0 commit 7bdc97b

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

drivers/net/ethernet/netronome/nfp/bpf/jit.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,26 +1247,30 @@ static int cmp_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta)
12471247
const struct bpf_insn *insn = &meta->insn;
12481248
u64 imm = insn->imm; /* sign extend */
12491249
const struct jmp_code_map *code;
1250+
enum alu_op alu_op, carry_op;
12501251
u8 reg = insn->dst_reg * 2;
12511252
swreg tmp_reg;
12521253

12531254
code = nfp_jmp_code_get(meta);
12541255
if (!code)
12551256
return -EINVAL;
12561257

1258+
alu_op = meta->jump_neg_op ? ALU_OP_ADD : ALU_OP_SUB;
1259+
carry_op = meta->jump_neg_op ? ALU_OP_ADD_C : ALU_OP_SUB_C;
1260+
12571261
tmp_reg = ur_load_imm_any(nfp_prog, imm & ~0U, imm_b(nfp_prog));
12581262
if (!code->swap)
1259-
emit_alu(nfp_prog, reg_none(), reg_a(reg), ALU_OP_SUB, tmp_reg);
1263+
emit_alu(nfp_prog, reg_none(), reg_a(reg), alu_op, tmp_reg);
12601264
else
1261-
emit_alu(nfp_prog, reg_none(), tmp_reg, ALU_OP_SUB, reg_a(reg));
1265+
emit_alu(nfp_prog, reg_none(), tmp_reg, alu_op, reg_a(reg));
12621266

12631267
tmp_reg = ur_load_imm_any(nfp_prog, imm >> 32, imm_b(nfp_prog));
12641268
if (!code->swap)
12651269
emit_alu(nfp_prog, reg_none(),
1266-
reg_a(reg + 1), ALU_OP_SUB_C, tmp_reg);
1270+
reg_a(reg + 1), carry_op, tmp_reg);
12671271
else
12681272
emit_alu(nfp_prog, reg_none(),
1269-
tmp_reg, ALU_OP_SUB_C, reg_a(reg + 1));
1273+
tmp_reg, carry_op, reg_a(reg + 1));
12701274

12711275
emit_br(nfp_prog, code->br_mask, insn->off, 0);
12721276

@@ -2745,21 +2749,35 @@ static void nfp_bpf_opt_neg_add_sub(struct nfp_prog *nfp_prog)
27452749
continue;
27462750

27472751
if (BPF_CLASS(insn.code) != BPF_ALU &&
2748-
BPF_CLASS(insn.code) != BPF_ALU64)
2752+
BPF_CLASS(insn.code) != BPF_ALU64 &&
2753+
BPF_CLASS(insn.code) != BPF_JMP)
27492754
continue;
27502755
if (BPF_SRC(insn.code) != BPF_K)
27512756
continue;
27522757
if (insn.imm >= 0)
27532758
continue;
27542759

2755-
if (BPF_OP(insn.code) == BPF_ADD)
2756-
insn.code = BPF_CLASS(insn.code) | BPF_SUB;
2757-
else if (BPF_OP(insn.code) == BPF_SUB)
2758-
insn.code = BPF_CLASS(insn.code) | BPF_ADD;
2759-
else
2760-
continue;
2760+
if (BPF_CLASS(insn.code) == BPF_JMP) {
2761+
switch (BPF_OP(insn.code)) {
2762+
case BPF_JGE:
2763+
case BPF_JSGE:
2764+
case BPF_JLT:
2765+
case BPF_JSLT:
2766+
meta->jump_neg_op = true;
2767+
break;
2768+
default:
2769+
continue;
2770+
}
2771+
} else {
2772+
if (BPF_OP(insn.code) == BPF_ADD)
2773+
insn.code = BPF_CLASS(insn.code) | BPF_SUB;
2774+
else if (BPF_OP(insn.code) == BPF_SUB)
2775+
insn.code = BPF_CLASS(insn.code) | BPF_ADD;
2776+
else
2777+
continue;
27612778

2762-
meta->insn.code = insn.code | BPF_K;
2779+
meta->insn.code = insn.code | BPF_K;
2780+
}
27632781

27642782
meta->insn.imm = -insn.imm;
27652783
}

drivers/net/ethernet/netronome/nfp/bpf/main.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ struct nfp_bpf_reg_state {
236236
* @xadd_over_16bit: 16bit immediate is not guaranteed
237237
* @xadd_maybe_16bit: 16bit immediate is possible
238238
* @jmp_dst: destination info for jump instructions
239+
* @jump_neg_op: jump instruction has inverted immediate, use ADD instead of SUB
239240
* @func_id: function id for call instructions
240241
* @arg1: arg1 for call instructions
241242
* @arg2: arg2 for call instructions
@@ -264,7 +265,10 @@ struct nfp_insn_meta {
264265
bool xadd_maybe_16bit;
265266
};
266267
/* jump */
267-
struct nfp_insn_meta *jmp_dst;
268+
struct {
269+
struct nfp_insn_meta *jmp_dst;
270+
bool jump_neg_op;
271+
};
268272
/* function calls */
269273
struct {
270274
u32 func_id;

0 commit comments

Comments
 (0)