X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firgopt.c;h=3e947631cbc6781551af5cd0a1ec3a72286e413a;hb=6537e66d6b82a7f18f69a8cb81d0180e824fb017;hp=c24181c939418a9a40ac54ac77545c49a35ebb53;hpb=a58a82dcc39d39e7797cdfe3912bac5363e2a7b9;p=libfirm diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index c24181c93..3e947631c 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -198,41 +198,34 @@ static INLINE void new_backedge_info(ir_node *n) { } } -/** - * Copies the node to the new obstack. The Ins of the new node point to - * the predecessors on the old obstack. For block/phi nodes not all - * predecessors might be copied. n->link points to the new node. +/* + * Copies a node to the current_ir_graph. The Ins of the new node point to + * the predecessors on the graph of the old node. For block/phi nodes not all + * predecessors might be copied. * For Phi and Block nodes the function allocates in-arrays with an arity * only for useful predecessors. The arity is determined by counting * the non-bad predecessors of the block. - * - * @param n The node to be copied - * @param env if non-NULL, the node number attribute will be copied to the new node - * - * Note: Also used for loop unrolling. */ -static void -firm_copy_node (ir_node *n, void *env) { +ir_node *copy_irn(ir_node *n, int copy_node_nr) { ir_node *nn, *block; int new_arity; - opcode op = get_irn_opcode(n); - int copy_node_nr = env != NULL; + ir_op *op = get_irn_op(n); /* The end node looses it's flexible in array. This doesn't matter, as dead node elimination builds End by hand, inlineing doesn't use the End node. */ - /* assert(n->op == op_End || ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC)); */ + /* assert(op == op_End || ((_ARR_DESCR(n->in))->cookie != ARR_F_MAGIC)); */ - if (op == iro_Bad) { + if (op == op_Bad) { /* node copied already */ - return; - } else if (op == iro_Block) { + return NULL; + } else if (op == op_Block) { block = NULL; new_arity = compute_new_arity(n); n->attr.block.graph_arr = NULL; } else { block = get_nodes_block(n); - if (get_irn_opcode(n) == iro_Phi) { + if (op == op_Phi) { new_arity = compute_new_arity(block); } else { new_arity = get_irn_arity(n); @@ -241,16 +234,15 @@ firm_copy_node (ir_node *n, void *env) { nn = new_ir_node(get_irn_dbg_info(n), current_ir_graph, block, - get_irn_op(n), + op, get_irn_mode(n), new_arity, - get_irn_in(n)); + get_irn_in(n) + 1); /* Copy the attributes. These might point to additional data. If this was allocated on the old obstack the pointers now are dangling. This frees e.g. the memory of the graph_arr allocated in new_immBlock. */ copy_node_attr(n, nn); new_backedge_info(nn); - set_new_node(n, nn); #if DEBUG_libfirm if (copy_node_nr) { @@ -259,10 +251,30 @@ firm_copy_node (ir_node *n, void *env) { } #endif - /* printf("\n old node: "); DDMSG2(n); - printf(" new node: "); DDMSG2(nn); */ + return nn; +} + +/** + * Copies the node to the new obstack. The Ins of the new node point to + * the predecessors on the old obstack. For block/phi nodes not all + * predecessors might be copied. n->link points to the new node. + * For Phi and Block nodes the function allocates in-arrays with an arity + * only for useful predecessors. The arity is determined by counting + * the non-bad predecessors of the block. + * + * @param n The node to be copied + * @param env if non-NULL, the node number attribute will be copied to the new node + * + * Note: Also used for loop unrolling. + */ +static void firm_copy_node (ir_node *n, void *env) { + ir_node *nn = copy_irn(n, env != NULL); + + if (nn) + set_new_node(n, nn); } + /** * Copies new predecessors of old node to new node remembered in link. * Spare the Bad predecessors of Phi and Block nodes. @@ -1702,18 +1714,26 @@ place_floats_late(ir_node *n, pdeq *worklist) dominator tree of all nodes' blocks depending on us; our final placement has to dominate DCA. */ - for (i = 0; i < get_irn_n_outs(n); ++i) { + for (i = get_irn_n_outs(n) - 1; i >= 0; --i) { ir_node *out = get_irn_out(n, i); + ir_node *outbl; + + if (get_irn_op(out) == op_End) { + /* + * This consumer is the End node, a keep alive edge. + * This is not a real consumer, so we ignore it + */ + continue; + } /* ignore if out is in dead code */ - ir_node *outbl = get_nodes_block(out); + outbl = get_irn_n(out, -1); if (is_Block_unreachable(outbl)) continue; dca = consumer_dom_dca(dca, out, n); } if (dca) { set_nodes_block(n, dca); - move_out_of_loops (n, early); } /* else all outs are in dead code */