- na->alap = rna->asap + fixed_latency(env->sel, root, env->block_env);
- }
- }
- }
-
- DB((env->dbg, LEVEL_2, "%u\n", na->alap));
-}
-
-/**
- * Accumulate the successors of all nodes from irn on upwards.
- */
-static void accumulate_succs(be_ilpsched_env_t *env, ir_node *irn) {
- unsigned i, n;
- be_ilpsched_irn_t *node = get_ilpsched_irn(env, irn);
- ilpsched_node_attr_t *na = get_ilpsched_node_attr(node);
- ir_node *block = get_nodes_block(irn);
- waitq *wq = new_waitq();
-
- DBG((env->dbg, LEVEL_3, "\taccumulating succs of %+F\n", irn));
-
- /* enqueue node for final alap calculation */
- if (! na->enqueued) {
- be_ilpsched_irn_t *block_node = get_ilpsched_irn(env, block);
- ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
-
- na->enqueued = 1;
- na->alap = ba->max_steps;
- waitq_put(env->alap_queue, node);
-
- set_irn_link(irn, ba->head_ilp_nodes);
- ba->head_ilp_nodes = irn;
- DBG((env->dbg, LEVEL_5, "\t\tlinked %+F to ilp nodes of %+F, attr %p\n", irn, block, ba));
- DBG((env->dbg, LEVEL_4, "\t\tenqueueing %+F for final ALAP calculation\n", irn));
- }
-
- for (i = 0, n = get_irn_ins_or_deps(irn); i < n; ++i) {
- ir_node *pred = skip_normal_Proj(env->arch_env->isa, get_irn_in_or_dep(irn, i));
- unsigned idx;
- be_ilpsched_irn_t *pred_node;
- ilpsched_node_attr_t *pna;
-
- if (be_is_Keep(pred))
- pred = skip_normal_Proj(env->arch_env->isa, get_irn_n(pred, 0));
-
- if (is_Phi(pred) || block != get_nodes_block(pred) || is_NoMem(pred))
- continue;
-
- pred_node = get_ilpsched_irn(env, pred);
- pna = get_ilpsched_node_attr(pred_node);
- idx = get_irn_idx(irn);
-
- /* accumulate the successors */
- if (pna->visit_idx != idx) {
- pna->visit_idx = idx;
- pna->transitive_block_nodes = bitset_or(pna->transitive_block_nodes, na->transitive_block_nodes);
-
- /* set current node as successor */
- bitset_set(pna->transitive_block_nodes, na->block_idx);
- waitq_put(wq, pred);
-
- DBG((env->dbg, LEVEL_3, "\taccumulating succs of %+F to %+F\n", irn, pred));
- }
- }
-
- /* process all predecessors */
- while (! waitq_empty(wq)) {
- accumulate_succs(env, waitq_get(wq));
- }
-
- del_waitq(wq);
-}
-
-/**
- * Calculate the ALAP scheduling step of all irns in current block.
- * Depends on ASAP being calculated.
- */
-static void calculate_block_alap(ir_node *block, void *walk_env) {
- be_ilpsched_env_t *env = walk_env;
- be_ilpsched_irn_t *block_node = get_ilpsched_irn(env, block);
- ilpsched_block_attr_t *ba = get_ilpsched_block_attr(block_node);
-
- assert(is_Block(block));
-
- DBG((env->dbg, LEVEL_2, "Calculating ALAP for nodes in %+F (%u nodes)\n", block, ba->n_interesting_nodes));
-
- /* TODO: Might be faster to use out edges and call phase_reinit_single_irn_data */
- phase_reinit_block_irn_data(&env->ph, block);
-
- /* calculate the alap of all nodes, starting at collected roots upwards */
- while (! waitq_empty(ba->root_nodes)) {
- accumulate_succs(env, waitq_get(ba->root_nodes));
- }
-
- /* we don't need it anymore */
- del_waitq(ba->root_nodes);
- ba->root_nodes = NULL;
-
- /* all interesting nodes should have their successors accumulated now */
- while (! waitq_empty(env->alap_queue)) {
- be_ilpsched_irn_t *node = waitq_get(env->alap_queue);
- ilpsched_node_attr_t *na = get_ilpsched_node_attr(node);
-
- /* control flow ops must always be scheduled last */
- if (is_cfop(node->irn) && ! is_Start(node->irn) && get_irn_opcode(node->irn) != iro_End)
- na->asap = na->alap;
- else
- na->alap -= bitset_popcnt(na->transitive_block_nodes);
- DBG((env->dbg, LEVEL_2, "\tALAP of %+F is %u (%u succs, %u consumer)\n",
- node->irn, na->alap, bitset_popcnt(na->transitive_block_nodes), na->n_consumer));
-
- /* maximum block steps is maximum alap of all nodes */
- ba->max_steps = MAX(ba->max_steps, na->alap);
- }