-void be_compute_spill_offsets(be_chordal_env_t *cenv) {
- ss_env_t ssenv;
- spill_slot_t **ss;
- int ss_size;
- pmap_entry *pme;
-
- obstack_init(&ssenv.ob);
- ssenv.cenv = cenv;
- ssenv.slots = pmap_create();
- ssenv.types = pmap_create();
- ssenv.dbg = firm_dbg_register("ir.be.spillslots");
-
- /* Get initial spill slots */
- irg_walk_graph(cenv->irg, NULL, compute_spill_slots_walker, &ssenv);
-
- /* Build an empty array for optimized spill slots */
- ss_size = pmap_count(ssenv.slots);
- ss = obstack_alloc(&ssenv.ob, ss_size * sizeof(*ss));
- optimize_slots(&ssenv, ss_size, ss);
-
- /* Integrate slots into the stack frame entity */
- assign_entities(&ssenv, ss_size, ss);
-
- /* Clean up */
- pmap_foreach(ssenv.slots, pme)
- del_pset(((spill_slot_t *)pme->value)->members);
- pmap_destroy(ssenv.slots);
- pmap_destroy(ssenv.types);
- obstack_free(&ssenv.ob, NULL);
-
- be_copy_entities_to_reloads(cenv->irg);
+/*
+ * ___ _ ____ _ _
+ * |_ _|_ __ ___ ___ _ __| |_ | _ \ ___| | ___ __ _ __| |___
+ * | || '_ \/ __|/ _ \ '__| __| | |_) / _ \ |/ _ \ / _` |/ _` / __|
+ * | || | | \__ \ __/ | | |_ | _ < __/ | (_) | (_| | (_| \__ \
+ * |___|_| |_|___/\___|_| \__| |_| \_\___|_|\___/ \__,_|\__,_|___/
+ *
+ */
+
+void be_insert_spills_reloads(spill_env_t *env) {
+ const arch_env_t *arch_env = env->arch_env;
+ int remats = 0;
+ int reloads = 0;
+ int spills = 0;
+ spill_info_t *si;
+ ir_nodeset_iterator_t iter;
+ ir_node *node;
+
+ /* create all phi-ms first, this is needed so, that phis, hanging on
+ spilled phis work correctly */
+ foreach_ir_nodeset(&env->mem_phis, node, iter) {
+ spill_info_t *info = get_spillinfo(env, node);
+ spill_phi(env, info);
+ }
+
+ /* process each spilled node */
+ for (si = set_first(env->spills); si; si = set_next(env->spills)) {
+ reloader_t *rld;
+ ir_node *spilled_node = si->spilled_node;
+ ir_mode *mode = get_irn_mode(spilled_node);
+ ir_node **copies = NEW_ARR_F(ir_node*, 0);
+
+ DBG((env->dbg, LEVEL_1, "\nhandling all reloaders of %+F:\n", spilled_node));
+
+ /* go through all reloads for this spill */
+ for (rld = si->reloaders; rld; rld = rld->next) {
+ ir_node *copy; /* a reaload is a "copy" of the original value */
+
+ if (rld->rematted_node != NULL) {
+ copy = rld->rematted_node;
+ remats++;
+ sched_add_before(rld->reloader, copy);
+ } else if (be_do_remats && rld->allow_remat &&
+ check_remat_conditions(env, spilled_node, rld->reloader)) {
+ copy = do_remat(env, spilled_node, rld->reloader);
+ remats++;
+ } else {
+ /* make sure we have a spill */
+ if (si->spill == NULL) {
+ spill_node(env, si);
+ spills++;
+ }
+
+ /* create a reload */
+ copy = be_reload(arch_env, si->reload_cls, rld->reloader, mode, si->spill);
+ reloads++;
+ }
+
+ DBG((env->dbg, LEVEL_1, " %+F of %+F before %+F\n",
+ copy, spilled_node, rld->reloader));
+ ARR_APP1(ir_node*, copies, copy);
+ }
+
+ /* if we had any reloads or remats, then we need to reconstruct the
+ * SSA form for the spilled value */
+ if (ARR_LEN(copies) > 0) {
+ /* Matze: used mem_phis as ignore uses in the past, I don't see how
+ one of the mem_phis can be a use of the spilled value...
+ so I changed this to NULL now */
+ be_ssa_construction(
+ be_get_birg_dom_front(env->birg),
+ be_get_birg_liveness(env->birg),
+ spilled_node, ARR_LEN(copies), copies,
+ NULL, 0);
+ }
+
+ DEL_ARR_F(copies);
+ si->reloaders = NULL;
+ }
+
+#ifdef FIRM_STATISTICS
+ if (be_stat_ev_is_active()) {
+ be_stat_ev("spill_spills", spills);
+ be_stat_ev("spill_reloads", reloads);
+ be_stat_ev("spill_remats", remats);
+ }
+#endif /* FIRM_STATISTICS */
+
+ be_remove_dead_nodes_from_schedule(env->irg);
+ /* Matze: In theory be_ssa_construction should take care of the livenes...
+ * try to disable this again in the future */
+ be_invalidate_liveness(env->birg);