besched: Add and use sched_replace().
[libfirm] / ir / be / bechordal_main.c
index d7cfa28..67f9eae 100644 (file)
@@ -32,7 +32,6 @@
 #include "pset.h"
 #include "list.h"
 #include "bitset.h"
-#include "iterator.h"
 
 #include "lc_opts.h"
 #include "lc_opts_enum.h"
@@ -40,7 +39,7 @@
 #include "ircons_t.h"
 #include "irmode_t.h"
 #include "irgraph_t.h"
-#include "irprintf_t.h"
+#include "irprintf.h"
 #include "irgwalk.h"
 #include "ircons.h"
 #include "irdump.h"
@@ -63,7 +62,7 @@
 #include "bearch.h"
 #include "beifg.h"
 #include "benode.h"
-#include "bestatevent.h"
+#include "statev_t.h"
 #include "bestat.h"
 #include "bemodule.h"
 #include "be_t.h"
 static be_ra_chordal_opts_t options = {
        BE_CH_DUMP_NONE,
        BE_CH_LOWER_PERM_SWAP,
-       BE_CH_VRFY_WARN,
-       "",
-       ""
+       BE_CH_VRFY_WARN
 };
 
-typedef struct post_spill_env_t {
-       be_chordal_env_t            cenv;
-       ir_graph                    *irg;
-       const arch_register_class_t *cls;
-       double                      pre_spill_cost;
-} post_spill_env_t;
-
 static const lc_opt_enum_int_items_t lower_perm_items[] = {
        { "copy", BE_CH_LOWER_PERM_COPY },
        { "swap", BE_CH_LOWER_PERM_SWAP },
@@ -235,47 +225,32 @@ static be_node_stats_t last_node_stats;
 /**
  * Perform things which need to be done per register class before spilling.
  */
-static void pre_spill(post_spill_env_t *pse, const arch_register_class_t *cls)
+static void pre_spill(be_chordal_env_t *const chordal_env, arch_register_class_t const *const cls, ir_graph *const irg)
 {
-       be_chordal_env_t *chordal_env = &pse->cenv;
-       ir_graph         *irg         = pse->irg;
-       ir_exec_freq     *exec_freq   = be_get_irg_exec_freq(irg);
-
-       pse->cls                      = cls;
        chordal_env->cls              = cls;
        chordal_env->border_heads     = pmap_create();
        chordal_env->allocatable_regs = bitset_malloc(chordal_env->cls->n_regs);
 
        be_assure_live_chk(irg);
 
-       if (stat_ev_enabled) {
-               pse->pre_spill_cost = be_estimate_irg_costs(irg, exec_freq);
-       }
-
        /* put all ignore registers into the ignore register set. */
-       be_put_allocatable_regs(irg, pse->cls, chordal_env->allocatable_regs);
+       be_put_allocatable_regs(irg, cls, chordal_env->allocatable_regs);
 
        be_timer_push(T_RA_CONSTR);
        be_pre_spill_prepare_constr(irg, chordal_env->cls);
        be_timer_pop(T_RA_CONSTR);
 
-       dump(BE_CH_DUMP_CONSTR, irg, pse->cls, "constr-pre");
+       dump(BE_CH_DUMP_CONSTR, irg, cls, "constr-pre");
 }
 
 /**
  * Perform things which need to be done per register class after spilling.
  */
-static void post_spill(post_spill_env_t *pse, int iteration)
+static void post_spill(be_chordal_env_t *const chordal_env, ir_graph *const irg)
 {
-       be_chordal_env_t *chordal_env = &pse->cenv;
-       ir_graph         *irg         = pse->irg;
-       ir_exec_freq     *exec_freq   = be_get_irg_exec_freq(irg);
-       int               allocatable_regs = be_get_n_allocatable_regs(irg, chordal_env->cls);
-
        /* some special classes contain only ignore regs, no work to be done */
+       int const allocatable_regs = be_get_n_allocatable_regs(irg, chordal_env->cls);
        if (allocatable_regs > 0) {
-               stat_ev_dbl("bechordal_spillcosts", be_estimate_irg_costs(irg, exec_freq) - pse->pre_spill_cost);
-
                /*
                        If we have a backend provided spiller, post spill is
                        called in a loop after spilling for each register class.
@@ -283,9 +258,7 @@ static void post_spill(post_spill_env_t *pse, int iteration)
                */
                be_timer_push(T_RA_SPILL_APPLY);
                check_for_memory_operands(irg);
-               if (iteration == 0) {
-                       be_abi_fix_stack_nodes(irg);
-               }
+               be_abi_fix_stack_nodes(irg);
                be_timer_pop(T_RA_SPILL_APPLY);
 
 
@@ -293,10 +266,10 @@ static void post_spill(post_spill_env_t *pse, int iteration)
                be_timer_push(T_VERIFY);
                if (chordal_env->opts->vrfy_option == BE_CH_VRFY_WARN) {
                        be_verify_schedule(irg);
-                       be_verify_register_pressure(irg, pse->cls);
+                       be_verify_register_pressure(irg, chordal_env->cls);
                } else if (chordal_env->opts->vrfy_option == BE_CH_VRFY_ASSERT) {
                        assert(be_verify_schedule(irg) && "Schedule verification failed");
-                       assert(be_verify_register_pressure(irg, pse->cls)
+                       assert(be_verify_register_pressure(irg, chordal_env->cls)
                                && "Register pressure verification failed");
                }
                be_timer_pop(T_VERIFY);
@@ -306,7 +279,7 @@ static void post_spill(post_spill_env_t *pse, int iteration)
                be_ra_chordal_coloring(chordal_env);
                be_timer_pop(T_RA_COLOR);
 
-               dump(BE_CH_DUMP_CONSTR, irg, pse->cls, "color");
+               dump(BE_CH_DUMP_CONSTR, irg, chordal_env->cls, "color");
 
                /* Create the ifg with the selected flavor */
                be_timer_push(T_RA_IFG);
@@ -335,14 +308,14 @@ static void post_spill(post_spill_env_t *pse, int iteration)
                co_driver(chordal_env);
                be_timer_pop(T_RA_COPYMIN);
 
-               dump(BE_CH_DUMP_COPYMIN, irg, pse->cls, "copymin");
+               dump(BE_CH_DUMP_COPYMIN, irg, chordal_env->cls, "copymin");
 
                /* ssa destruction */
                be_timer_push(T_RA_SSA);
                be_ssa_destruction(chordal_env);
                be_timer_pop(T_RA_SSA);
 
-               dump(BE_CH_DUMP_SSADESTR, irg, pse->cls, "ssadestr");
+               dump(BE_CH_DUMP_SSADESTR, irg, chordal_env->cls, "ssadestr");
 
                if (chordal_env->opts->vrfy_option != BE_CH_VRFY_OFF) {
                        be_timer_push(T_VERIFY);
@@ -371,24 +344,17 @@ static void be_ra_chordal_main(ir_graph *irg)
        const arch_env_t *arch_env = be_get_irg_arch_env(irg);
        int               j;
        int               m;
-       be_chordal_env_t  chordal_env;
-       struct obstack    obst;
 
        be_timer_push(T_RA_OTHER);
 
-       be_timer_push(T_RA_PROLOG);
-
-       chordal_env.obst             = &obst;
+       be_chordal_env_t chordal_env;
+       obstack_init(&chordal_env.obst);
        chordal_env.opts             = &options;
        chordal_env.irg              = irg;
        chordal_env.border_heads     = NULL;
        chordal_env.ifg              = NULL;
        chordal_env.allocatable_regs = NULL;
 
-       obstack_init(&obst);
-
-       be_timer_pop(T_RA_PROLOG);
-
        if (stat_ev_enabled) {
                be_collect_node_stats(&last_node_stats, irg);
        }
@@ -397,7 +363,6 @@ static void be_ra_chordal_main(ir_graph *irg)
 
        /* Perform the following for each register class. */
        for (j = 0, m = arch_env->n_register_classes; j < m; ++j) {
-               post_spill_env_t pse;
                const arch_register_class_t *cls = &arch_env->register_classes[j];
 
                if (arch_register_class_flags(cls) & arch_register_class_flag_manual_ra)
@@ -406,21 +371,23 @@ static void be_ra_chordal_main(ir_graph *irg)
 
                stat_ev_ctx_push_str("bechordal_cls", cls->name);
 
+               double pre_spill_cost = 0;
                if (stat_ev_enabled) {
                        be_do_stat_reg_pressure(irg, cls);
+                       pre_spill_cost = be_estimate_irg_costs(irg);
                }
 
-               pse.cenv = chordal_env;
-               pse.irg = irg;
-               pre_spill(&pse, cls);
+               pre_spill(&chordal_env, cls, irg);
 
                be_timer_push(T_RA_SPILL);
                be_do_spill(irg, cls);
                be_timer_pop(T_RA_SPILL);
 
-               dump(BE_CH_DUMP_SPILL, irg, pse.cls, "spill");
+               dump(BE_CH_DUMP_SPILL, irg, cls, "spill");
+
+               stat_ev_dbl("bechordal_spillcosts", be_estimate_irg_costs(irg) - pre_spill_cost);
 
-               post_spill(&pse, 0);
+               post_spill(&chordal_env, irg);
 
                if (stat_ev_enabled) {
                        be_node_stats_t node_stats;
@@ -447,7 +414,7 @@ static void be_ra_chordal_main(ir_graph *irg)
        lower_nodes_after_ra(irg, options.lower_perm_opt == BE_CH_LOWER_PERM_COPY);
        dump(BE_CH_DUMP_LOWER, irg, NULL, "belower-after-ra");
 
-       obstack_free(&obst, NULL);
+       obstack_free(&chordal_env.obst, NULL);
        be_invalidate_live_sets(irg);
        be_timer_pop(T_RA_EPILOG);