- if(cond->visited_nr >= visited_nr)
- return;
-
- cond->visited_nr = visited_nr;
-
- if(pre)
- pre(cond, env);
-
- for(i = 0; i < 2; ++i) {
- cond_t *c = cond->cases[i].masked_by;
-
- if(c)
- _walk_conds(c, pre, post, visited_nr, env);
- }
-
- if(post)
- post(cond, env);
-}
-
-static long cond_visited_nr = 0;
-
-static void walk_conds(cond_t *cond, cond_walker_t *pre, cond_walker_t *post, void *env)
-{
- _walk_conds(cond, pre, post, ++cond_visited_nr, env);
-}
-
-static void link_conds(cond_t *cond, void *env)
-{
- cond_t **ptr = (cond_t **) env;
-
- cond->link = *ptr;
- *ptr = cond;
-}
-
-/**
- * Compare two conds for use in a firm set.
- * Two cond_t's are equal, if they designate the same cond node.
- * @param a A cond_t.
- * @param b Another one.
- * @param size Not used.
- * @return 0 (!) if they are equal, != 0 otherwise.
- */
-static int cond_cmp(const void *a, const void *b, size_t size)
-{
- const cond_t *x = a;
- const cond_t *y = b;
- return x->cond != y->cond;
-}
-
-/**
- * Information about conds which can be made to muxes.
- * Instances of this struct are attached to the link field of
- * blocks in which phis are located.
- */
-typedef struct _cond_info_t {
- struct list_head list; /**< Used to list all of these structs per class. */
-
- struct list_head roots; /**< A list of non-depending Conds. Two Conds are
- independent, if it's not possible not reach one from the
- other (all Conds in this list have to dominate the
- block this struct is attached to). */
-
- ir_node *first_phi; /**< The first phi node this cond info was made for. */
- set *cond_set; /**< A set of all dominating reachable Conds. */
-} cond_info_t;
-
-/**
- * @see find_conds.
- */
-static void _find_conds(ir_node *irn, unsigned long visited_nr,
- ir_node *dominator, cond_t *masked_by, int pos, int depth, cond_info_t *ci)
-{
- ir_node *block;
- int saw_select_cond = 0;
-
- block = get_nodes_block(irn);
-
- /*
- * Only check this block if it is dominated by the specified
- * dominator or it has not been visited yet.
- */
- if (block_dominates(dominator, block) && get_Block_block_visited(block) < visited_nr) {
- cond_t *res = masked_by;
- int i, n;
-
- /* check, if we're on a ProjX
- *
- * Further, the ProjX/Cond block must dominate the base block
- * (the block with the phi in it), otherwise, the Cond
- * is not affecting the phi so that a mux can be inserted.
- */
- if(is_Proj(irn) && get_irn_mode(irn) == mode_X) {
-
- int proj = get_Proj_proj(irn);
- ir_node *cond = get_Proj_pred(irn);
-
- /* true, if the mode is a mode_b cond _NO_ switch cond */
- int is_modeb_cond = get_irn_opcode(cond) == iro_Cond
- && get_irn_mode(get_Cond_selector(cond)) == mode_b;
-
- saw_select_cond = !is_modeb_cond;
-
- /* Check, if the pred of the proj is a Cond
- * with a Projb as selector.
- */
- if(is_modeb_cond) {
- cond_t c;
-
- memset(&c, 0, sizeof(c));
- c.cond = cond;
- c.is_new = 1;
- c.cases[0].pos = -1;
- c.cases[1].pos = -1;
-
- /* get or insert the cond info into the set. */
- res = set_insert(ci->cond_set, &c, sizeof(c), HASH_PTR(cond));
-
- /*
- * If this cond is already masked by the masked_by cond
- * return immediately, since we don't have anything to add.
- */
- if(masked_by && res->cases[proj].masked_by == masked_by)
- return;
-
- if(res->is_new) {
- res->is_new = 0;
- list_add(&res->list, &ci->roots);
- }
-
- /*
- * Set masked by (either NULL or another cond node.
- * If this cond is truly masked by another one, set
- * the position of the actually investigated branch
- * to -1. Since the cond is masked by another one,
- * there could be more ways from the start block
- * to this branch, so we choose -1.
- */
- res->cases[proj].masked_by = masked_by;
-
- if(!masked_by)
- res->cases[proj].pos = pos;
-
- /*
- * Since the masked_by nodes masks a cond, remove it from the
- * root list of the conf trees.
- */
- else {
- assert(res->cases[proj].pos < 0);
- list_del_init(&masked_by->list);
- }
-
- DBG((dbg, LEVEL_2, "%n (%s branch) "
- "for pos %d in block %n reached by %n\n",
- cond, proj ? "true" : "false", pos,
- block, masked_by ? masked_by->cond : NULL));
- }
- }
-
- if(get_Block_block_visited(block) < visited_nr && !saw_select_cond) {
-
- set_Block_block_visited(block, visited_nr);
-
- /* Search recursively from this cond. */
- for(i = 0, n = get_irn_arity(block); i < n; ++i) {
- ir_node *pred = get_irn_n(block, i);
-
- /*
- * If the depth is 0 (the first recursion), we set the pos to
- * the current viewed predecessor, else we adopt the position
- * as given by the caller. We also increase the depth for the
- * recursively called functions.
- */
- _find_conds(pred, visited_nr, dominator, res, pos, depth + (res != masked_by), ci);
- }
- }
- }