/*
 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *  Optimization module for BPF code intermediate representation.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <pcap-types.h>

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <setjmp.h>
#include <string.h>

#include <errno.h>

#include "pcap-int.h"

#include "gencode.h"
#include "optimize.h"

#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif

#ifdef BDEBUG
/*
 * The internal "debug printout" flag for the filter expression optimizer.
 * The code to print that stuff is present only if BDEBUG is defined, so
 * the flag, and the routine to set it, are defined only if BDEBUG is
 * defined.
 */
static int pcap_optimizer_debug;

/*
 * Routine to set that flag.
 *
 * This is intended for libpcap developers, not for general use.
 * If you want to set these in a program, you'll have to declare this
 * routine yourself, with the appropriate DLL import attribute on Windows;
 * it's not declared in any header file, and won't be declared in any
 * header file provided by libpcap.
 */
PCAP_API void pcap_set_optimizer_debug(int value);

PCAP_API_DEF void
pcap_set_optimizer_debug(int value)
{
	pcap_optimizer_debug = value;
}

/*
 * The internal "print dot graph" flag for the filter expression optimizer.
 * The code to print that stuff is present only if BDEBUG is defined, so
 * the flag, and the routine to set it, are defined only if BDEBUG is
 * defined.
 */
static int pcap_print_dot_graph;

/*
 * Routine to set that flag.
 *
 * This is intended for libpcap developers, not for general use.
 * If you want to set these in a program, you'll have to declare this
 * routine yourself, with the appropriate DLL import attribute on Windows;
 * it's not declared in any header file, and won't be declared in any
 * header file provided by libpcap.
 */
PCAP_API void pcap_set_print_dot_graph(int value);

PCAP_API_DEF void
pcap_set_print_dot_graph(int value)
{
	pcap_print_dot_graph = value;
}

#endif

/*
 * lowest_set_bit().
 *
 * Takes a 32-bit integer as an argument.
 *
 * If handed a non-zero value, returns the index of the lowest set bit,
 * counting upwards from zero.
 *
 * If handed zero, the results are platform- and compiler-dependent.
 * Keep it out of the light, don't give it any water, don't feed it
 * after midnight, and don't pass zero to it.
 *
 * This is the same as the count of trailing zeroes in the word.
 */
#if PCAP_IS_AT_LEAST_GNUC_VERSION(3,4)
  /*
   * GCC 3.4 and later; we have __builtin_ctz().
   */
  #define lowest_set_bit(mask) ((u_int)__builtin_ctz(mask))
#elif defined(_MSC_VER)
  /*
   * Visual Studio; we support only 2005 and later, so use
   * _BitScanForward().
   */
#include <intrin.h>

#ifndef __clang__
#pragma intrinsic(_BitScanForward)
#endif

static __forceinline u_int
lowest_set_bit(int mask)
{
	unsigned long bit;

	/*
	 * Don't sign-extend mask if long is longer than int.
	 * (It's currently not, in MSVC, even on 64-bit platforms, but....)
	 */
	if (_BitScanForward(&bit, (unsigned int)mask) == 0)
		abort();	/* mask is zero */
	return (u_int)bit;
}
#elif defined(MSDOS) && defined(__DJGPP__)
  /*
   * MS-DOS with DJGPP, which declares ffs() in <string.h>, which
   * we've already included.
   */
  #define lowest_set_bit(mask)	((u_int)(ffs((mask)) - 1))
#elif (defined(MSDOS) && defined(__WATCOMC__)) || defined(STRINGS_H_DECLARES_FFS)
  /*
   * MS-DOS with Watcom C, which has <strings.h> and declares ffs() there,
   * or some other platform (UN*X conforming to a sufficient recent version
   * of the Single UNIX Specification).
   */
  #include <strings.h>
  #define lowest_set_bit(mask)	(u_int)((ffs((mask)) - 1))
#else
/*
 * None of the above.
 * Use a perfect-hash-function-based function.
 */
static u_int
lowest_set_bit(int mask)
{
	unsigned int v = (unsigned int)mask;

	static const u_int MultiplyDeBruijnBitPosition[32] = {
		0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
		31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
	};

	/*
	 * We strip off all but the lowermost set bit (v & ~v),
	 * and perform a minimal perfect hash on it to look up the
	 * number of low-order zero bits in a table.
	 *
	 * See:
	 *
	 *	http://7ooo.mooo.com/text/ComputingTrailingZerosHOWTO.pdf
	 *
	 *	http://supertech.csail.mit.edu/papers/debruijn.pdf
	 */
	return (MultiplyDeBruijnBitPosition[((v & -v) * 0x077CB531U) >> 27]);
}
#endif

/*
 * Represents a deleted instruction.
 */
#define NOP -1

/*
 * Register numbers for use-def values.
 * 0 through BPF_MEMWORDS-1 represent the corresponding scratch memory
 * location.  A_ATOM is the accumulator and X_ATOM is the index
 * register.
 */
#define A_ATOM BPF_MEMWORDS
#define X_ATOM (BPF_MEMWORDS+1)

/*
 * This define is used to represent *both* the accumulator and
 * x register in use-def computations.
 * Currently, the use-def code assumes only one definition per instruction.
 */
#define AX_ATOM N_ATOMS

/*
 * These data structures are used in a Cocke and Shwarz style
 * value numbering scheme.  Since the flowgraph is acyclic,
 * exit values can be propagated from a node's predecessors
 * provided it is uniquely defined.
 */
struct valnode {
	int code;
	bpf_u_int32 v0, v1;
	int val;		/* the value number */
	struct valnode *next;
};

/* Integer constants mapped with the load immediate opcode. */
#define K(i) F(opt_state, BPF_LD|BPF_IMM|BPF_W, i, 0U)

struct vmapinfo {
	int is_const;
	bpf_u_int32 const_val;
};

typedef struct {
	/*
	 * Place to longjmp to on an error.
	 */
	jmp_buf top_ctx;

	/*
	 * The buffer into which to put error message.
	 */
	char *errbuf;

	/*
	 * A flag to indicate that further optimization is needed.
	 * Iterative passes are continued until a given pass yields no
	 * code simplification or branch movement.
	 */
	int done;

	/*
	 * XXX - detect loops that do nothing but repeated AND/OR pullups
	 * and edge moves.
	 * If 100 passes in a row do nothing but that, treat that as a
	 * sign that we're in a loop that just shuffles in a cycle in
	 * which each pass just shuffles the code and we eventually
	 * get back to the original configuration.
	 *
	 * XXX - we need a non-heuristic way of detecting, or preventing,
	 * such a cycle.
	 */
	int non_branch_movement_performed;

	u_int n_blocks;		/* number of blocks in the CFG; guaranteed to be > 0, as it's a RET instruction at a minimum */
	struct block **blocks;
	u_int n_edges;		/* twice n_blocks, so guaranteed to be > 0 */
	struct edge **edges;

	/*
	 * A bit vector set representation of the dominators.
	 * We round up the set size to the next power of two.
	 */
	u_int nodewords;	/* number of 32-bit words for a bit vector of "number of nodes" bits; guaranteed to be > 0 */
	u_int edgewords;	/* number of 32-bit words for a bit vector of "number of edges" bits; guaranteed to be > 0 */
	struct block **levels;
	bpf_u_int32 *space;

#define BITS_PER_WORD (8*sizeof(bpf_u_int32))
/*
 * True if a is in uset {p}
 */
#define SET_MEMBER(p, a) \
((p)[(unsigned)(a) / BITS_PER_WORD] & ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD)))

/*
 * Add 'a' to uset p.
 */
#define SET_INSERT(p, a) \
(p)[(unsigned)(a) / BITS_PER_WORD] |= ((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))

/*
 * Delete 'a' from uset p.
 */
#define SET_DELETE(p, a) \
(p)[(unsigned)(a) / BITS_PER_WORD] &= ~((bpf_u_int32)1 << ((unsigned)(a) % BITS_PER_WORD))

/*
 * a := a intersect b
 * n must be guaranteed to be > 0
 */
#define SET_INTERSECT(a, b, n)\
{\
	register bpf_u_int32 *_x = a, *_y = b;\
	register u_int _n = n;\
	do *_x++ &= *_y++; while (--_n != 0);\
}

/*
 * a := a - b
 * n must be guaranteed to be > 0
 */
#define SET_SUBTRACT(a, b, n)\
{\
	register bpf_u_int32 *_x = a, *_y = b;\
	register u_int _n = n;\
	do *_x++ &=~ *_y++; while (--_n != 0);\
}

/*
 * a := a union b
 * n must be guaranteed to be > 0
 */
#define SET_UNION(a, b, n)\
{\
	register bpf_u_int32 *_x = a, *_y = b;\
	register u_int _n = n;\
	do *_x++ |= *_y++; while (--_n != 0);\
}

	uset all_dom_sets;
	uset all_closure_sets;
	uset all_edge_sets;

#define MODULUS 213
	struct valnode *hashtbl[MODULUS];
	bpf_u_int32 curval;
	bpf_u_int32 maxval;

	struct vmapinfo *vmap;
	struct valnode *vnode_base;
	struct valnode *next_vnode;
} opt_state_t;

typedef struct {
	/*
	 * Place to longjmp to on an error.
	 */
	jmp_buf top_ctx;

	/*
	 * The buffer into which to put error message.
	 */
	char *errbuf;

	/*
	 * Some pointers used to convert the basic block form of the code,
	 * into the array form that BPF requires.  'fstart' will point to
	 * the malloc'd array while 'ftail' is used during the recursive
	 * traversal.
	 */
	struct bpf_insn *fstart;
	struct bpf_insn *ftail;
} conv_state_t;

static void opt_init(opt_state_t *, struct icode *);
static void opt_cleanup(opt_state_t *);
static void PCAP_NORETURN opt_error(opt_state_t *, const char *, ...)
    PCAP_PRINTFLIKE(2, 3);

static void intern_blocks(opt_state_t *, struct icode *);

static void find_inedges(opt_state_t *, struct block *);
#ifdef BDEBUG
static void opt_dump(opt_state_t *, struct icode *);
#endif

#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif

static void
find_levels_r(opt_state_t *opt_state, struct icode *ic, struct block *b)
{
	int level;

	if (isMarked(ic, b))
		return;

	Mark(ic, b);
	b->link = 0;

	if (JT(b)) {
		find_levels_r(opt_state, ic, JT(b));
		find_levels_r(opt_state, ic, JF(b));
		level = MAX(JT(b)->level, JF(b)->level) + 1;
	} else
		level = 0;
	b->level = level;
	b->link = opt_state->levels[level];
	opt_state->levels[level] = b;
}

/*
 * Level graph.  The levels go from 0 at the leaves to
 * N_LEVELS at the root.  The opt_state->levels[] array points to the
 * first node of the level list, whose elements are linked
 * with the 'link' field of the struct block.
 */
