beifg: Factorise code to count interference components.
[libfirm] / ir / be / beschedrand.c
1 /*
2  * This file is part of libFirm.
3  * Copyright (C) 2012 University of Karlsruhe.
4  */
5
6 /**
7  * @file
8  * @brief       Random node selector.
9  * @author      Matthias Braun
10  * @date        29.08.2006
11  */
12 #include "config.h"
13
14 #include <stdlib.h>
15
16 #include "besched.h"
17 #include "belistsched.h"
18 #include "bemodule.h"
19
20 /**
21  * The random selector:
22  * Just assure that branches are executed last, otherwise select a random node
23  */
24 static ir_node *random_select(void *block_env, ir_nodeset_t *ready_set)
25 {
26         int only_branches_left = 1;
27         (void)block_env;
28
29         /* assure that branches and constants are executed last */
30         foreach_ir_nodeset(ready_set, irn, iter) {
31                 if (!is_cfop(irn)) {
32                         only_branches_left = 0;
33                         break;
34                 }
35         }
36
37         ir_node *rand_node = NULL;
38         if (only_branches_left) {
39                 /* at last: schedule branches */
40                 rand_node = ir_nodeset_first(ready_set);
41         } else {
42                 do {
43                         /* take 1 random node */
44                         int n = rand() % ir_nodeset_size(ready_set);
45                         int i = 0;
46                         foreach_ir_nodeset(ready_set, irn, iter) {
47                                 rand_node = irn;
48                                 if (i == n) {
49                                         break;
50                                 }
51                                 ++i;
52                         }
53                 } while (is_cfop(rand_node));
54         }
55
56         return rand_node;
57 }
58
59 static void *random_init_graph(ir_graph *irg)
60 {
61         (void)irg;
62         /* TODO: add commandline option for the seed */
63         srand(0x4711);
64         return NULL;
65 }
66
67 static void *random_init_block(void *graph_env, ir_node *block)
68 {
69         (void)graph_env;
70         (void)block;
71         return NULL;
72 }
73
74 static void sched_random(ir_graph *irg)
75 {
76         static const list_sched_selector_t random_selector = {
77                 random_init_graph,
78                 random_init_block,
79                 random_select,
80                 NULL,                /* node_ready */
81                 NULL,                /* node_selected */
82                 NULL,                /* finish_block */
83                 NULL                 /* finish_graph */
84         };
85         be_list_sched_graph(irg, &random_selector);
86 }
87
88 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched_rand)
89 void be_init_sched_rand(void)
90 {
91         be_register_scheduler("random", sched_random);
92 }