-/**
- * Removes Tuples from Block control flow predecessors.
- * Optimizes blocks with equivalent_node(). This is tricky,
- * as we want to avoid nodes that have as block predecessor Bads.
- * Therefore we also optimize at control flow operations, depending
- * how we first reach the Block.
- */
-static void merge_blocks(ir_node *node, void *ctx) {
- int i;
- ir_node *new_block;
- merge_env *env = ctx;
-
- /* clear the link field for ALL nodes first */
- set_irn_link(node, NULL);
-
- if (is_Block(node)) {
- /* Remove Tuples */
- for (i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
- ir_node *pred = get_Block_cfgpred(node, i);
- ir_node *skipped = skip_Tuple(pred);
- if (pred != skipped) {
- set_Block_cfgpred(node, i, skipped);
- env->changed = 1;
- }
- }
-
- /* see below */
- new_block = equivalent_node(node);
- if (new_block != node && ! is_Block_dead(new_block)) {
- exchange(node, new_block);
- env->changed = 1;
- }
-
- } else if (get_opt_optimize() && (get_irn_mode(node) == mode_X)) {
- /* We will soon visit a block. Optimize it before visiting! */
- ir_node *b = get_nodes_block(skip_Proj(node));
-
- if (!is_Block_dead(b)) {
- new_block = equivalent_node(b);
-
- while (irn_not_visited(b) && (!is_Block_dead(new_block)) && (new_block != b)) {
- /* We would have to run gigo() if new is bad, so we
- promote it directly below. Nevertheless, we sometimes reach a block
- the first time through a dataflow node. In this case we optimized the
- block as such and have to promote the Bad here. */
- assert((get_opt_control_flow_straightening() ||
- get_opt_control_flow_weak_simplification()) &&
- ("strange flag setting"));
- exchange(b, new_block);
- env->changed = 1;
- b = new_block;
- new_block = equivalent_node(b);
- }
-
- /* normally, we would create a Bad block here, but this must be
- * prevented, so just set it's cf to Bad.
- */
- if (is_Block_dead(new_block)) {
- exchange(node, new_Bad());
- env->changed = 1;
- }
- }
- }