+void be_add_spill(spill_env_t *env, ir_node *to_spill, ir_node *before)
+{
+#if 1
+ spill_info_t *spill_info = get_spillinfo(env, to_spill);
+ spill_t *spill;
+ spill_t *s;
+ spill_t *last;
+
+ assert(! arch_irn_is(env->arch_env, to_spill, dont_spill));
+ DB((dbg, LEVEL_1, "Add spill of %+F before %+F\n", to_spill, before));
+
+ /* Just for safety make sure that we do not insert the spill in front of a phi */
+ for (; is_Phi(before); before = sched_next(before));
+
+ /* spills that are dominated by others are not needed */
+ last = NULL;
+ s = spill_info->spills;
+ for( ; s != NULL; s = s->next) {
+ /* no need to add this spill if it is dominated by another */
+ if(value_dominates(s->before, before)) {
+ DB((dbg, LEVEL_1, "...dominated by %+F, not added\n", s->before));
+ return;
+ }
+ /* remove spills that we dominate */
+ if(value_dominates(before, s->before)) {
+ DB((dbg, LEVEL_1, "...remove old spill at %+F\n", s->before));
+ if(last != NULL) {
+ last->next = s->next;
+ } else {
+ spill_info->spills = s->next;
+ }
+ } else {
+ last = s;
+ }
+ }
+
+ spill = obstack_alloc(&env->obst, sizeof(spill[0]));
+ spill->before = before;
+ spill->next = spill_info->spills;
+ spill->spill = NULL;
+
+ spill_info->spills = spill;
+#endif
+}
+
+void be_add_remat(spill_env_t *env, ir_node *to_spill, ir_node *before,
+ ir_node *rematted_node)
+{
+ spill_info_t *spill_info;
+ reloader_t *reloader;
+
+ spill_info = get_spillinfo(env, to_spill);
+
+ /* add the remat information */
+ reloader = obstack_alloc(&env->obst, sizeof(reloader[0]));
+ reloader->next = spill_info->reloaders;
+ reloader->reloader = before;
+ reloader->rematted_node = rematted_node;
+ reloader->remat_cost_delta = 0; /* We will never have a cost win over a
+ reload since we're not even allowed to
+ create a reload */
+
+ spill_info->reloaders = reloader;
+
+ DBG((dbg, LEVEL_1, "creating spillinfo for %+F, will be rematerialized before %+F\n",
+ to_spill, before));
+}
+
+void be_add_reload2(spill_env_t *env, ir_node *to_spill, ir_node *before,
+ ir_node *can_spill_after, const arch_register_class_t *reload_cls,
+ int allow_remat)
+{
+ spill_info_t *info;
+ reloader_t *rel;
+
+ assert(! arch_irn_is(env->arch_env, to_spill, dont_spill));
+
+ info = get_spillinfo(env, to_spill);
+
+ if (is_Phi(to_spill)) {
+ int i, arity;
+
+ /* create spillinfos for the phi arguments */
+ for (i = 0, arity = get_irn_arity(to_spill); i < arity; ++i) {
+ ir_node *arg = get_irn_n(to_spill, i);
+ get_spillinfo(env, arg);
+ }
+ }
+
+ assert(!is_Proj(before) && !be_is_Keep(before));
+
+ /* put reload into list */
+ rel = obstack_alloc(&env->obst, sizeof(rel[0]));
+ rel->next = info->reloaders;
+ rel->reloader = before;
+ rel->rematted_node = NULL;
+ rel->can_spill_after = can_spill_after;
+ rel->remat_cost_delta = allow_remat ? 0 : REMAT_COST_INFINITE;
+
+ info->reloaders = rel;
+ assert(info->reload_cls == NULL || info->reload_cls == reload_cls);
+ info->reload_cls = reload_cls;
+
+ DBG((dbg, LEVEL_1, "creating spillinfo for %+F, will be reloaded before %+F, may%s be rematerialized\n",
+ to_spill, before, allow_remat ? "" : " not"));
+}
+
+void be_add_reload(spill_env_t *senv, ir_node *to_spill, ir_node *before,
+ const arch_register_class_t *reload_cls, int allow_remat)
+{
+ be_add_reload2(senv, to_spill, before, to_spill, reload_cls, allow_remat);
+
+}
+
+ir_node *be_get_end_of_block_insertion_point(const ir_node *block)
+{
+ ir_node *last = sched_last(block);
+
+ /* we might have keeps behind the jump... */
+ while(be_is_Keep(last)) {
+ last = sched_prev(last);
+ assert(!sched_is_end(last));
+ }
+
+ assert(is_cfop(last));
+
+ /* add the reload before the (cond-)jump */
+ return last;
+}
+
+static ir_node *skip_keeps_phis(ir_node *node)
+{
+ node = sched_next(node);
+ while(is_Phi(node) || be_is_Keep(node)) {
+ node = sched_next(node);
+ }
+ return node;
+}
+
+/**
+ * Returns the point at which you can insert a node that should be executed
+ * before block @p block when coming from pred @p pos.
+ */
+static ir_node *get_block_insertion_point(ir_node *block, int pos)
+{
+ ir_node *predblock;
+
+ /* simply add the reload to the beginning of the block if we only have 1
+ * predecessor. We don't need to check for phis as there can't be any in a
+ * block with only 1 pred. */
+ if(get_Block_n_cfgpreds(block) == 1) {
+ assert(!is_Phi(sched_first(block)));
+ return sched_first(block);
+ }
+
+ /* We have to reload the value in pred-block */
+ predblock = get_Block_cfgpred_block(block, pos);
+ return be_get_end_of_block_insertion_point(predblock);
+}
+
+void be_add_reload_at_end(spill_env_t *env, ir_node *to_spill,
+ const ir_node *block,
+ const arch_register_class_t *reload_cls,
+ int allow_remat)
+{
+ ir_node *before = be_get_end_of_block_insertion_point(block);
+ be_add_reload(env, to_spill, before, reload_cls, allow_remat);
+}
+
+void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block,
+ int pos, const arch_register_class_t *reload_cls,
+ int allow_remat)
+{
+ ir_node *before = get_block_insertion_point(block, pos);
+ be_add_reload(env, to_spill, before, reload_cls, allow_remat);
+}
+
+void be_spill_phi(spill_env_t *env, ir_node *node)
+{
+ ir_node *block;
+ spill_info_t* spill;
+ int i, arity;
+
+ assert(is_Phi(node));
+
+ ir_nodeset_insert(&env->mem_phis, node);
+
+ /* create spills for the phi arguments */
+ block = get_nodes_block(node);
+ spill = get_spillinfo(env, node);
+ for(i = 0, arity = get_irn_arity(node); i < arity; ++i) {
+ ir_node *arg = get_irn_n(node, i);
+ ir_node *insert;
+ //get_spillinfo(env, arg);
+
+ /* some backends have virtual noreg/unknown nodes that are not scheduled
+ * and simply always available. */
+ if(!sched_is_scheduled(arg)) {
+ ir_node *pred_block = get_Block_cfgpred_block(block, i);
+ insert = be_get_end_of_block_insertion_point(pred_block);
+ } else {
+ insert = skip_keeps_phis(arg);
+ }