-
- /*
- * Set masked by (either NULL or another cond node.
- * If this cond is truly masked by another one, set
- * the position of the actually investigated branch
- * to -1. Since the cond is masked by another one,
- * there could be more ways from the start block
- * to this branch, so we choose -1.
- */
- res->cases[proj].masked_by = masked_by;
-
- if(!masked_by)
- res->cases[proj].pos = pos;
-
- /*
- * Since the masked_by nodes masks a cond, remove it from the
- * root list of the conf trees.
- */
- else {
- assert(res->cases[proj].pos < 0);
- list_del_init(&masked_by->list);
+ if (!supported)
+ continue;
+
+ DB((dbg, LEVEL_1, "Found Cond %+F with proj %+F and %+F\n",
+ cond, projx0, projx1
+ ));
+
+ env->changed = true;
+ prepare_path(block, i, dependency);
+ prepare_path(block, j, dependency);
+ arity = get_irn_arity(block);
+
+ mux_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* mux;
+ ir_node* next_phi;
+
+ if (val_i == val_j) {
+ mux = val_i;
+ DB((dbg, LEVEL_2, "Generating no Mux, because both values are equal\n"));
+ } else {
+ ir_node *t, *f;
+
+ /* 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 (negated) {
+ t = val_j;
+ f = val_i;
+ } else {
+ t = val_i;
+ f = val_j;
+ }
+
+ mux = new_rd_Mux(cond_dbg, mux_block, sel, f, t, get_irn_mode(phi));
+ DB((dbg, LEVEL_2, "Generating %+F for %+F\n", mux, phi));
+ }
+
+ next_phi = get_Phi_next(phi);
+
+ if (arity == 2) {
+ exchange(phi, mux);
+ } else {
+ rewire(phi, i, j, mux);
+ }
+ phi = next_phi;
+ } while (phi != NULL);
+
+ exchange(get_nodes_block(get_irn_n(block, i)), mux_block);
+ exchange(get_nodes_block(get_irn_n(block, j)), mux_block);
+
+ if (arity == 2) {
+ unsigned mark;
+#if 1
+ DB((dbg, LEVEL_1, "Welding block %+F and %+F\n", block, mux_block));
+ /* copy the block-info from the Mux-block to the block before merging */
+
+ mark = get_Block_mark(mux_block) | get_Block_mark(block);
+ set_Block_mark(block, mark);
+ set_Block_phis(block, get_Block_phis(mux_block));
+
+ set_irn_in(block, get_irn_arity(mux_block), get_irn_in(mux_block) + 1);
+ exchange_cdep(mux_block, block);
+ exchange(mux_block, block);
+#else
+ DB((dbg, LEVEL_1, "Welding block %+F to %+F\n", block, mux_block));
+ mark = get_Block_mark(mux_block) | get_Block_mark(block);
+ /* mark both block just to be sure, should be enough to mark mux_block */
+ set_Block_mark(mux_block, mark);
+ exchange(block, mux_block);
+#endif
+ return;
+ } else {
+ rewire(block, i, j, new_r_Jmp(mux_block));
+ goto restart;