- NEW_ARR_A(ir_node *, conds, new_arity);
- NEW_ARR_A(ir_node *, vals, new_arity + 1);
- cond = get_Psi_cond(psi, 0);
- val = get_Psi_val(psi, 0);
- j = 0;
- for (i = 1; i < arity; ++i) {
- ir_node* v = get_Psi_val(psi, i);
-
- if (v == val) {
- cond = new_r_Or(
- current_ir_graph, get_nodes_block(psi),
- cond, get_Psi_cond(psi, i), mode_b
- );
- } else {
- conds[j] = cond;
- vals[j] = val;
- ++j;
- val = v;
+ 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);
+ }
+ } else if (is_Mux(f)) {
+ 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(f);
+ ir_node* t1 = get_Mux_true(f);
+ ir_node* f1 = get_Mux_false(f);
+ if (t == t1) {
+ /* Mux(c0, x, Mux(c1, x, y)) -> typical if (c0 || c1) x else y */
+ ir_node* or_ = new_r_Or(irg, block, c0, c1, mode_b);
+ ir_node* new_mux = new_r_Mux(irg, block, or_, f1, t1, mode);
+ exchange(mux, new_mux);
+ } else if (t == f1) {
+ /* Mux(c0, x, Mux(c1, y, x)) */
+ ir_node* not_c1 = new_r_Not(irg, block, c1, mode_b);
+ ir_node* or_ = new_r_Or(irg, block, c0, not_c1, mode_b);
+ ir_node* new_mux = new_r_Mux(irg, block, or_, t1, f1, mode);
+ exchange(mux, new_mux);