typo fixed
[libfirm] / ir / be / bechordal_main.c
index fb3d9ad..d5c0b0e 100644 (file)
@@ -86,8 +86,10 @@ static be_ra_chordal_opts_t options = {
 static int be_elr_split = 0;
 
 typedef struct _post_spill_env_t {
-       be_chordal_env_t cenv;
-       double           pre_spill_cost;
+       be_chordal_env_t            cenv;
+       be_irg_t                    *birg;
+       const arch_register_class_t *cls;
+       double                      pre_spill_cost;
 } post_spill_env_t;
 
 static be_ra_timer_t ra_timer = {
@@ -115,6 +117,7 @@ static const lc_opt_enum_int_items_t lower_perm_stat_items[] = {
 };
 
 static const lc_opt_enum_int_items_t dump_items[] = {
+       { "none",       BE_CH_DUMP_NONE       },
        { "spill",      BE_CH_DUMP_SPILL      },
        { "live",       BE_CH_DUMP_LIVE       },
        { "color",      BE_CH_DUMP_COLOR      },
@@ -172,18 +175,6 @@ static void dump(unsigned mask, ir_graph *irg,
        }
 }
 
-static void put_ignore_colors(be_chordal_env_t *chordal_env)
-{
-       int n_colors = chordal_env->cls->n_regs;
-       int i;
-
-       bitset_clear_all(chordal_env->ignore_colors);
-       be_abi_put_ignore_regs(chordal_env->birg->abi, chordal_env->cls, chordal_env->ignore_colors);
-       for(i = 0; i < n_colors; ++i)
-               if(arch_register_type_is(&chordal_env->cls->regs[i], ignore))
-                       bitset_set(chordal_env->ignore_colors, i);
-}
-
 /**
  * Checks for every reload if it's user can perform the load on itself.
  */
@@ -243,17 +234,18 @@ typedef struct _node_stat_t {
 } node_stat_t;
 
 struct node_stat_walker {
-       node_stat_t *stat;
-       const be_chordal_env_t *cenv;
-       bitset_t *mem_phis;
+       node_stat_t      *stat;
+       const arch_env_t *arch_env;
+       bitset_t         *mem_phis;
+       const arch_register_class_t *cls;
 };
 
 static void node_stat_walker(ir_node *irn, void *data)
 {
-       struct node_stat_walker *env = data;
-       const arch_env_t *aenv       = env->cenv->birg->main_env->arch_env;
+       struct node_stat_walker *env  = data;
+       const arch_env_t        *aenv = env->arch_env;
 
-       if(arch_irn_consider_in_reg_alloc(aenv, env->cenv->cls, irn)) {
+       if (arch_irn_consider_in_reg_alloc(aenv, env->cls, irn)) {
 
                /* if the node is a normal phi */
                if(is_Phi(irn))
@@ -288,15 +280,16 @@ static void node_stat_walker(ir_node *irn, void *data)
        }
 }
 
-static void node_stats(const be_chordal_env_t *cenv, node_stat_t *stat)
+static void node_stats(be_irg_t *birg, const arch_register_class_t *cls, node_stat_t *stat)
 {
        struct node_stat_walker env;
 
        memset(stat, 0, sizeof(stat[0]));
-       env.cenv     = cenv;
-       env.mem_phis = bitset_irg_malloc(cenv->irg);
+       env.arch_env = birg->main_env->arch_env;
+       env.mem_phis = bitset_irg_malloc(birg->irg);
        env.stat     = stat;
-       irg_walk_graph(cenv->irg, NULL, node_stat_walker, &env);
+       env.cls      = cls;
+       irg_walk_graph(birg->irg, NULL, node_stat_walker, &env);
        bitset_free(env.mem_phis);
 }
 
@@ -390,33 +383,35 @@ static void be_init_timer(be_options_t *main_opts)
  */
 static void pre_spill(const arch_isa_t *isa, int cls_idx, post_spill_env_t *pse) {
        be_chordal_env_t *chordal_env = &pse->cenv;
+       be_irg_t         *birg        = pse->birg;
        node_stat_t      node_stat;
 
-       chordal_env->cls           = arch_isa_get_reg_class(isa, cls_idx);
+       pse->cls                   = arch_isa_get_reg_class(isa, cls_idx);
+       chordal_env->cls           = pse->cls;
        chordal_env->border_heads  = pmap_create();
        chordal_env->ignore_colors = bitset_malloc(chordal_env->cls->n_regs);
 
 #ifdef FIRM_STATISTICS
        if (be_stat_ev_is_active()) {
-               be_stat_tags[STAT_TAG_CLS] = chordal_env->cls->name;
+               be_stat_tags[STAT_TAG_CLS] = pse->cls->name;
                be_stat_ev_push(be_stat_tags, STAT_TAG_LAST, be_stat_file);
 
                /* perform some node statistics. */
-               node_stats(chordal_env, &node_stat);
+               node_stats(birg, pse->cls, &node_stat);
                be_stat_ev("phis_before_spill", node_stat.n_phis);
        }
 #endif /* FIRM_STATISTICS */
 
        /* put all ignore registers into the ignore register set. */
-       put_ignore_colors(chordal_env);
+       be_put_ignore_regs(birg, pse->cls, chordal_env->ignore_colors);
 
        be_pre_spill_prepare_constr(chordal_env);
-       dump(BE_CH_DUMP_CONSTR, chordal_env->irg, chordal_env->cls, "-constr-pre", dump_ir_block_graph_sched);
+       dump(BE_CH_DUMP_CONSTR, birg->irg, pse->cls, "-constr-pre", dump_ir_block_graph_sched);
 
 #ifdef FIRM_STATISTICS
        if (be_stat_ev_is_active()) {
-               pse->pre_spill_cost = be_estimate_irg_costs(chordal_env->irg,
-                       chordal_env->birg->main_env->arch_env, chordal_env->birg->exec_freq);
+               pse->pre_spill_cost = be_estimate_irg_costs(birg->irg,
+                       birg->main_env->arch_env, birg->exec_freq);
        }
 #endif /* FIRM_STATISTICS */
 }
@@ -424,10 +419,10 @@ static void pre_spill(const arch_isa_t *isa, int cls_idx, post_spill_env_t *pse)
 /**
  * Perform things which need to be done per register class after spilling.
  */
-static void post_spill(post_spill_env_t *pse) {
+static void post_spill(post_spill_env_t *pse, int iteration) {
        be_chordal_env_t    *chordal_env = &pse->cenv;
-       ir_graph            *irg         = chordal_env->irg;
-       be_irg_t            *birg        = chordal_env->birg;
+       be_irg_t            *birg        = pse->birg;
+       ir_graph            *irg         = birg->irg;
        const be_main_env_t *main_env    = birg->main_env;
        be_options_t        *main_opts   = main_env->options;
        static int          splitted     = 0;
@@ -439,7 +434,7 @@ static void post_spill(post_spill_env_t *pse) {
 
                be_stat_ev_l("spillcosts", (long) spillcosts);
 
-               node_stats(chordal_env, &node_stat);
+               node_stats(birg, pse->cls, &node_stat);
                be_stat_ev("phis_after_spill", node_stat.n_phis);
                be_stat_ev("mem_phis", node_stat.n_mem_phis);
                be_stat_ev("reloads", node_stat.n_reloads);
@@ -447,20 +442,26 @@ static void post_spill(post_spill_env_t *pse) {
        }
 #endif /* FIRM_STATISTICS */
 
-       check_for_memory_operands(chordal_env);
-
-       be_abi_fix_stack_nodes(birg->abi, birg->lv);
+       /*
+               If we have a backend provided spiller, post spill is
+               called in a loop after spilling for each register class.
+               But we only need to fix stack nodes once in this case.
+       */
+       if (iteration == 0) {
+               check_for_memory_operands(chordal_env);
+               be_abi_fix_stack_nodes(birg->abi, birg->lv);
+       }
 
        BE_TIMER_PUSH(ra_timer.t_verify);
 
        /* verify schedule and register pressure */
        if (chordal_env->opts->vrfy_option == BE_CH_VRFY_WARN) {
                be_verify_schedule(irg);
-               be_verify_register_pressure(chordal_env->birg, chordal_env->cls, irg);
+               be_verify_register_pressure(birg, pse->cls, irg);
        }
        else if (chordal_env->opts->vrfy_option == BE_CH_VRFY_ASSERT) {
                assert(be_verify_schedule(irg) && "Schedule verification failed");
-               assert(be_verify_register_pressure(chordal_env->birg, chordal_env->cls, irg)
+               assert(be_verify_register_pressure(birg, pse->cls, irg)
                        && "Register pressure verification failed");
        }
        BE_TIMER_POP(ra_timer.t_verify);
@@ -475,7 +476,7 @@ static void post_spill(post_spill_env_t *pse) {
        be_ra_chordal_color(chordal_env);
        BE_TIMER_POP(ra_timer.t_color);
 
-       dump(BE_CH_DUMP_CONSTR, irg, chordal_env->cls, "-color", dump_ir_block_graph_sched);
+       dump(BE_CH_DUMP_CONSTR, irg, pse->cls, "-color", dump_ir_block_graph_sched);
 
        /* Create the ifg with the selected flavor */
        BE_TIMER_PUSH(ra_timer.t_ifg);
@@ -485,12 +486,13 @@ static void post_spill(post_spill_env_t *pse) {
 #ifdef FIRM_STATISTICS
        if (be_stat_ev_is_active()) {
                be_ifg_stat_t stat;
-               be_ifg_stat(chordal_env, &stat);
+
+               be_ifg_stat(birg, chordal_env->ifg, &stat);
                be_stat_ev("ifg_nodes", stat.n_nodes);
                be_stat_ev("ifg_edges", stat.n_edges);
                be_stat_ev("ifg_comps", stat.n_comps);
 
-               node_stats(chordal_env, &node_stat);
+               node_stats(birg, pse->cls, &node_stat);
                be_stat_ev("perms_before_coal", node_stat.n_perms);
                be_stat_ev("copies_before_coal", node_stat.n_copies);
        }
@@ -501,7 +503,7 @@ static void post_spill(post_spill_env_t *pse) {
        co_driver(chordal_env);
        BE_TIMER_POP(ra_timer.t_copymin);
 
-       dump(BE_CH_DUMP_COPYMIN, irg, chordal_env->cls, "-copymin", dump_ir_block_graph_sched);
+       dump(BE_CH_DUMP_COPYMIN, irg, pse->cls, "-copymin", dump_ir_block_graph_sched);
 
        BE_TIMER_PUSH(ra_timer.t_ssa);
 
@@ -510,7 +512,7 @@ static void post_spill(post_spill_env_t *pse) {
 
        BE_TIMER_POP(ra_timer.t_ssa);
 
-       dump(BE_CH_DUMP_SSADESTR, irg, chordal_env->cls, "-ssadestr", dump_ir_block_graph_sched);
+       dump(BE_CH_DUMP_SSADESTR, irg, pse->cls, "-ssadestr", dump_ir_block_graph_sched);
 
        BE_TIMER_PUSH(ra_timer.t_verify);
        if (chordal_env->opts->vrfy_option != BE_CH_VRFY_OFF) {
@@ -518,13 +520,14 @@ static void post_spill(post_spill_env_t *pse) {
        }
        BE_TIMER_POP(ra_timer.t_verify);
 
+       /* free some data structures */
        be_ifg_free(chordal_env->ifg);
        pmap_destroy(chordal_env->border_heads);
        bitset_free(chordal_env->ignore_colors);
 
 #ifdef FIRM_STATISTICS
        if (be_stat_ev_is_active()) {
-               node_stats(chordal_env, &node_stat);
+               node_stats(birg, pse->cls, &node_stat);
                be_stat_ev("perms_after_coal", node_stat.n_perms);
                be_stat_ev("copies_after_coal", node_stat.n_copies);
                be_stat_ev_pop();
@@ -573,15 +576,16 @@ static void be_ra_chordal_main(be_irg_t *birg)
                        post_spill_env_t pse;
 
                        memcpy(&pse.cenv, &chordal_env, sizeof(chordal_env));
+                       pse.birg = birg;
                        pre_spill(isa, j, &pse);
 
                        BE_TIMER_PUSH(ra_timer.t_spill);
                        be_do_spill(&pse.cenv);
                        BE_TIMER_POP(ra_timer.t_spill);
 
-                       dump(BE_CH_DUMP_SPILL, irg, pse.cenv.cls, "-spill", dump_ir_block_graph_sched);
+                       dump(BE_CH_DUMP_SPILL, irg, pse.cls, "-spill", dump_ir_block_graph_sched);
 
-                       post_spill(&pse);
+                       post_spill(&pse, 0);
                }
        }
        else {
@@ -594,16 +598,17 @@ static void be_ra_chordal_main(be_irg_t *birg)
 
                for (j = 0; j < m; ++j) {
                        memcpy(&pse[j].cenv, &chordal_env, sizeof(chordal_env));
+                       pse[j].birg = birg;
                        pre_spill(isa, j, &pse[j]);
                }
 
                BE_TIMER_PUSH(ra_timer.t_spill);
-               arch_code_generator_spill(birg->cg, &chordal_env);
+               arch_code_generator_spill(birg->cg, birg);
                BE_TIMER_POP(ra_timer.t_spill);
                dump(BE_CH_DUMP_SPILL, irg, NULL, "-spill", dump_ir_block_graph_sched);
 
                for (j = 0; j < m; ++j) {
-                       post_spill(&pse[j]);
+                       post_spill(&pse[j], j);
                }
        }
 
@@ -627,7 +632,7 @@ static void be_ra_chordal_main(be_irg_t *birg)
        BE_TIMER_PUSH(ra_timer.t_epilog);
        dump(BE_CH_DUMP_LOWER, irg, NULL, "-spilloff", dump_ir_block_graph_sched);
 
-       lower_nodes_after_ra(&chordal_env, options.lower_perm_opt & BE_CH_LOWER_PERM_COPY ? 1 : 0);
+       lower_nodes_after_ra(birg, options.lower_perm_opt & BE_CH_LOWER_PERM_COPY ? 1 : 0);
        dump(BE_CH_DUMP_LOWER, irg, NULL, "-belower-after-ra", dump_ir_block_graph_sched);
 
        obstack_free(&chordal_env.obst, NULL);