fixed precedence constraint
[libfirm] / ir / be / beschedrss.c
index cad9322..8df2838 100644 (file)
@@ -9,7 +9,7 @@
  * @cvs-id  $Id$
  */
 #ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
 #endif
 
 #include <limits.h>
 #include "height.h"
 
 #include "beabi.h"
+#include "bemodule.h"
 #include "benode_t.h"
 #include "besched_t.h"
 
-#ifdef WITH_LIBCORE
 #include <libcore/lc_opts.h>
 #include <libcore/lc_opts_enum.h>
-#endif /* WITH_LIBCORE */
 
 
 #define ARR_LEN_SAFE(arr) ((arr) != NULL ? ARR_LEN((arr)) : 0)
@@ -148,14 +147,20 @@ typedef struct _rss {
  * We need some special nodes:
  * a source and a sink for all live-in and live-out values of a block
  */
-
 enum {
        iro_rss_Source,
        iro_rss_Sink,
        iro_rss_last
 };
 
+/** The opcode of the rss_Source node once allocated. */
+static ir_op *op_rss_Source;
+/** The opcode of the rss_Sink node once allocated. */
+static ir_op *op_rss_Sink;
+
+/** The rss_Source node of the current graph. */
 static ir_node *_source = NULL;
+/** The rss_Sink node of the current graph. */
 static ir_node *_sink   = NULL;
 
 #define is_Source(irn) ((irn) == _source)
@@ -175,7 +180,6 @@ static rss_opts_t rss_options = {
        RSS_DUMP_NONE,
 };
 
-#ifdef WITH_LIBCORE
 static const lc_opt_enum_int_items_t dump_items[] = {
        { "none",  RSS_DUMP_NONE  },
        { "cbc",   RSS_DUMP_CBC   },
@@ -195,7 +199,6 @@ static const lc_opt_table_entry_t rss_option_table[] = {
        LC_OPT_ENT_ENUM_MASK("dump", "dump phases", &dump_var),
        { NULL }
 };
-#endif /* WITH_LIBCORE */
 
 /******************************************************************************
  *  _          _                    __                  _   _
@@ -209,15 +212,19 @@ static const lc_opt_table_entry_t rss_option_table[] = {
  ******************************************************************************/
 
 /**
- * Acquire opcodes and create source and sink nodes.
+ * Acquire opcodes if needed and create source and sink nodes.
  */
 static void init_rss_special_nodes(ir_graph *irg) {
-       ir_node *block         = get_irg_start_block(irg);
-       int     iro_rss_base   = get_next_ir_opcodes(iro_rss_last);
-       ir_op   *op_rss_Source = new_ir_op(iro_rss_base + iro_rss_Source, "rss_Source", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
-       ir_op   *op_rss_Sink   = new_ir_op(iro_rss_base + iro_rss_Sink,   "rss_Sink",   op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
-       _source                = new_ir_node(NULL, irg, block, op_rss_Source, mode_ANY, 0, NULL);
-       _sink                  = new_ir_node(NULL, irg, block, op_rss_Sink, mode_ANY, 0, NULL);
+       ir_node *block;
+
+       if (op_rss_Source == NULL) {
+               int iro_rss_base = get_next_ir_opcodes(iro_rss_last);
+               op_rss_Source = new_ir_op(iro_rss_base + iro_rss_Source, "rss_Source", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
+               op_rss_Sink   = new_ir_op(iro_rss_base + iro_rss_Sink,   "rss_Sink",   op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL);
+       }
+       block   = get_irg_start_block(irg);
+       _source = new_ir_node(NULL, irg, block, op_rss_Source, mode_ANY, 0, NULL);
+       _sink   = new_ir_node(NULL, irg, block, op_rss_Sink, mode_ANY, 0, NULL);
 }
 
 static int cmp_int(const void *a, const void *b) {
@@ -297,12 +304,14 @@ static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack
  *
  *****************************************************/
 
+#ifdef DEBUG_libfirm
 static void dump_nodeset(nodeset *ns, const char *prefix) {
        ir_node *irn;
        foreach_nodeset(ns, irn) {
                ir_fprintf(stderr, "%s%+F\n", prefix, irn);
        }
 }
+#endif
 
 static void build_file_name(rss_t *rss, const char *suffix, size_t suf_len, char *buf, size_t len) {
        const char *irg_name;
@@ -598,7 +607,11 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int *
                        if (arch_irn_is(rss->arch_env, user, ignore))
                                continue;
 
-                       if (get_irn_mode(user) == mode_X) {
+                       /*
+                               (a) mode_X means Jump            -> out_edge
+                               (b) Phi as user of a normal node -> out-edge
+                       */
+                       if (get_irn_mode(user) == mode_X || is_Phi(user)) {
                                if (! *got_sink)
                                        goto force_sink;
                                else
@@ -639,7 +652,7 @@ static void collect_single_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *con
 
        assert(! is_Proj(consumer) && "Cannot handle Projs");
 
-       if (! is_Block(consumer) && get_nodes_block(consumer) == block) {
+       if (! is_Phi(consumer) && ! is_Block(consumer) && get_nodes_block(consumer) == block) {
                if (! arch_irn_is(rss->arch_env, consumer, ignore) && ! plist_has_value(rss_irn->consumer_list, consumer)) {
                        plist_insert_back(rss_irn->consumer_list, consumer);
                        DBG((rss->dbg, LEVEL_2, "\t\tconsumer %+F\n", consumer));
@@ -850,6 +863,7 @@ static void build_kill_edges(rss_t *rss, pset *epk) {
        }
 }
 
+#ifdef DEBUG_libfirm
 /* print the given cbc for debugging purpose */
 static void debug_print_cbc(firm_dbg_module_t *mod, cbc_t *cbc) {
        ir_node    *n;
@@ -868,6 +882,7 @@ static void debug_print_cbc(firm_dbg_module_t *mod, cbc_t *cbc) {
                DBG((mod, LEVEL_3, "\t\t\t%+F -> %+F\n", ke->src, ke->tgt));
        }
 }
+#endif
 
 /**
  * Construct the bipartite decomposition.
@@ -1666,8 +1681,8 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese
        ir_node    *irn;
        rss_edge_t min_benefit_edge;
        rss_edge_t min_omega20_edge;
-       rss_irn_t  *ser_u_omega1, *ser_v_omega1;
-       rss_irn_t  *ser_u_omega20, *ser_v_omega20;
+       rss_irn_t  *ser_u_omega1 = NULL, *ser_v_omega1 = NULL;
+       rss_irn_t  *ser_u_omega20 = NULL, *ser_v_omega20 = NULL;
 
        DBG((rss->dbg, LEVEL_1, "\tcomputing admissible serializations:\n"));
 
@@ -1886,7 +1901,7 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese
 static void perform_value_serialization_heuristic(rss_t *rss) {
        bitset_t *arch_nonign_bs = bitset_alloca(arch_register_class_n_regs(rss->cls));
        bitset_t *abi_ign_bs     = bitset_alloca(arch_register_class_n_regs(rss->cls));
-       int      available_regs, iteration, num_live;
+       int      available_regs, iteration;
        dvg_t    dvg;
        nodeset  *sat_vals;
        pset *ser_set = new_pset(cmp_rss_edges, 20);
@@ -1896,7 +1911,7 @@ static void perform_value_serialization_heuristic(rss_t *rss) {
        be_abi_put_ignore_regs(rss->abi, rss->cls, abi_ign_bs);
        bitset_andnot(arch_nonign_bs, abi_ign_bs);
        available_regs  = bitset_popcnt(arch_nonign_bs);
-       //um_live = pset_count(rss->live_block);
+       //num_live = pset_count(rss->live_block);
        //available_regs -= num_live < available_regs ? num_live : 0;
 
        DBG((rss->dbg, LEVEL_1, "\n\t#available regs: %d\n\n", available_regs));
@@ -2063,22 +2078,18 @@ static void process_block(ir_node *block, void *env) {
        phase_free(&rss->ph);
 }
 
-#ifdef WITH_LIBCORE
 /**
  * Register the options.
  */
-void rss_register_options(lc_opt_entry_t *grp) {
-       static int     run_once = 0;
-       lc_opt_entry_t *rss_grp;
-
-       if (! run_once) {
-               run_once = 1;
-               rss_grp  = lc_opt_get_grp(grp, "rss");
+void be_init_schedrss(void) {
+       lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
+       lc_opt_entry_t *sched_grp = lc_opt_get_grp(be_grp, "sched");
+       lc_opt_entry_t *rss_grp = lc_opt_get_grp(sched_grp, "rss");
 
-               lc_opt_add_table(rss_grp, rss_option_table);
-       }
+       lc_opt_add_table(rss_grp, rss_option_table);
 }
-#endif /* WITH_LIBCORE */
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_schedrss);
 
 /**
  * Preprocess the irg for scheduling.