static void
find_levels(opt_state_t *opt_state, struct icode *ic)
{
	memset((char *)opt_state->levels, 0, opt_state->n_blocks * sizeof(*opt_state->levels));
	unMarkAll(ic);
	find_levels_r(opt_state, ic, ic->root);
}

/*
 * Find dominator relationships.
 * Assumes graph has been leveled.
 */
static void
find_dom(opt_state_t *opt_state, struct block *root)
{
	u_int i;
	int level;
	struct block *b;
	bpf_u_int32 *x;

	/*
	 * Initialize sets to contain all nodes.
	 */
	x = opt_state->all_dom_sets;
	/*
	 * In opt_init(), we've made sure the product doesn't overflow.
	 */
	i = opt_state->n_blocks * opt_state->nodewords;
	while (i != 0) {
		--i;
		*x++ = 0xFFFFFFFFU;
	}
	/* Root starts off empty. */
	for (i = opt_state->nodewords; i != 0;) {
		--i;
		root->dom[i] = 0;
	}

	/* root->level is the highest level no found. */
	for (level = root->level; level >= 0; --level) {
		for (b = opt_state->levels[level]; b; b = b->link) {
			SET_INSERT(b->dom, b->id);
			if (JT(b) == 0)
				continue;
			SET_INTERSECT(JT(b)->dom, b->dom, opt_state->nodewords);
			SET_INTERSECT(JF(b)->dom, b->dom, opt_state->nodewords);
		}
	}
}

static void
propedom(opt_state_t *opt_state, struct edge *ep)
{
	SET_INSERT(ep->edom, ep->id);
	if (ep->succ) {
		SET_INTERSECT(ep->succ->et.edom, ep->edom, opt_state->edgewords);
		SET_INTERSECT(ep->succ->ef.edom, ep->edom, opt_state->edgewords);
	}
}

/*
 * Compute edge dominators.
 * Assumes graph has been leveled and predecessors established.
 */
