+ /* Bail out, if there are no Phis at all */
+ if (get_block_blockinfo(block)->phi == NULL) return;
+
+restart:
+ arity = get_irn_arity(block);
+ for (i = 0; i < arity; ++i) {
+ ir_node* pred0;
+ ir_cdep* cdep;
+
+ pred0 = get_nodes_block(get_irn_n(block, i));
+ for (cdep = find_cdep(pred0); cdep != NULL; cdep = cdep->next) {
+ const ir_node* dependency = cdep->node;
+ ir_node* projx0 = walk_to_projx(pred0, dependency);
+ ir_node* cond;
+ int j;
+
+ if (projx0 == NULL) continue;
+
+ cond = get_Proj_pred(projx0);
+ if (get_irn_op(cond) != op_Cond) continue;
+
+ /* We only handle boolean decisions, no switches */
+ if (get_irn_mode(get_Cond_selector(cond)) != mode_b) continue;
+
+ for (j = i + 1; j < arity; ++j) {
+ ir_node* projx1;
+ ir_node* conds[1];
+ ir_node* psi_block;
+ ir_node* phi;
+ ir_node* pred1;
+ dbg_info* cond_dbg;
+
+ pred1 = get_nodes_block(get_irn_n(block, j));
+
+ if (!is_cdep_on(pred1, dependency)) continue;
+
+ projx1 = walk_to_projx(pred1, dependency);
+
+ if (projx1 == NULL) continue;
+
+ phi = get_block_blockinfo(block)->phi;
+ if (!opt_info->allow_ifconv(get_Cond_selector(cond), phi, i, j)) continue;
+
+ DB((dbg, LEVEL_1, "Found Cond %+F with proj %+F and %+F\n",
+ cond, projx0, projx1
+ ));
+
+ prepare_path(block, i, dependency);
+ prepare_path(block, j, dependency);
+ arity = get_irn_arity(block);
+
+ conds[0] = get_Cond_selector(cond);
+
+ psi_block = get_nodes_block(cond);
+ cond_dbg = get_irn_dbg_info(cond);
+ do {
+ ir_node* val_i = get_irn_n(phi, i);
+ ir_node* val_j = get_irn_n(phi, j);
+ ir_node* psi;
+ ir_node* next_phi;
+
+ if (val_i == val_j) {
+ psi = val_i;
+ DB((dbg, LEVEL_2, "Generating no psi, because both values are equal\n"));
+ } else {
+ ir_node* vals[2];
+
+ /* Something is very fishy if two predecessors of a PhiM point into
+ * one block, but not at the same memory node
+ */
+ assert(get_irn_mode(phi) != mode_M);
+ if (get_Proj_proj(projx0) == pn_Cond_true) {
+ vals[0] = val_i;
+ vals[1] = val_j;
+ } else {
+ vals[0] = val_j;
+ vals[1] = val_i;
+ }
+
+ psi = new_rd_Psi(cond_dbg, current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi));
+ DB((dbg, LEVEL_2, "Generating %+F for %+F\n", psi, phi));
+ }