- return cond->mux;
-}
-
-typedef struct _phi_info_t {
- struct list_head list;
- cond_info_t *cond_info;
- ir_node *irn;
-} phi_info_t;
-
-
-/**
- * Examine a phi node if it can be replaced by some muxes.
- * @param irn A phi node.
- * @param info Parameters for the if conversion algorithm.
- */
-static void check_out_phi(phi_info_t *phi_info, opt_if_conv_info_t *info)
-{
- int max_depth = info->max_depth;
- int i, n;
- ir_node *irn = phi_info->irn;
- ir_node *block, *nw;
- cond_info_t *cond_info = phi_info->cond_info;
- cond_t *cond;
- int arity;
-
- set *cond_set = cond_info->cond_set;
- bitset_t *positions;
-
- block = get_nodes_block(irn);
- arity = get_irn_arity(irn);
-
- assert(is_Phi(irn));
- assert(get_irn_arity(irn) == get_irn_arity(block));
- assert(arity > 0);
-
- positions = bitset_alloca(arity);
-
- DBG((dbg, LEVEL_5, "phi candidate: %n\n", irn));
-
- list_for_each_entry(cond_t, cond, &cond_info->roots, list) {
- int cannot_move = 0;
- ir_node *cidom = get_nodes_block(cond->cond);
-
- cond_t *p, *head = NULL;
-
- DBG((dbg, LEVEL_5, "\tcond root: %n\n", cond->cond));
-
- /* clear the position array. */
- bitset_clear_all(positions);
-
- /*
- * Link all conds which are in the subtree of
- * the current cond in the list together.
- */
- walk_conds(cond, link_conds, NULL, cond_set, &head);
-
- for(p = head, n = 0; p; p = p->link)
- cidom = common_idom(cidom, get_nodes_block(p->cond));
-
- DBG((dbg, LEVEL_5, "\tcommon idom: %n\n", cidom));
-
- for(p = head, n = 0; p && !cannot_move; p = p->link) {
-
- if(!can_move_to(get_Cond_selector(p->cond), cidom, max_depth)) {
- DBG((dbg, LEVEL_5, "\tcannot move selector of %n\n", p->cond));
- cannot_move = 1;
- break;
- }
-
- for(i = 0; i < 2; ++i) {
- int pos = p->cases[i].pos;
-
- if(pos != -1) {
- bitset_set(positions, pos);
-
- if(!can_move_to(get_irn_n(irn, pos), cidom, max_depth)) {
- cannot_move = 1;
- DBG((dbg, LEVEL_5, "\tcannot move phi operand %d\n", pos));
- break;
- }
-
- DBG((dbg, LEVEL_5, "\tcan move phi operand %d\n", pos));
- }
- }
+ if (is_Mux(t)) {
+ ir_graph* irg = current_ir_graph;
+ ir_node* block = get_nodes_block(mux);
+ ir_mode* mode = get_irn_mode(mux);
+ ir_node* c0 = get_Mux_sel(mux);
+ ir_node* c1 = get_Mux_sel(t);
+ ir_node* t1 = get_Mux_true(t);
+ ir_node* f1 = get_Mux_false(t);
+ if (f == f1) {
+ /* Mux(c0, Mux(c1, x, y), y) -> typical if (c0 && c1) x else y */
+ ir_node* and_ = new_r_And(irg, block, c0, c1, mode_b);
+ ir_node* new_mux = new_r_Mux(irg, block, and_, f1, t1, mode);
+ exchange(mux, new_mux);
+ } else if (f == t1) {
+ /* Mux(c0, Mux(c1, x, y), x) */
+ ir_node* not_c1 = new_r_Not(irg, block, c1, mode_b);
+ ir_node* and_ = new_r_And(irg, block, c0, not_c1, mode_b);
+ ir_node* new_mux = new_r_Mux(irg, block, and_, t1, f1, mode);
+ exchange(mux, new_mux);