besched: Add and use sched_replace().
[libfirm] / ir / be / beschedrand.c
index b074c4c..394b771 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
  * @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;
-       const arch_env_t *arch_env = block_env;
-       ir_node          *irn      = NULL;
        int only_branches_left = 1;
+       (void)block_env;
 
        /* 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(arch_env, 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(arch_env, irn, branch));
+               } while (is_cfop(rand_node));
        }
 
-       return irn;
+       return rand_node;
 }
 
-static void *random_init_graph(const list_sched_selector_t *vtab, const arch_env_t *arch_env, ir_graph *irg)
+static void *random_init_graph(ir_graph *irg)
 {
-       /* 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 (void *)arch_env;
+       return NULL;
 }
 
-static void *random_init_block(void *graph_env, ir_node *bl)
+static void *random_init_block(void *graph_env, ir_node *block)
 {
-       return graph_env;
+       (void)graph_env;
+       (void)block;
+       return NULL;
 }
 
-static const list_sched_selector_t random_selector_struct = {
-       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);
+}
 
-const list_sched_selector_t *random_selector = &random_selector_struct;
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_rand)
+void be_init_sched_rand(void)
+{
+       be_register_scheduler("random", sched_random);
+}