besched: Add and use sched_replace().
[libfirm] / ir / be / beschedrand.c
index db52cd7..394b771 100644 (file)
  * @brief       Random node selector.
  * @author      Matthias Braun
  * @date        29.08.2006
- * @version     $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <stdlib.h>
 
-#include "besched_t.h"
+#include "besched.h"
 #include "belistsched.h"
+#include "bemodule.h"
 
 /**
  * The random selector:
  * Just assure that branches are executed last, otherwise select a random node
  */
-static ir_node *random_select(void *block_env, ir_nodeset_t *ready_set,
-                              ir_nodeset_t *live_set)
+static ir_node *random_select(void *block_env, ir_nodeset_t *ready_set)
 {
-       ir_nodeset_iterator_t iter;
-       ir_node          *irn      = NULL;
        int only_branches_left = 1;
        (void)block_env;
-       (void)live_set;
 
        /* assure that branches and constants are executed last */
-       ir_nodeset_iterator_init(&iter, ready_set);
-       while( (irn = ir_nodeset_iterator_next(&iter)) != NULL) {
-               if (!arch_irn_class_is(irn, branch)) {
+       foreach_ir_nodeset(ready_set, irn, iter) {
+               if (!is_cfop(irn)) {
                        only_branches_left = 0;
                        break;
                }
        }
 
+       ir_node *rand_node = NULL;
        if (only_branches_left) {
                /* at last: schedule branches */
-               ir_nodeset_iterator_init(&iter, ready_set);
-               irn = ir_nodeset_iterator_next(&iter);
+               rand_node = ir_nodeset_first(ready_set);
        } else {
                do {
                        /* take 1 random node */
                        int n = rand() % ir_nodeset_size(ready_set);
                        int i = 0;
-                       ir_nodeset_iterator_init(&iter, ready_set);
-                       while ((irn = ir_nodeset_iterator_next(&iter)) != NULL) {
-                               if(i == n) {
+                       foreach_ir_nodeset(ready_set, irn, iter) {
+                               rand_node = irn;
+                               if (i == n) {
                                        break;
                                }
                                ++i;
                        }
-               } while (arch_irn_class_is(irn, branch));
+               } while (is_cfop(rand_node));
        }
 
-       return irn;
+       return rand_node;
 }
 
-static void *random_init_graph(const list_sched_selector_t *vtab, const be_irg_t *birg)
+static void *random_init_graph(ir_graph *irg)
 {
-       (void)vtab;
-       (void)birg;
-       /* Using time(NULL) as a seed here gives really random results,
-          but is NOT deterministic which makes debugging impossible.
-          Moreover no-one want non-deterministic compilers ... */
+       (void)irg;
+       /* TODO: add commandline option for the seed */
        srand(0x4711);
        return NULL;
 }
@@ -95,15 +85,22 @@ static void *random_init_block(void *graph_env, ir_node *block)
        return NULL;
 }
 
-const list_sched_selector_t random_selector = {
-       random_init_graph,
-       random_init_block,
-       random_select,
-       NULL,                /* to_appear_in_schedule */
-       NULL,                /* node_ready */
-       NULL,                /* node_selected */
-       NULL,                /* exectime */
-       NULL,                /* latency */
-       NULL,                /* finish_block */
-       NULL                 /* finish_graph */
-};
+static void sched_random(ir_graph *irg)
+{
+       static const list_sched_selector_t random_selector = {
+               random_init_graph,
+               random_init_block,
+               random_select,
+               NULL,                /* node_ready */
+               NULL,                /* node_selected */
+               NULL,                /* finish_block */
+               NULL                 /* finish_graph */
+       };
+       be_list_sched_graph(irg, &random_selector);
+}
+
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_rand)
+void be_init_sched_rand(void)
+{
+       be_register_scheduler("random", sched_random);
+}