irn classify is now a mask
[libfirm] / ir / be / belistsched.c
index 4db8f1e..2f11c87 100644 (file)
@@ -102,7 +102,7 @@ static ir_node *trivial_select(void *block_env, nodeset *ready_set)
        for (irn = nodeset_first(ready_set); irn; irn = nodeset_next(ready_set)) {
                arch_irn_class_t irn_class = arch_irn_classify(arch_env, irn);
 
-               if (irn_class != arch_irn_class_branch && (const_last ? (irn_class != arch_irn_class_const) : 1)) {
+               if (! arch_irn_class_is(arch_env, irn, branch) && (const_last ? (! arch_irn_class_is(arch_env, irn, const)) : 1)) {
                        nodeset_break(ready_set);
                        return irn;
                }
@@ -111,7 +111,7 @@ static ir_node *trivial_select(void *block_env, nodeset *ready_set)
        /* assure that constants are executed before branches */
        if (const_last) {
                for (irn = nodeset_first(ready_set); irn; irn = nodeset_next(ready_set)) {
-                       if (arch_irn_classify(arch_env, irn) != arch_irn_class_branch) {
+                       if (! arch_irn_class_is(arch_env, irn, branch)) {
                                nodeset_break(ready_set);
                                return irn;
                        }
@@ -138,12 +138,12 @@ static void *trivial_init_block(void *graph_env, ir_node *bl)
 
 static INLINE int must_appear_in_schedule(const list_sched_selector_t *sel, void *block_env, const ir_node *irn)
 {
-       int res = 0;
+       int res = -1;
 
        if(sel->to_appear_in_schedule)
                res = sel->to_appear_in_schedule(block_env, irn);
 
-       return res || to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_RegParams(irn);
+       return res >= 0 ? res : (to_appear_in_schedule(irn) || be_is_Keep(irn) || be_is_RegParams(irn));
 }
 
 static const list_sched_selector_t trivial_selector_struct = {
@@ -294,12 +294,14 @@ static void *reg_pressure_block_init(void *graph_env, ir_node *bl)
                        int i, n;
 
                        for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
-                               ir_node *op = get_irn_n(irn, i);
+                               //ir_node *op = get_irn_n(irn, i);
                                if(must_appear_in_schedule(env->main_env->vtab, env, irn)) {
                                        usage_stats_t *us = get_or_set_usage_stats(env, irn);
+#if 0 /* Liveness is not computed here! */
                                        if(is_live_end(bl, op))
                                                us->uses_in_block = 99999;
                                        else
+#endif
                                                us->uses_in_block++;
                                }
                        }
@@ -369,7 +371,7 @@ static ir_node *reg_pressure_select(void *block_env, nodeset *ready_set)
                        Ignore branch instructions for the time being.
                        They should only be scheduled if there is nothing else.
                */
-               if (arch_irn_classify(env->main_env->arch_env, irn) != arch_irn_class_branch) {
+               if (! arch_irn_class_is(env->main_env->arch_env, irn, branch)) {
                        int costs = reg_pr_costs(env, irn);
                        if (costs <= curr_cost) {
                                res       = irn;
@@ -598,17 +600,6 @@ static INLINE void make_users_ready(block_sched_env_t *env, ir_node *irn)
        }
 }
 
-/**
- * Compare to nodes using pointer equality.
- * @param p1 Node one.
- * @param p2 Node two.
- * @return 0 if they are identical.
- */
-static int node_cmp_func(const void *p1, const void *p2)
-{
-    return p1 != p2;
-}
-
 /**
  * Append an instruction to a schedule.
  * @param env The block scheduling environment.
@@ -712,6 +703,8 @@ static int is_root(ir_node *root, ir_node *block) {
 static char _mark;
 #define MARK   &_mark
 
+static firm_dbg_module_t *xxxdbg;
+
 /**
  * descent into a dag and create a pre-order list.
  */
@@ -723,6 +716,7 @@ static void descent(ir_node *root, ir_node *block, ir_node **list) {
                for (i = get_irn_arity(root) - 1; i >= 0; --i) {
                        ir_node *pred = get_irn_n(root, i);
 
+                       DBG((xxxdbg, LEVEL_3, "   node %+F\n", pred));
                        /* Blocks may happen as predecessors of End nodes */
                        if (is_Block(pred))
                                continue;
@@ -735,6 +729,8 @@ static void descent(ir_node *root, ir_node *block, ir_node **list) {
                        if (get_nodes_block(pred) != block)
                                continue;
 
+                       set_irn_link(pred, NULL);
+
                        descent(pred, block, list);
                }
        }
@@ -779,8 +775,9 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        be.selector          = selector;
        be.sched_env         = env;
        FIRM_DBG_REGISTER(be.dbg, "firm.be.sched");
+       FIRM_DBG_REGISTER(xxxdbg, "firm.be.sched");
 
-//     firm_dbg_set_mask(be.dbg, SET_LEVEL_3);
+       //      firm_dbg_set_mask(be.dbg, SET_LEVEL_3);
 
        if (selector->init_block)
                be.selector_block_env = selector->init_block(env->selector_env, block);
@@ -804,17 +801,18 @@ static void list_sched_block(ir_node *block, void *env_ptr)
        preord = NULL;
        for (curr = root; curr; curr = irn) {
                irn = get_irn_link(curr);
+               DBG((be.dbg, LEVEL_2, "   DAG root %+F\n", curr));
                descent(curr, block, &preord);
        }
        root = preord;
 
        /* Third step: calculate the Delay. Note that our
-        * list is now in pre-order, starting at root
-        */
+       * list is now in pre-order, starting at root
+       */
        for (curr = root; curr; curr = get_irn_link(curr)) {
                sched_timestep_t d;
 
-               if (arch_irn_classify(env->arch_env, curr) == arch_irn_class_branch) {
+               if (arch_irn_class_is(env->arch_env, curr, branch)) {
                        /* assure, that branches can be executed last */
                        d = 0;
                }
@@ -853,7 +851,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
 
                if (is_Phi(irn)) {
                        /* Phi functions are scheduled immediately, since they only transfer
-                        * data flow from the predecessors to this block. */
+                       * data flow from the predecessors to this block. */
 
                        /* Increase the time step. */
                        be.curr_time += get_irn_etime(&be, irn);
@@ -869,7 +867,7 @@ static void list_sched_block(ir_node *block, void *env_ptr)
                }
                else {
                        /* Other nodes must have all operands in other blocks to be made
-                        * ready */
+                       * ready */
                        int ready = 1;
 
                        /* Check, if the operands of a node are not local to this block */
@@ -909,10 +907,10 @@ static void list_sched_block(ir_node *block, void *env_ptr)
 
                /* calculate mcands and ecands */
                foreach_nodeset(be.cands, irn) {
-      if (be_is_Keep(irn)) {
-        nodeset_break(be.cands);
-        break;
-      }
+                       if (be_is_Keep(irn)) {
+                               nodeset_break(be.cands);
+                               break;
+                       }
                        if (get_irn_delay(&be, irn) == max_delay) {
                                nodeset_insert(mcands, irn);
                                if (get_irn_etime(&be, irn) <= be.curr_time)
@@ -920,42 +918,39 @@ static void list_sched_block(ir_node *block, void *env_ptr)
                        }
                }
 
-    if (irn) {
-      /* Keeps must be immediately scheduled */
-    }
-    else {
-                 DB((be.dbg, LEVEL_2, "\tbe.curr_time = %u\n", be.curr_time));
-
-                 /* select a node to be scheduled and check if it was ready */
-                 if (nodeset_count(mcands) == 1) {
-                         DB((be.dbg, LEVEL_3, "\tmcand = 1, max_delay = %u\n", max_delay));
-                         irn = nodeset_first(mcands);
-                 }
-                 else {
-                         int cnt = nodeset_count(ecands);
-                         if (cnt == 1) {
-                                       arch_irn_class_t irn_class;
-
-                                 irn = nodeset_first(ecands);
-                                       irn_class = arch_irn_classify(env->arch_env, irn);
-
-                                       if (irn_class == arch_irn_class_branch) {
+               if (irn) {
+                       /* Keeps must be immediately scheduled */
+               }
+               else {
+                       DB((be.dbg, LEVEL_2, "\tbe.curr_time = %u\n", be.curr_time));
+
+                       /* select a node to be scheduled and check if it was ready */
+                       if (nodeset_count(mcands) == 1) {
+                               DB((be.dbg, LEVEL_3, "\tmcand = 1, max_delay = %u\n", max_delay));
+                               irn = nodeset_first(mcands);
+                       }
+                       else {
+                               int cnt = nodeset_count(ecands);
+                               if (cnt == 1) {
+                                       irn = nodeset_first(ecands);
+
+                                       if (arch_irn_class_is(env->arch_env, irn, branch)) {
                                                /* BEWARE: don't select a JUMP if others are still possible */
                                                goto force_mcands;
                                        }
-                                 DB((be.dbg, LEVEL_3, "\tecand = 1, max_delay = %u\n", max_delay));
-                         }
-                         else if (cnt > 1) {
-                                 DB((be.dbg, LEVEL_3, "\tecand = %d, max_delay = %u\n", cnt, max_delay));
-                                 irn = select_node_heuristic(&be, ecands);
-                         }
-                         else {
+                                       DB((be.dbg, LEVEL_3, "\tecand = 1, max_delay = %u\n", max_delay));
+                               }
+                               else if (cnt > 1) {
+                                       DB((be.dbg, LEVEL_3, "\tecand = %d, max_delay = %u\n", cnt, max_delay));
+                                       irn = select_node_heuristic(&be, ecands);
+                               }
+                               else {
 force_mcands:
-                                 DB((be.dbg, LEVEL_3, "\tmcand = %d\n", nodeset_count(mcands)));
-                                 irn = select_node_heuristic(&be, mcands);
-                         }
-                 }
-    }
+                                       DB((be.dbg, LEVEL_3, "\tmcand = %d\n", nodeset_count(mcands)));
+                                       irn = select_node_heuristic(&be, mcands);
+                               }
+                       }
+               }
                del_nodeset(mcands);
                del_nodeset(ecands);
 
@@ -997,7 +992,7 @@ static const list_sched_selector_t reg_pressure_selector_struct = {
 const list_sched_selector_t *reg_pressure_selector = &reg_pressure_selector_struct;
 
 /* List schedule a graph. */
-void list_sched(const be_irg_t *birg, int disable_mris)
+void list_sched(const be_irg_t *birg, int enable_mris)
 {
        const arch_env_t *arch_env = birg->main_env->arch_env;
        ir_graph *irg              = birg->irg;
@@ -1009,7 +1004,7 @@ void list_sched(const be_irg_t *birg, int disable_mris)
        /* Assure, that the out edges are computed */
        edges_assure(irg);
 
-       if(!disable_mris)
+       if(enable_mris)
                mris = be_sched_mris_preprocess(birg);
 
        num_nodes = get_irg_last_idx(irg);
@@ -1031,7 +1026,7 @@ void list_sched(const be_irg_t *birg, int disable_mris)
        if (env.selector->finish_graph)
                env.selector->finish_graph(env.selector_env);
 
-       if(!disable_mris)
+       if(enable_mris)
                be_sched_mris_free(mris);
 
        DEL_ARR_F(env.sched_info);