+ ir_graph *irg;
+
+ assert(old && nw);
+ assert(old != nw && "Exchanging node with itself is not allowed");
+
+ irg = get_irn_irg(old);
+ assert(irg == get_irn_irg(nw) && "New node must be in same irg as old node");
+
+ hook_replace(old, nw);
+
+ /*
+ * If new outs are on, we can skip the id node creation and reroute
+ * the edges from the old node to the new directly.
+ */
+ if (edges_activated(irg)) {
+ /* copy all dependencies from old to new */
+ add_irn_deps(nw, old);
+
+ edges_reroute(old, nw);
+ edges_reroute_kind(old, nw, EDGE_KIND_DEP);
+ edges_node_deleted(old);
+ /* noone is allowed to reference this node anymore */
+ set_irn_op(old, op_Deleted);
+ } else {
+ /* Else, do it the old-fashioned way. */
+ ir_node *block;
+
+ hook_turn_into_id(old);
+
+ block = old->in[0];
+ if (! block) {
+ block = is_Block(nw) ? nw : get_nodes_block(nw);
+
+ if (! block) {
+ panic("cannot find legal block for id");
+ }
+ }
+
+ if (get_irn_op(old)->opar == oparity_dynamic) {
+ DEL_ARR_F(get_irn_in(old));
+ }
+
+ old->op = op_Id;
+ old->in = NEW_ARR_D(ir_node*, get_irg_obstack(irg), 2);
+ old->in[0] = block;
+ old->in[1] = nw;
+ }
+
+ /* update irg flags */
+ clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS
+ | IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
+}
+
+/**
+ * Walker: links all Phi nodes to their Blocks lists,
+ * all Proj nodes to there predecessors.
+ */
+static void collect_phiprojs_walker(ir_node *n, void *env)
+{
+ ir_node *pred;
+ (void) env;
+
+ if (is_Phi(n)) {
+ ir_node *block = get_nodes_block(n);
+ add_Block_phi(block, n);
+ } else if (is_Proj(n)) {
+ pred = n;
+ do {
+ pred = get_Proj_pred(pred);
+ } while (is_Proj(pred));
+
+ set_irn_link(n, get_irn_link(pred));
+ set_irn_link(pred, n);
+ }
+}