sync partly with tcpdump.org. ok'ed by itojun
patches #454 from yamt@mwd.biglobe.ne.jp - avoid optimization involving subtract operations - correct optimization of bitwise operations TODO: re-introduce subtract optimization
This commit is contained in:
parent
2ccf86d7da
commit
d3538cc488
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: gencode.c,v 1.30 2002/05/16 19:57:22 wiz Exp $ */
|
||||
/* $NetBSD: gencode.c,v 1.31 2002/08/26 11:21:18 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||
|
@ -26,7 +26,7 @@
|
|||
static const char rcsid[] =
|
||||
"@(#) Header: gencode.c,v 1.93 97/06/12 14:22:47 leres Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: gencode.c,v 1.30 2002/05/16 19:57:22 wiz Exp $");
|
||||
__RCSID("$NetBSD: gencode.c,v 1.31 2002/08/26 11:21:18 yamt Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -2635,16 +2635,16 @@ gen_relation(code, a0, a1, reversed)
|
|||
|
||||
s0 = xfer_to_x(a1);
|
||||
s1 = xfer_to_a(a0);
|
||||
s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
|
||||
b = new_block(JMP(code));
|
||||
if (code == BPF_JGT || code == BPF_JGE) {
|
||||
reversed = !reversed;
|
||||
b->s.k = 0x80000000;
|
||||
if (code == BPF_JEQ) {
|
||||
s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
|
||||
b = new_block(JMP(code));
|
||||
sappend(s1, s2);
|
||||
}
|
||||
else
|
||||
b = new_block(BPF_JMP|code|BPF_X);
|
||||
if (reversed)
|
||||
gen_not(b);
|
||||
|
||||
sappend(s1, s2);
|
||||
sappend(s0, s1);
|
||||
sappend(a1->s, s0);
|
||||
sappend(a0->s, a1->s);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: optimize.c,v 1.14 2002/08/12 02:39:22 itojun Exp $ */
|
||||
/* $NetBSD: optimize.c,v 1.15 2002/08/26 11:21:19 yamt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
|
||||
|
@ -28,7 +28,7 @@
|
|||
static const char rcsid[] =
|
||||
"@(#) Header: optimize.c,v 1.60 96/09/26 23:28:14 leres Exp (LBL)";
|
||||
#else
|
||||
__RCSID("$NetBSD: optimize.c,v 1.14 2002/08/12 02:39:22 itojun Exp $");
|
||||
__RCSID("$NetBSD: optimize.c,v 1.15 2002/08/26 11:21:19 yamt Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -669,7 +669,7 @@ opt_peep(b)
|
|||
return;
|
||||
|
||||
last = s;
|
||||
while (1) {
|
||||
for (/*empty*/; /*empty*/; s = next) {
|
||||
s = this_op(s);
|
||||
if (s == 0)
|
||||
break;
|
||||
|
@ -712,23 +712,23 @@ opt_peep(b)
|
|||
* any local dependencies.
|
||||
*/
|
||||
if (ATOMELEM(b->out_use, X_ATOM))
|
||||
break;
|
||||
continue;
|
||||
|
||||
if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
|
||||
add = next;
|
||||
else
|
||||
add = this_op(next->next);
|
||||
if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
|
||||
break;
|
||||
continue;
|
||||
|
||||
tax = this_op(add->next);
|
||||
if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
|
||||
break;
|
||||
continue;
|
||||
|
||||
ild = this_op(tax->next);
|
||||
if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
|
||||
BPF_MODE(ild->s.code) != BPF_IND)
|
||||
break;
|
||||
continue;
|
||||
/*
|
||||
* XXX We need to check that X is not
|
||||
* subsequently used. We know we can eliminate the
|
||||
|
@ -758,57 +758,45 @@ opt_peep(b)
|
|||
tax->s.code = NOP;
|
||||
done = 0;
|
||||
}
|
||||
s = next;
|
||||
}
|
||||
/*
|
||||
* If we have a subtract to do a comparison, and the X register
|
||||
* is a known constant, we can merge this value into the
|
||||
* comparison.
|
||||
*/
|
||||
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
val = b->val[X_ATOM];
|
||||
if (vmap[val].is_const) {
|
||||
int op;
|
||||
|
||||
b->s.k += vmap[val].const_val;
|
||||
op = BPF_OP(b->s.code);
|
||||
if (op == BPF_JGT || op == BPF_JGE) {
|
||||
struct block *t = JT(b);
|
||||
JT(b) = JF(b);
|
||||
JF(b) = t;
|
||||
b->s.k += 0x80000000;
|
||||
if (BPF_OP(b->s.code) == BPF_JEQ) {
|
||||
if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
val = b->val[X_ATOM];
|
||||
if (vmap[val].is_const) {
|
||||
/*
|
||||
* sub x -> nop
|
||||
* jeq #y jeq #(x+y)
|
||||
*/
|
||||
b->s.k += vmap[val].const_val;
|
||||
last->s.code = NOP;
|
||||
done = 0;
|
||||
} else if (b->s.k == 0) {
|
||||
/*
|
||||
* sub #x -> nop
|
||||
* jeq #0 jeq #x
|
||||
*/
|
||||
last->s.code = NOP;
|
||||
b->s.code = BPF_CLASS(b->s.code) |
|
||||
BPF_OP(b->s.code) | BPF_X;
|
||||
done = 0;
|
||||
}
|
||||
last->s.code = NOP;
|
||||
done = 0;
|
||||
} else if (b->s.k == 0) {
|
||||
/*
|
||||
* sub x -> nop
|
||||
* j #0 j x
|
||||
*/
|
||||
last->s.code = NOP;
|
||||
b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
|
||||
BPF_X;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Likewise, a constant subtract can be simplified.
|
||||
*/
|
||||
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
int op;
|
||||
/*
|
||||
* Likewise, a constant subtract can be simplified.
|
||||
*/
|
||||
else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
|
||||
!ATOMELEM(b->out_use, A_ATOM)) {
|
||||
|
||||
b->s.k += last->s.k;
|
||||
last->s.code = NOP;
|
||||
op = BPF_OP(b->s.code);
|
||||
if (op == BPF_JGT || op == BPF_JGE) {
|
||||
struct block *t = JT(b);
|
||||
JT(b) = JF(b);
|
||||
JF(b) = t;
|
||||
b->s.k += 0x80000000;
|
||||
last->s.code = NOP;
|
||||
b->s.k += last->s.k;
|
||||
done = 0;
|
||||
}
|
||||
done = 0;
|
||||
}
|
||||
/*
|
||||
* and #k nop
|
||||
|
@ -988,18 +976,17 @@ opt_stmt(s, val, alter)
|
|||
* that is 0, and simplify. This may not seem like
|
||||
* much of a simplification but it could open up further
|
||||
* optimizations.
|
||||
* XXX We could also check for mul by 1, and -1, etc.
|
||||
* XXX We could also check for mul by 1, etc.
|
||||
*/
|
||||
if (alter && vmap[val[A_ATOM]].is_const
|
||||
&& vmap[val[A_ATOM]].const_val == 0) {
|
||||
if (op == BPF_ADD || op == BPF_OR ||
|
||||
op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
|
||||
if (op == BPF_ADD || op == BPF_OR) {
|
||||
s->code = BPF_MISC|BPF_TXA;
|
||||
vstore(s, &val[A_ATOM], val[X_ATOM], alter);
|
||||
break;
|
||||
}
|
||||
else if (op == BPF_MUL || op == BPF_DIV ||
|
||||
op == BPF_AND) {
|
||||
op == BPF_AND || op == BPF_LSH || op == BPF_RSH) {
|
||||
s->code = BPF_LD|BPF_IMM;
|
||||
s->k = 0;
|
||||
vstore(s, &val[A_ATOM], K(s->k), alter);
|
||||
|
|
Loading…
Reference in New Issue