optimize.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:40k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
  3.  * The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  *  Optimization module for tcpdump intermediate representation.
  22.  */
  23. #ifndef lint
  24. static const char rcsid[] =
  25.     "@(#) $Header: /usr/local/cvs/nessus-libraries/libpcap-nessus/optimize.c,v 1.3 2003/02/06 20:28:08 renaud Exp $ (LBL)";
  26. #endif
  27. #include <sys/types.h>
  28. #include <sys/time.h>
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <memory.h>
  32. #include "pcap-int.h"
  33. #include "gencode.h"
  34. #include "gnuc.h"
  35. #ifdef HAVE_OS_PROTO_H
  36. #include "os-proto.h"
  37. #endif
  38. #ifdef BDEBUG
  39. extern int dflag;
  40. #endif
  41. #define A_ATOM BPF_MEMWORDS
  42. #define X_ATOM (BPF_MEMWORDS+1)
  43. #define NOP -1
  44. /*
  45.  * This define is used to represent *both* the accumulator and
  46.  * x register in use-def computations.
  47.  * Currently, the use-def code assumes only one definition per instruction.
  48.  */
  49. #define AX_ATOM N_ATOMS
  50. /*
  51.  * A flag to indicate that further optimization is needed.
  52.  * Iterative passes are continued until a given pass yields no
  53.  * branch movement.
  54.  */
  55. static int done;
  56. /*
  57.  * A block is marked if only if its mark equals the current mark.
  58.  * Rather than traverse the code array, marking each item, 'cur_mark' is
  59.  * incremented.  This automatically makes each element unmarked.
  60.  */
  61. static int cur_mark;
  62. #define isMarked(p) ((p)->mark == cur_mark)
  63. #define unMarkAll() cur_mark += 1
  64. #define Mark(p) ((p)->mark = cur_mark)
  65. static void opt_init(struct block *);
  66. static void opt_cleanup(void);
  67. static void make_marks(struct block *);
  68. static void mark_code(struct block *);
  69. static void intern_blocks(struct block *);
  70. static int eq_slist(struct slist *, struct slist *);
  71. static void find_levels_r(struct block *);
  72. static void find_levels(struct block *);
  73. static void find_dom(struct block *);
  74. static void propedom(struct edge *);
  75. static void find_edom(struct block *);
  76. static void find_closure(struct block *);
  77. static int atomuse(struct stmt *);
  78. static int atomdef(struct stmt *);
  79. static void compute_local_ud(struct block *);
  80. static void find_ud(struct block *);
  81. static void init_val(void);
  82. static int F(int, int, int);
  83. static inline void vstore(struct stmt *, int *, int, int);
  84. static void opt_blk(struct block *, int);
  85. static int use_conflict(struct block *, struct block *);
  86. static void opt_j(struct edge *);
  87. static void or_pullup(struct block *);
  88. static void and_pullup(struct block *);
  89. static void opt_blks(struct block *, int);
  90. static inline void link_inedge(struct edge *, struct block *);
  91. static void find_inedges(struct block *);
  92. static void opt_root(struct block **);
  93. static void opt_loop(struct block *, int);
  94. static void fold_op(struct stmt *, int, int);
  95. static inline struct slist *this_op(struct slist *);
  96. static void opt_not(struct block *);
  97. static void opt_peep(struct block *);
  98. static void opt_stmt(struct stmt *, int[], int);
  99. static void deadstmt(struct stmt *, struct stmt *[]);
  100. static void opt_deadstores(struct block *);
  101. static void opt_blk(struct block *, int);
  102. static int use_conflict(struct block *, struct block *);
  103. static void opt_j(struct edge *);
  104. static struct block *fold_edge(struct block *, struct edge *);
  105. static inline int eq_blk(struct block *, struct block *);
  106. static int slength(struct slist *);
  107. static int count_blocks(struct block *);
  108. static void number_blks_r(struct block *);
  109. static int count_stmts(struct block *);
  110. static int convert_code_r(struct block *);
  111. #ifdef BDEBUG
  112. static void opt_dump(struct block *);
  113. #endif
  114. static int n_blocks;
  115. struct block **blocks;
  116. static int n_edges;
  117. struct edge **edges;
  118. /*
  119.  * A bit vector set representation of the dominators.
  120.  * We round up the set size to the next power of two.
  121.  */
  122. static int nodewords;
  123. static int edgewords;
  124. struct block **levels;
  125. bpf_u_int32 *space;
  126. #define BITS_PER_WORD (8*sizeof(bpf_u_int32))
  127. /*
  128.  * True if a is in uset {p}
  129.  */
  130. #define SET_MEMBER(p, a) 
  131. ((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
  132. /*
  133.  * Add 'a' to uset p.
  134.  */
  135. #define SET_INSERT(p, a) 
  136. (p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
  137. /*
  138.  * Delete 'a' from uset p.
  139.  */
  140. #define SET_DELETE(p, a) 
  141. (p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
  142. /*
  143.  * a := a intersect b
  144.  */
  145. #define SET_INTERSECT(a, b, n)
  146. {
  147. register bpf_u_int32 *_x = a, *_y = b;
  148. register int _n = n;
  149. while (--_n >= 0) *_x++ &= *_y++;
  150. }
  151. /*
  152.  * a := a - b
  153.  */
  154. #define SET_SUBTRACT(a, b, n)
  155. {
  156. register bpf_u_int32 *_x = a, *_y = b;
  157. register int _n = n;
  158. while (--_n >= 0) *_x++ &=~ *_y++;
  159. }
  160. /*
  161.  * a := a union b
  162.  */
  163. #define SET_UNION(a, b, n)
  164. {
  165. register bpf_u_int32 *_x = a, *_y = b;
  166. register int _n = n;
  167. while (--_n >= 0) *_x++ |= *_y++;
  168. }
  169. static uset all_dom_sets;
  170. static uset all_closure_sets;
  171. static uset all_edge_sets;
  172. #ifndef MAX
  173. #define MAX(a,b) ((a)>(b)?(a):(b))
  174. #endif
  175. static void
  176. find_levels_r(b)
  177. struct block *b;
  178. {
  179. int level;
  180. if (isMarked(b))
  181. return;
  182. Mark(b);
  183. b->link = 0;
  184. if (JT(b)) {
  185. find_levels_r(JT(b));
  186. find_levels_r(JF(b));
  187. level = MAX(JT(b)->level, JF(b)->level) + 1;
  188. } else
  189. level = 0;
  190. b->level = level;
  191. b->link = levels[level];
  192. levels[level] = b;
  193. }
  194. /*
  195.  * Level graph.  The levels go from 0 at the leaves to
  196.  * N_LEVELS at the root.  The levels[] array points to the
  197.  * first node of the level list, whose elements are linked
  198.  * with the 'link' field of the struct block.
  199.  */
  200. static void
  201. find_levels(root)
  202. struct block *root;
  203. {
  204. memset((char *)levels, 0, n_blocks * sizeof(*levels));
  205. unMarkAll();
  206. find_levels_r(root);
  207. }
  208. /*
  209.  * Find dominator relationships.
  210.  * Assumes graph has been leveled.
  211.  */
  212. static void
  213. find_dom(root)
  214. struct block *root;
  215. {
  216. int i;
  217. struct block *b;
  218. bpf_u_int32 *x;
  219. /*
  220.  * Initialize sets to contain all nodes.
  221.  */
  222. x = all_dom_sets;
  223. i = n_blocks * nodewords;
  224. while (--i >= 0)
  225. *x++ = ~0;
  226. /* Root starts off empty. */
  227. for (i = nodewords; --i >= 0;)
  228. root->dom[i] = 0;
  229. /* root->level is the highest level no found. */
  230. for (i = root->level; i >= 0; --i) {
  231. for (b = levels[i]; b; b = b->link) {
  232. SET_INSERT(b->dom, b->id);
  233. if (JT(b) == 0)
  234. continue;
  235. SET_INTERSECT(JT(b)->dom, b->dom, nodewords);
  236. SET_INTERSECT(JF(b)->dom, b->dom, nodewords);
  237. }
  238. }
  239. }
  240. static void
  241. propedom(ep)
  242. struct edge *ep;
  243. {
  244. SET_INSERT(ep->edom, ep->id);
  245. if (ep->succ) {
  246. SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords);
  247. SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords);
  248. }
  249. }
  250. /*
  251.  * Compute edge dominators.
  252.  * Assumes graph has been leveled and predecessors established.
  253.  */
  254. static void
  255. find_edom(root)
  256. struct block *root;
  257. {
  258. int i;
  259. uset x;
  260. struct block *b;
  261. x = all_edge_sets;
  262. for (i = n_edges * edgewords; --i >= 0; )
  263. x[i] = ~0;
  264. /* root->level is the highest level no found. */
  265. memset(root->et.edom, 0, edgewords * sizeof(*(uset)0));
  266. memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0));
  267. for (i = root->level; i >= 0; --i) {
  268. for (b = levels[i]; b != 0; b = b->link) {
  269. propedom(&b->et);
  270. propedom(&b->ef);
  271. }
  272. }
  273. }
  274. /*
  275.  * Find the backwards transitive closure of the flow graph.  These sets
  276.  * are backwards in the sense that we find the set of nodes that reach
  277.  * a given node, not the set of nodes that can be reached by a node.
  278.  *
  279.  * Assumes graph has been leveled.
  280.  */
  281. static void
  282. find_closure(root)
  283. struct block *root;
  284. {
  285. int i;
  286. struct block *b;
  287. /*
  288.  * Initialize sets to contain no nodes.
  289.  */
  290. memset((char *)all_closure_sets, 0,
  291.       n_blocks * nodewords * sizeof(*all_closure_sets));
  292. /* root->level is the highest level no found. */
  293. for (i = root->level; i >= 0; --i) {
  294. for (b = levels[i]; b; b = b->link) {
  295. SET_INSERT(b->closure, b->id);
  296. if (JT(b) == 0)
  297. continue;
  298. SET_UNION(JT(b)->closure, b->closure, nodewords);
  299. SET_UNION(JF(b)->closure, b->closure, nodewords);
  300. }
  301. }
  302. }
  303. /*
  304.  * Return the register number that is used by s.  If A and X are both
  305.  * used, return AX_ATOM.  If no register is used, return -1.
  306.  *
  307.  * The implementation should probably change to an array access.
  308.  */
  309. static int
  310. atomuse(s)
  311. struct stmt *s;
  312. {
  313. register int c = s->code;
  314. if (c == NOP)
  315. return -1;
  316. switch (BPF_CLASS(c)) {
  317. case BPF_RET:
  318. return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
  319. (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;
  320. case BPF_LD:
  321. case BPF_LDX:
  322. return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
  323. (BPF_MODE(c) == BPF_MEM) ? s->k : -1;
  324. case BPF_ST:
  325. return A_ATOM;
  326. case BPF_STX:
  327. return X_ATOM;
  328. case BPF_JMP:
  329. case BPF_ALU:
  330. if (BPF_SRC(c) == BPF_X)
  331. return AX_ATOM;
  332. return A_ATOM;
  333. case BPF_MISC:
  334. return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
  335. }
  336. abort();
  337. /* NOTREACHED */
  338. }
  339. /*
  340.  * Return the register number that is defined by 's'.  We assume that
  341.  * a single stmt cannot define more than one register.  If no register
  342.  * is defined, return -1.
  343.  *
  344.  * The implementation should probably change to an array access.
  345.  */
  346. static int
  347. atomdef(s)
  348. struct stmt *s;
  349. {
  350. if (s->code == NOP)
  351. return -1;
  352. switch (BPF_CLASS(s->code)) {
  353. case BPF_LD:
  354. case BPF_ALU:
  355. return A_ATOM;
  356. case BPF_LDX:
  357. return X_ATOM;
  358. case BPF_ST:
  359. case BPF_STX:
  360. return s->k;
  361. case BPF_MISC:
  362. return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
  363. }
  364. return -1;
  365. }
  366. static void
  367. compute_local_ud(b)
  368. struct block *b;
  369. {
  370. struct slist *s;
  371. atomset def = 0, use = 0, kill = 0;
  372. int atom;
  373. for (s = b->stmts; s; s = s->next) {
  374. if (s->s.code == NOP)
  375. continue;
  376. atom = atomuse(&s->s);
  377. if (atom >= 0) {
  378. if (atom == AX_ATOM) {
  379. if (!ATOMELEM(def, X_ATOM))
  380. use |= ATOMMASK(X_ATOM);
  381. if (!ATOMELEM(def, A_ATOM))
  382. use |= ATOMMASK(A_ATOM);
  383. }
  384. else if (atom < N_ATOMS) {
  385. if (!ATOMELEM(def, atom))
  386. use |= ATOMMASK(atom);
  387. }
  388. else
  389. abort();
  390. }
  391. atom = atomdef(&s->s);
  392. if (atom >= 0) {
  393. if (!ATOMELEM(use, atom))
  394. kill |= ATOMMASK(atom);
  395. def |= ATOMMASK(atom);
  396. }
  397. }
  398. if (!ATOMELEM(def, A_ATOM) && BPF_CLASS(b->s.code) == BPF_JMP)
  399. use |= ATOMMASK(A_ATOM);
  400. b->def = def;
  401. b->kill = kill;
  402. b->in_use = use;
  403. }
  404. /*
  405.  * Assume graph is already leveled.
  406.  */
  407. static void
  408. find_ud(root)
  409. struct block *root;
  410. {
  411. int i, maxlevel;
  412. struct block *p;
  413. /*
  414.  * root->level is the highest level no found;
  415.  * count down from there.
  416.  */
  417. maxlevel = root->level;
  418. for (i = maxlevel; i >= 0; --i)
  419. for (p = levels[i]; p; p = p->link) {
  420. compute_local_ud(p);
  421. p->out_use = 0;
  422. }
  423. for (i = 1; i <= maxlevel; ++i) {
  424. for (p = levels[i]; p; p = p->link) {
  425. p->out_use |= JT(p)->in_use | JF(p)->in_use;
  426. p->in_use |= p->out_use &~ p->kill;
  427. }
  428. }
  429. }
  430. /*
  431.  * These data structures are used in a Cocke and Shwarz style
  432.  * value numbering scheme.  Since the flowgraph is acyclic,
  433.  * exit values can be propagated from a node's predecessors
  434.  * provided it is uniquely defined.
  435.  */
  436. struct valnode {
  437. int code;
  438. int v0, v1;
  439. int val;
  440. struct valnode *next;
  441. };
  442. #define MODULUS 213
  443. static struct valnode *hashtbl[MODULUS];
  444. static int curval;
  445. static int maxval;
  446. /* Integer constants mapped with the load immediate opcode. */
  447. #define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
  448. struct vmapinfo {
  449. int is_const;
  450. bpf_int32 const_val;
  451. };
  452. struct vmapinfo *vmap;
  453. struct valnode *vnode_base;
  454. struct valnode *next_vnode;
  455. static void
  456. init_val()
  457. {
  458. curval = 0;
  459. next_vnode = vnode_base;
  460. memset((char *)vmap, 0, maxval * sizeof(*vmap));
  461. memset((char *)hashtbl, 0, sizeof hashtbl);
  462. }
  463. /* Because we really don't have an IR, this stuff is a little messy. */
  464. static int
  465. F(code, v0, v1)
  466. int code;
  467. int v0, v1;
  468. {
  469. u_int hash;
  470. int val;
  471. struct valnode *p;
  472. hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
  473. hash %= MODULUS;
  474. for (p = hashtbl[hash]; p; p = p->next)
  475. if (p->code == code && p->v0 == v0 && p->v1 == v1)
  476. return p->val;
  477. val = ++curval;
  478. if (BPF_MODE(code) == BPF_IMM &&
  479.     (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
  480. vmap[val].const_val = v0;
  481. vmap[val].is_const = 1;
  482. }
  483. p = next_vnode++;
  484. p->val = val;
  485. p->code = code;
  486. p->v0 = v0;
  487. p->v1 = v1;
  488. p->next = hashtbl[hash];
  489. hashtbl[hash] = p;
  490. return val;
  491. }
  492. static inline void
  493. vstore(s, valp, newval, alter)
  494. struct stmt *s;
  495. int *valp;
  496. int newval;
  497. int alter;
  498. {
  499. if (alter && *valp == newval)
  500. s->code = NOP;
  501. else
  502. *valp = newval;
  503. }
  504. static void
  505. fold_op(s, v0, v1)
  506. struct stmt *s;
  507. int v0, v1;
  508. {
  509. bpf_int32 a, b;
  510. a = vmap[v0].const_val;
  511. b = vmap[v1].const_val;
  512. switch (BPF_OP(s->code)) {
  513. case BPF_ADD:
  514. a += b;
  515. break;
  516. case BPF_SUB:
  517. a -= b;
  518. break;
  519. case BPF_MUL:
  520. a *= b;
  521. break;
  522. case BPF_DIV:
  523. if (b == 0)
  524. bpf_error("division by zero");
  525. a /= b;
  526. break;
  527. case BPF_AND:
  528. a &= b;
  529. break;
  530. case BPF_OR:
  531. a |= b;
  532. break;
  533. case BPF_LSH:
  534. a <<= b;
  535. break;
  536. case BPF_RSH:
  537. a >>= b;
  538. break;
  539. case BPF_NEG:
  540. a = -a;
  541. break;
  542. default:
  543. abort();
  544. }
  545. s->k = a;
  546. s->code = BPF_LD|BPF_IMM;
  547. done = 0;
  548. }
  549. static inline struct slist *
  550. this_op(s)
  551. struct slist *s;
  552. {
  553. while (s != 0 && s->s.code == NOP)
  554. s = s->next;
  555. return s;
  556. }
  557. static void
  558. opt_not(b)
  559. struct block *b;
  560. {
  561. struct block *tmp = JT(b);
  562. JT(b) = JF(b);
  563. JF(b) = tmp;
  564. }
  565. static void
  566. opt_peep(b)
  567. struct block *b;
  568. {
  569. struct slist *s;
  570. struct slist *next, *last;
  571. int val;
  572. s = b->stmts;
  573. if (s == 0)
  574. return;
  575. last = s;
  576. while (1) {
  577. s = this_op(s);
  578. if (s == 0)
  579. break;
  580. next = this_op(s->next);
  581. if (next == 0)
  582. break;
  583. last = next;
  584. /*
  585.  * st  M[k] --> st  M[k]
  586.  * ldx M[k] tax
  587.  */
  588. if (s->s.code == BPF_ST &&
  589.     next->s.code == (BPF_LDX|BPF_MEM) &&
  590.     s->s.k == next->s.k) {
  591. done = 0;
  592. next->s.code = BPF_MISC|BPF_TAX;
  593. }
  594. /*
  595.  * ld  #k --> ldx  #k
  596.  * tax txa
  597.  */
  598. if (s->s.code == (BPF_LD|BPF_IMM) &&
  599.     next->s.code == (BPF_MISC|BPF_TAX)) {
  600. s->s.code = BPF_LDX|BPF_IMM;
  601. next->s.code = BPF_MISC|BPF_TXA;
  602. done = 0;
  603. }
  604. /*
  605.  * This is an ugly special case, but it happens
  606.  * when you say tcp[k] or udp[k] where k is a constant.
  607.  */
  608. if (s->s.code == (BPF_LD|BPF_IMM)) {
  609. struct slist *add, *tax, *ild;
  610. /*
  611.  * Check that X isn't used on exit from this
  612.  * block (which the optimizer might cause).
  613.  * We know the code generator won't generate
  614.  * any local dependencies.
  615.  */
  616. if (ATOMELEM(b->out_use, X_ATOM))
  617. break;
  618. if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
  619. add = next;
  620. else
  621. add = this_op(next->next);
  622. if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
  623. break;
  624. tax = this_op(add->next);
  625. if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
  626. break;
  627. ild = this_op(tax->next);
  628. if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
  629.     BPF_MODE(ild->s.code) != BPF_IND)
  630. break;
  631. /*
  632.  * XXX We need to check that X is not
  633.  * subsequently used.  We know we can eliminate the
  634.  * accumulator modifications since it is defined
  635.  * by the last stmt of this sequence.
  636.  *
  637.  * We want to turn this sequence:
  638.  *
  639.  * (004) ldi     #0x2 {s}
  640.  * (005) ldxms   [14] {next}  -- optional
  641.  * (006) addx {add}
  642.  * (007) tax {tax}
  643.  * (008) ild     [x+0] {ild}
  644.  *
  645.  * into this sequence:
  646.  *
  647.  * (004) nop
  648.  * (005) ldxms   [14]
  649.  * (006) nop
  650.  * (007) nop
  651.  * (008) ild     [x+2]
  652.  *
  653.  */
  654. ild->s.k += s->s.k;
  655. s->s.code = NOP;
  656. add->s.code = NOP;
  657. tax->s.code = NOP;
  658. done = 0;
  659. }
  660. s = next;
  661. }
  662. /*
  663.  * If we have a subtract to do a comparison, and the X register
  664.  * is a known constant, we can merge this value into the
  665.  * comparison.
  666.  */
  667. if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X) &&
  668.     !ATOMELEM(b->out_use, A_ATOM)) {
  669. val = b->val[X_ATOM];
  670. if (vmap[val].is_const) {
  671. int op;
  672. b->s.k += vmap[val].const_val;
  673. op = BPF_OP(b->s.code);
  674. if (op == BPF_JGT || op == BPF_JGE) {
  675. struct block *t = JT(b);
  676. JT(b) = JF(b);
  677. JF(b) = t;
  678. b->s.k += 0x80000000;
  679. }
  680. last->s.code = NOP;
  681. done = 0;
  682. } else if (b->s.k == 0) {
  683. /*
  684.  * sub x  -> nop
  685.  * j  #0 j  x
  686.  */
  687. last->s.code = NOP;
  688. b->s.code = BPF_CLASS(b->s.code) | BPF_OP(b->s.code) |
  689. BPF_X;
  690. done = 0;
  691. }
  692. }
  693. /*
  694.  * Likewise, a constant subtract can be simplified.
  695.  */
  696. else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K) &&
  697.  !ATOMELEM(b->out_use, A_ATOM)) {
  698. int op;
  699. b->s.k += last->s.k;
  700. last->s.code = NOP;
  701. op = BPF_OP(b->s.code);
  702. if (op == BPF_JGT || op == BPF_JGE) {
  703. struct block *t = JT(b);
  704. JT(b) = JF(b);
  705. JF(b) = t;
  706. b->s.k += 0x80000000;
  707. }
  708. done = 0;
  709. }
  710. /*
  711.  * and #k nop
  712.  * jeq #0  -> jset #k
  713.  */
  714. if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
  715.     !ATOMELEM(b->out_use, A_ATOM) && b->s.k == 0) {
  716. b->s.k = last->s.k;
  717. b->s.code = BPF_JMP|BPF_K|BPF_JSET;
  718. last->s.code = NOP;
  719. done = 0;
  720. opt_not(b);
  721. }
  722. /*
  723.  * If the accumulator is a known constant, we can compute the
  724.  * comparison result.
  725.  */
  726. val = b->val[A_ATOM];
  727. if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
  728. bpf_int32 v = vmap[val].const_val;
  729. switch (BPF_OP(b->s.code)) {
  730. case BPF_JEQ:
  731. v = v == b->s.k;
  732. break;
  733. case BPF_JGT:
  734. v = (unsigned)v > b->s.k;
  735. break;
  736. case BPF_JGE:
  737. v = (unsigned)v >= b->s.k;
  738. break;
  739. case BPF_JSET:
  740. v &= b->s.k;
  741. break;
  742. default:
  743. abort();
  744. }
  745. if (JF(b) != JT(b))
  746. done = 0;
  747. if (v)
  748. JF(b) = JT(b);
  749. else
  750. JT(b) = JF(b);
  751. }
  752. }
  753. /*
  754.  * Compute the symbolic value of expression of 's', and update
  755.  * anything it defines in the value table 'val'.  If 'alter' is true,
  756.  * do various optimizations.  This code would be cleaner if symbolic
  757.  * evaluation and code transformations weren't folded together.
  758.  */
  759. static void
  760. opt_stmt(s, val, alter)
  761. struct stmt *s;
  762. int val[];
  763. int alter;
  764. {
  765. int op;
  766. int v;
  767. switch (s->code) {
  768. case BPF_LD|BPF_ABS|BPF_W:
  769. case BPF_LD|BPF_ABS|BPF_H:
  770. case BPF_LD|BPF_ABS|BPF_B:
  771. v = F(s->code, s->k, 0L);
  772. vstore(s, &val[A_ATOM], v, alter);
  773. break;
  774. case BPF_LD|BPF_IND|BPF_W:
  775. case BPF_LD|BPF_IND|BPF_H:
  776. case BPF_LD|BPF_IND|BPF_B:
  777. v = val[X_ATOM];
  778. if (alter && vmap[v].is_const) {
  779. s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
  780. s->k += vmap[v].const_val;
  781. v = F(s->code, s->k, 0L);
  782. done = 0;
  783. }
  784. else
  785. v = F(s->code, s->k, v);
  786. vstore(s, &val[A_ATOM], v, alter);
  787. break;
  788. case BPF_LD|BPF_LEN:
  789. v = F(s->code, 0L, 0L);
  790. vstore(s, &val[A_ATOM], v, alter);
  791. break;
  792. case BPF_LD|BPF_IMM:
  793. v = K(s->k);
  794. vstore(s, &val[A_ATOM], v, alter);
  795. break;
  796. case BPF_LDX|BPF_IMM:
  797. v = K(s->k);
  798. vstore(s, &val[X_ATOM], v, alter);
  799. break;
  800. case BPF_LDX|BPF_MSH|BPF_B:
  801. v = F(s->code, s->k, 0L);
  802. vstore(s, &val[X_ATOM], v, alter);
  803. break;
  804. case BPF_ALU|BPF_NEG:
  805. if (alter && vmap[val[A_ATOM]].is_const) {
  806. s->code = BPF_LD|BPF_IMM;
  807. s->k = -vmap[val[A_ATOM]].const_val;
  808. val[A_ATOM] = K(s->k);
  809. }
  810. else
  811. val[A_ATOM] = F(s->code, val[A_ATOM], 0L);
  812. break;
  813. case BPF_ALU|BPF_ADD|BPF_K:
  814. case BPF_ALU|BPF_SUB|BPF_K:
  815. case BPF_ALU|BPF_MUL|BPF_K:
  816. case BPF_ALU|BPF_DIV|BPF_K:
  817. case BPF_ALU|BPF_AND|BPF_K:
  818. case BPF_ALU|BPF_OR|BPF_K:
  819. case BPF_ALU|BPF_LSH|BPF_K:
  820. case BPF_ALU|BPF_RSH|BPF_K:
  821. op = BPF_OP(s->code);
  822. if (alter) {
  823. if (s->k == 0) {
  824. if (op == BPF_ADD || op == BPF_SUB ||
  825.     op == BPF_LSH || op == BPF_RSH ||
  826.     op == BPF_OR) {
  827. s->code = NOP;
  828. break;
  829. }
  830. if (op == BPF_MUL || op == BPF_AND) {
  831. s->code = BPF_LD|BPF_IMM;
  832. val[A_ATOM] = K(s->k);
  833. break;
  834. }
  835. }
  836. if (vmap[val[A_ATOM]].is_const) {
  837. fold_op(s, val[A_ATOM], K(s->k));
  838. val[A_ATOM] = K(s->k);
  839. break;
  840. }
  841. }
  842. val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k));
  843. break;
  844. case BPF_ALU|BPF_ADD|BPF_X:
  845. case BPF_ALU|BPF_SUB|BPF_X:
  846. case BPF_ALU|BPF_MUL|BPF_X:
  847. case BPF_ALU|BPF_DIV|BPF_X:
  848. case BPF_ALU|BPF_AND|BPF_X:
  849. case BPF_ALU|BPF_OR|BPF_X:
  850. case BPF_ALU|BPF_LSH|BPF_X:
  851. case BPF_ALU|BPF_RSH|BPF_X:
  852. op = BPF_OP(s->code);
  853. if (alter && vmap[val[X_ATOM]].is_const) {
  854. if (vmap[val[A_ATOM]].is_const) {
  855. fold_op(s, val[A_ATOM], val[X_ATOM]);
  856. val[A_ATOM] = K(s->k);
  857. }
  858. else {
  859. s->code = BPF_ALU|BPF_K|op;
  860. s->k = vmap[val[X_ATOM]].const_val;
  861. done = 0;
  862. val[A_ATOM] =
  863. F(s->code, val[A_ATOM], K(s->k));
  864. }
  865. break;
  866. }
  867. /*
  868.  * Check if we're doing something to an accumulator
  869.  * that is 0, and simplify.  This may not seem like
  870.  * much of a simplification but it could open up further
  871.  * optimizations.
  872.  * XXX We could also check for mul by 1, and -1, etc.
  873.  */
  874. if (alter && vmap[val[A_ATOM]].is_const
  875.     && vmap[val[A_ATOM]].const_val == 0) {
  876. if (op == BPF_ADD || op == BPF_OR ||
  877.     op == BPF_LSH || op == BPF_RSH || op == BPF_SUB) {
  878. s->code = BPF_MISC|BPF_TXA;
  879. vstore(s, &val[A_ATOM], val[X_ATOM], alter);
  880. break;
  881. }
  882. else if (op == BPF_MUL || op == BPF_DIV ||
  883.  op == BPF_AND) {
  884. s->code = BPF_LD|BPF_IMM;
  885. s->k = 0;
  886. vstore(s, &val[A_ATOM], K(s->k), alter);
  887. break;
  888. }
  889. else if (op == BPF_NEG) {
  890. s->code = NOP;
  891. break;
  892. }
  893. }
  894. val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]);
  895. break;
  896. case BPF_MISC|BPF_TXA:
  897. vstore(s, &val[A_ATOM], val[X_ATOM], alter);
  898. break;
  899. case BPF_LD|BPF_MEM:
  900. v = val[s->k];
  901. if (alter && vmap[v].is_const) {
  902. s->code = BPF_LD|BPF_IMM;
  903. s->k = vmap[v].const_val;
  904. done = 0;
  905. }
  906. vstore(s, &val[A_ATOM], v, alter);
  907. break;
  908. case BPF_MISC|BPF_TAX:
  909. vstore(s, &val[X_ATOM], val[A_ATOM], alter);
  910. break;
  911. case BPF_LDX|BPF_MEM:
  912. v = val[s->k];
  913. if (alter && vmap[v].is_const) {
  914. s->code = BPF_LDX|BPF_IMM;
  915. s->k = vmap[v].const_val;
  916. done = 0;
  917. }
  918. vstore(s, &val[X_ATOM], v, alter);
  919. break;
  920. case BPF_ST:
  921. vstore(s, &val[s->k], val[A_ATOM], alter);
  922. break;
  923. case BPF_STX:
  924. vstore(s, &val[s->k], val[X_ATOM], alter);
  925. break;
  926. }
  927. }
  928. static void
  929. deadstmt(s, last)
  930. register struct stmt *s;
  931. register struct stmt *last[];
  932. {
  933. register int atom;
  934. atom = atomuse(s);
  935. if (atom >= 0) {
  936. if (atom == AX_ATOM) {
  937. last[X_ATOM] = 0;
  938. last[A_ATOM] = 0;
  939. }
  940. else
  941. last[atom] = 0;
  942. }
  943. atom = atomdef(s);
  944. if (atom >= 0) {
  945. if (last[atom]) {
  946. done = 0;
  947. last[atom]->code = NOP;
  948. }
  949. last[atom] = s;
  950. }
  951. }
  952. static void
  953. opt_deadstores(b)
  954. register struct block *b;
  955. {
  956. register struct slist *s;
  957. register int atom;
  958. struct stmt *last[N_ATOMS];
  959. memset((char *)last, 0, sizeof last);
  960. for (s = b->stmts; s != 0; s = s->next)
  961. deadstmt(&s->s, last);
  962. deadstmt(&b->s, last);
  963. for (atom = 0; atom < N_ATOMS; ++atom)
  964. if (last[atom] && !ATOMELEM(b->out_use, atom)) {
  965. last[atom]->code = NOP;
  966. done = 0;
  967. }
  968. }
  969. static void
  970. opt_blk(b, do_stmts)
  971. struct block *b;
  972. int do_stmts;
  973. {
  974. struct slist *s;
  975. struct edge *p;
  976. int i;
  977. bpf_int32 aval;
  978. /*
  979.  * Initialize the atom values.
  980.  * If we have no predecessors, everything is undefined.
  981.  * Otherwise, we inherent our values from our predecessors.
  982.  * If any register has an ambiguous value (i.e. control paths are
  983.  * merging) give it the undefined value of 0.
  984.  */
  985. p = b->in_edges;
  986. if (p == 0)
  987. memset((char *)b->val, 0, sizeof(b->val));
  988. else {
  989. memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
  990. while ((p = p->next) != NULL) {
  991. for (i = 0; i < N_ATOMS; ++i)
  992. if (b->val[i] != p->pred->val[i])
  993. b->val[i] = 0;
  994. }
  995. }
  996. aval = b->val[A_ATOM];
  997. for (s = b->stmts; s; s = s->next)
  998. opt_stmt(&s->s, b->val, do_stmts);
  999. /*
  1000.  * This is a special case: if we don't use anything from this
  1001.  * block, and we load the accumulator with value that is
  1002.  * already there, or if this block is a return,
  1003.  * eliminate all the statements.
  1004.  */
  1005. if (do_stmts && 
  1006.     ((b->out_use == 0 && aval != 0 &&b->val[A_ATOM] == aval) ||
  1007.      BPF_CLASS(b->s.code) == BPF_RET)) {
  1008. if (b->stmts != 0) {
  1009. b->stmts = 0;
  1010. done = 0;
  1011. }
  1012. } else {
  1013. opt_peep(b);
  1014. opt_deadstores(b);
  1015. }
  1016. /*
  1017.  * Set up values for branch optimizer.
  1018.  */
  1019. if (BPF_SRC(b->s.code) == BPF_K)
  1020. b->oval = K(b->s.k);
  1021. else
  1022. b->oval = b->val[X_ATOM];
  1023. b->et.code = b->s.code;
  1024. b->ef.code = -b->s.code;
  1025. }
  1026. /*
  1027.  * Return true if any register that is used on exit from 'succ', has
  1028.  * an exit value that is different from the corresponding exit value
  1029.  * from 'b'.
  1030.  */
  1031. static int
  1032. use_conflict(b, succ)
  1033. struct block *b, *succ;
  1034. {
  1035. int atom;
  1036. atomset use = succ->out_use;
  1037. if (use == 0)
  1038. return 0;
  1039. for (atom = 0; atom < N_ATOMS; ++atom)
  1040. if (ATOMELEM(use, atom))
  1041. if (b->val[atom] != succ->val[atom])
  1042. return 1;
  1043. return 0;
  1044. }
  1045. static struct block *
  1046. fold_edge(child, ep)
  1047. struct block *child;
  1048. struct edge *ep;
  1049. {
  1050. int sense;
  1051. int aval0, aval1, oval0, oval1;
  1052. int code = ep->code;
  1053. if (code < 0) {
  1054. code = -code;
  1055. sense = 0;
  1056. } else
  1057. sense = 1;
  1058. if (child->s.code != code)
  1059. return 0;
  1060. aval0 = child->val[A_ATOM];
  1061. oval0 = child->oval;
  1062. aval1 = ep->pred->val[A_ATOM];
  1063. oval1 = ep->pred->oval;
  1064. if (aval0 != aval1)
  1065. return 0;
  1066. if (oval0 == oval1)
  1067. /*
  1068.  * The operands are identical, so the
  1069.  * result is true if a true branch was
  1070.  * taken to get here, otherwise false.
  1071.  */
  1072. return sense ? JT(child) : JF(child);
  1073. if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
  1074. /*
  1075.  * At this point, we only know the comparison if we
  1076.  * came down the true branch, and it was an equality
  1077.  * comparison with a constant.  We rely on the fact that
  1078.  * distinct constants have distinct value numbers.
  1079.  */
  1080. return JF(child);
  1081. return 0;
  1082. }
  1083. static void
  1084. opt_j(ep)
  1085. struct edge *ep;
  1086. {
  1087. register int i, k;
  1088. register struct block *target;
  1089. if (JT(ep->succ) == 0)
  1090. return;
  1091. if (JT(ep->succ) == JF(ep->succ)) {
  1092. /*
  1093.  * Common branch targets can be eliminated, provided
  1094.  * there is no data dependency.
  1095.  */
  1096. if (!use_conflict(ep->pred, ep->succ->et.succ)) {
  1097. done = 0;
  1098. ep->succ = JT(ep->succ);
  1099. }
  1100. }
  1101. /*
  1102.  * For each edge dominator that matches the successor of this
  1103.  * edge, promote the edge successor to the its grandchild.
  1104.  *
  1105.  * XXX We violate the set abstraction here in favor a reasonably
  1106.  * efficient loop.
  1107.  */
  1108.  top:
  1109. for (i = 0; i < edgewords; ++i) {
  1110. register bpf_u_int32 x = ep->edom[i];
  1111. while (x != 0) {
  1112. k = ffs(x) - 1;
  1113. x &=~ (1 << k);
  1114. k += i * BITS_PER_WORD;
  1115. target = fold_edge(ep->succ, edges[k]);
  1116. /*
  1117.  * Check that there is no data dependency between
  1118.  * nodes that will be violated if we move the edge.
  1119.  */
  1120. if (target != 0 && !use_conflict(ep->pred, target)) {
  1121. done = 0;
  1122. ep->succ = target;
  1123. if (JT(target) != 0)
  1124. /*
  1125.  * Start over unless we hit a leaf.
  1126.  */
  1127. goto top;
  1128. return;
  1129. }
  1130. }
  1131. }
  1132. }
  1133. static void
  1134. or_pullup(b)
  1135. struct block *b;
  1136. {
  1137. int val, at_top;
  1138. struct block *pull;
  1139. struct block **diffp, **samep;
  1140. struct edge *ep;
  1141. ep = b->in_edges;
  1142. if (ep == 0)
  1143. return;
  1144. /*
  1145.  * Make sure each predecessor loads the same value.
  1146.  * XXX why?
  1147.  */
  1148. val = ep->pred->val[A_ATOM];
  1149. for (ep = ep->next; ep != 0; ep = ep->next)
  1150. if (val != ep->pred->val[A_ATOM])
  1151. return;
  1152. if (JT(b->in_edges->pred) == b)
  1153. diffp = &JT(b->in_edges->pred);
  1154. else
  1155. diffp = &JF(b->in_edges->pred);
  1156. at_top = 1;
  1157. while (1) {
  1158. if (*diffp == 0)
  1159. return;
  1160. if (JT(*diffp) != JT(b))
  1161. return;
  1162. if (!SET_MEMBER((*diffp)->dom, b->id))
  1163. return;
  1164. if ((*diffp)->val[A_ATOM] != val)
  1165. break;
  1166. diffp = &JF(*diffp);
  1167. at_top = 0;
  1168. }
  1169. samep = &JF(*diffp);
  1170. while (1) {
  1171. if (*samep == 0)
  1172. return;
  1173. if (JT(*samep) != JT(b))
  1174. return;
  1175. if (!SET_MEMBER((*samep)->dom, b->id))
  1176. return;
  1177. if ((*samep)->val[A_ATOM] == val)
  1178. break;
  1179. /* XXX Need to check that there are no data dependencies
  1180.    between dp0 and dp1.  Currently, the code generator
  1181.    will not produce such dependencies. */
  1182. samep = &JF(*samep);
  1183. }
  1184. #ifdef notdef
  1185. /* XXX This doesn't cover everything. */
  1186. for (i = 0; i < N_ATOMS; ++i)
  1187. if ((*samep)->val[i] != pred->val[i])
  1188. return;
  1189. #endif
  1190. /* Pull up the node. */
  1191. pull = *samep;
  1192. *samep = JF(pull);
  1193. JF(pull) = *diffp;
  1194. /*
  1195.  * At the top of the chain, each predecessor needs to point at the
  1196.  * pulled up node.  Inside the chain, there is only one predecessor
  1197.  * to worry about.
  1198.  */
  1199. if (at_top) {
  1200. for (ep = b->in_edges; ep != 0; ep = ep->next) {
  1201. if (JT(ep->pred) == b)
  1202. JT(ep->pred) = pull;
  1203. else
  1204. JF(ep->pred) = pull;
  1205. }
  1206. }
  1207. else
  1208. *diffp = pull;
  1209. done = 0;
  1210. }
  1211. static void
  1212. and_pullup(b)
  1213. struct block *b;
  1214. {
  1215. int val, at_top;
  1216. struct block *pull;
  1217. struct block **diffp, **samep;
  1218. struct edge *ep;
  1219. ep = b->in_edges;
  1220. if (ep == 0)
  1221. return;
  1222. /*
  1223.  * Make sure each predecessor loads the same value.
  1224.  */
  1225. val = ep->pred->val[A_ATOM];
  1226. for (ep = ep->next; ep != 0; ep = ep->next)
  1227. if (val != ep->pred->val[A_ATOM])
  1228. return;
  1229. if (JT(b->in_edges->pred) == b)
  1230. diffp = &JT(b->in_edges->pred);
  1231. else
  1232. diffp = &JF(b->in_edges->pred);
  1233. at_top = 1;
  1234. while (1) {
  1235. if (*diffp == 0)
  1236. return;
  1237. if (JF(*diffp) != JF(b))
  1238. return;
  1239. if (!SET_MEMBER((*diffp)->dom, b->id))
  1240. return;
  1241. if ((*diffp)->val[A_ATOM] != val)
  1242. break;
  1243. diffp = &JT(*diffp);
  1244. at_top = 0;
  1245. }
  1246. samep = &JT(*diffp);
  1247. while (1) {
  1248. if (*samep == 0)
  1249. return;
  1250. if (JF(*samep) != JF(b))
  1251. return;
  1252. if (!SET_MEMBER((*samep)->dom, b->id))
  1253. return;
  1254. if ((*samep)->val[A_ATOM] == val)
  1255. break;
  1256. /* XXX Need to check that there are no data dependencies
  1257.    between diffp and samep.  Currently, the code generator
  1258.    will not produce such dependencies. */
  1259. samep = &JT(*samep);
  1260. }
  1261. #ifdef notdef
  1262. /* XXX This doesn't cover everything. */
  1263. for (i = 0; i < N_ATOMS; ++i)
  1264. if ((*samep)->val[i] != pred->val[i])
  1265. return;
  1266. #endif
  1267. /* Pull up the node. */
  1268. pull = *samep;
  1269. *samep = JT(pull);
  1270. JT(pull) = *diffp;
  1271. /*
  1272.  * At the top of the chain, each predecessor needs to point at the
  1273.  * pulled up node.  Inside the chain, there is only one predecessor
  1274.  * to worry about.
  1275.  */
  1276. if (at_top) {
  1277. for (ep = b->in_edges; ep != 0; ep = ep->next) {
  1278. if (JT(ep->pred) == b)
  1279. JT(ep->pred) = pull;
  1280. else
  1281. JF(ep->pred) = pull;
  1282. }
  1283. }
  1284. else
  1285. *diffp = pull;
  1286. done = 0;
  1287. }
  1288. static void
  1289. opt_blks(root, do_stmts)
  1290. struct block *root;
  1291. int do_stmts;
  1292. {
  1293. int i, maxlevel;
  1294. struct block *p;
  1295. init_val();
  1296. maxlevel = root->level;
  1297. for (i = maxlevel; i >= 0; --i)
  1298. for (p = levels[i]; p; p = p->link)
  1299. opt_blk(p, do_stmts);
  1300. if (do_stmts)
  1301. /*
  1302.  * No point trying to move branches; it can't possibly
  1303.  * make a difference at this point.
  1304.  */
  1305. return;
  1306. for (i = 1; i <= maxlevel; ++i) {
  1307. for (p = levels[i]; p; p = p->link) {
  1308. opt_j(&p->et);
  1309. opt_j(&p->ef);
  1310. }
  1311. }
  1312. for (i = 1; i <= maxlevel; ++i) {
  1313. for (p = levels[i]; p; p = p->link) {
  1314. or_pullup(p);
  1315. and_pullup(p);
  1316. }
  1317. }
  1318. }
  1319. static inline void
  1320. link_inedge(parent, child)
  1321. struct edge *parent;
  1322. struct block *child;
  1323. {
  1324. parent->next = child->in_edges;
  1325. child->in_edges = parent;
  1326. }
  1327. static void
  1328. find_inedges(root)
  1329. struct block *root;
  1330. {
  1331. int i;
  1332. struct block *b;
  1333. for (i = 0; i < n_blocks; ++i)
  1334. blocks[i]->in_edges = 0;
  1335. /*
  1336.  * Traverse the graph, adding each edge to the predecessor
  1337.  * list of its successors.  Skip the leaves (i.e. level 0).
  1338.  */
  1339. for (i = root->level; i > 0; --i) {
  1340. for (b = levels[i]; b != 0; b = b->link) {
  1341. link_inedge(&b->et, JT(b));
  1342. link_inedge(&b->ef, JF(b));
  1343. }
  1344. }
  1345. }
  1346. static void
  1347. opt_root(b)
  1348. struct block **b;
  1349. {
  1350. struct slist *tmp, *s;
  1351. s = (*b)->stmts;
  1352. (*b)->stmts = 0;
  1353. while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
  1354. *b = JT(*b);
  1355. tmp = (*b)->stmts;
  1356. if (tmp != 0)
  1357. sappend(s, tmp);
  1358. (*b)->stmts = s;
  1359. /*
  1360.  * If the root node is a return, then there is no
  1361.  * point executing any statements (since the bpf machine
  1362.  * has no side effects).
  1363.  */
  1364. if (BPF_CLASS((*b)->s.code) == BPF_RET)
  1365. (*b)->stmts = 0;
  1366. }
  1367. static void
  1368. opt_loop(root, do_stmts)
  1369. struct block *root;
  1370. int do_stmts;
  1371. {
  1372. #ifdef BDEBUG
  1373. if (dflag > 1)
  1374. opt_dump(root);
  1375. #endif
  1376. do {
  1377. done = 1;
  1378. find_levels(root);
  1379. find_dom(root);
  1380. find_closure(root);
  1381. find_inedges(root);
  1382. find_ud(root);
  1383. find_edom(root);
  1384. opt_blks(root, do_stmts);
  1385. #ifdef BDEBUG
  1386. if (dflag > 1)
  1387. opt_dump(root);
  1388. #endif
  1389. } while (!done);
  1390. }
  1391. /*
  1392.  * Optimize the filter code in its dag representation.
  1393.  */
  1394. void
  1395. bpf_optimize(rootp)
  1396. struct block **rootp;
  1397. {
  1398. struct block *root;
  1399. root = *rootp;
  1400. opt_init(root);
  1401. opt_loop(root, 0);
  1402. opt_loop(root, 1);
  1403. intern_blocks(root);
  1404. opt_root(rootp);
  1405. opt_cleanup();
  1406. }
  1407. static void
  1408. make_marks(p)
  1409. struct block *p;
  1410. {
  1411. if (!isMarked(p)) {
  1412. Mark(p);
  1413. if (BPF_CLASS(p->s.code) != BPF_RET) {
  1414. make_marks(JT(p));
  1415. make_marks(JF(p));
  1416. }
  1417. }
  1418. }
  1419. /*
  1420.  * Mark code array such that isMarked(i) is true
  1421.  * only for nodes that are alive.
  1422.  */
  1423. static void
  1424. mark_code(p)
  1425. struct block *p;
  1426. {
  1427. cur_mark += 1;
  1428. make_marks(p);
  1429. }
  1430. /*
  1431.  * True iff the two stmt lists load the same value from the packet into
  1432.  * the accumulator.
  1433.  */
  1434. static int
  1435. eq_slist(x, y)
  1436. struct slist *x, *y;
  1437. {
  1438. while (1) {
  1439. while (x && x->s.code == NOP)
  1440. x = x->next;
  1441. while (y && y->s.code == NOP)
  1442. y = y->next;
  1443. if (x == 0)
  1444. return y == 0;
  1445. if (y == 0)
  1446. return x == 0;
  1447. if (x->s.code != y->s.code || x->s.k != y->s.k)
  1448. return 0;
  1449. x = x->next;
  1450. y = y->next;
  1451. }
  1452. }
  1453. static inline int
  1454. eq_blk(b0, b1)
  1455. struct block *b0, *b1;
  1456. {
  1457. if (b0->s.code == b1->s.code &&
  1458.     b0->s.k == b1->s.k &&
  1459.     b0->et.succ == b1->et.succ &&
  1460.     b0->ef.succ == b1->ef.succ)
  1461. return eq_slist(b0->stmts, b1->stmts);
  1462. return 0;
  1463. }
  1464. static void
  1465. intern_blocks(root)
  1466. struct block *root;
  1467. {
  1468. struct block *p;
  1469. int i, j;
  1470. int done;
  1471.  top:
  1472. done = 1;
  1473. for (i = 0; i < n_blocks; ++i)
  1474. blocks[i]->link = 0;
  1475. mark_code(root);
  1476. for (i = n_blocks - 1; --i >= 0; ) {
  1477. if (!isMarked(blocks[i]))
  1478. continue;
  1479. for (j = i + 1; j < n_blocks; ++j) {
  1480. if (!isMarked(blocks[j]))
  1481. continue;
  1482. if (eq_blk(blocks[i], blocks[j])) {
  1483. blocks[i]->link = blocks[j]->link ?
  1484. blocks[j]->link : blocks[j];
  1485. break;
  1486. }
  1487. }
  1488. }
  1489. for (i = 0; i < n_blocks; ++i) {
  1490. p = blocks[i];
  1491. if (JT(p) == 0)
  1492. continue;
  1493. if (JT(p)->link) {
  1494. done = 0;
  1495. JT(p) = JT(p)->link;
  1496. }
  1497. if (JF(p)->link) {
  1498. done = 0;
  1499. JF(p) = JF(p)->link;
  1500. }
  1501. }
  1502. if (!done)
  1503. goto top;
  1504. }
  1505. static void
  1506. opt_cleanup()
  1507. {
  1508. free((void *)vnode_base);
  1509. free((void *)vmap);
  1510. free((void *)edges);
  1511. free((void *)space);
  1512. free((void *)levels);
  1513. free((void *)blocks);
  1514. }
  1515. /*
  1516.  * Return the number of stmts in 's'.
  1517.  */
  1518. static int
  1519. slength(s)
  1520. struct slist *s;
  1521. {
  1522. int n = 0;
  1523. for (; s; s = s->next)
  1524. if (s->s.code != NOP)
  1525. ++n;
  1526. return n;
  1527. }
  1528. /*
  1529.  * Return the number of nodes reachable by 'p'.
  1530.  * All nodes should be initially unmarked.
  1531.  */
  1532. static int
  1533. count_blocks(p)
  1534. struct block *p;
  1535. {
  1536. if (p == 0 || isMarked(p))
  1537. return 0;
  1538. Mark(p);
  1539. return count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
  1540. }
  1541. /*
  1542.  * Do a depth first search on the flow graph, numbering the
  1543.  * the basic blocks, and entering them into the 'blocks' array.`
  1544.  */
  1545. static void
  1546. number_blks_r(p)
  1547. struct block *p;
  1548. {
  1549. int n;
  1550. if (p == 0 || isMarked(p))
  1551. return;
  1552. Mark(p);
  1553. n = n_blocks++;
  1554. p->id = n;
  1555. blocks[n] = p;
  1556. number_blks_r(JT(p));
  1557. number_blks_r(JF(p));
  1558. }
  1559. /*
  1560.  * Return the number of stmts in the flowgraph reachable by 'p'.
  1561.  * The nodes should be unmarked before calling.
  1562.  */
  1563. static int
  1564. count_stmts(p)
  1565. struct block *p;
  1566. {
  1567. int n;
  1568. if (p == 0 || isMarked(p))
  1569. return 0;
  1570. Mark(p);
  1571. n = count_stmts(JT(p)) + count_stmts(JF(p));
  1572. return slength(p->stmts) + n + 1;
  1573. }
  1574. /*
  1575.  * Allocate memory.  All allocation is done before optimization
  1576.  * is begun.  A linear bound on the size of all data structures is computed
  1577.  * from the total number of blocks and/or statements.
  1578.  */
  1579. static void
  1580. opt_init(root)
  1581. struct block *root;
  1582. {
  1583. bpf_u_int32 *p;
  1584. int i, n, max_stmts;
  1585. /*
  1586.  * First, count the blocks, so we can malloc an array to map
  1587.  * block number to block.  Then, put the blocks into the array.
  1588.  */
  1589. unMarkAll();
  1590. n = count_blocks(root);
  1591. blocks = (struct block **)malloc(n * sizeof(*blocks));
  1592. unMarkAll();
  1593. n_blocks = 0;
  1594. number_blks_r(root);
  1595. n_edges = 2 * n_blocks;
  1596. edges = (struct edge **)malloc(n_edges * sizeof(*edges));
  1597. /*
  1598.  * The number of levels is bounded by the number of nodes.
  1599.  */
  1600. levels = (struct block **)malloc(n_blocks * sizeof(*levels));
  1601. edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
  1602. nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
  1603. /* XXX */
  1604. space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
  1605.  + n_edges * edgewords * sizeof(*space));
  1606. p = space;
  1607. all_dom_sets = p;
  1608. for (i = 0; i < n; ++i) {
  1609. blocks[i]->dom = p;
  1610. p += nodewords;
  1611. }
  1612. all_closure_sets = p;
  1613. for (i = 0; i < n; ++i) {
  1614. blocks[i]->closure = p;
  1615. p += nodewords;
  1616. }
  1617. all_edge_sets = p;
  1618. for (i = 0; i < n; ++i) {
  1619. register struct block *b = blocks[i];
  1620. b->et.edom = p;
  1621. p += edgewords;
  1622. b->ef.edom = p;
  1623. p += edgewords;
  1624. b->et.id = i;
  1625. edges[i] = &b->et;
  1626. b->ef.id = n_blocks + i;
  1627. edges[n_blocks + i] = &b->ef;
  1628. b->et.pred = b;
  1629. b->ef.pred = b;
  1630. }
  1631. max_stmts = 0;
  1632. for (i = 0; i < n; ++i)
  1633. max_stmts += slength(blocks[i]->stmts) + 1;
  1634. /*
  1635.  * We allocate at most 3 value numbers per statement,
  1636.  * so this is an upper bound on the number of valnodes
  1637.  * we'll need.
  1638.  */
  1639. maxval = 3 * max_stmts;
  1640. vmap = (struct vmapinfo *)malloc(maxval * sizeof(*vmap));
  1641. vnode_base = (struct valnode *)malloc(maxval * sizeof(*vmap));
  1642. }
  1643. /*
  1644.  * Some pointers used to convert the basic block form of the code,
  1645.  * into the array form that BPF requires.  'fstart' will point to
  1646.  * the malloc'd array while 'ftail' is used during the recursive traversal.
  1647.  */
  1648. static struct bpf_insn *fstart;
  1649. static struct bpf_insn *ftail;
  1650. #ifdef BDEBUG
  1651. int bids[1000];
  1652. #endif
  1653. /*
  1654.  * Returns true if successful.  Returns false if a branch has
  1655.  * an offset that is too large.  If so, we have marked that
  1656.  * branch so that on a subsequent iteration, it will be treated
  1657.  * properly.
  1658.  */
  1659. static int
  1660. convert_code_r(p)
  1661. struct block *p;
  1662. {
  1663. struct bpf_insn *dst;
  1664. struct slist *src;
  1665. int slen;
  1666. u_int off;
  1667. int extrajmps; /* number of extra jumps inserted */
  1668. if (p == 0 || isMarked(p))
  1669. return (1);
  1670. Mark(p);
  1671. if (convert_code_r(JF(p)) == 0)
  1672. return (0);
  1673. if (convert_code_r(JT(p)) == 0)
  1674. return (0);
  1675. slen = slength(p->stmts);
  1676. dst = ftail -= (slen + 1 + p->longjt + p->longjf);
  1677. /* inflate length by any extra jumps */
  1678. p->offset = dst - fstart;
  1679. for (src = p->stmts; src; src = src->next) {
  1680. if (src->s.code == NOP)
  1681. continue;
  1682. dst->code = (u_short)src->s.code;
  1683. dst->k = src->s.k;
  1684. ++dst;
  1685. }
  1686. #ifdef BDEBUG
  1687. bids[dst - fstart] = p->id + 1;
  1688. #endif
  1689. dst->code = (u_short)p->s.code;
  1690. dst->k = p->s.k;
  1691. if (JT(p)) {
  1692. extrajmps = 0;
  1693. off = JT(p)->offset - (p->offset + slen) - 1;
  1694. if (off >= 256) {
  1695.     /* offset too large for branch, must add a jump */
  1696.     if (p->longjt == 0) {
  1697.      /* mark this instruction and retry */
  1698. p->longjt++;
  1699. return(0);
  1700.     }
  1701.     /* branch if T to following jump */
  1702.     dst->jt = extrajmps;
  1703.     extrajmps++;
  1704.     dst[extrajmps].code = BPF_JMP|BPF_JA;
  1705.     dst[extrajmps].k = off - extrajmps;
  1706. }
  1707. else
  1708.     dst->jt = off;
  1709. off = JF(p)->offset - (p->offset + slen) - 1;
  1710. if (off >= 256) {
  1711.     /* offset too large for branch, must add a jump */
  1712.     if (p->longjf == 0) {
  1713.      /* mark this instruction and retry */
  1714. p->longjf++;
  1715. return(0);
  1716.     }
  1717.     /* branch if F to following jump */
  1718.     /* if two jumps are inserted, F goes to second one */
  1719.     dst->jf = extrajmps;
  1720.     extrajmps++;
  1721.     dst[extrajmps].code = BPF_JMP|BPF_JA;
  1722.     dst[extrajmps].k = off - extrajmps;
  1723. }
  1724. else
  1725.     dst->jf = off;
  1726. }
  1727. return (1);
  1728. }
  1729. /*
  1730.  * Convert flowgraph intermediate representation to the
  1731.  * BPF array representation.  Set *lenp to the number of instructions.
  1732.  */
  1733. struct bpf_insn *
  1734. icode_to_fcode(root, lenp)
  1735. struct block *root;
  1736. int *lenp;
  1737. {
  1738. int n;
  1739. struct bpf_insn *fp;
  1740. /*
  1741.  * Loop doing convert_codr_r() until no branches remain
  1742.  * with too-large offsets.
  1743.  */
  1744. while (1) {
  1745.     unMarkAll();
  1746.     n = *lenp = count_stmts(root);
  1747.     
  1748.     fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
  1749.     memset((char *)fp, 0, sizeof(*fp) * n);
  1750.     fstart = fp;
  1751.     ftail = fp + n;
  1752.     
  1753.     unMarkAll();
  1754.     if (convert_code_r(root))
  1755. break;
  1756.     free(fp);
  1757. }
  1758. return fp;
  1759. }
  1760. #ifdef BDEBUG
  1761. static void
  1762. opt_dump(root)
  1763. struct block *root;
  1764. {
  1765. struct bpf_program f;
  1766. memset(bids, 0, sizeof bids);
  1767. f.bf_insns = icode_to_fcode(root, &f.bf_len);
  1768. bpf_dump(&f, 1);
  1769. putchar('n');
  1770. free((char *)f.bf_insns);
  1771. }
  1772. #endif