- int i;
- ir_node *projb = get_Cond_selector(cond->cond);
- ir_node *operands[2];
-
- for(i = 0; i < 2; ++i) {
-
- /*
- * If this cond branch is masked by another cond, make the mux
- * for that cond first, since the mux for this cond takes
- * it as an operand.
- */
- if(cond->cases[i].masked_by) {
- cond_t templ;
- cond_t *masking_cond;
-
- templ.cond = cond->cases[i].masked_by;
- masking_cond = set_find(cond_set, &templ, sizeof(templ), HASH_PTR(templ.cond));
-
- operands[i] = make_mux_on_demand(phi, dom, masking_cond, cond_set);
- }
-
- /*
- * If this cond branch is not masked by another cond, take
- * the corresponding phi operand as an operand to the mux.
- */
- else {
- assert(cond->cases[i].pos >= 0);
- operands[i] = get_irn_n(phi, cond->cases[i].pos);
- }
-
- /* Move the selected operand to the dominator block. */
- move_to(operands[i], dom);
- }
-
- /* Move the comparison expression of the cond to the dominator. */
- move_to(projb, dom);
-
- /* Make the mux. */
- cond->mux = new_r_Mux(current_ir_graph, dom, projb,
- operands[0], operands[1], get_irn_mode(operands[0]));
-
- return cond->mux;
+ int i, can_move[2];
+ ir_node *projb = get_Cond_selector(cond->cond);
+ ir_node *bl = get_nodes_block(cond->cond);
+ ir_node *operands[2];
+ int set[2];
+
+ cond->visited_nr = visited_nr;
+ DBG((dbg, LEVEL_2, "%n\n", cond->cond));
+ for(i = 0; i < 2; ++i) {
+ cond_t *masked_by = cond->cases[i].masked_by;
+ int pos = cond->cases[i].pos;
+
+ operands[i] = NULL;
+ set[i] = -1;
+
+ /*
+ * If this Cond branch is masked by another cond, make the mux
+ * for that Cond first, since the Mux for this cond takes
+ * it as an operand.
+ */
+ if(masked_by) {
+ assert(pos < 0);
+ DBG((dbg, LEVEL_2, "\tmasked by: %n\n", masked_by->cond));
+ if(masked_by->visited_nr < visited_nr)
+ operands[i] = make_mux_on_demand(phi, dom, masked_by, info, mux, positions, muxes_made, visited_nr);
+ }
+
+ /*
+ * If this cond branch is not masked by another cond, take
+ * the corresponding phi operand as an operand to the mux.
+ */
+ else if(pos >= 0) {
+ operands[i] = get_irn_n(phi, pos);
+ set[i] = pos;
+ }
+ }
+
+ /*
+ * Move the operands to the dominator block if the cond
+ * made sense. Some Conds found are not suitable for making a mux
+ * out of them, since one of their branches cannot be reached from
+ * the phi block. In that case we do not make a mux and return NULL.
+ */
+ if(operands[0] && operands[1]) {
+ if (operands[0] == operands[1]) {
+ /* there is no gain in using mux in this case, as
+ it will be optimized away. We will NOT move the
+ content of the blocks either
+ */
+ for (i = 0; i < 2; ++i)
+ if(set[i] >= 0)
+ bitset_set(positions, set[i]);
+
+ *mux = operands[0];
+ return *mux;
+ }
+
+ can_move[0] = can_move_to(operands[0], bl, info);
+ can_move[1] = can_move_to(operands[1], bl, info);
+
+ if (can_move[0] == SUCCESS && can_move[1] == SUCCESS) {
+ if (info->allow_mux(projb, operands[0], operands[1])) {
+ move_to(operands[0], bl);
+ move_to(operands[1], bl);
+
+ /* Make the mux. */
+ *mux = new_r_Mux(current_ir_graph, bl, projb,
+ operands[0], operands[1], get_irn_mode(operands[0]));
+
+ *muxes_made += 1;
+
+ DBG((dbg, LEVEL_2, "\t%n(%n, %n, %n)[%d, %d]\n",
+ *mux, projb, operands[0], operands[1], set[0], set[1]));
+
+ for(i = 0; i < 2; ++i)
+ if(set[i] >= 0) {
+ bitset_set(positions, set[i]);
+
+ /* we have done one */
+ hook_if_conversion(current_ir_graph, phi, set[i], *mux, IF_RESULT_SUCCESS);
+ }
+ }
+ else {
+ hook_if_conversion(current_ir_graph, phi, set[i], *mux, IF_RESULT_DENIED);
+ }
+ }
+ else {
+ if(can_move[0] != SUCCESS)
+ hook_if_conversion(current_ir_graph, phi, set[0], NULL, can_move[0]);
+ if(can_move[1] != SUCCESS)
+ hook_if_conversion(current_ir_graph, phi, set[1], NULL, can_move[1]);
+ }
+ }
+ else {
+ if(operands[0])
+ hook_if_conversion(current_ir_graph, phi, set[0], NULL, IF_RESULT_BAD_CF);
+ if(operands[1])
+ hook_if_conversion(current_ir_graph, phi, set[1], NULL, IF_RESULT_BAD_CF);
+ }
+
+ return *mux;