-/* Insert irnode `new' in place of irnode `old'
- Since `new' may be bigger than `old' replace `old'
- by an op_Id which is smaller than everything */
-inline void
-exchange (ir_node *old, ir_node *new)
-{
- ir_node *block = old->in[0];
-
- old->op = op_Id;
- old->in = NEW_ARR_D (ir_node *, current_ir_graph->obst, 2);
- old->in[0] = block;
- old->in[1] = new;
+/**
+ * Insert irnode `new' in place of irnode `old'
+ * Since `new' may be bigger than `old' replace `old'
+ * by an op_Id which is smaller than everything.
+ */
+void exchange(ir_node *old, ir_node *nw) {
+ 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, irg);
+ edges_reroute_kind(old, nw, EDGE_KIND_DEP, irg);
+ edges_node_deleted(old, irg);
+ old->op = op_Bad;
+ } 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 *, irg->obst, 2);
+ old->in[0] = block;
+ old->in[1] = nw;
+ }