fixed be_Return gen
[libfirm] / ir / be / belistsched.c
index 7972a12..aff47e0 100644 (file)
 #include "irprintf_t.h"
 #include "array.h"
 #include "debug.h"
+#include "irtools.h"
 
 #include "besched_t.h"
 #include "beutil.h"
 #include "belive_t.h"
 #include "belistsched.h"
+#include "beschedmris.h"
 #include "bearch.h"
 #include "bestat.h"
 
-#define MAX(x,y) ((x) > (y) ? (x) : (y))
-#define MIN(x,y) ((x) < (y) ? (x) : (y))
-
 /**
  * All scheduling info needed per node.
  */
@@ -139,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 = {
@@ -295,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++;
                                }
                        }
@@ -599,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.
@@ -655,6 +645,9 @@ static void add_tuple_projs(block_sched_env_t *env, ir_node *irn)
 
        assert(get_irn_mode(irn) == mode_T && "Mode of node must be tuple");
 
+       if(is_Bad(irn))
+               return;
+
        foreach_out_edge(irn, edge) {
                ir_node *out = edge->src;
 
@@ -697,6 +690,9 @@ static int is_root(ir_node *root, ir_node *block) {
 
                if (is_Block(succ))
                        continue;
+               /* Phi nodes are always in "another block */
+               if (is_Phi(succ))
+                       continue;
                if (get_nodes_block(succ) == block)
                        return 0;
        }
@@ -707,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.
  */
@@ -718,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;
@@ -730,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);
                }
        }
@@ -774,6 +775,7 @@ 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);
 
@@ -799,6 +801,7 @@ 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;
@@ -992,10 +995,22 @@ 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 arch_env_t *arch_env, ir_graph *irg)
+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;
+
+       int num_nodes;
        sched_env_t env;
-       int num_nodes = get_irg_last_idx(irg);
+       mris_env_t *mris;
+
+       /* Assure, that the out edges are computed */
+       edges_assure(irg);
+
+       if(enable_mris)
+               mris = be_sched_mris_preprocess(birg);
+
+       num_nodes = get_irg_last_idx(irg);
 
        memset(&env, 0, sizeof(env));
        env.selector   = arch_env->isa->impl->get_list_sched_selector(arch_env->isa);
@@ -1008,14 +1023,14 @@ void list_sched(const arch_env_t *arch_env, ir_graph *irg)
        if (env.selector->init_graph)
                env.selector_env = env.selector->init_graph(env.selector, arch_env, irg);
 
-       /* Assure, that the out edges are computed */
-       edges_assure(irg);
-
        /* Schedule each single block. */
        irg_block_walk_graph(irg, list_sched_block, NULL, &env);
 
        if (env.selector->finish_graph)
                env.selector->finish_graph(env.selector_env);
 
+       if(enable_mris)
+               be_sched_mris_free(mris);
+
        DEL_ARR_F(env.sched_info);
 }