bestack: Fetch the start block only once.
[libfirm] / ir / be / belistsched.c
index b5eca5c..dbdf8cf 100644 (file)
@@ -22,7 +22,6 @@
  * @brief       Primitive list scheduling with different node selectors.
  * @author      Sebastian Hack
  * @date        20.10.2004
- * @version     $Id$
  */
 #include "config.h"
 
 
 #include "obst.h"
 #include "list.h"
-#include "iterator.h"
 
 #include "iredges_t.h"
 #include "irgwalk.h"
 #include "irnode_t.h"
 #include "irmode_t.h"
 #include "irdump.h"
-#include "irprintf_t.h"
+#include "irprintf.h"
 #include "array.h"
 #include "debug.h"
 #include "irtools.h"
 #include "belistsched.h"
 #include "bearch.h"
 #include "bestat.h"
-#include "beirg.h"
 
 #include "lc_opts.h"
 #include "lc_opts_enum.h"
 
-/* we have prolog, "normal" and epilog */
-#define N_PRIORITY_CLASSES  3
-
-DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL);
+DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 
 /**
  * Scheduling environment for the whole graph.
@@ -82,28 +76,13 @@ typedef struct block_sched_env_t {
        /** scheduling info per node, copied from the global scheduler object */
        unsigned                    *scheduled;
        /** the set of candidates */
-       ir_nodeset_t                 cands[N_PRIORITY_CLASSES];
+       ir_nodeset_t                 cands;
        ir_node                     *block;     /**< the current block */
        sched_env_t                 *sched_env; /**< the scheduler environment */
        const list_sched_selector_t *selector;
        void                        *selector_block_env;
 } block_sched_env_t;
 
-/**
- * map prolog/normal/epilog into 3 priority levels
- */
-static unsigned get_priority(const ir_node *node)
-{
-       arch_irn_flags_t flags = arch_irn_get_flags(node);
-       if (flags & arch_irn_flags_prolog) {
-               assert(! (flags & arch_irn_flags_epilog));
-               return 0;
-       } else if (flags & arch_irn_flags_epilog) {
-               return 2;
-       }
-       return 1;
-}
-
 /**
  * Returns non-zero if the node is already scheduled
  */
@@ -132,15 +111,14 @@ static void add_to_sched(block_sched_env_t *env, ir_node *irn);
 static void node_ready(block_sched_env_t *env, ir_node *pred, ir_node *irn)
 {
        if (is_Proj(irn)
-           || (arch_irn_get_flags(irn) & arch_irn_flags_not_scheduled)) {
+           || (arch_get_irn_flags(irn) & arch_irn_flags_not_scheduled)) {
                selected(env, irn);
                DB((dbg, LEVEL_3, "\tmaking immediately available: %+F\n", irn));
        } else if (be_is_Keep(irn) || be_is_CopyKeep(irn)) {
                /* Keeps must be scheduled immediately */
                add_to_sched(env, irn);
        } else {
-               unsigned priority = get_priority(irn);
-               ir_nodeset_insert(&env->cands[priority], irn);
+               ir_nodeset_insert(&env->cands, irn);
 
                /* Notify selector about the ready node. */
                if (env->selector->node_ready)
@@ -184,8 +162,6 @@ static void try_make_ready(block_sched_env_t *env, ir_node *pred, ir_node *irn)
 
 static void selected(block_sched_env_t *env, ir_node *node)
 {
-       const ir_edge_t *edge;
-
        /* notify the selector about the finally selected node. */
        if (env->selector->node_selected)
                env->selector->node_selected(env->selector_block_env, node);
@@ -212,16 +188,14 @@ static void selected(block_sched_env_t *env, ir_node *node)
  */
 static void add_to_sched(block_sched_env_t *env, ir_node *irn)
 {
-       unsigned priority = get_priority(irn);
-
-       assert(! (arch_irn_get_flags(irn) & arch_irn_flags_not_scheduled));
+       assert(! (arch_get_irn_flags(irn) & arch_irn_flags_not_scheduled));
 
        sched_add_before(env->block, irn);
 
        DB((dbg, LEVEL_2, "\tschedule %+F\n", irn));
 
        /* Remove the node from the ready set */
-       ir_nodeset_remove(&env->cands[priority], irn);
+       ir_nodeset_remove(&env->cands, irn);
 
        selected(env, irn);
 }
@@ -243,8 +217,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        const list_sched_selector_t *selector = env->selector;
 
        block_sched_env_t be;
-       const ir_edge_t *edge;
-       unsigned p;
+       ir_nodeset_t *cands = &be.cands;
 
        /* Initialize the block's list head that will hold the schedule. */
        sched_init_block(block);
@@ -253,9 +226,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        be.block     = block;
        be.selector  = selector;
        be.sched_env = env;
-       for (p = 0; p < N_PRIORITY_CLASSES; ++p) {
-               ir_nodeset_init_size(&be.cands[p], get_irn_n_edges(block));
-       }
+       ir_nodeset_init_size(cands, get_irn_n_edges(block));
 
        DB((dbg, LEVEL_1, "scheduling %+F\n", block));
 
@@ -279,29 +250,20 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        }
 
        /* Iterate over all remaining nodes */
-       for (p = 0; p < N_PRIORITY_CLASSES; ++p) {
-               ir_nodeset_t *p_cands = &be.cands[p];
-               while (ir_nodeset_size(p_cands) > 0) {
-                       ir_node *irn = be.selector->select(be.selector_block_env, p_cands);
-                       DB((dbg, LEVEL_2, "\tpicked node %+F\n", irn));
-
-                       /* remove the scheduled node from the ready list. */
-                       ir_nodeset_remove(p_cands, irn);
-                       /* Add the node to the schedule. */
-                       add_to_sched(&be, irn);
-               }
+       while (ir_nodeset_size(cands) > 0) {
+               ir_node *irn = be.selector->select(be.selector_block_env, cands);
+               DB((dbg, LEVEL_2, "\tpicked node %+F\n", irn));
+
+               /* remove the scheduled node from the ready list. */
+               ir_nodeset_remove(cands, irn);
+               /* Add the node to the schedule. */
+               add_to_sched(&be, irn);
        }
 
+       ir_nodeset_destroy(cands);
+
        if (selector->finish_block)
                selector->finish_block(be.selector_block_env);
-
-       for (p = 0; p < N_PRIORITY_CLASSES; ++p) {
-               /** all cand lists should be empty. Otherwise there was some invalid
-                * dependencies between priority classes (ie. priority 0 value depending
-                * on a priority 1 value) */
-               assert(ir_nodeset_size(&be.cands[p]) == 0);
-               ir_nodeset_init_size(&be.cands[p], get_irn_n_edges(block));
-       }
 }
 
 /* List schedule a graph. */
@@ -336,7 +298,7 @@ void be_list_sched_graph(ir_graph *irg, const list_sched_selector_t *selector)
        free(env.scheduled);
 }
 
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_listsched);
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_listsched)
 void be_init_listsched(void)
 {
        FIRM_DBG_REGISTER(dbg, "firm.be.sched");