-
- nodeset_insert(env->already_scheduled, res);
- return res;
-}
-
-static const list_sched_selector_t reg_pressure_selector_struct = {
- reg_pressure_graph_init,
- reg_pressure_block_init,
- reg_pressure_select,
- NULL,
- reg_pressure_block_free,
- free
-};
-
-const list_sched_selector_t *reg_pressure_selector = ®_pressure_selector_struct;
-
-static void list_sched_block(ir_node *block, void *env_ptr);
-
-void list_sched(const arch_env_t *arch_env, ir_graph *irg)
-{
- sched_env_t env;
-
- memset(&env, 0, sizeof(env));
- env.selector = arch_env->isa->impl->get_list_sched_selector(arch_env->isa);
- env.arch_env = arch_env;
- env.irg = irg;
-
- if(env.selector->init_graph)
- env.selector_env = env.selector->init_graph(env.selector, arch_env, irg);
-
- /* Assure, that the out edges are computed */
- edges_assure(irg);
-
- /* Schedule each single block. */
- irg_block_walk_graph(irg, list_sched_block, NULL, &env);
-
- if(env.selector->finish_graph)
- env.selector->finish_graph(env.selector_env);
-}
-
-
-/**
- * Environment for a block scheduler.
- */
-typedef struct _block_sched_env_t {
- int curr_time;
- nodeset *ready_set;
- nodeset *already_scheduled;
- ir_node *block;
- const list_sched_selector_t *selector;
- void *selector_block_env;
- DEBUG_ONLY(firm_dbg_module_t *dbg;)
-} block_sched_env_t;
-
-/**
- * Try to put a node in the ready set.
- * @param env The block scheduler environment.
- * @param irn The node to make ready.
- * @return 1, if the node could be made ready, 0 else.
- */
-static INLINE int make_ready(block_sched_env_t *env, ir_node *irn)
-{
- int i, n;
-
- /* Blocks cannot be scheduled. */
- if(is_Block(irn))
- return 0;
-
- /*
- * Check, if the given ir node is in a different block as the
- * currently scheduled one. If that is so, don't make the node ready.
- */
- if(env->block != get_nodes_block(irn))
- return 0;
-
- for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
- ir_node *op = get_irn_n(irn, i);
-
- /* if irn is an End we have keep-alives and op might be a block, skip that */
- if (is_Block(op)) {
- assert(get_irn_op(irn) == op_End);
- continue;
- }
-
- /* If the operand is local to the scheduled block and not yet
- * scheduled, this nodes cannot be made ready, so exit. */
- if(!nodeset_find(env->already_scheduled, op) && get_nodes_block(op) == env->block)
- return 0;
- }
-
- DBG((env->dbg, LEVEL_2, "\tmaking ready: %+F\n", irn));
- nodeset_insert(env->ready_set, irn);
-
- return 1;
-}
-
-/**
- * Check, if a node is ready in a block schedule.
- * @param env The block schedule environment.
- * @param irn The node to check for.
- * @return 1 if the node was ready, 0 if not.
- */
-#define is_ready(env,irn) \
- (nodeset_find((env)->ready_set, irn) != NULL)
-
-/**
- * Check, if a node has already been schedules.
- * @param env The block schedule environment.
- * @param irn The node to check for.
- * @return 1 if the node was already scheduled, 0 if not.
- */
-#define is_scheduled(env,irn) \
- (nodeset_find((env)->already_scheduled, irn) != NULL)
-
-/**
- * Try, to make all users of a node ready.
- * In fact, a usage node can only be made ready, if all its operands
- * have already been scheduled yet. This is checked my make_ready().
- * @param env The block schedule environment.
- * @param irn The node, which usages (successors) are to be made ready.
- */
-static INLINE void make_users_ready(block_sched_env_t *env, ir_node *irn)
-{
- const ir_edge_t *edge;
-
- foreach_out_edge(irn, edge) {
- ir_node *user = edge->src;
- if(!is_Phi(user))
- make_ready(env, user);