+ * Removes all copies introduced for phi-spills
+ */
+static void remove_copies(spill_env_t *env) {
+ int i;
+
+ for(i = 0; i < ARR_LEN(env->copies); ++i) {
+ ir_node *node = env->copies[i];
+ ir_node *src;
+ const ir_edge_t *edge, *ne;
+
+ assert(be_is_Copy(node));
+
+ src = be_get_Copy_op(node);
+ foreach_out_edge_safe(node, edge, ne) {
+ ir_node *user = get_edge_src_irn(edge);
+ int user_pos = get_edge_src_pos(edge);
+
+ set_irn_n(user, user_pos, src);
+ }
+ }
+
+ ARR_SETLEN(ir_node*, env->copies, 0);
+}
+
+static INLINE ir_node *skip_projs(ir_node *node) {
+ while(is_Proj(node)) {
+ node = sched_next(node);
+ assert(!sched_is_end(node));
+ }
+
+ return node;
+}
+
+/**
+ * Searchs the schedule backwards until we reach the first use or def of a
+ * value or a phi.
+ * Returns the node after this node (so that you can do sched_add_before)
+ */
+static ir_node *find_last_use_def(spill_env_t *env, ir_node *block, ir_node *value) {
+ ir_node *node, *last;
+
+ last = NULL;
+ sched_foreach_reverse(block, node) {
+ int i, arity;
+
+ if(is_Phi(node)) {
+ return last;
+ }
+ if(value == node) {
+ return skip_projs(last);
+ }
+ for(i = 0, arity = get_irn_arity(node); i < arity; ++i) {
+ ir_node *arg = get_irn_n(node, i);
+ if(arg == value) {
+ return skip_projs(last);
+ }
+ }
+ last = node;
+ }
+
+ // simply return first node if no def or use found
+ return sched_first(block);
+}
+
+/**
+ * If the first usage of a Phi result would be out of memory