static void
find_edom(opt_state_t *opt_state, struct block *root)
{
	u_int i;
	uset x;
	int level;
	struct block *b;

	x = opt_state->all_edge_sets;
	/*
	 * In opt_init(), we've made sure the product doesn't overflow.
	 */
	for (i = opt_state->n_edges * opt_state->edgewords; i != 0; ) {
		--i;
		x[i] = 0xFFFFFFFFU;
	}

	/* root->level is the highest level no found. */
	memset(root->et.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
	memset(root->ef.edom, 0, opt_state->edgewords * sizeof(*(uset)0));
	for (level = root->level; level >= 0; --level) {
		for (b = opt_state->levels[level]; b != 0; b = b->link) {
			propedom(opt_state, &b->et);
			propedom(opt_state, &b->ef);
		}
	}
}

/*
 * Find the backwards transitive closure of the flow graph.  These sets
 * are backwards in the sense that we find the set of nodes that reach
 * a given node, not the set of nodes that can be reached by a node.
 *
 * Assumes graph has been leveled.
 */
static void
find_closure(opt_state_t *opt_state, struct block *root)
{
	int level;
	struct block *b;

	/*
	 * Initialize sets to contain no nodes.
	 */
	memset((char *)opt_state->all_closure_sets, 0,
	      opt_state->n_blocks * opt_state->nodewords * sizeof(*opt_state->all_closure_sets));

	/* root->level is the highest level no found. */
	for (level = root->level; level >= 0; --level) {
		for (b = opt_state->levels[level]; b; b = b->link) {
			SET_INSERT(b->closure, b->id);
			if (JT(b) == 0)
				continue;
			SET_UNION(JT(b)->closure, b->closure, opt_state->nodewords);
			SET_UNION(JF(b)->closure, b->closure, opt_state->nodewords);
		}
	}
}

/*
 * Return the register number that is used by s.
 *
 * Returns ATOM_A if A is used, ATOM_X if X is used, AX_ATOM if both A and X
 * are used, the scratch memory location's number if a scratch memory
 * location is used (e.g., 0 for M[0]), or -1 if none of those are used.
 *
 * The implementation should probably change to an array access.
 */
static int
atomuse(struct stmt *s)
{
	register int c = s->code;

	if (c == NOP)
		return -1;

	switch (BPF_CLASS(c)) {

	case BPF_RET:
		return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
			(BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;

	case BPF_LD:
	case BPF_LDX:
		/*
		 * As there are fewer than 2^31 memory locations,
		 * s->k should be convertible to int without problems.
		 */
		return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
			(BPF_MODE(c) == BPF_MEM) ? (int)s->k : -1;

	case BPF_ST:
		return A_ATOM;

	case BPF_STX:
		return X_ATOM;

	case BPF_JMP:
	case BPF_ALU:
		if (BPF_SRC(c) == BPF_X)
			return AX_ATOM;
		return A_ATOM;

	case BPF_MISC:
		return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
	}
	abort();
	/* NOTREACHED */
}

/*
 * Return the register number that is defined by 's'.  We assume that
 * a single stmt cannot define more than one register.  If no register
 * is defined, return -1.
 *
 * The implementation should probably change to an array access.
 */
static int
atomdef(struct stmt *s)
{
	if (s->code == NOP)
		return -1;

	switch (BPF_CLASS(s->code)) {

	case BPF_LD:
	case BPF_ALU:
		return A_ATOM;

	case BPF_LDX:
		return X_ATOM;

	case BPF_ST:
	case BPF_STX:
		return s->k;

	case BPF_MISC:
		return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
	}
	return -1;
}

/*
 * Compute the sets of registers used, defined, and killed by 'b'.
 *
 * "Used" means that a statement in 'b' uses the register before any
 * statement in 'b' defines it, i.e. it uses the value left in
 * that register by a predecessor block of this block.
 * "Defined" means that a statement in 'b' defines it.
 * "Killed" means that a statement in 'b' defines it before any
 * statement in 'b' uses it, i.e. it kills the value left in that
 * register by a predecessor block of this block.
 */
static void
compute_local_ud(struct block *b)
{
	struct slist *s;
	atomset def = 0, use = 0, killed = 0;
	int atom;

	for (s = b->stmts; s; s = s->next) {
		if (s->s.code == NOP)
			continue;
		atom = atomuse(&s->s);
		if (atom >= 0) {
			if (atom == AX_ATOM) {
				if (!ATOMELEM(def, X_ATOM))
					use |= ATOMMASK(X_ATOM);
				if (!ATOMELEM(def, A_ATOM))
					use |= ATOMMASK(A_ATOM);
			}
			else if (atom < N_ATOMS) {
				if (!ATOMELEM(def, atom))
					use |= ATOMMASK(atom);
			}
			else
				abort();
		}
		atom = atomdef(&s->s);
		if (atom >= 0) {
			if (!ATOMELEM(use, atom))
				killed |= ATOMMASK(atom);
			def |= ATOMMASK(atom);
		}
	}
	if (BPF_CLASS(b->s.code) == BPF_JMP) {
		/*
		 * XXX - what about RET?
		 */
		atom = atomuse(&b->s);
		if (atom >= 0) {
			if (atom == AX_ATOM) {
				if (!ATOMELEM(def, X_ATOM))
					use |= ATOMMASK(X_ATOM);
				if (!ATOMELEM(def, A_ATOM))
					use |= ATOMMASK(A_ATOM);
			}
			else if (atom < N_ATOMS) {
				if (!ATOMELEM(def, atom))
					use |= ATOMMASK(atom);
			}
			else
				abort();
		}
	}

	b->def = def;
	b->kill = killed;
	b->in_use = use;
}

/*
 * Assume graph is already leveled.
 */
static void
find_ud(opt_state_t *opt_state, struct block *root)
{
	int i, maxlevel;
	struct block *p;

	/*
	 * root->level is the highest level no found;
	 * count down from there.
	 */
	maxlevel = root->level;
	for (i = maxlevel; i >= 0; --i)
		for (p = opt_state->levels[i]; p; p = p->link) {
			compute_local_ud(p);
			p->out_use = 0;
		}

	for (i = 1; i <= maxlevel; ++i) {
		for (p = opt_state->levels[i]; p; p = p->link) {
			p->out_use |= JT(p)->in_use | JF(p)->in_use;
			p->in_use |= p->out_use &~ p->kill;
		}
	}
}
static void
init_val(opt_state_t *opt_state)
{
	opt_state->curval = 0;
	opt_state->next_vnode = opt_state->vnode_base;
	memset((char *)opt_state->vmap, 0, opt_state->maxval * sizeof(*opt_state->vmap));
	memset((char *)opt_state->hashtbl, 0, sizeof opt_state->hashtbl);
}

/*
 * Because we really don't have an IR, this stuff is a little messy.
 *
 * This routine looks in the table of existing value number for a value
 * with generated from an operation with the specified opcode and
 * the specified values.  If it finds it, it returns its value number,
 * otherwise it makes a new entry in the table and returns the
 * value number of that entry.
 */
static bpf_u_int32
F(opt_state_t *opt_state, int code, bpf_u_int32 v0, bpf_u_int32 v1)
{
	u_int hash;
	bpf_u_int32 val;
	struct valnode *p;

	hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
	hash %= MODULUS;

	for (p = opt_state->hashtbl[hash]; p; p = p->next)
		if (p->code == code && p->v0 == v0 && p->v1 == v1)
			return p->val;

	/*
	 * Not found.  Allocate a new value, and assign it a new
	 * value number.
	 *
	 * opt_state->curval starts out as 0, which means VAL_UNKNOWN; we
	 * increment it before using it as the new value number, which
	 * means we never assign VAL_UNKNOWN.
	 *
	 * XXX - unless we overflow, but we probably won't have 2^32-1
	 * values; we treat 32 bits as effectively infinite.
	 */
	val = ++opt_state->curval;
	if (BPF_MODE(code) == BPF_IMM &&
	    (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
		opt_state->vmap[val].const_val = v0;
		opt_state->vmap[val].is_const = 1;
	}
	p = opt_state->next_vnode++;
	p->val = val;
	p->code = code;
	p->v0 = v0;
	p->v1 = v1;
	p->next = opt_state->hashtbl[hash];
	opt_state->hashtbl[hash] = p;

	return val;
}

static inline void
vstore(struct stmt *s, bpf_u_int32 *valp, bpf_u_int32 newval, int alter)
{
	if (alter && newval != VAL_UNKNOWN && *valp == newval)
		s->code = NOP;
	else
		*valp = newval;
}

/*
 * Do constant-folding on binary operators.
 * (Unary operators are handled elsewhere.)
 */
static void
fold_op(opt_state_t *opt_state, struct stmt *s, bpf_u_int32 v0, bpf_u_int32 v1)
{
	bpf_u_int32 a, b;

	a = opt_state->vmap[v0].const_val;
	b = opt_state->vmap[v1].const_val;

	switch (BPF_OP(s->code)) {
	case BPF_ADD:
		a += b;
		break;

	case BPF_SUB:
		a -= b;
		break;

	case BPF_MUL:
		a *= b;
		break;

	case BPF_DIV:
		if (b == 0)
			opt_error(opt_state, "division by zero");
		a /= b;
		break;

	case BPF_MOD:
		if (b == 0)
			opt_error(opt_state, "modulus by zero");
		a %= b;
		break;

	case BPF_AND:
		a &= b;
		break;

	case BPF_OR:
		a |= b;
		break;

	case BPF_XOR:
		a ^= b;
		break;

	case BPF_LSH:
		/*
		 * A left shift of more than the width of the type
		 * is undefined in C; we'll just treat it as shifting
		 * all the bits out.
		 *
		 * XXX - the BPF interpreter doesn't check for this,
		 * so its behavior is dependent on the behavior of
		 * the processor on which it's running.  There are
		 * processors on which it shifts all the bits out
		 * and processors on which it does no shift.
		 */
		if (b < 32)
			a <<= b;
		else
			a = 0;
		break;

	case BPF_RSH:
		/*
		 * A right shift of more than the width of the type
		 * is undefined in C; we'll just treat it as shifting
		 * all the bits out.
		 *
		 * XXX - the BPF interpreter doesn't check for this,
		 * so its behavior is dependent on the behavior of
		 * the processor on which it's running.  There are
		 * processors on which it shifts all the bits out
		 * and processors on which it does no shift.
		 */
		if (b < 32)
			a >>= b;
		else
			a = 0;
		break;

	default:
		abort();
	}
	s->k = a;
	s->code = BPF_LD|BPF_IMM;
	/*
	 * XXX - optimizer loop detection.
	 */
	opt_state->non_branch_movement_performed = 1;
	opt_state->done = 0;
}

static inline struct slist *
this_op(struct slist *s)
{
	while (s != 0 && s->s.code == NOP)
		s = s->next;
	return s;
}

static void
opt_not(struct block *b)
{
	struct block *tmp = JT(b);

	JT(b) = JF(b);
	JF(b) = tmp;
}

static void
opt_peep(opt_state_t *opt_state, struct block *b)
{
	struct slist *s;
	struct slist *next, *last;
	bpf_u_int32 val;

	s = b->stmts;
	if (s == 0)
		return;

	last = s;
	for (/*empty*/; /*empty*/; s = next) {
		/*
		 * Skip over nops.
		 */
		s = this_op(s);
		if (s == 0)
			break;	/* nothing left in the block */

		/*
		 * Find the next real instruction after that one
		 * (skipping nops).
		 */
		next = this_op(s->next);
		if (next == 0)
			break;	/* no next instruction */
		last = next;

		/*
		 * st  M[k]	-->	st  M[k]
		 * ldx M[k]		tax
		 */
		if (s->s.code == BPF_ST &&
		    next->s.code == (BPF_LDX|BPF_MEM) &&
		    s->s.k == next->s.k) {
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
			next->s.code = BPF_MISC|BPF_TAX;
		}
		/*
		 * ld  #k	-->	ldx  #k
		 * tax			txa
		 */
		if (s->s.code == (BPF_LD|BPF_IMM) &&
		    next->s.code == (BPF_MISC|BPF_TAX)) {
			s->s.code = BPF_LDX|BPF_IMM;
			next->s.code = BPF_MISC|BPF_TXA;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		/*
		 * This is an ugly special case, but it happens
		 * when you say tcp[k] or udp[k] where k is a constant.
		 */
		if (s->s.code == (BPF_LD|BPF_IMM)) {
			struct slist *add, *tax, *ild;

			/*
			 * Check that X isn't used on exit from this
			 * block (which the optimizer might cause).
			 * We know the code generator won't generate
			 * any local dependencies.
			 */
			if (ATOMELEM(b->out_use, X_ATOM))
				continue;

			/*
			 * Check that the instruction following the ldi
			 * is an addx, or it's an ldxms with an addx
			 * following it (with 0 or more nops between the
			 * ldxms and addx).
			 */
			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))
				continue;

			/*
			 * Check that a tax follows that (with 0 or more
			 * nops between them).
			 */
			tax = this_op(add->next);
			if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
				continue;

			/*
			 * Check that an ild follows that (with 0 or more
			 * nops between them).
			 */
			ild = this_op(tax->next);
			if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
			    BPF_MODE(ild->s.code) != BPF_IND)
				continue;
			/*
			 * We want to turn this sequence:
			 *
			 * (004) ldi     #0x2		{s}
			 * (005) ldxms   [14]		{next}  -- optional
			 * (006) addx			{add}
			 * (007) tax			{tax}
			 * (008) ild     [x+0]		{ild}
			 *
			 * into this sequence:
			 *
			 * (004) nop
			 * (005) ldxms   [14]
			 * (006) nop
			 * (007) nop
			 * (008) ild     [x+2]
			 *
			 * XXX We need to check that X is not
			 * subsequently used, because we want to change
			 * what'll be in it after this sequence.
			 *
			 * We know we can eliminate the accumulator
			 * modifications earlier in the sequence since
			 * it is defined by the last stmt of this sequence
			 * (i.e., the last statement of the sequence loads
			 * a value into the accumulator, so we can eliminate
			 * earlier operations on the accumulator).
			 */
			ild->s.k += s->s.k;
			s->s.code = NOP;
			add->s.code = NOP;
			tax->s.code = NOP;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
	}
	/*
	 * If the comparison at the end of a block is an equality
	 * comparison against a constant, and nobody uses the value
	 * we leave in the A register at the end of a block, and
	 * the operation preceding the comparison is an arithmetic
	 * operation, we can sometime optimize it away.
	 */
	if (b->s.code == (BPF_JMP|BPF_JEQ|BPF_K) &&
	    !ATOMELEM(b->out_use, A_ATOM)) {
		/*
		 * We can optimize away certain subtractions of the
		 * X register.
		 */
		if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X)) {
			val = b->val[X_ATOM];
			if (opt_state->vmap[val].is_const) {
				/*
				 * 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:
				 *
				 * sub x  ->	nop
				 * jeq #y	jeq #(x+y)
				 */
				b->s.k += opt_state->vmap[val].const_val;
				last->s.code = NOP;
				/*
				 * XXX - optimizer loop detection.
				 */
				opt_state->non_branch_movement_performed = 1;
				opt_state->done = 0;
			} else if (b->s.k == 0) {
				/*
				 * If the X register isn't a constant,
				 * and the comparison in the test is
				 * against 0, we can compare with the
				 * X register, instead:
				 *
				 * sub x  ->	nop
				 * jeq #0	jeq x
				 */
				last->s.code = NOP;
				b->s.code = BPF_JMP|BPF_JEQ|BPF_X;
				/*
				 * XXX - optimizer loop detection.
				 */
				opt_state->non_branch_movement_performed = 1;
				opt_state->done = 0;
			}
		}
		/*
		 * Likewise, a constant subtract can be simplified:
		 *
		 * sub #x ->	nop
		 * jeq #y ->	jeq #(x+y)
		 */
		else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K)) {
			last->s.code = NOP;
			b->s.k += last->s.k;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		/*
		 * And, similarly, a constant AND can be simplified
		 * if we're testing against 0, i.e.:
		 *
		 * and #k	nop
		 * jeq #0  ->	jset #k
		 */
		else if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
		    b->s.k == 0) {
			b->s.k = last->s.k;
			b->s.code = BPF_JMP|BPF_K|BPF_JSET;
			last->s.code = NOP;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
			opt_not(b);
		}
	}
	/*
	 * jset #0        ->   never
	 * jset #ffffffff ->   always
	 */
	if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) {
		if (b->s.k == 0)
			JT(b) = JF(b);
		if (b->s.k == 0xffffffffU)
			JF(b) = JT(b);
	}
	/*
	 * If we're comparing against the index register, and the index
	 * register is a known constant, we can just compare against that
	 * constant.
	 */
	val = b->val[X_ATOM];
	if (opt_state->vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) {
		bpf_u_int32 v = opt_state->vmap[val].const_val;
		b->s.code &= ~BPF_X;
		b->s.k = v;
	}
	/*
	 * If the accumulator is a known constant, we can compute the
	 * comparison result.
	 */
	val = b->val[A_ATOM];
	if (opt_state->vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
		bpf_u_int32 v = opt_state->vmap[val].const_val;
		switch (BPF_OP(b->s.code)) {

		case BPF_JEQ:
			v = v == b->s.k;
			break;

		case BPF_JGT:
			v = v > b->s.k;
			break;

		case BPF_JGE:
			v = v >= b->s.k;
			break;

		case BPF_JSET:
			v &= b->s.k;
			break;

		default:
			abort();
		}
		if (JF(b) != JT(b)) {
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		if (v)
			JF(b) = JT(b);
		else
			JT(b) = JF(b);
	}
}

/*
 * Compute the symbolic value of expression of 's', and update
 * anything it defines in the value table 'val'.  If 'alter' is true,
 * do various optimizations.  This code would be cleaner if symbolic
 * evaluation and code transformations weren't folded together.
 */
