- ir_node* pred;
- ir_node* cond;
- ir_node* projx0;
- int j;
-
- projx0 = walk_to_projx(get_irn_n(block, i));
- if (projx0 == NULL) return;
- pred = get_Proj_pred(projx0);
- if (get_irn_op(pred) != op_Cond || get_irn_mode(get_Cond_selector(pred)) != mode_b) continue;
- cond = pred;
-
- if (!can_empty_block(get_nodes_block(get_irn_n(block, i)))) {
- ir_fprintf(stderr, "Cannot empty block %+F\n",
- get_nodes_block(get_irn_n(block, i))
- );
- continue;
- }
-
- for (j = i + 1; j < arity; ++j) {
- ir_node* projx1;
- ir_node* psi_block;
- ir_node* conds[1];
- ir_node* vals[2];
- ir_node* psi;
-
- projx1 = walk_to_projx(get_irn_n(block, j));
- if (projx1 == NULL) continue;
- pred = get_Proj_pred(projx1);
- if (get_irn_op(pred) != op_Cond || get_irn_mode(get_Cond_selector(pred)) != mode_b) continue;
- if (pred != cond) continue;
- ir_fprintf(stderr, "Found Cond %+F with proj %+F and %+F\n", cond, projx0, projx1);
-
- if (!can_empty_block(get_nodes_block(get_irn_n(block, j)))) {
- ir_fprintf(stderr, "Cannot empty block %+F\n",
- get_nodes_block(get_irn_n(block, j))
- );
- continue;
- }
-
- conds[0] = get_Cond_selector(cond);
-
- psi_block = get_nodes_block(cond);
- phi = ((block_info*)get_irn_link(block))->phi;
- do {
- // Don't generate PsiMs
- if (get_irn_mode(phi) == mode_M) {
- /* Something is very fishy if to predecessors of a PhiM point into the
- * block but not at the same memory node
- */
- assert(get_irn_n(phi, i) == get_irn_n(phi, j));
- // fake memory Psi
- psi = get_irn_n(phi, i);
- ir_fprintf(stderr, "Handling memory Phi %+F\n", phi);
- } else {
- if (get_Proj_proj(projx0) == pn_Cond_true) {
- vals[0] = get_irn_n(phi, i);
- vals[1] = get_irn_n(phi, j);
- } else {
- vals[0] = get_irn_n(phi, j);
- vals[1] = get_irn_n(phi, i);
- }
- psi = new_r_Psi(
- current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi)
- );
- ir_fprintf(stderr, "Generating %+F for %+F\n", psi, phi);
- }
-
- if (arity == 2) {
- exchange(phi, psi);
- } else {
- ir_node** ins = malloc(sizeof(*ins) * (arity - 1));
- int k;
- int l;
-
- l = 0;
- for (k = 0; k < i; ++k) ins[l++] = get_irn_n(phi, k);
- for (++k; k < j; ++k) ins[l++] = get_irn_n(phi, k);
- for (++k; k < arity; ++k) ins[l++] = get_irn_n(phi, k);
- ins[l++] = psi;
- assert(l == arity - 1);
- set_irn_in(phi, l, ins);
-
- free(ins);
- }
-
- phi = get_irn_link(phi);
- } while (phi != NULL && get_irn_op(phi) == op_Phi);
-
- exchange(get_nodes_block(get_irn_n(block, i)), psi_block);
- exchange(get_nodes_block(get_irn_n(block, j)), psi_block);
-
- if (arity == 2) {
- ir_fprintf(stderr, "Welding block %+F to %+F\n", block, psi_block);
- ((block_info*)get_irn_link(psi_block))->evil |=
- ((block_info*)get_irn_link(block))->evil;
- exchange(block, psi_block);
- return;
- } else {
- ir_node** ins = malloc(sizeof(*ins) * (arity - 1));
- int k;
- int l;
-
- l = 0;
- for (k = 0; k < i; ++k) ins[l++] = get_irn_n(block, k);
- for (++k; k < j; ++k) ins[l++] = get_irn_n(block, k);
- for (++k; k < arity; ++k) ins[l++] = get_irn_n(block, k);
- ins[l++] = new_r_Jmp(current_ir_graph, psi_block);
- assert(l == arity - 1);
- set_irn_in(block, l, ins);
-
- free(ins);
- goto restart;