2 * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief Scheduling utilities for nodes in Blocks and Blocks.
23 * @author Sebastian Hack
29 #include "firm_types.h"
30 #include "iredges_t.h"
39 #include "belistsched.h"
43 #include "lc_opts_enum.h"
46 #define SCHED_INITIAL_GRANULARITY (1 << 14)
48 static void sched_renumber(const ir_node *block)
51 sched_timestep_t step = SCHED_INITIAL_GRANULARITY;
53 sched_foreach(block, irn) {
54 inf = get_irn_sched_info(irn);
55 inf->time_step = step;
56 step += SCHED_INITIAL_GRANULARITY;
60 static inline void sched_set_time_stamp(const ir_node *irn)
62 sched_info_t *info = get_irn_sched_info(irn);
63 const sched_info_t *prev_info = get_irn_sched_info(info->prev);
64 const sched_info_t *next_info = get_irn_sched_info(info->next);
65 sched_timestep_t before_ts = prev_info->time_step;
66 sched_timestep_t after_ts = next_info->time_step;
69 * If we are the last, we can give us a big time step,
70 * else we have to compute our time step from our
73 if(before_ts >= after_ts) {
74 info->time_step = before_ts + SCHED_INITIAL_GRANULARITY;
76 if (info->time_step <= before_ts) {
77 sched_renumber(get_nodes_block(irn));
80 sched_timestep_t ts = (before_ts + after_ts) / 2;
83 * If the resolution went out, we have to renumber
86 if(ts == before_ts || ts == after_ts)
87 sched_renumber(get_nodes_block(irn));
93 void sched_add_before(ir_node *before, ir_node *irn)
95 sched_info_t *info = get_irn_sched_info(irn);
96 ir_node *next = before;
97 sched_info_t *next_info = get_irn_sched_info(next);
98 ir_node *prev = next_info->prev;
99 sched_info_t *prev_info = get_irn_sched_info(prev);
100 assert(sched_is_scheduled(before));
101 assert(!sched_is_scheduled(irn));
102 assert(!is_Proj(before));
103 assert(!is_Proj(irn));
107 prev_info->next = irn;
108 next_info->prev = irn;
109 sched_set_time_stamp(irn);
112 void sched_add_after(ir_node *after, ir_node *irn)
114 sched_info_t *info = get_irn_sched_info(irn);
115 ir_node *prev = after;
116 sched_info_t *prev_info = get_irn_sched_info(prev);
117 ir_node *next = prev_info->next;
118 sched_info_t *next_info = get_irn_sched_info(next);
119 assert(sched_is_scheduled(after));
120 assert(!sched_is_scheduled(irn));
121 assert(!is_Proj(after));
122 assert(!is_Proj(irn));
126 prev_info->next = irn;
127 next_info->prev = irn;
128 sched_set_time_stamp(irn);
131 void sched_remove(ir_node *irn)
133 sched_info_t *info = get_irn_sched_info(irn);
134 ir_node *prev = info->prev;
135 ir_node *next = info->next;
136 sched_info_t *prev_info = get_irn_sched_info(prev);
137 sched_info_t *next_info = get_irn_sched_info(next);
138 assert(sched_is_scheduled(irn));
140 prev_info->next = next;
141 next_info->prev = prev;
146 void sched_replace(ir_node *const old, ir_node *const irn)
148 assert(sched_is_scheduled(old));
149 assert(!sched_is_scheduled(irn));
151 sched_info_t *const old_info = get_irn_sched_info(old);
152 sched_info_t *const irn_info = get_irn_sched_info(irn);
153 *irn_info = *old_info;
155 old_info->prev = NULL;
156 old_info->next = NULL;
158 ir_node *const prev = irn_info->prev;
159 ir_node *const next = irn_info->next;
160 get_irn_sched_info(prev)->next = irn;
161 get_irn_sched_info(next)->prev = irn;
164 static be_module_list_entry_t *schedulers;
165 static schedule_func scheduler;
167 void be_register_scheduler(const char *name, schedule_func func)
169 if (scheduler == NULL)
171 be_add_module_to_list(&schedulers, name, (void*)func);
174 void be_schedule_graph(ir_graph *irg)
179 BE_REGISTER_MODULE_CONSTRUCTOR(be_init_sched)
180 void be_init_sched(void)
182 lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be");
183 be_add_module_list_opt(be_grp, "scheduler", "scheduling algorithm",
184 &schedulers, (void**)&scheduler);