static void
opt_stmt(opt_state_t *opt_state, struct stmt *s, bpf_u_int32 val[], int alter)
{
	int op;
	bpf_u_int32 v;

	switch (s->code) {

	case BPF_LD|BPF_ABS|BPF_W:
	case BPF_LD|BPF_ABS|BPF_H:
	case BPF_LD|BPF_ABS|BPF_B:
		v = F(opt_state, s->code, s->k, 0L);
		vstore(s, &val[A_ATOM], v, alter);
		break;

	case BPF_LD|BPF_IND|BPF_W:
	case BPF_LD|BPF_IND|BPF_H:
	case BPF_LD|BPF_IND|BPF_B:
		v = val[X_ATOM];
		if (alter && opt_state->vmap[v].is_const) {
			s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
			s->k += opt_state->vmap[v].const_val;
			v = F(opt_state, s->code, s->k, 0L);
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		else
			v = F(opt_state, s->code, s->k, v);
		vstore(s, &val[A_ATOM], v, alter);
		break;

	case BPF_LD|BPF_LEN:
		v = F(opt_state, s->code, 0L, 0L);
		vstore(s, &val[A_ATOM], v, alter);
		break;

	case BPF_LD|BPF_IMM:
		v = K(s->k);
		vstore(s, &val[A_ATOM], v, alter);
		break;

	case BPF_LDX|BPF_IMM:
		v = K(s->k);
		vstore(s, &val[X_ATOM], v, alter);
		break;

	case BPF_LDX|BPF_MSH|BPF_B:
		v = F(opt_state, s->code, s->k, 0L);
		vstore(s, &val[X_ATOM], v, alter);
		break;

	case BPF_ALU|BPF_NEG:
		if (alter && opt_state->vmap[val[A_ATOM]].is_const) {
			s->code = BPF_LD|BPF_IMM;
			/*
			 * Do this negation as unsigned arithmetic; that's
			 * what modern BPF engines do, and it guarantees
			 * that all possible values can be negated.  (Yeah,
			 * negating 0x80000000, the minimum signed 32-bit
			 * two's-complement value, results in 0x80000000,
			 * so it's still negative, but we *should* be doing
			 * all unsigned arithmetic here, to match what
			 * modern BPF engines do.)
			 *
			 * Express it as 0U - (unsigned value) so that we
			 * don't get compiler warnings about negating an
			 * unsigned value and don't get UBSan warnings
			 * about the result of negating 0x80000000 being
			 * undefined.
			 */
			s->k = 0U - opt_state->vmap[val[A_ATOM]].const_val;
			val[A_ATOM] = K(s->k);
		}
		else
			val[A_ATOM] = F(opt_state, s->code, val[A_ATOM], 0L);
		break;

	case BPF_ALU|BPF_ADD|BPF_K:
	case BPF_ALU|BPF_SUB|BPF_K:
	case BPF_ALU|BPF_MUL|BPF_K:
	case BPF_ALU|BPF_DIV|BPF_K:
	case BPF_ALU|BPF_MOD|BPF_K:
	case BPF_ALU|BPF_AND|BPF_K:
	case BPF_ALU|BPF_OR|BPF_K:
	case BPF_ALU|BPF_XOR|BPF_K:
	case BPF_ALU|BPF_LSH|BPF_K:
	case BPF_ALU|BPF_RSH|BPF_K:
		op = BPF_OP(s->code);
		if (alter) {
			if (s->k == 0) {
				/*
				 * Optimize operations where the constant
				 * is zero.
				 *
				 * Don't optimize away "sub #0"
				 * as it may be needed later to
				 * fixup the generated math code.
				 *
				 * Fail if we're dividing by zero or taking
				 * a modulus by zero.
				 */
				if (op == BPF_ADD ||
				    op == BPF_LSH || op == BPF_RSH ||
				    op == BPF_OR || op == BPF_XOR) {
					s->code = NOP;
					break;
				}
				if (op == BPF_MUL || op == BPF_AND) {
					s->code = BPF_LD|BPF_IMM;
					val[A_ATOM] = K(s->k);
					break;
				}
				if (op == BPF_DIV)
					opt_error(opt_state,
					    "division by zero");
				if (op == BPF_MOD)
					opt_error(opt_state,
					    "modulus by zero");
			}
			if (opt_state->vmap[val[A_ATOM]].is_const) {
				fold_op(opt_state, s, val[A_ATOM], K(s->k));
				val[A_ATOM] = K(s->k);
				break;
			}
		}
		val[A_ATOM] = F(opt_state, s->code, val[A_ATOM], K(s->k));
		break;

	case BPF_ALU|BPF_ADD|BPF_X:
	case BPF_ALU|BPF_SUB|BPF_X:
	case BPF_ALU|BPF_MUL|BPF_X:
	case BPF_ALU|BPF_DIV|BPF_X:
	case BPF_ALU|BPF_MOD|BPF_X:
	case BPF_ALU|BPF_AND|BPF_X:
	case BPF_ALU|BPF_OR|BPF_X:
	case BPF_ALU|BPF_XOR|BPF_X:
	case BPF_ALU|BPF_LSH|BPF_X:
	case BPF_ALU|BPF_RSH|BPF_X:
		op = BPF_OP(s->code);
		if (alter && opt_state->vmap[val[X_ATOM]].is_const) {
			if (opt_state->vmap[val[A_ATOM]].is_const) {
				fold_op(opt_state, s, val[A_ATOM], val[X_ATOM]);
				val[A_ATOM] = K(s->k);
			}
			else {
				s->code = BPF_ALU|BPF_K|op;
				s->k = opt_state->vmap[val[X_ATOM]].const_val;
				if ((op == BPF_LSH || op == BPF_RSH) &&
				    s->k > 31)
					opt_error(opt_state,
					    "shift by more than 31 bits");
				/*
				 * XXX - optimizer loop detection.
				 */
				opt_state->non_branch_movement_performed = 1;
				opt_state->done = 0;
				val[A_ATOM] =
					F(opt_state, s->code, val[A_ATOM], K(s->k));
			}
			break;
		}
		/*
		 * Check if we're doing something to an accumulator
		 * 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, etc.
		 */
		if (alter && opt_state->vmap[val[A_ATOM]].is_const
		    && opt_state->vmap[val[A_ATOM]].const_val == 0) {
			if (op == BPF_ADD || op == BPF_OR || op == BPF_XOR) {
				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_MOD ||
				 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);
				break;
			}
			else if (op == BPF_NEG) {
				s->code = NOP;
				break;
			}
		}
		val[A_ATOM] = F(opt_state, s->code, val[A_ATOM], val[X_ATOM]);
		break;

	case BPF_MISC|BPF_TXA:
		vstore(s, &val[A_ATOM], val[X_ATOM], alter);
		break;

	case BPF_LD|BPF_MEM:
		v = val[s->k];
		if (alter && opt_state->vmap[v].is_const) {
			s->code = BPF_LD|BPF_IMM;
			s->k = opt_state->vmap[v].const_val;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		vstore(s, &val[A_ATOM], v, alter);
		break;

	case BPF_MISC|BPF_TAX:
		vstore(s, &val[X_ATOM], val[A_ATOM], alter);
		break;

	case BPF_LDX|BPF_MEM:
		v = val[s->k];
		if (alter && opt_state->vmap[v].is_const) {
			s->code = BPF_LDX|BPF_IMM;
			s->k = opt_state->vmap[v].const_val;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
		vstore(s, &val[X_ATOM], v, alter);
		break;

	case BPF_ST:
		vstore(s, &val[s->k], val[A_ATOM], alter);
		break;

	case BPF_STX:
		vstore(s, &val[s->k], val[X_ATOM], alter);
		break;
	}
}

static void
deadstmt(opt_state_t *opt_state, register struct stmt *s, register struct stmt *last[])
{
	register int atom;

	atom = atomuse(s);
	if (atom >= 0) {
		if (atom == AX_ATOM) {
			last[X_ATOM] = 0;
			last[A_ATOM] = 0;
		}
		else
			last[atom] = 0;
	}
	atom = atomdef(s);
	if (atom >= 0) {
		if (last[atom]) {
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
			last[atom]->code = NOP;
		}
		last[atom] = s;
	}
}

static void
opt_deadstores(opt_state_t *opt_state, register struct block *b)
{
	register struct slist *s;
	register int atom;
	struct stmt *last[N_ATOMS];

	memset((char *)last, 0, sizeof last);

	for (s = b->stmts; s != 0; s = s->next)
		deadstmt(opt_state, &s->s, last);
	deadstmt(opt_state, &b->s, last);

	for (atom = 0; atom < N_ATOMS; ++atom)
		if (last[atom] && !ATOMELEM(b->out_use, atom)) {
			last[atom]->code = NOP;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
}

static void
opt_blk(opt_state_t *opt_state, struct block *b, int do_stmts)
{
	struct slist *s;
	struct edge *p;
	int i;
	bpf_u_int32 aval, xval;

#if 0
	for (s = b->stmts; s && s->next; s = s->next)
		if (BPF_CLASS(s->s.code) == BPF_JMP) {
			do_stmts = 0;
			break;
		}
#endif

	/*
	 * Initialize the atom values.
	 */
	p = b->in_edges;
	if (p == 0) {
		/*
		 * We have no predecessors, so everything is undefined
		 * upon entry to this block.
		 */
		memset((char *)b->val, 0, sizeof(b->val));
	} else {
		/*
		 * Inherit values from our predecessors.
		 *
		 * First, get the values from the predecessor along the
		 * first edge leading to this node.
		 */
		memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
		/*
		 * Now look at all the other nodes leading to this node.
		 * If, for the predecessor along that edge, a register
		 * has a different value from the one we have (i.e.,
		 * control paths are merging, and the merging paths
		 * assign different values to that register), give the
		 * register the undefined value of 0.
		 */
		while ((p = p->next) != NULL) {
			for (i = 0; i < N_ATOMS; ++i)
				if (b->val[i] != p->pred->val[i])
					b->val[i] = 0;
		}
	}
	aval = b->val[A_ATOM];
	xval = b->val[X_ATOM];
	for (s = b->stmts; s; s = s->next)
		opt_stmt(opt_state, &s->s, b->val, do_stmts);

	/*
	 * This is a special case: if we don't use anything from this
	 * block, and we load the accumulator or index register with a
	 * value that is already there, or if this block is a return,
	 * eliminate all the statements.
	 *
	 * XXX - what if it does a store?  Presumably that falls under
	 * the heading of "if we don't use anything from this block",
	 * i.e., if we use any memory location set to a different
	 * value by this block, then we use something from this block.
	 *
	 * XXX - why does it matter whether we use anything from this
	 * block?  If the accumulator or index register doesn't change
	 * its value, isn't that OK even if we use that value?
	 *
	 * XXX - if we load the accumulator with a different value,
	 * and the block ends with a conditional branch, we obviously
	 * can't eliminate it, as the branch depends on that value.
	 * For the index register, the conditional branch only depends
	 * on the index register value if the test is against the index
	 * register value rather than a constant; if nothing uses the
	 * value we put into the index register, and we're not testing
	 * against the index register's value, and there aren't any
	 * other problems that would keep us from eliminating this
	 * block, can we eliminate it?
	 */
	if (do_stmts &&
	    ((b->out_use == 0 &&
	      aval != VAL_UNKNOWN && b->val[A_ATOM] == aval &&
	      xval != VAL_UNKNOWN && b->val[X_ATOM] == xval) ||
	     BPF_CLASS(b->s.code) == BPF_RET)) {
		if (b->stmts != 0) {
			b->stmts = 0;
			/*
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
		}
	} else {
		opt_peep(opt_state, b);
		opt_deadstores(opt_state, b);
	}
	/*
	 * Set up values for branch optimizer.
	 */
	if (BPF_SRC(b->s.code) == BPF_K)
		b->oval = K(b->s.k);
	else
		b->oval = b->val[X_ATOM];
	b->et.code = b->s.code;
	b->ef.code = -b->s.code;
}

/*
 * Return true if any register that is used on exit from 'succ', has
 * an exit value that is different from the corresponding exit value
 * from 'b'.
 */
static int
use_conflict(struct block *b, struct block *succ)
{
	int atom;
	atomset use = succ->out_use;

	if (use == 0)
		return 0;

	for (atom = 0; atom < N_ATOMS; ++atom)
		if (ATOMELEM(use, atom))
			if (b->val[atom] != succ->val[atom])
				return 1;
	return 0;
}

/*
 * Given a block that is the successor of an edge, and an edge that
 * dominates that edge, return either a pointer to a child of that
 * block (a block to which that block jumps) if that block is a
 * candidate to replace the successor of the latter edge or NULL
 * if neither of the children of the first block are candidates.
 */
static struct block *
fold_edge(struct block *child, struct edge *ep)
{
	int sense;
	bpf_u_int32 aval0, aval1, oval0, oval1;
	int code = ep->code;

	if (code < 0) {
		/*
		 * This edge is a "branch if false" edge.
		 */
		code = -code;
		sense = 0;
	} else {
		/*
		 * This edge is a "branch if true" edge.
		 */
		sense = 1;
	}

	/*
	 * If the opcode for the branch at the end of the block we
	 * were handed isn't the same as the opcode for the branch
	 * to which the edge we were handed corresponds, the tests
	 * for those branches aren't testing the same conditions,
	 * so the blocks to which the first block branches aren't
	 * candidates to replace the successor of the edge.
	 */
	if (child->s.code != code)
		return 0;

	aval0 = child->val[A_ATOM];
	oval0 = child->oval;
	aval1 = ep->pred->val[A_ATOM];
	oval1 = ep->pred->oval;

	/*
	 * If the A register value on exit from the successor block
	 * isn't the same as the A register value on exit from the
	 * predecessor of the edge, the blocks to which the first
	 * block branches aren't candidates to replace the successor
	 * of the edge.
	 */
	if (aval0 != aval1)
		return 0;

	if (oval0 == oval1)
		/*
		 * The operands of the branch instructions are
		 * identical, so the branches are testing the
		 * same condition, and the result is true if a true
		 * branch was taken to get here, otherwise false.
		 */
		return sense ? JT(child) : JF(child);

	if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
		/*
		 * At this point, we only know the comparison if we
		 * came down the true branch, and it was an equality
		 * comparison with a constant.
		 *
		 * I.e., if we came down the true branch, and the branch
		 * was an equality comparison with a constant, we know the
		 * accumulator contains that constant.  If we came down
		 * the false branch, or the comparison wasn't with a
		 * constant, we don't know what was in the accumulator.
		 *
		 * We rely on the fact that distinct constants have distinct
		 * value numbers.
		 */
		return JF(child);

	return 0;
}

/*
 * If we can make this edge go directly to a child of the edge's current
 * successor, do so.
 */
static void
opt_j(opt_state_t *opt_state, struct edge *ep)
{
	register u_int i, k;
	register struct block *target;

	/*
	 * Does this edge go to a block where, if the test
	 * at the end of it succeeds, it goes to a block
	 * that's a leaf node of the DAG, i.e. a return
	 * statement?
	 * If so, there's nothing to optimize.
	 */
	if (JT(ep->succ) == 0)
		return;

	/*
	 * Does this edge go to a block that goes, in turn, to
	 * the same block regardless of whether the test at the
	 * end succeeds or fails?
	 */
	if (JT(ep->succ) == JF(ep->succ)) {
		/*
		 * Common branch targets can be eliminated, provided
		 * there is no data dependency.
		 *
		 * Check whether any register used on exit from the
		 * block to which the successor of this edge goes
		 * has a value at that point that's different from
		 * the value it has on exit from the predecessor of
		 * this edge.  If not, the predecessor of this edge
		 * can just go to the block to which the successor
		 * of this edge goes, bypassing the successor of this
		 * edge, as the successor of this edge isn't doing
		 * any calculations whose results are different
		 * from what the blocks before it did and isn't
		 * doing any tests the results of which matter.
		 */
		if (!use_conflict(ep->pred, JT(ep->succ))) {
			/*
			 * No, there isn't.
			 * Make this edge go to the block to
			 * which the successor of that edge
			 * goes.
			 *
			 * XXX - optimizer loop detection.
			 */
			opt_state->non_branch_movement_performed = 1;
			opt_state->done = 0;
			ep->succ = JT(ep->succ);
		}
	}
	/*
	 * For each edge dominator that matches the successor of this
	 * edge, promote the edge successor to the its grandchild.
	 *
	 * XXX We violate the set abstraction here in favor a reasonably
	 * efficient loop.
	 */
 top:
	for (i = 0; i < opt_state->edgewords; ++i) {
		/* i'th word in the bitset of dominators */
		register bpf_u_int32 x = ep->edom[i];

		while (x != 0) {
			/* Find the next dominator in that word and mark it as found */
			k = lowest_set_bit(x);
			x &=~ ((bpf_u_int32)1 << k);
			k += i * BITS_PER_WORD;

			target = fold_edge(ep->succ, opt_state->edges[k]);
			/*
			 * We have a candidate to replace the successor
			 * of ep.
			 *
			 * Check that there is no data dependency between
			 * nodes that will be violated if we move the edge;
			 * i.e., if any register used on exit from the
			 * candidate has a value at that point different
			 * from the value it has when we exit the
			 * predecessor of that edge, there's a data
			 * dependency that will be violated.
			 */
			if (target != 0 && !use_conflict(ep->pred, target)) {
				/*
				 * It's safe to replace the successor of
				 * ep; do so, and note that we've made
				 * at least one change.
				 *
				 * XXX - this is one of the operations that
				 * happens when the optimizer gets into
				 * one of those infinite loops.
				 */
				opt_state->done = 0;
				ep->succ = target;
				if (JT(target) != 0)
					/*
					 * Start over unless we hit a leaf.
					 */
					goto top;
				return;
			}
		}
	}
}

/*
 * XXX - is this, and and_pullup(), what's described in section 6.1.2
 * "Predicate Assertion Propagation" in the BPF+ paper?
 *
 * Note that this looks at block dominators, not edge dominators.
 * Don't think so.
 *
 * "A or B" compiles into
 *
 *          A
 *       t / \ f
 *        /   B
 *       / t / \ f
 *      \   /
 *       \ /
 *        X
 *
 *
 */
static void
or_pullup(opt_state_t *opt_state, struct block *b)
{
	bpf_u_int32 val;
	int at_top;
	struct block *pull;
	struct block **diffp, **samep;
	struct edge *ep;

	ep = b->in_edges;
	if (ep == 0)
		return;

	/*
	 * Make sure each predecessor loads the same value.
	 * XXX why?
	 */
	val = ep->pred->val[A_ATOM];
	for (ep = ep->next; ep != 0; ep = ep->next)
		if (val != ep->pred->val[A_ATOM])
			return;

	/*
	 * For the first edge in the list of edges coming into this block,
	 * see whether the predecessor of that edge comes here via a true
	 * branch or a false branch.
	 */
	if (JT(b->in_edges->pred) == b)
		diffp = &JT(b->in_edges->pred);	/* jt */
	else
		diffp = &JF(b->in_edges->pred);	/* jf */

	/*
	 * diffp is a pointer to a pointer to the block.
	 *
	 * Go down the false chain looking as far as you can,
	 * making sure that each jump-compare is doing the
	 * same as the original block.
	 *
	 * If you reach the bottom before you reach a
	 * different jump-compare, just exit.  There's nothing
	 * to do here.  XXX - no, this version is checking for
	 * the value leaving the block; that's from the BPF+
	 * pullup routine.
	 */
	at_top = 1;
	for (;;) {
		/*
		 * Done if that's not going anywhere XXX
		 */
		if (*diffp == 0)
			return;

		/*
		 * Done if that predecessor blah blah blah isn't
		 * going the same place we're going XXX
		 *
		 * Does the true edge of this block point to the same
		 * location as the true edge of b?
		 */
		if (JT(*diffp) != JT(b))
			return;

		/*
		 * Done if this node isn't a dominator of that
		 * node blah blah blah XXX
		 *
		 * Does b dominate diffp?
		 */
		if (!SET_MEMBER((*diffp)->dom, b->id))
			return;

		/*
		 * Break out of the loop if that node's value of A
		 * isn't the value of A above XXX
		 */
		if ((*diffp)->val[A_ATOM] != val)
			break;

		/*
		 * Get the JF for that node XXX
		 * Go down the false path.
		 */
		diffp = &JF(*diffp);
		at_top = 0;
	}

	/*
	 * Now that we've found a different jump-compare in a chain
	 * below b, search further down until we find another
	 * jump-compare that looks at the original value.  This
	 * jump-compare should get pulled up.  XXX again we're
	 * comparing values not jump-compares.
	 */
	samep = &JF(*diffp);
	for (;;) {
		/*
		 * Done if that's not going anywhere XXX
		 */
		if (*samep == 0)
			return;

		/*
		 * Done if that predecessor blah blah blah isn't
		 * going the same place we're going XXX
		 */
		if (JT(*samep) != JT(b))
			return;

		/*
		 * Done if this node isn't a dominator of that
		 * node blah blah blah XXX
		 *
		 * Does b dominate samep?
		 */
		if (!SET_MEMBER((*samep)->dom, b->id))
			return;

		/*
		 * Break out of the loop if that node's value of A
		 * is the value of A above XXX
		 */
		if ((*samep)->val[A_ATOM] == val)
			break;

		/* XXX Need to check that there are no data dependencies
		   between dp0 and dp1.  Currently, the code generator
		   will not produce such dependencies. */
		samep = &JF(*samep);
	}
#ifdef notdef
	/* XXX This doesn't cover everything. */
	for (i = 0; i < N_ATOMS; ++i)
		if ((*samep)->val[i] != pred->val[i])
			return;
#endif
	/* Pull up the node. */
	pull = *samep;
	*samep = JF(pull);
	JF(pull) = *diffp;

	/*
	 * At the top of the chain, each predecessor needs to point at the
	 * pulled up node.  Inside the chain, there is only one predecessor
	 * to worry about.
	 */
	if (at_top) {
		for (ep = b->in_edges; ep != 0; ep = ep->next) {
			if (JT(ep->pred) == b)
				JT(ep->pred) = pull;
			else
				JF(ep->pred) = pull;
		}
	}
	else
		*diffp = pull;

	/*
	 * XXX - this is one of the operations that happens when the
	 * optimizer gets into one of those infinite loops.
	 */
	opt_state->done = 0;
}

static void
and_pullup(opt_state_t *opt_state, struct block *b)
{
	bpf_u_int32 val;
	int at_top;
	struct block *pull;
	struct block **diffp, **samep;
	struct edge *ep;

	ep = b->in_edges;
	if (ep == 0)
		return;

	/*
	 * Make sure each predecessor loads the same value.
	 */
	val = ep->pred->val[A_ATOM];
	for (ep = ep->next; ep != 0; ep = ep->next)
		if (val != ep->pred->val[A_ATOM])
			return;

	if (JT(b->in_edges->pred) == b)
		diffp = &JT(b->in_edges->pred);
	else
		diffp = &JF(b->in_edges->pred);

	at_top = 1;
	for (;;) {
		if (*diffp == 0)
			return;

		if (JF(*diffp) != JF(b))
			return;

		if (!SET_MEMBER((*diffp)->dom, b->id))
			return;

		if ((*diffp)->val[A_ATOM] != val)
			break;

		diffp = &JT(*diffp);
		at_top = 0;
	}
	samep = &JT(*diffp);
	for (;;) {
		if (*samep == 0)
			return;

		if (JF(*samep) != JF(b))
			return;

		if (!SET_MEMBER((*samep)->dom, b->id))
			return;

		if ((*samep)->val[A_ATOM] == val)
			break;

		/* XXX Need to check that there are no data dependencies
		   between diffp and samep.  Currently, the code generator
		   will not produce such dependencies. */
		samep = &JT(*samep);
	}
#ifdef notdef
	/* XXX This doesn't cover everything. */
	for (i = 0; i < N_ATOMS; ++i)
		if ((*samep)->val[i] != pred->val[i])
			return;
#endif
	/* Pull up the node. */
	pull = *samep;
	*samep = JT(pull);
	JT(pull) = *diffp;

	/*
	 * At the top of the chain, each predecessor needs to point at the
	 * pulled up node.  Inside the chain, there is only one predecessor
	 * to worry about.
	 */
	if (at_top) {
		for (ep = b->in_edges; ep != 0; ep = ep->next) {
			if (JT(ep->pred) == b)
				JT(ep->pred) = pull;
			else
				JF(ep->pred) = pull;
		}
	}
	else
		*diffp = pull;

	/*
	 * XXX - this is one of the operations that happens when the
	 * optimizer gets into one of those infinite loops.
	 */
	opt_state->done = 0;
}

static void
opt_blks(opt_state_t *opt_state, struct icode *ic, int do_stmts)
{
	int i, maxlevel;
	struct block *p;

	init_val(opt_state);
	maxlevel = ic->root->level;

	find_inedges(opt_state, ic->root);
	for (i = maxlevel; i >= 0; --i)
		for (p = opt_state->levels[i]; p; p = p->link)
			opt_blk(opt_state, p, do_stmts);

	if (do_stmts)
		/*
		 * No point trying to move branches; it can't possibly
		 * make a difference at this point.
		 *
		 * XXX - this might be after we detect a loop where
		 * we were just looping infinitely moving branches
		 * in such a fashion that we went through two or more
		 * versions of the machine code, eventually returning
		 * to the first version.  (We're really not doing a
		 * full loop detection, we're just testing for two
		 * passes in a row where where we do nothing but
		 * move branches.)
		 */
		return;

	/*
	 * Is this what the BPF+ paper describes in sections 6.1.1,
	 * 6.1.2, and 6.1.3?
	 */
	for (i = 1; i <= maxlevel; ++i) {
		for (p = opt_state->levels[i]; p; p = p->link) {
			opt_j(opt_state, &p->et);
			opt_j(opt_state, &p->ef);
		}
	}

	find_inedges(opt_state, ic->root);
	for (i = 1; i <= maxlevel; ++i) {
		for (p = opt_state->levels[i]; p; p = p->link) {
			or_pullup(opt_state, p);
			and_pullup(opt_state, p);
		}
	}
}

static inline void
link_inedge(struct edge *parent, struct block *child)
{
	parent->next = child->in_edges;
	child->in_edges = parent;
}

static void
find_inedges(opt_state_t *opt_state, struct block *root)
{
	u_int i;
	int level;
	struct block *b;

	for (i = 0; i < opt_state->n_blocks; ++i)
		opt_state->blocks[i]->in_edges = 0;

	/*
	 * Traverse the graph, adding each edge to the predecessor
	 * list of its successors.  Skip the leaves (i.e. level 0).
	 */
	for (level = root->level; level > 0; --level) {
		for (b = opt_state->levels[level]; b != 0; b = b->link) {
			link_inedge(&b->et, JT(b));
			link_inedge(&b->ef, JF(b));
		}
	}
}

static void
opt_root(struct block **b)
{
	struct slist *tmp, *s;

	s = (*b)->stmts;
	(*b)->stmts = 0;
	while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
		*b = JT(*b);

	tmp = (*b)->stmts;
	if (tmp != 0)
		sappend(s, tmp);
	(*b)->stmts = s;

	/*
	 * If the root node is a return, then there is no
	 * point executing any statements (since the bpf machine
	 * has no side effects).
	 */
	if (BPF_CLASS((*b)->s.code) == BPF_RET)
		(*b)->stmts = 0;
}

static void
opt_loop(opt_state_t *opt_state, struct icode *ic, int do_stmts)
{

#ifdef BDEBUG
	if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
		printf("opt_loop(root, %d) begin\n", do_stmts);
		opt_dump(opt_state, ic);
	}
#endif

	/*
	 * XXX - optimizer loop detection.
	 */
	int loop_count = 0;
	for (;;) {
		opt_state->done = 1;
		/*
		 * XXX - optimizer loop detection.
		 */
		opt_state->non_branch_movement_performed = 0;
		find_levels(opt_state, ic);
		find_dom(opt_state, ic->root);
		find_closure(opt_state, ic->root);
		find_ud(opt_state, ic->root);
		find_edom(opt_state, ic->root);
		opt_blks(opt_state, ic, do_stmts);
#ifdef BDEBUG
		if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
			printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
			opt_dump(opt_state, ic);
		}
#endif

		/*
		 * Was anything done in this optimizer pass?
		 */
		if (opt_state->done) {
			/*
			 * No, so we've reached a fixed point.
			 * We're done.
			 */
			break;
		}

		/*
		 * XXX - was anything done other than branch movement
		 * in this pass?
		 */
		if (opt_state->non_branch_movement_performed) {
			/*
			 * Yes.  Clear any loop-detection counter;
			 * we're making some form of progress (assuming
			 * we can't get into a cycle doing *other*
			 * optimizations...).
			 */
			loop_count = 0;
		} else {
			/*
			 * No - increment the counter, and quit if
			 * it's up to 100.
			 */
			loop_count++;
			if (loop_count >= 100) {
				/*
				 * We've done nothing but branch movement
				 * for 100 passes; we're probably
				 * in a cycle and will never reach a
				 * fixed point.
				 *
				 * XXX - yes, we really need a non-
				 * heuristic way of detecting a cycle.
				 */
				opt_state->done = 1;
				break;
			}
		}
	}
}

/*
 * Optimize the filter code in its dag representation.
 * Return 0 on success, -1 on error.
 */
int
bpf_optimize(struct icode *ic, char *errbuf)
{
	opt_state_t opt_state;

	memset(&opt_state, 0, sizeof(opt_state));
	opt_state.errbuf = errbuf;
	opt_state.non_branch_movement_performed = 0;
	if (setjmp(opt_state.top_ctx)) {
		opt_cleanup(&opt_state);
		return -1;
	}
	opt_init(&opt_state, ic);
	opt_loop(&opt_state, ic, 0);
	opt_loop(&opt_state, ic, 1);
	intern_blocks(&opt_state, ic);
#ifdef BDEBUG
	if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
		printf("after intern_blocks()\n");
		opt_dump(&opt_state, ic);
	}
#endif
	opt_root(&ic->root);
#ifdef BDEBUG
	if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
		printf("after opt_root()\n");
		opt_dump(&opt_state, ic);
	}
#endif
	opt_cleanup(&opt_state);
	return 0;
}

static void
make_marks(struct icode *ic, struct block *p)
{
	if (!isMarked(ic, p)) {
		Mark(ic, p);
		if (BPF_CLASS(p->s.code) != BPF_RET) {
			make_marks(ic, JT(p));
			make_marks(ic, JF(p));
		}
	}
}

/*
 * Mark code array such that isMarked(ic->cur_mark, i) is true
 * only for nodes that are alive.
 */
static void
mark_code(struct icode *ic)
{
	ic->cur_mark += 1;
	make_marks(ic, ic->root);
}

/*
 * True iff the two stmt lists load the same value from the packet into
 * the accumulator.
 */
static int
eq_slist(struct slist *x, struct slist *y)
{
	for (;;) {
		while (x && x->s.code == NOP)
			x = x->next;
		while (y && y->s.code == NOP)
			y = y->next;
		if (x == 0)
			return y == 0;
		if (y == 0)
			return x == 0;
		if (x->s.code != y->s.code || x->s.k != y->s.k)
			return 0;
		x = x->next;
		y = y->next;
	}
}

static inline int
eq_blk(struct block *b0, struct block *b1)
{
	if (b0->s.code == b1->s.code &&
	    b0->s.k == b1->s.k &&
	    b0->et.succ == b1->et.succ &&
	    b0->ef.succ == b1->ef.succ)
		return eq_slist(b0->stmts, b1->stmts);
	return 0;
}

static void
intern_blocks(opt_state_t *opt_state, struct icode *ic)
{
	struct block *p;
	u_int i, j;
	int done1; /* don't shadow global */
 top:
	done1 = 1;
	for (i = 0; i < opt_state->n_blocks; ++i)
		opt_state->blocks[i]->link = 0;

	mark_code(ic);

	for (i = opt_state->n_blocks - 1; i != 0; ) {
		--i;
		if (!isMarked(ic, opt_state->blocks[i]))
			continue;
		for (j = i + 1; j < opt_state->n_blocks; ++j) {
			if (!isMarked(ic, opt_state->blocks[j]))
				continue;
			if (eq_blk(opt_state->blocks[i], opt_state->blocks[j])) {
				opt_state->blocks[i]->link = opt_state->blocks[j]->link ?
					opt_state->blocks[j]->link : opt_state->blocks[j];
				break;
			}
		}
	}
	for (i = 0; i < opt_state->n_blocks; ++i) {
		p = opt_state->blocks[i];
		if (JT(p) == 0)
			continue;
		if (JT(p)->link) {
			done1 = 0;
			JT(p) = JT(p)->link;
		}
		if (JF(p)->link) {
			done1 = 0;
			JF(p) = JF(p)->link;
		}
	}
	if (!done1)
		goto top;
}

static void
opt_cleanup(opt_state_t *opt_state)
{
	free((void *)opt_state->vnode_base);
	free((void *)opt_state->vmap);
	free((void *)opt_state->edges);
	free((void *)opt_state->space);
	free((void *)opt_state->levels);
	free((void *)opt_state->blocks);
}

/*
 * For optimizer errors.
 */
static void PCAP_NORETURN
opt_error(opt_state_t *opt_state, const char *fmt, ...)
{
	va_list ap;

	if (opt_state->errbuf != NULL) {
		va_start(ap, fmt);
		(void)vsnprintf(opt_state->errbuf,
		    PCAP_ERRBUF_SIZE, fmt, ap);
		va_end(ap);
	}
	longjmp(opt_state->top_ctx, 1);
	/* NOTREACHED */
}

/*
 * Return the number of stmts in 's'.
 */
static u_int
slength(struct slist *s)
{
	u_int n = 0;

	for (; s; s = s->next)
		if (s->s.code != NOP)
			++n;
	return n;
}

/*
 * Return the number of nodes reachable by 'p'.
 * All nodes should be initially unmarked.
 */
static int
count_blocks(struct icode *ic, struct block *p)
{
	if (p == 0 || isMarked(ic, p))
		return 0;
	Mark(ic, p);
	return count_blocks(ic, JT(p)) + count_blocks(ic, JF(p)) + 1;
}

/*
 * Do a depth first search on the flow graph, numbering the
 * the basic blocks, and entering them into the 'blocks' array.`
 */
static void
number_blks_r(opt_state_t *opt_state, struct icode *ic, struct block *p)
{
	u_int n;

	if (p == 0 || isMarked(ic, p))
		return;

	Mark(ic, p);
	n = opt_state->n_blocks++;
	if (opt_state->n_blocks == 0) {
		/*
		 * Overflow.
		 */
		opt_error(opt_state, "filter is too complex to optimize");
	}
	p->id = n;
	opt_state->blocks[n] = p;

	number_blks_r(opt_state, ic, JT(p));
	number_blks_r(opt_state, ic, JF(p));
}

/*
 * Return the number of stmts in the flowgraph reachable by 'p'.
 * The nodes should be unmarked before calling.
 *
 * Note that "stmts" means "instructions", and that this includes
 *
 *	side-effect statements in 'p' (slength(p->stmts));
 *
 *	statements in the true branch from 'p' (count_stmts(JT(p)));
 *
 *	statements in the false branch from 'p' (count_stmts(JF(p)));
 *
 *	the conditional jump itself (1);
 *
 *	an extra long jump if the true branch requires it (p->longjt);
 *
 *	an extra long jump if the false branch requires it (p->longjf).
 */
static u_int
count_stmts(struct icode *ic, struct block *p)
{
	u_int n;

	if (p == 0 || isMarked(ic, p))
		return 0;
	Mark(ic, p);
	n = count_stmts(ic, JT(p)) + count_stmts(ic, JF(p));
	return slength(p->stmts) + n + 1 + p->longjt + p->longjf;
}

/*
 * Allocate memory.  All allocation is done before optimization
 * is begun.  A linear bound on the size of all data structures is computed
 * from the total number of blocks and/or statements.
 */
static void
opt_init(opt_state_t *opt_state, struct icode *ic)
{
	bpf_u_int32 *p;
	int i, n, max_stmts;
	u_int product;
	size_t block_memsize, edge_memsize;

	/*
	 * First, count the blocks, so we can malloc an array to map
	 * block number to block.  Then, put the blocks into the array.
	 */
	unMarkAll(ic);
	n = count_blocks(ic, ic->root);
	opt_state->blocks = (struct block **)calloc(n, sizeof(*opt_state->blocks));
	if (opt_state->blocks == NULL)
		opt_error(opt_state, "malloc");
	unMarkAll(ic);
	opt_state->n_blocks = 0;
	number_blks_r(opt_state, ic, ic->root);

	/*
	 * This "should not happen".
	 */
	if (opt_state->n_blocks == 0)
		opt_error(opt_state, "filter has no instructions; please report this as a libpcap issue");

	opt_state->n_edges = 2 * opt_state->n_blocks;
	if ((opt_state->n_edges / 2) != opt_state->n_blocks) {
		/*
		 * Overflow.
		 */
		opt_error(opt_state, "filter is too complex to optimize");
	}
	opt_state->edges = (struct edge **)calloc(opt_state->n_edges, sizeof(*opt_state->edges));
	if (opt_state->edges == NULL) {
		opt_error(opt_state, "malloc");
	}

	/*
	 * The number of levels is bounded by the number of nodes.
	 */
	opt_state->levels = (struct block **)calloc(opt_state->n_blocks, sizeof(*opt_state->levels));
	if (opt_state->levels == NULL) {
		opt_error(opt_state, "malloc");
	}

	opt_state->edgewords = opt_state->n_edges / BITS_PER_WORD + 1;
	opt_state->nodewords = opt_state->n_blocks / BITS_PER_WORD + 1;

	/*
	 * Make sure opt_state->n_blocks * opt_state->nodewords fits
	 * in a u_int; we use it as a u_int number-of-iterations
	 * value.
	 */
	product = opt_state->n_blocks * opt_state->nodewords;
	if ((product / opt_state->n_blocks) != opt_state->nodewords) {
		/*
		 * XXX - just punt and don't try to optimize?
		 * In practice, this is unlikely to happen with
		 * a normal filter.
		 */
		opt_error(opt_state, "filter is too complex to optimize");
	}

	/*
	 * Make sure the total memory required for that doesn't
	 * overflow.
	 */
	block_memsize = (size_t)2 * product * sizeof(*opt_state->space);
	if ((block_memsize / product) != 2 * sizeof(*opt_state->space)) {
		opt_error(opt_state, "filter is too complex to optimize");
	}

	/*
	 * Make sure opt_state->n_edges * opt_state->edgewords fits
	 * in a u_int; we use it as a u_int number-of-iterations
	 * value.
	 */
	product = opt_state->n_edges * opt_state->edgewords;
	if ((product / opt_state->n_edges) != opt_state->edgewords) {
		opt_error(opt_state, "filter is too complex to optimize");
	}

	/*
	 * Make sure the total memory required for that doesn't
	 * overflow.
	 */
	edge_memsize = (size_t)product * sizeof(*opt_state->space);
	if (edge_memsize / product != sizeof(*opt_state->space)) {
		opt_error(opt_state, "filter is too complex to optimize");
	}

	/*
	 * Make sure the total memory required for both of them dosn't
	 * overflow.
	 */
	if (block_memsize > SIZE_MAX - edge_memsize) {
		opt_error(opt_state, "filter is too complex to optimize");
	}

	/* XXX */
	opt_state->space = (bpf_u_int32 *)malloc(block_memsize + edge_memsize);
	if (opt_state->space == NULL) {
		opt_error(opt_state, "malloc");
	}
	p = opt_state->space;
	opt_state->all_dom_sets = p;
	for (i = 0; i < n; ++i) {
		opt_state->blocks[i]->dom = p;
		p += opt_state->nodewords;
	}
	opt_state->all_closure_sets = p;
	for (i = 0; i < n; ++i) {
		opt_state->blocks[i]->closure = p;
		p += opt_state->nodewords;
	}
	opt_state->all_edge_sets = p;
	for (i = 0; i < n; ++i) {
		register struct block *b = opt_state->blocks[i];

		b->et.edom = p;
		p += opt_state->edgewords;
		b->ef.edom = p;
		p += opt_state->edgewords;
		b->et.id = i;
		opt_state->edges[i] = &b->et;
		b->ef.id = opt_state->n_blocks + i;
		opt_state->edges[opt_state->n_blocks + i] = &b->ef;
		b->et.pred = b;
		b->ef.pred = b;
	}
	max_stmts = 0;
	for (i = 0; i < n; ++i)
		max_stmts += slength(opt_state->blocks[i]->stmts) + 1;
	/*
	 * We allocate at most 3 value numbers per statement,
	 * so this is an upper bound on the number of valnodes
	 * we'll need.
	 */
	opt_state->maxval = 3 * max_stmts;
	opt_state->vmap = (struct vmapinfo *)calloc(opt_state->maxval, sizeof(*opt_state->vmap));
	if (opt_state->vmap == NULL) {
		opt_error(opt_state, "malloc");
	}
	opt_state->vnode_base = (struct valnode *)calloc(opt_state->maxval, sizeof(*opt_state->vnode_base));
	if (opt_state->vnode_base == NULL) {
		opt_error(opt_state, "malloc");
	}
}

/*
 * This is only used when supporting optimizer debugging.  It is
 * global state, so do *not* do more than one compile in parallel
 * and expect it to provide meaningful information.
 */
#ifdef BDEBUG
int bids[NBIDS];
#endif

static void PCAP_NORETURN conv_error(conv_state_t *, const char *, ...)
    PCAP_PRINTFLIKE(2, 3);

/*
 * Returns true if successful.  Returns false if a branch has
 * an offset that is too large.  If so, we have marked that
 * branch so that on a subsequent iteration, it will be treated
 * properly.
 */
static int
convert_code_r(conv_state_t *conv_state, struct icode *ic, struct block *p)
{
	struct bpf_insn *dst;
	struct slist *src;
	u_int slen;
	u_int off;
	struct slist **offset = NULL;

	if (p == 0 || isMarked(ic, p))
		return (1);
	Mark(ic, p);

	if (convert_code_r(conv_state, ic, JF(p)) == 0)
		return (0);
	if (convert_code_r(conv_state, ic, JT(p)) == 0)
		return (0);

	slen = slength(p->stmts);
	dst = conv_state->ftail -= (slen + 1 + p->longjt + p->longjf);
		/* inflate length by any extra jumps */

	p->offset = (int)(dst - conv_state->fstart);

	/* generate offset[] for convenience  */
	if (slen) {
		offset = (struct slist **)calloc(slen, sizeof(struct slist *));
		if (!offset) {
			conv_error(conv_state, "not enough core");
			/*NOTREACHED*/
		}
	}
	src = p->stmts;
	for (off = 0; off < slen && src; off++) {
#if 0
		printf("off=%d src=%x\n", off, src);
#endif
		offset[off] = src;
		src = src->next;
	}

	off = 0;
	for (src = p->stmts; src; src = src->next) {
		if (src->s.code == NOP)
			continue;
		dst->code = (u_short)src->s.code;
		dst->k = src->s.k;

		/* fill block-local relative jump */
		if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
#if 0
			if (src->s.jt || src->s.jf) {
				free(offset);
				conv_error(conv_state, "illegal jmp destination");
				/*NOTREACHED*/
			}
#endif
			goto filled;
		}
		if (off == slen - 2)	/*???*/
			goto filled;

	    {
		u_int i;
		int jt, jf;
		const char ljerr[] = "%s for block-local relative jump: off=%d";

#if 0
		printf("code=%x off=%d %x %x\n", src->s.code,
			off, src->s.jt, src->s.jf);
#endif

		if (!src->s.jt || !src->s.jf) {
			free(offset);
			conv_error(conv_state, ljerr, "no jmp destination", off);
			/*NOTREACHED*/
		}

		jt = jf = 0;
		for (i = 0; i < slen; i++) {
			if (offset[i] == src->s.jt) {
				if (jt) {
					free(offset);
					conv_error(conv_state, ljerr, "multiple matches", off);
					/*NOTREACHED*/
				}

				if (i - off - 1 >= 256) {
					free(offset);
					conv_error(conv_state, ljerr, "out-of-range jump", off);
					/*NOTREACHED*/
				}
				dst->jt = (u_char)(i - off - 1);
				jt++;
			}
			if (offset[i] == src->s.jf) {
				if (jf) {
					free(offset);
					conv_error(conv_state, ljerr, "multiple matches", off);
					/*NOTREACHED*/
				}
				if (i - off - 1 >= 256) {
					free(offset);
					conv_error(conv_state, ljerr, "out-of-range jump", off);
					/*NOTREACHED*/
				}
				dst->jf = (u_char)(i - off - 1);
				jf++;
			}
		}
		if (!jt || !jf) {
			free(offset);
			conv_error(conv_state, ljerr, "no destination found", off);
			/*NOTREACHED*/
		}
	    }
filled:
		++dst;
		++off;
	}
	if (offset)
		free(offset);

#ifdef BDEBUG
	if (dst - conv_state->fstart < NBIDS)
		bids[dst - conv_state->fstart] = p->id + 1;
#endif
	dst->code = (u_short)p->s.code;
	dst->k = p->s.k;
	if (JT(p)) {
		/* number of extra jumps inserted */
		u_char extrajmps = 0;
		off = JT(p)->offset - (p->offset + slen) - 1;
		if (off >= 256) {
		    /* offset too large for branch, must add a jump */
		    if (p->longjt == 0) {
			/* mark this instruction and retry */
			p->longjt++;
			return(0);
		    }
		    dst->jt = extrajmps;
		    extrajmps++;
		    dst[extrajmps].code = BPF_JMP|BPF_JA;
		    dst[extrajmps].k = off - extrajmps;
		}
		else
		    dst->jt = (u_char)off;
		off = JF(p)->offset - (p->offset + slen) - 1;
		if (off >= 256) {
		    /* offset too large for branch, must add a jump */
		    if (p->longjf == 0) {
			/* mark this instruction and retry */
			p->longjf++;
			return(0);
		    }
		    /* branch if F to following jump */
		    /* if two jumps are inserted, F goes to second one */
		    dst->jf = extrajmps;
		    extrajmps++;
		    dst[extrajmps].code = BPF_JMP|BPF_JA;
		    dst[extrajmps].k = off - extrajmps;
		}
		else
		    dst->jf = (u_char)off;
	}
	return (1);
}


