-static void cfscc (ir_node *n) {
- int i;
-
- assert(is_Block(n));
-
- 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_StartBlock(n)) {
- int arity = get_irn_arity(n);
-
- for (i = 0; i < arity; i++) {
- ir_node *m;
- if (is_backedge(n, i)) continue;
- m = get_nodes_block(skip_Proj(get_irn_n(n, i)));
-
- cfscc (m);
- if (irn_is_in_stack(m)) {
- /* Uplink of m is smaller if n->m is a backedge.
- Propagate the uplink to mark the cfloop. */
- 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 cfloop!
- 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 cfloop head for the analysis. Proper cfloop
- heads are Block and Phi nodes. find_tail searches the stack for
- Block's and Phi's and takes those nodes as cfloop heads for the current
- cfloop instead and marks the incoming edge as backedge. */
-
- ir_node *tail = find_tail(n);
- if (tail) {
- /* We have a cfloop, that is no straight line code,
- because we found a cfloop head!
- Next actions: Open a new cfloop on the cfloop tree and
- try to find inner cfloops */
-
-#if NO_CFLOOPS_WITHOUT_HEAD
-
- /* This is an adaption of the algorithm from fiasco / optscc to
- * avoid cfloops 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 cfloops without firm nodes that cause errors
- * in the heap analyses. */
-
- 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 cfloop 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 thats left (the current cfloop without the backedge)
- in order to find more inner cfloops. */
-
- cfscc (tail);
-
- assert (irn_visited(n));
-#if NO_CFLOOPS_WITHOUT_HEAD
- if (close)
-#endif
- close_loop(l);
- }
- else
- {
- /* AS: No cfloop head was found, that is we have straightline code.
- Pop all nodes from the stack to the current cfloop. */
- pop_scc_to_loop(n);
- }
- }
-}
-
-/* Constructs backedge information for irg. */
-int construct_cf_backedges(ir_graph *irg) {
- ir_graph *rem = current_ir_graph;
- ir_loop *head_rem;
- ir_node *end = get_irg_end(irg);
- int i;
-
- assert(!get_interprocedural_view() &&
- "use construct_ip_backedges");
- max_loop_depth = 0;
-
- current_ir_graph = irg;
- outermost_ir_graph = irg;
-
- init_scc(current_ir_graph);
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- head_rem = current_loop; /* Just for assertion */
-
- inc_irg_visited(current_ir_graph);
-
- cfscc(get_irg_end_block(current_ir_graph));
- for (i = 0; i < get_End_n_keepalives(end); i++) {
- ir_node *el = get_End_keepalive(end, i);
- if (is_Block(el)) cfscc(el);
- }
-
- assert(head_rem == current_loop);
- set_irg_loop(current_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_consistent);
- assert(get_irg_loop(current_ir_graph)->kind == k_ir_loop);
-
- current_ir_graph = rem;
- return max_loop_depth;
+ 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 cfloop!
+ 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 cfloop head for the analysis. Proper cfloop
+ heads are Block and Phi nodes. find_tail searches the stack for
+ Block's and Phi's and takes those nodes as cfloop heads for the current
+ cfloop instead and marks the incoming edge as backedge. */
+
+ ir_node *tail = find_tail(n);
+ if (tail) {
+ /* We have a cfloop, that is no straight line code,
+ because we found a cfloop head!
+ Next actions: Open a new cfloop on the cfloop tree and
+ try to find inner cfloops */
+
+ /* This is an adaption of the algorithm from fiasco / optscc to
+ * avoid cfloops 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 cfloops without firm nodes that cause errors
+ * in the heap analyses. */
+
+ 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;
+ }
+
+ /* Remove the cfloop 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 thats left (the current cfloop without the backedge)
+ in order to find more inner cfloops. */
+
+ cfscc(tail);
+
+ assert(irn_visited(n));
+ if (close)
+ close_loop(l);
+ } else {
+ /* AS: No cfloop head was found, that is we have straight line code.
+ Pop all nodes from the stack to the current cfloop. */
+ pop_scc_to_loop(n);
+ }
+ }