-static void place_phi_functions(ir_node *orig, pset *copies,
- pset *copy_blocks, dom_front_info_t *df_info)
-{
- int i;
- ir_node *orig_block = get_nodes_block(orig);
- ir_graph *irg = get_irn_irg(orig);
- ir_mode *mode = get_irn_mode(orig);
- pdeq *worklist = new_pdeq();
- pset *phi_blocks = pset_new_ptr(8);
- ir_node **ins = NULL;
- void *it;
- firm_dbg_module_t *dbg = DBG_MODULE;
-
- /*
- * Allocate an array for all blocks where the copies and the original
- * value were defined.
- */
- int n_orig_blocks = pset_count(copy_blocks);
- ir_node **orig_blocks = malloc(n_orig_blocks * sizeof(orig_blocks[0]));
-
- /*
- * Fill the worklist queue and the rest of the orig blocks array.
- */
- for(it = pset_first(copies), i = 0; it; it = pset_next(copies)) {
- ir_node *copy_block = get_nodes_block(it);
-
- if(!block_dominates(orig_block, copy_block)) {
- assert(block_dominates(orig_block, copy_block)
- && "The block of the copy must be dominated by the block of the value");
- }
-
- pdeq_putr(worklist, copy_block);
- orig_blocks[i++] = copy_block;
- }
-
- while(!pdeq_empty(worklist)) {
- ir_node *bl = pdeq_getl(worklist);
- ir_node *y;
- pset *df = be_get_dominance_frontier(df_info, bl);
-
- for(y = pset_first(df); y; y = pset_next(df)) {
- int n_preds = get_irn_arity(y);
-
- if(!pset_find_ptr(phi_blocks, y)) {
- ir_node *phi;
- int insert = 1;
-
- /*
- * Set the orig node as the only operand of the
- * phi node.
- */
- ins = realloc(ins, n_preds * sizeof(ins[0]));
- for(i = 0; i < n_preds; ++i)
- ins[i] = orig;
-
- /* Insert phi node */
- phi = new_r_Phi(irg, y, n_preds, ins, mode);
- DBG((dbg, LEVEL_2, " inserting phi %+F with %d args in block %+F\n",
- phi, n_preds, bl));
-
- /*
- * The phi node itself is also a copy of the original
- * value. So put it in the copies set also, so that
- * the rename phase can treat them right.
- */
- pset_insert_ptr(copies, phi);
- pset_insert_ptr(copy_blocks, y);
-
- /* Insert the phi node into the schedule */
- sched_add_before(sched_first(y), phi);
-
- /* Insert the phi node in the phi blocks set. */
- pset_insert_ptr(phi_blocks, y);
-
- /*
- * If orig or a copy of it were not defined in y,
- * add y to the worklist.
- */
- for(i = 0; i < n_orig_blocks; ++i)
- if(orig_blocks[i] == y) {
- insert = 0;
- break;
- }
-
- if(insert)
- pdeq_putr(worklist, y);
-
- }
- }
- }
-
- del_pset(phi_blocks);
- del_pdeq(worklist);
-
- free(orig_blocks);
-
- if(ins)
- free(ins);
+static void remove_empty_block(ir_node *block, void *data) {
+ const ir_edge_t *edge, *next;
+ ir_node *node;
+ int *changed = data;
+ ir_node *jump = NULL;
+
+ assert(is_Block(block));
+
+ if (get_Block_n_cfgpreds(block) != 1)
+ return;
+
+ sched_foreach(block, node) {
+ if (! is_Jmp(node))
+ return;
+ if (jump != NULL) {
+ /* we should never have 2 jumps in a block */
+ panic("We should never have 2 jumps in a block");
+ }
+ jump = node;
+ }
+
+ if (jump == NULL)
+ return;
+
+ node = get_Block_cfgpred(block, 0);
+ foreach_out_edge_safe(jump, edge, next) {
+ ir_node *block = get_edge_src_irn(edge);
+ int pos = get_edge_src_pos(edge);
+
+ set_irn_n(block, pos, node);
+ }
+
+ set_Block_cfgpred(block, 0, new_Bad());
+ be_kill_node(jump);
+ *changed = 1;