/*
 * Convert flowgraph intermediate representation to the
 * BPF array representation.  Set *lenp to the number of instructions.
 *
 * This routine does *NOT* leak the memory pointed to by fp.  It *must
 * not* do free(fp) before returning fp; doing so would make no sense,
 * as the BPF array pointed to by the return value of icode_to_fcode()
 * must be valid - it's being returned for use in a bpf_program structure.
 *
 * If it appears that icode_to_fcode() is leaking, the problem is that
 * the program using pcap_compile() is failing to free the memory in
 * the BPF program when it's done - the leak is in the program, not in
 * the routine that happens to be allocating the memory.  (By analogy, if
 * a program calls fopen() without ever calling fclose() on the FILE *,
 * it will leak the FILE structure; the leak is not in fopen(), it's in
 * the program.)  Change the program to use pcap_freecode() when it's
 * done with the filter program.  See the pcap man page.
 */
struct bpf_insn *
icode_to_fcode(struct icode *ic, struct block *root, u_int *lenp,
    char *errbuf)
{
	u_int n;
	struct bpf_insn *fp;
	conv_state_t conv_state;

	conv_state.fstart = NULL;
	conv_state.errbuf = errbuf;
	if (setjmp(conv_state.top_ctx) != 0) {
		free(conv_state.fstart);
		return NULL;
	}

	/*
	 * Loop doing convert_code_r() until no branches remain
	 * with too-large offsets.
	 */
	for (;;) {
	    unMarkAll(ic);
	    n = *lenp = count_stmts(ic, root);

	    fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
	    if (fp == NULL) {
		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
		    "malloc");
		free(fp);
		return NULL;
	    }
	    memset((char *)fp, 0, sizeof(*fp) * n);
	    conv_state.fstart = fp;
	    conv_state.ftail = fp + n;

	    unMarkAll(ic);
	    if (convert_code_r(&conv_state, ic, root))
		break;
	    free(fp);
	}

	return fp;
}

