-/* Returns index of the predecessor with the smallest dfn number
- greater-equal than limit. */
-static int
-smallest_dfn_pred (ir_node *n, int limit)
-{
- int i, index = -2, min = -1;
-
- if (!is_outermost_StartBlock(n)) {
- int arity = get_irn_arity(n);
- for (i = 0; i < arity; i++) {
- ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
- if (is_backedge(n, i) || !irn_is_in_stack(pred)) continue;
- if (get_irn_dfn(pred) >= limit && (min == -1 || get_irn_dfn(pred) < min)) {
- index = i;
- min = get_irn_dfn(pred);
- }
- }
- }
- return index;
-}
-
-/* Returns index of the predecessor with the largest dfn number. */
-static int
-largest_dfn_pred (ir_node *n)
-{
- int i, index = -2, max = -1;
-
- if (!is_outermost_StartBlock(n)) {
- int arity = get_irn_arity(n);
- for (i = 0; i < arity; i++) {
- ir_node *pred = get_nodes_block(skip_Proj(get_irn_n(n, i)));
- if (is_backedge (n, i) || !irn_is_in_stack(pred)) continue;
- if (get_irn_dfn(pred) > max) {
- index = i;
- max = get_irn_dfn(pred);
- }
- }
- }
- return index;
-}
-
-/* Searches the stack for possible loop heads. Tests these for backedges.
- If it finds a head with an unmarked backedge it marks this edge and
- returns the tail of the loop.
- If it finds no backedge returns NULL.
- ("disable_backedge" in fiasco) */
-static ir_node *
-find_tail (ir_node *n) {
- ir_node *m;
- int i, res_index = -2;
-
- m = stack[tos-1]; /* tos = top of stack */
- if (is_head (m, n)) {
- res_index = smallest_dfn_pred(m, 0);
- if ((res_index == -2) && /* no smallest dfn pred found. */
- (n == m))
- return NULL;
- } else {
- if (m == n) return NULL;
- for (i = tos-2; ; --i) {
- m = stack[i];
- if (is_head (m, n)) {
- res_index = smallest_dfn_pred (m, get_irn_dfn(m) + 1);
- if (res_index == -2) /* no smallest dfn pred found. */
- res_index = largest_dfn_pred (m);
- break;
- }
- }
- }
- assert (res_index > -2);
-
- set_backedge (m, res_index);
- return is_outermost_StartBlock(n) ? NULL : get_nodes_block(skip_Proj(get_irn_n(m, res_index)));
-}