+ ir_node* t;
+ ir_node* f;
+
+ (void) env;
+
+ if (!is_Psi(psi)) return;
+
+ t = get_Psi_val(psi, 0);
+ f = get_Psi_default(psi);
+
+ DB((dbg, LEVEL_3, "Simplify %+F T=%+F F=%+F\n", psi, t, f));
+
+ if (is_Unknown(t)) {
+ DB((dbg, LEVEL_3, "Replace Psi with unknown operand by %+F\n", f));
+ exchange(psi, f);
+ return;
+ }
+ if (is_Unknown(f)) {
+ DB((dbg, LEVEL_3, "Replace Psi with unknown operand by %+F\n", t));
+ exchange(psi, t);
+ return;
+ }
+
+ if (is_Psi(t)) {
+ ir_graph* irg = current_ir_graph;
+ ir_node* block = get_nodes_block(psi);
+ ir_mode* mode = get_irn_mode(psi);
+ ir_node* c0 = get_Psi_cond(psi, 0);
+ ir_node* c1 = get_Psi_cond(t, 0);
+ ir_node* t1 = get_Psi_val(t, 0);
+ ir_node* f1 = get_Psi_default(t);
+ if (f == f1) {
+ /* Psi(c0, Psi(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* vals[2] = { t1, f1 };
+ ir_node* new_psi = new_r_Psi(irg, block, 1, &and_, vals, mode);
+ exchange(psi, new_psi);
+ } else if (f == t1) {
+ /* Psi(c0, Psi(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* vals[2] = { f1, t1 };
+ ir_node* new_psi = new_r_Psi(irg, block, 1, &and_, vals, mode);
+ exchange(psi, new_psi);
+ }
+ } else if (is_Psi(f)) {
+ ir_graph* irg = current_ir_graph;
+ ir_node* block = get_nodes_block(psi);
+ ir_mode* mode = get_irn_mode(psi);
+ ir_node* c0 = get_Psi_cond(psi, 0);
+ ir_node* c1 = get_Psi_cond(f, 0);
+ ir_node* t1 = get_Psi_val(f, 0);
+ ir_node* f1 = get_Psi_default(f);
+ if (t == t1) {
+ /* Psi(c0, x, Psi(c1, x, y)) -> typical if (c0 || c1) x else y */
+ ir_node* or_ = new_r_Or(irg, block, c0, c1, mode_b);
+ ir_node* vals[2] = { t1, f1 };
+ ir_node* new_psi = new_r_Psi(irg, block, 1, &or_, vals, mode);
+ exchange(psi, new_psi);
+ } else if (t == f1) {
+ /* Psi(c0, x, Psi(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* vals[2] = { f1, t1 };
+ ir_node* new_psi = new_r_Psi(irg, block, 1, &or_, vals, mode);
+ exchange(psi, new_psi);
+ }
+ }