/*
 * For iconv_to_fconv() errors.
 */
static void PCAP_NORETURN
conv_error(conv_state_t *conv_state, const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	(void)vsnprintf(conv_state->errbuf,
	    PCAP_ERRBUF_SIZE, fmt, ap);
	va_end(ap);
	longjmp(conv_state->top_ctx, 1);
	/* NOTREACHED */
}

/*
 * Make a copy of a BPF program and put it in the "fcode" member of
 * a "pcap_t".
 *
 * If we fail to allocate memory for the copy, fill in the "errbuf"
 * member of the "pcap_t" with an error message, and return -1;
 * otherwise, return 0.
 */
int
install_bpf_program(pcap_t *p, struct bpf_program *fp)
{
	size_t prog_size;

	/*
	 * Validate the program.
	 */
	if (!pcap_validate_filter(fp->bf_insns, fp->bf_len)) {
		snprintf(p->errbuf, sizeof(p->errbuf),
			"BPF program is not valid");
		return (-1);
	}

	/*
	 * Free up any already installed program.
	 */
	pcap_freecode(&p->fcode);

	prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
	p->fcode.bf_len = fp->bf_len;
	p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
	if (p->fcode.bf_insns == NULL) {
		pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
		    errno, "malloc");
		return (-1);
	}
	memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
	return (0);
}

