- obstack_init(&env.obst);
- env.chordal_env = chordal_env;
- env.spills = new_set(cmp_spill, 10);
- env.reloads = NEW_ARR_F(ir_node*, 0);
- env.affinity_edges = NEW_ARR_F(affinity_edge_t*, 0);
- env.memperms = new_set(cmp_memperm, 10);
- FIRM_DBG_REGISTER(dbg, "firm.be.spillslots");
- //firm_dbg_set_mask(dbg, DBG_COALESCING);
+ slotcount = 0;
+ for(spill = set_first(env->spills); spill != NULL;
+ spill = set_next(env->spills)) {
+ int spillslot = spill->spillslot;
+ if(!bitset_is_set(counted, spillslot)) {
+ slotcount++;
+ bitset_set(counted, spillslot);
+ }
+ }
+
+ return slotcount;
+}
+
+be_fec_env_t *be_new_frame_entity_coalescer(be_irg_t *birg)
+{
+ const arch_env_t *arch_env = birg->main_env->arch_env;
+ be_fec_env_t *env = xmalloc(sizeof(env[0]));
+
+ be_liveness_assure_chk(be_assure_liveness(birg));
+
+ obstack_init(&env->obst);
+ env->arch_env = arch_env;
+ env->birg = birg;
+ env->spills = new_set(cmp_spill, 10);
+ env->reloads = NEW_ARR_F(ir_node*, 0);
+ env->affinity_edges = NEW_ARR_F(affinity_edge_t*, 0);
+ env->memperms = new_set(cmp_memperm, 10);
+
+ return env;
+}
+
+void be_free_frame_entity_coalescer(be_fec_env_t *env)
+{
+ del_set(env->memperms);
+ DEL_ARR_F(env->reloads);
+ DEL_ARR_F(env->affinity_edges);
+ del_set(env->spills);
+ obstack_free(&env->obst, NULL);
+
+ free(env);
+}
+
+void be_assign_entities(be_fec_env_t *env)
+{
+ stat_ev_dbl("spillslots", set_count(env->spills));
+
+ if(be_coalesce_spill_slots) {
+ do_greedy_coalescing(env);
+ }
+
+ stat_ev_dbl("spillslots_after_coalescing", count_spillslots(env));
+
+ assign_spillslots(env);
+
+ create_memperms(env);
+}
+
+/**
+ * This walker function searches for reloads and collects all the spills
+ * and memphis attached to them.
+ */
+static void collect_spills_walker(ir_node *node, void *data)
+{
+ be_fec_env_t *env = data;
+ const arch_env_t *arch_env = env->arch_env;
+ const ir_mode *mode;
+ const arch_register_class_t *cls;
+ int align;
+
+ /* classify returns classification of the irn the proj is attached to */
+ if (is_Proj(node))
+ return;
+
+ if (!arch_irn_class_is(arch_env, node, reload))
+ return;
+
+ mode = get_irn_mode(node);
+ cls = arch_get_irn_reg_class(arch_env, node, -1);
+ align = arch_env_get_reg_class_alignment(arch_env, cls);