cleanup besched header
[libfirm] / ir / be / besched.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       Scheduling utilities for nodes in Blocks and Blocks.
23  * @author      Sebastian Hack
24  * @version     $Id$
25  */
26 #include "config.h"
27
28 #include <stdlib.h>
29
30 #include "irprintf.h"
31 #include "irgwalk.h"
32 #include "firm_types.h"
33 #include "irgraph_t.h"
34 #include "iredges_t.h"
35 #include "ircons.h"
36 #include "irextbb.h"
37 #include "irgmod.h"
38 #include "debug.h"
39
40 #include "bemodule.h"
41 #include "bearch.h"
42 #include "besched.h"
43 #include "beutil.h"
44 #include "belistsched.h"
45 #include "belive.h"
46
47 #define SCHED_INITIAL_GRANULARITY (1 << 14)
48
49 static void sched_renumber(const ir_node *block)
50 {
51         ir_node *irn;
52         sched_info_t *inf;
53         sched_timestep_t step = SCHED_INITIAL_GRANULARITY;
54
55         sched_foreach(block, irn) {
56                 inf = get_irn_sched_info(irn);
57                 inf->time_step = step;
58                 step += SCHED_INITIAL_GRANULARITY;
59         }
60 }
61
62 static inline void sched_set_time_stamp(const ir_node *irn)
63 {
64         sched_info_t       *info      = get_irn_sched_info(irn);
65         const sched_info_t *prev_info = get_irn_sched_info(info->prev);
66         const sched_info_t *next_info = get_irn_sched_info(info->next);
67         sched_timestep_t    before_ts = prev_info->time_step;
68         sched_timestep_t    after_ts  = next_info->time_step;
69
70         /*
71          * If we are the last, we can give us a big time step,
72          * else we have to compute our time step from our
73          * neighbours.
74          */
75         if(before_ts >= after_ts) {
76                 info->time_step = before_ts + SCHED_INITIAL_GRANULARITY;
77                 /* overflow? */
78                 if (info->time_step <= before_ts) {
79                         sched_renumber(get_nodes_block(irn));
80                 }
81         } else {
82                 sched_timestep_t ts = (before_ts + after_ts) / 2;
83
84                 /*
85                  * If the resolution went out, we have to renumber
86                  * this block.
87                  */
88                 if(ts == before_ts || ts == after_ts)
89                         sched_renumber(get_nodes_block(irn));
90                 else
91                         info->time_step = ts;
92         }
93 }
94
95 void sched_add_before(ir_node *before, ir_node *irn)
96 {
97         sched_info_t *info      = get_irn_sched_info(irn);
98         ir_node      *next      = before;
99         sched_info_t *next_info = get_irn_sched_info(next);
100         ir_node      *prev      = next_info->prev;
101         sched_info_t *prev_info = get_irn_sched_info(prev);
102         assert(sched_is_scheduled(before));
103         assert(!sched_is_scheduled(irn));
104         assert(!is_Proj(before));
105         assert(!is_Proj(irn));
106
107         info->prev = prev;
108         info->next = next;
109         prev_info->next = irn;
110         next_info->prev = irn;
111         sched_set_time_stamp(irn);
112 }
113
114 void sched_add_after(ir_node *after, ir_node *irn)
115 {
116         sched_info_t *info      = get_irn_sched_info(irn);
117         ir_node      *prev      = after;
118         sched_info_t *prev_info = get_irn_sched_info(prev);
119         ir_node      *next      = prev_info->next;
120         sched_info_t *next_info = get_irn_sched_info(next);
121         assert(sched_is_scheduled(after));
122         assert(!sched_is_scheduled(irn));
123         assert(!is_Proj(after));
124         assert(!is_Proj(irn));
125
126         info->prev = prev;
127         info->next = next;
128         prev_info->next = irn;
129         next_info->prev = irn;
130         sched_set_time_stamp(irn);
131 }
132
133 void sched_remove(ir_node *irn)
134 {
135         sched_info_t *info      = get_irn_sched_info(irn);
136         ir_node      *prev      = info->prev;
137         ir_node      *next      = info->next;
138         sched_info_t *prev_info = get_irn_sched_info(prev);
139         sched_info_t *next_info = get_irn_sched_info(next);
140         assert(sched_is_scheduled(irn));
141
142         prev_info->next = next;
143         next_info->prev = prev;
144         info->next      = NULL;
145         info->prev      = NULL;
146 }
147
148 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched);
149 void be_init_sched(void)
150 {
151 }