assert(arch_irn_consider_in_reg_alloc(env->chordal_env->birg->main_env->arch_env, env->cls, to_spill));
+ if(is_Phi(to_spill)) {
+ be_spill_phi(env, to_spill);
+ }
+
templ.spilled_node = to_spill;
templ.reloaders = NULL;
res = set_insert(env->spills, &templ, sizeof(templ), HASH_PTR(to_spill));
#define set_block_info(blk, info) set_irn_link(blk, info)
/**
- * @return The distance to the next use
- * Or 0 if irn is an ignore node
+ * @return The distance to the next use or 0 if irn has dont_spill flag set
*/
-static INLINE unsigned get_distance(belady_env_t *bel, const ir_node *from, unsigned from_step, const ir_node *def, int skip_from_uses)
+static INLINE unsigned get_distance(belady_env_t *env, const ir_node *from, unsigned from_step, const ir_node *def, int skip_from_uses)
{
- unsigned dist = be_get_next_use(bel->uses, from, from_step, def, skip_from_uses);
+ int flags = arch_irn_get_flags(env->arch, def);
+ unsigned dist = be_get_next_use(env->uses, from, from_step, def, skip_from_uses);
- assert(! (arch_irn_get_flags(bel->arch, def) & (arch_irn_flags_ignore | arch_irn_flags_dont_spill)));
+ assert(! (flags & arch_irn_flags_ignore));
+ // we have to keep nonspillable nodes in the workingset
+ if(flags & arch_irn_flags_dont_spill)
+ return 0;
return dist;
}
if (!is_Phi(irn) || get_nodes_block(irn) != blk)
continue;
- be_spill_phi(env->senv, irn);
+ //be_spill_phi(env->senv, irn);
}
obstack_free(&ob, NULL);
#include "bespillmorgan.h"
-#include "bechordal.h"
#include "bechordal_t.h"
#include "bespill.h"
-#include "belive.h"
#include "belive_t.h"
#include "irgwalk.h"
#include "besched.h"
#include "beutil.h"
-#include "irloop.h"
#include "irloop_t.h"
-#include "irgraph.h"
#include "irgraph_t.h"
-#include "irphase.h"
#include "irphase_t.h"
#include "irprintf.h"
//---------------------------------------------------------------------------
+static INLINE int consider_for_spilling(const arch_env_t *env, const arch_register_class_t *cls, const ir_node *node) {
+ if(!arch_irn_has_reg_class(env, node, -1, cls))
+ return 0;
+
+ return !(arch_irn_get_flags(env, node) & (arch_irn_flags_ignore | arch_irn_flags_dont_spill));
+}
+
/**
* Determine edges going out of a loop (= edges that go to a block that is not inside
* the loop or one of its subloops)
if(!live_is_in(li) || !live_is_out(li))
continue;
- if(!arch_irn_consider_in_reg_alloc(env->arch, env->cls, li->irn))
+ if(!consider_for_spilling(env->arch, env->cls, li->irn))
continue;
node_idx = get_irn_idx(li->irn);
to_spill = get_idx_irn(env->irg, i);
foreach_block_succ(block, edge) {
DBG((dbg, DBG_PRESSURE, "Spilling node %+F around block %+F\n", to_spill, block));
- if(is_Phi(to_spill)) {
- be_spill_phi(env->senv, to_spill);
- }
be_add_reload_on_edge(env->senv, to_spill, edge->src, edge->pos);
}
}
ir_node *to_spill = get_idx_irn(env->irg, i);
for(edge = set_first(loop_attr->out_edges); edge != NULL; edge = set_next(loop_attr->out_edges)) {
- if(is_Phi(to_spill)) {
- be_spill_phi(env->senv, to_spill);
- }
-
be_add_reload_on_edge(env->senv, to_spill, edge->block, edge->pos);
}
}