#ifdef BDEBUG
static void
dot_dump_node(struct icode *ic, struct block *block, struct bpf_program *prog,
    FILE *out)
{
	int icount, noffset;
	int i;

	if (block == NULL || isMarked(ic, block))
		return;
	Mark(ic, block);

	icount = slength(block->stmts) + 1 + block->longjt + block->longjf;
	noffset = min(block->offset + icount, (int)prog->bf_len);

	fprintf(out, "\tblock%u [shape=ellipse, id=\"block-%u\" label=\"BLOCK%u\\n", block->id, block->id, block->id);
	for (i = block->offset; i < noffset; i++) {
		fprintf(out, "\\n%s", bpf_image(prog->bf_insns + i, i));
	}
	fprintf(out, "\" tooltip=\"");
	for (i = 0; i < BPF_MEMWORDS; i++)
		if (block->val[i] != VAL_UNKNOWN)
			fprintf(out, "val[%d]=%d ", i, block->val[i]);
	fprintf(out, "val[A]=%d ", block->val[A_ATOM]);
	fprintf(out, "val[X]=%d", block->val[X_ATOM]);
	fprintf(out, "\"");
	if (JT(block) == NULL)
		fprintf(out, ", peripheries=2");
	fprintf(out, "];\n");

	dot_dump_node(ic, JT(block), prog, out);
	dot_dump_node(ic, JF(block), prog, out);
}

