+/* Constructs backedge information for irg. In interprocedural view constructs
+ backedges for all methods called by irg, too. */
+int construct_backedges(ir_graph *irg) {
+ ir_graph *rem = current_ir_graph;
+ ir_loop *head_rem;
+ struct obstack temp;
+
+ assert(!get_interprocedural_view() &&
+ "not implemented, use construct_ip_backedges()");
+
+ max_loop_depth = 0;
+ current_ir_graph = irg;
+ outermost_ir_graph = irg;
+
+ obstack_init(&temp);
+ init_scc(irg, &temp);
+
+ current_loop = NULL;
+ new_loop(); /* sets current_loop */
+ head_rem = current_loop; /* Just for assertion */
+
+ inc_irg_visited(irg);
+
+ scc(get_irg_end(irg));
+
+ finish_scc();
+ obstack_free(&temp, NULL);
+
+ assert(head_rem == current_loop);
+ mature_loops(current_loop, irg->obst);
+ set_irg_loop(irg, current_loop);
+ set_irg_loopinfo_state(irg, loopinfo_consistent);
+ assert(get_irg_loop(irg)->kind == k_ir_loop);
+ current_ir_graph = rem;
+ return max_loop_depth;
+}
+
+
+#ifdef INTERPROCEDURAL_VIEW
+int construct_ip_backedges(void) {
+ ir_graph *rem = current_ir_graph;
+ int rem_ipv = get_interprocedural_view();
+ int i;
+ strcut obstack temp;
+
+ max_loop_depth = 0;
+ assert(get_irp_ip_view_state() == ip_view_valid);
+
+ outermost_ir_graph = get_irp_main_irg();
+
+ obstack_init(&temp);
+ init_ip_scc(&temp);
+
+ current_loop = NULL;
+ new_loop(); /* sets current_loop */
+ set_interprocedural_view(1);
+
+ inc_max_irg_visited();
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ set_irg_visited(get_irp_irg(i), get_max_irg_visited());
+
+ /** We have to start the walk at the same nodes as cg_walk. **/
+ /* Walk starting at unreachable procedures. Only these
+ * have End blocks visible in interprocedural view. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *sb;
+ current_ir_graph = get_irp_irg(i);
+
+ sb = get_irg_start_block(current_ir_graph);
+
+ if ((get_Block_n_cfgpreds(sb) > 1) ||
+ (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb))
+ continue;
+
+ scc(get_irg_end(current_ir_graph));
+ }
+
+ /* Check whether we walked all procedures: there could be procedures
+ with cyclic calls but no call from the outside. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *sb;
+ current_ir_graph = get_irp_irg(i);
+
+ /* Test start block: if inner procedure end and end block are not
+ * visible and therefore not marked. */
+ sb = get_irg_start_block(current_ir_graph);
+ if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) scc(sb);
+ }
+
+ /* Walk all endless loops in inner procedures.
+ * We recognize an inner procedure if the End node is not visited. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *e;
+ current_ir_graph = get_irp_irg(i);
+
+ e = get_irg_end(current_ir_graph);
+ if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
+ int j;
+ /* Don't visit the End node. */
+ for (j = 0; j < get_End_n_keepalives(e); j++)
+ scc(get_End_keepalive(e, j));
+ }
+ }
+
+ set_irg_loop(outermost_ir_graph, current_loop);
+ set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
+ assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
+
+ obstack_free(&temp, NULL);
+ current_ir_graph = rem;
+ set_interprocedural_view(rem_ipv);
+ return max_loop_depth;
+}
+
+void my_construct_ip_backedges(void) {
+ ir_graph *rem = current_ir_graph;
+ int rem_ipv = get_interprocedural_view();
+ int i;
+
+ assert(get_irp_ip_view_state() == ip_view_valid);
+
+ outermost_ir_graph = get_irp_main_irg();
+
+ init_ip_scc();
+
+ current_loop = NULL;
+ new_loop(); /* sets current_loop */
+ set_interprocedural_view(1);
+
+ inc_max_irg_visited();
+ for (i = 0; i < get_irp_n_irgs(); i++)
+ set_irg_visited(get_irp_irg(i), get_max_irg_visited());
+
+ /** We have to start the walk at the same nodes as cg_walk. **/
+ /* Walk starting at unreachable procedures. Only these
+ * have End blocks visible in interprocedural view. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *sb;
+ current_ir_graph = get_irp_irg(i);
+
+ sb = get_irg_start_block(current_ir_graph);
+
+ if ((get_Block_n_cfgpreds(sb) > 1) ||
+ (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
+
+ my_scc(get_irg_end(current_ir_graph));
+ }
+
+ /* Check whether we walked all procedures: there could be procedures
+ with cyclic calls but no call from the outside. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *sb;
+ current_ir_graph = get_irp_irg(i);
+
+ /* Test start block: if inner procedure end and end block are not
+ * visible and therefore not marked. */
+ sb = get_irg_start_block(current_ir_graph);
+ if (get_irn_visited(sb) < get_irg_visited(current_ir_graph))
+ scc(sb);
+ }
+
+ /* Walk all endless loops in inner procedures.
+ * We recognize an inner procedure if the End node is not visited. */
+ for (i = 0; i < get_irp_n_irgs(); i++) {
+ ir_node *e;
+ current_ir_graph = get_irp_irg(i);
+
+ e = get_irg_end(current_ir_graph);
+ if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
+ int j;
+ /* Don't visit the End node. */
+ for (j = 0; j < get_End_n_keepalives(e); j++) scc(get_End_keepalive(e, j));
+ }
+ }
+
+ set_irg_loop(outermost_ir_graph, current_loop);
+ set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
+ assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
+
+ current_ir_graph = rem;
+ set_interprocedural_view(rem_ipv);