-static void scc (ir_node *n) {
- int i;
- if (irn_visited(n)) return;
- mark_irn_visited(n);
-
- /* Initialize the node */
- set_irn_dfn(n, current_dfn); /* Depth first number for this node */
- set_irn_uplink(n, current_dfn); /* ... is default uplink. */
- set_irn_loop(n, NULL);
- current_dfn ++;
- push(n);
-
- /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
- array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
- so is_backedge does not access array[-1] but correctly returns false! */
-
- if (!is_outermost_Start(n)) {
- int arity = get_irn_arity(n);
-
- for (i = get_start_index(n); i < arity; i++) {
- ir_node *m;
- if (is_backedge(n, i)) continue;
- m = get_irn_n(n, i); /* get_irn_ip_pred(n, i); */
- /* if ((!m) || (get_irn_op(m) == op_Unknown)) continue; */
- scc (m);
- if (irn_is_in_stack(m)) {
- /* Uplink of m is smaller if n->m is a backedge.
- Propagate the uplink to mark the loop. */
- if (get_irn_uplink(m) < get_irn_uplink(n))
- set_irn_uplink(n, get_irn_uplink(m));
- }
- }
- }
-
- if (get_irn_dfn(n) == get_irn_uplink(n)) {
- /* This condition holds for
- 1) the node with the incoming backedge.
- That is: We found a loop!
- 2) Straight line code, because no uplink has been propagated, so the
- uplink still is the same as the dfn.
-
- But n might not be a proper loop head for the analysis. Proper loop
- heads are Block and Phi nodes. find_tail searches the stack for
- Block's and Phi's and takes those nodes as loop heads for the current
- loop instead and marks the incoming edge as backedge. */
-
- ir_node *tail = find_tail(n);
- if (tail) {
- /* We have a loop, that is no straight line code,
- because we found a loop head!
- Next actions: Open a new loop on the loop tree and
- try to find inner loops */
-
-#if NO_LOOPS_WITHOUT_HEAD
- /* This is an adaption of the algorithm from fiasco / optscc to
- * avoid loops without Block or Phi as first node. This should
- * severely reduce the number of evaluations of nodes to detect
- * a fixpoint in the heap analysis.
- * Further it avoids loops without firm nodes that cause errors
- * in the heap analyses.
- * But attention: don't do it for the outermost loop: This loop
- * is not iterated. A first block can be a loop head in case of
- * an endless recursion. */
-
- ir_loop *l;
- int close;
- if ((get_loop_n_elements(current_loop) > 0) || (is_outermost_loop(current_loop))) {
- l = new_loop();
- close = 1;
- } else {
- l = current_loop;
- close = 0;
- }
-#else
- ir_loop *l = new_loop();
-#endif
-
- /* Remove the loop from the stack ... */
- pop_scc_unmark_visit (n);
-
- /* The current backedge has been marked, that is temporarily eliminated,
- by find tail. Start the scc algorithm
- anew on the subgraph that is left (the current loop without the backedge)
- in order to find more inner loops. */
- scc (tail);
-
- assert (irn_visited(n));
-#if NO_LOOPS_WITHOUT_HEAD
- if (close)
-#endif
- close_loop(l);
- }
- else
- {
- /* No loop head was found, that is we have straightline code.
- Pop all nodes from the stack to the current loop. */
- pop_scc_to_loop(n);
- }
- }
-}
-
-static void my_scc (ir_node *n) {
- int i;
- if (irn_visited(n)) return;
- mark_irn_visited(n);
-
- /* Initialize the node */
- set_irn_dfn(n, current_dfn); /* Depth first number for this node */
- set_irn_uplink(n, current_dfn); /* ... is default uplink. */
- set_irn_loop(n, NULL);
- current_dfn ++;
- push(n);
-
- /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
- array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
- so is_backedge does not access array[-1] but correctly returns false! */
-
- if (!is_outermost_Start(n)) {
- int arity = get_irn_arity(n);
-
- for (i = get_start_index(n); i < arity; i++) {
- ir_node *m;
- if (is_backedge(n, i)) continue;
- m = get_irn_n(n, i); /* get_irn_ip_pred(n, i); */
- /* if ((!m) || (get_irn_op(m) == op_Unknown)) continue; */
- my_scc (m);
- if (irn_is_in_stack(m)) {
- /* Uplink of m is smaller if n->m is a backedge.
- Propagate the uplink to mark the loop. */
- if (get_irn_uplink(m) < get_irn_uplink(n))
- set_irn_uplink(n, get_irn_uplink(m));
- }
- }
- }
-
- if (get_irn_dfn(n) == get_irn_uplink(n)) {
- /* This condition holds for
- 1) the node with the incoming backedge.
- That is: We found a loop!
- 2) Straight line code, because no uplink has been propagated, so the
- uplink still is the same as the dfn.
-
- But n might not be a proper loop head for the analysis. Proper loop
- heads are Block and Phi nodes. find_tail searches the stack for
- Block's and Phi's and takes those nodes as loop heads for the current
- loop instead and marks the incoming edge as backedge. */
-
- ir_node *tail = find_tail(n);
- if (tail) {
- /* We have a loop, that is no straight line code,
- because we found a loop head!
- Next actions: Open a new loop on the loop tree and
- try to find inner loops */
+/**
+ * The core algorithm: Find strongly coupled components.
+ *
+ * @param n node to start
+ */
+static void scc(ir_node *n)
+{
+ if (irn_visited_else_mark(n))
+ return;
+
+ /* Initialize the node */
+ set_irn_dfn(n, current_dfn); /* Depth first number for this node */
+ set_irn_uplink(n, current_dfn); /* ... is default uplink. */
+ set_irn_loop(n, NULL);
+ ++current_dfn;
+ push(n);
+
+ /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
+ array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
+ so is_backedge does not access array[-1] but correctly returns false! */
+
+ if (!is_outermost_Start(n)) {
+ int i, arity = get_irn_arity(n);
+
+ for (i = get_start_index(n); i < arity; ++i) {
+ ir_node *m;
+ if (is_backedge(n, i))
+ continue;
+ m = get_irn_n(n, i);
+ scc(m);
+ if (irn_is_in_stack(m)) {
+ /* Uplink of m is smaller if n->m is a backedge.
+ Propagate the uplink to mark the loop. */
+ if (get_irn_uplink(m) < get_irn_uplink(n))
+ set_irn_uplink(n, get_irn_uplink(m));
+ }
+ }
+ }
+
+ if (get_irn_dfn(n) == get_irn_uplink(n)) {
+ /* This condition holds for
+ 1) the node with the incoming backedge.
+ That is: We found a loop!
+ 2) Straight line code, because no uplink has been propagated, so the
+ uplink still is the same as the dfn.
+
+ But n might not be a proper loop head for the analysis. Proper loop
+ heads are Block and Phi nodes. find_tail() searches the stack for
+ Block's and Phi's and takes those nodes as loop heads for the current
+ loop instead and marks the incoming edge as backedge. */
+
+ ir_node *tail = find_tail(n);
+ if (tail != NULL) {
+ /* We have a loop, that is no straight line code,
+ because we found a loop head!
+ Next actions: Open a new loop on the loop tree and
+ try to find inner loops */