static void
dot_dump_edge(struct icode *ic, struct block *block, FILE *out)
{
	if (block == NULL || isMarked(ic, block))
		return;
	Mark(ic, block);

	if (JT(block)) {
		fprintf(out, "\t\"block%u\":se -> \"block%u\":n [label=\"T\"]; \n",
				block->id, JT(block)->id);
		fprintf(out, "\t\"block%u\":sw -> \"block%u\":n [label=\"F\"]; \n",
			   block->id, JF(block)->id);
	}
	dot_dump_edge(ic, JT(block), out);
	dot_dump_edge(ic, JF(block), out);
}

/* Output the block CFG using graphviz/DOT language
 * In the CFG, block's code, value index for each registers at EXIT,
 * and the jump relationship is show.
 *
 * example DOT for BPF `ip src host 1.1.1.1' is:
    digraph BPF {
    	block0 [shape=ellipse, id="block-0" label="BLOCK0\n\n(000) ldh      [12]\n(001) jeq      #0x800           jt 2	jf 5" tooltip="val[A]=0 val[X]=0"];
    	block1 [shape=ellipse, id="block-1" label="BLOCK1\n\n(002) ld       [26]\n(003) jeq      #0x1010101       jt 4	jf 5" tooltip="val[A]=0 val[X]=0"];
    	block2 [shape=ellipse, id="block-2" label="BLOCK2\n\n(004) ret      #68" tooltip="val[A]=0 val[X]=0", peripheries=2];
    	block3 [shape=ellipse, id="block-3" label="BLOCK3\n\n(005) ret      #0" tooltip="val[A]=0 val[X]=0", peripheries=2];
    	"block0":se -> "block1":n [label="T"];
    	"block0":sw -> "block3":n [label="F"];
    	"block1":se -> "block2":n [label="T"];
    	"block1":sw -> "block3":n [label="F"];
    }
 *
 *  After install graphviz on https://www.graphviz.org/, save it as bpf.dot
 *  and run `dot -Tpng -O bpf.dot' to draw the graph.
 */
static int
dot_dump(struct icode *ic, char *errbuf)
{
	struct bpf_program f;
	FILE *out = stdout;

	memset(bids, 0, sizeof bids);
	f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
	if (f.bf_insns == NULL)
		return -1;

	fprintf(out, "digraph BPF {\n");
	unMarkAll(ic);
	dot_dump_node(ic, ic->root, &f, out);
	unMarkAll(ic);
	dot_dump_edge(ic, ic->root, out);
	fprintf(out, "}\n");

	free((char *)f.bf_insns);
	return 0;
}

static int
plain_dump(struct icode *ic, char *errbuf)
{
	struct bpf_program f;

	memset(bids, 0, sizeof bids);
	f.bf_insns = icode_to_fcode(ic, ic->root, &f.bf_len, errbuf);
	if (f.bf_insns == NULL)
		return -1;
	bpf_dump(&f, 1);
	putchar('\n');
	free((char *)f.bf_insns);
	return 0;
}

static void
opt_dump(opt_state_t *opt_state, struct icode *ic)
{
	int status;
	char errbuf[PCAP_ERRBUF_SIZE];

	/*
	 * If the CFG, in DOT format, is requested, output it rather than
	 * the code that would be generated from that graph.
	 */
	if (pcap_print_dot_graph)
		status = dot_dump(ic, errbuf);
	else
		status = plain_dump(ic, errbuf);
	if (status == -1)
		opt_error(opt_state, "opt_dump: icode_to_fcode failed: %s", errbuf);
}
#endif
