]> The Tcpdump Group git mirrors - libpcap/blobdiff - optimize.c
tches #454 from [email protected]
[libpcap] / optimize.c
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);