+
+void copystat_dump_pretty(ir_graph *irg) {
+ int i;
+ char buf[1024];
+ FILE *out;
+
+ snprintf(buf, sizeof(buf), "%s__%s", get_irp_prog_name(), get_entity_name(get_irg_entity(irg)));
+ buf[sizeof(buf) - 1] = '\0';
+ out = be_ffopen(buf, "pstat", "wt");
+
+ fprintf(out, "Nodes %4d\n", curr_vals[I_ALL_NODES]);
+ fprintf(out, "Blocks %4d\n", curr_vals[I_BLOCKS]);
+ fprintf(out, "CopyIrn %4d\n", curr_vals[I_CPY_CNT]);
+
+ fprintf(out, "\nPhis %4d\n", curr_vals[I_PHI_CNT]);
+ fprintf(out, "... argument types\n");
+ fprintf(out, " Total %4d\n", curr_vals[I_PHI_ARG_CNT]);
+ fprintf(out, " Self %4d\n", curr_vals[I_PHI_ARG_SELF]);
+ fprintf(out, " Constants %4d\n", curr_vals[I_PHI_ARG_CONST]);
+ fprintf(out, " CF-Pred %4d\n", curr_vals[I_PHI_ARG_PRED]);
+ fprintf(out, " Others %4d\n", curr_vals[I_PHI_ARG_GLOB]);
+ fprintf(out, "... arities\n");
+ for (i = I_PHI_ARITY_S; i<=I_PHI_ARITY_E; i++)
+ fprintf(out, " %2i %4d\n", i-I_PHI_ARITY_S, curr_vals[i]);
+
+ fprintf(out, "\nPhi classes %4d\n", curr_vals[I_CLS_CNT]);
+ fprintf(out, " compl. free %4d\n", curr_vals[I_CLS_IF_FREE]);
+ fprintf(out, " inner intf. %4d / %4d\n", curr_vals[I_CLS_IF_CNT], curr_vals[I_CLS_IF_MAX]);
+ fprintf(out, "... sizes\n");
+ for (i = I_CLS_SIZE_S; i<=I_CLS_SIZE_E; i++)
+ fprintf(out, " %2i %4d\n", i-I_CLS_SIZE_S, curr_vals[i]);
+ fprintf(out, "... contained phis\n");
+ for (i = I_CLS_PHIS_S; i<=I_CLS_PHIS_E; i++)
+ fprintf(out, " %2i %4d\n", i-I_CLS_PHIS_S, curr_vals[i]);
+
+ fprintf(out, "\nILP stat\n");
+ fprintf(out, " Time %8d\n", curr_vals[I_ILP_TIME]);
+ fprintf(out, " Iter %8d\n", curr_vals[I_ILP_ITER]);
+
+ fprintf(out, "\nCopy stat\n");
+ fprintf(out, " Max %4d\n", curr_vals[I_COPIES_MAX]);
+ fprintf(out, " Init %4d\n", curr_vals[I_COPIES_INIT]);
+ fprintf(out, " Heur %4d\n", curr_vals[I_COPIES_HEUR]);
+ fprintf(out, " Opt %4d\n", curr_vals[I_COPIES_OPT]);
+ fprintf(out, " Intf %4d\n", curr_vals[I_COPIES_IF]);
+
+ fclose(out);
+}
+
+/**
+ * Helpers for saving and restoring colors of nodes.
+ * Used to get dependable and comparable benchmark results.
+ */
+typedef struct color_saver {
+ be_chordal_env_t *chordal_env;
+ pmap *saved_colors;
+ int flag; /* 0 save, 1 load */
+} color_save_t;
+
+static void save_load(ir_node *irn, void *env) {
+ color_save_t *saver = env;
+ if (saver->chordal_env->cls == arch_get_irn_reg_class_out(irn)) {
+ if (saver->flag == 0) { /* save */
+ const arch_register_t *reg = arch_get_irn_register(irn);
+ pmap_insert(saver->saved_colors, irn, (void *) reg);
+ } else { /*load */
+ arch_register_t *reg = pmap_get(saver->saved_colors, irn);
+ arch_set_irn_register(irn, reg);
+ }
+ }
+}
+
+static void save_colors(color_save_t *color_saver) {
+ color_saver->flag = 0;
+ irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
+}
+
+#ifdef WITH_ILP
+static void load_colors(color_save_t *color_saver) {
+ color_saver->flag = 1;
+ irg_walk_graph(color_saver->chordal_env->irg, save_load, NULL, color_saver);
+}
+#endif
+
+/**
+ * Main compare routine
+ */
+void co_compare_solvers(be_chordal_env_t *chordal_env) {
+ copy_opt_t *co;
+ ir_timer_t *timer;
+ color_save_t saver;
+ int costs_inevit, costs_init, costs_solved, lower_bound;
+
+ copystat_collect_cls(chordal_env);
+
+ co = new_copy_opt(chordal_env, co_get_costs_loop_depth);
+ co_build_ou_structure(co);
+ co_build_graph_structure(co);
+ DBG((dbg, LEVEL_1, "----> CO: %s\n", co->name));
+
+ /* save colors */
+ saver.chordal_env = chordal_env;
+ saver.saved_colors = pmap_create();
+ save_colors(&saver);
+
+ /* initial values */
+ costs_inevit = co_get_inevit_copy_costs(co);
+ lower_bound = co_get_lower_bound(co);
+ costs_init = co_get_copy_costs(co);
+
+ DBG((dbg, LEVEL_1, "Inevit Costs: %3d\n", costs_inevit));
+ DBG((dbg, LEVEL_1, "Lower Bound: %3d\n", lower_bound));
+ DBG((dbg, LEVEL_1, "Init costs: %3d\n", costs_init));
+
+ copystat_add_inevit_costs(costs_inevit);
+ copystat_add_init_costs(costs_init);
+ copystat_add_max_costs(co_get_max_copy_costs(co));
+
+ /* heuristic 1 (Daniel Grund) */
+ timer = ir_timer_register("heur1", NULL);
+ ir_timer_reset_and_start(timer);
+
+ co_solve_heuristic(co);
+
+ ir_timer_stop(timer);
+
+ costs_solved = co_get_copy_costs(co);
+ DBG((dbg, LEVEL_1, "HEUR1 costs: %3d\n", costs_solved));
+ copystat_add_heur_time(ir_timer_elapsed_msec(timer));
+ copystat_add_heur_costs(costs_solved);
+ assert(lower_bound <= costs_solved);
+
+ /* heuristic 2 (Sebastian Hack) */
+ timer = ir_timer_register("heur2", NULL);
+ ir_timer_reset_and_start(timer);
+
+ co_solve_heuristic_new(co);
+
+ ir_timer_stop(timer);
+
+ costs_solved = co_get_copy_costs(co);
+ DBG((dbg, LEVEL_1, "HEUR2 costs: %3d\n", costs_solved));
+ copystat_add_heur_time(ir_timer_elapsed_msec(timer));
+ copystat_add_heur_costs(costs_solved);
+ assert(lower_bound <= costs_solved);
+
+ /* Park & Moon register coalescing (Kimon Hoffmann) */
+ timer = ir_timer_register("park", NULL);
+ ir_timer_reset_and_start(timer);
+
+ co_solve_park_moon(co);
+
+ ir_timer_stop(timer);
+
+ costs_solved = co_get_copy_costs(co);
+ DBG((dbg, LEVEL_1, "Park/Moon costs: %3d\n", costs_solved));
+ copystat_add_heur_time(ir_timer_elapsed_msec(timer));
+ copystat_add_heur_costs(costs_solved);
+ assert(lower_bound <= costs_solved);
+
+
+#ifdef WITH_ILP
+
+ /* ILP 1 is not yet implemented, so it makes no sense to compare */
+#if 0
+ load_colors(&saver);
+
+ co_solve_ilp1(co, 60.0);
+
+ costs_solved = co_get_copy_costs(co);
+ DBG((dbg, LEVEL_1, "ILP1 costs: %3d\n", costs_solved));
+ copystat_add_opt_costs(costs_solved); /* TODO: ADAPT */
+ assert(lower_bound <= costs_solved);
+#endif /* 0 */
+
+ /* ILP 2 */
+ load_colors(&saver);
+
+ co_solve_ilp2(co);
+
+ costs_solved = co_get_copy_costs(co);
+ DBG((dbg, LEVEL_1, "ILP2 costs: %3d\n", costs_solved));
+ copystat_add_opt_costs(costs_solved); /* TODO: ADAPT */
+ assert(lower_bound <= costs_solved);
+
+#endif /* WITH_ILP */
+
+ /* free memory for statistic structures */
+ pmap_destroy(saver.saved_colors);
+ co_free_graph_structure(co);
+ co_free_ou_structure(co);
+ free_copy_opt(co);
+}