+ const arch_env_t *arch_env = env->arch_env;
+ ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
+ ir_graph *irg = get_irn_irg(bl);
+ pset *live = put_live_end(bl, pset_new_ptr_default());
+ firm_dbg_module_t *dbg = firm_dbg_register("firm.be.node");
+
+ ir_node *curr, *irn, *perm, **nodes;
+ int i, n;
+
+ firm_dbg_set_mask(dbg, DBG_LEVEL);
+ DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos));
+
+ sched_foreach_reverse(bl, irn) {
+ ir_node *x;
+
+ /*
+ * If we encounter the node we want to insert the Perm after,
+ * exit immediately, so that this node is still live
+ */
+ if(irn == pos)
+ break;
+
+ DBG((dbg, LEVEL_1, "%+F\n", irn));
+ for(x = pset_first(live); x; x = pset_next(live))
+ DBG((dbg, LEVEL_1, "\tlive: %+F\n", x));
+
+ if(arch_irn_has_reg_class(arch_env, irn, -1, cls))
+ pset_remove_ptr(live, irn);
+
+ for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
+ ir_node *op = get_irn_n(irn, i);
+
+ if(arch_irn_has_reg_class(arch_env, op, -1, cls))
+ pset_insert_ptr(live, op);
+ }
+ }
+
+ n = pset_count(live);
+ nodes = malloc(n * sizeof(nodes[0]));
+
+ DBG((dbg, LEVEL_1, "live:\n"));
+ for(irn = pset_first(live), i = 0; irn; irn = pset_next(live), i++) {
+ DBG((dbg, LEVEL_1, "\t%+F\n", irn));
+ nodes[i] = irn;
+ }
+
+ perm = new_Perm(env->node_factory, cls, irg, bl, n, nodes);
+ sched_add_after(pos, perm);
+ free(nodes);
+
+ curr = perm;
+ for(i = 0; i < n; ++i) {
+ ir_node *copies[1];
+ ir_node *perm_op = get_irn_n(perm, i);
+ const arch_register_t *reg = arch_get_irn_register(arch_env, perm_op);
+
+ ir_mode *mode = get_irn_mode(perm_op);
+ ir_node *proj = new_r_Proj(irg, bl, perm, mode, i);
+ arch_set_irn_register(arch_env, proj, reg);
+
+ sched_add_after(curr, proj);
+ curr = proj;
+
+ copies[0] = proj;
+ be_introduce_copies(dom_front, perm_op, array_size(copies), copies);
+ }
+ return perm;