]> The Tcpdump Group git mirrors - libpcap/commitdiff
tches #454 from [email protected]
authoritojun <itojun>
Tue, 11 Jun 2002 05:30:39 +0000 (05:30 +0000)
committeritojun <itojun>
Tue, 11 Jun 2002 05:30:39 +0000 (05:30 +0000)
- avoid optimization involving subtract operations
- correct optimization of bitwise operations

TODO: re-introduce subtract optimization

gencode.c
optimize.c

index 7b51246961e9072f9864a68c4f9b84c165635026..853f9307cc49c1555a20bf17dd04c1d36466688f 100644 (file)
--- a/gencode.c
+++ b/gencode.c
@@ -21,7 +21,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.165 2002-06-01 23:22:57 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.166 2002-06-11 05:30:39 itojun Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -3539,16 +3539,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);
index c72c8cb1089e966d2576140ca51ac27735490a3d..2fefbef0c6f8a6969ee0891f0bd175cb98748a2c 100644 (file)
@@ -22,7 +22,7 @@
  */
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.72 2002-03-24 23:21:51 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.73 2002-06-11 05:30:40 itojun Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -664,7 +664,7 @@ opt_peep(b)
                return;
 
        last = s;
-       while (1) {
+       for (/*empty*/; /*empty*/; s = next) {
                s = this_op(s);
                if (s == 0)
                        break;
@@ -707,23 +707,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
@@ -753,57 +753,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
@@ -996,18 +984,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);