struct loops * loop_optimizer_init (FILE *dumpfile) { struct loops *loops = xcalloc (1, sizeof (struct loops)); edge e; /* Initialize structures for layout changes. */ cfg_layout_initialize (0); /* Avoid annoying special cases of edges going to exit block. */ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next) if ((e->flags & EDGE_FALLTHRU) && e->src->succ->succ_next) split_edge (e); /* Find the loops. */ if (flow_loops_find (loops, LOOP_TREE) <= 1) { basic_block bb; /* No loops. */ flow_loops_free (loops); free_dominance_info (CDI_DOMINATORS); free (loops); /* Make chain. */ FOR_EACH_BB (bb) if (bb->next_bb != EXIT_BLOCK_PTR) bb->rbi->next = bb->next_bb; cfg_layout_finalize (); return NULL; }
struct loops * loop_optimizer_init (FILE *dumpfile) { struct loops *loops = xcalloc (1, sizeof (struct loops)); edge e; edge_iterator ei; static bool first_time = true; if (first_time) { first_time = false; init_set_costs (); } /* Avoid annoying special cases of edges going to exit block. */ for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); ) if ((e->flags & EDGE_FALLTHRU) && !single_succ_p (e->src)) split_edge (e); else ei_next (&ei); /* Find the loops. */ if (flow_loops_find (loops) <= 1) { /* No loops. */ flow_loops_free (loops); free (loops); return NULL; } /* Not going to update these. */ free (loops->cfg.rc_order); loops->cfg.rc_order = NULL; free (loops->cfg.dfs_order); loops->cfg.dfs_order = NULL; /* Create pre-headers. */ create_preheaders (loops, CP_SIMPLE_PREHEADERS); /* Force all latches to have only single successor. */ force_single_succ_latches (loops); /* Mark irreducible loops. */ mark_irreducible_loops (loops); /* Dump loops. */ flow_loops_dump (loops, dumpfile, NULL, 1); #ifdef ENABLE_CHECKING verify_dominators (CDI_DOMINATORS); verify_loop_structure (loops); #endif return loops; }
int flow_loops_update (struct loops *loops, int flags) { /* One day we may want to update the current loop data. For now throw away the old stuff and rebuild what we need. */ if (loops->parray) flow_loops_free (loops); return flow_loops_find (loops, flags); }
void loop_optimizer_finalize (void) { struct loop *loop; basic_block bb; timevar_push (TV_LOOP_FINI); if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS)) release_recorded_exits (); free_numbers_of_iterations_estimates (); /* If we should preserve loop structure, do not free it but clear flags that advanced properties are there as we are not preserving that in full. */ if (cfun->curr_properties & PROP_loops) { loops_state_clear (LOOP_CLOSED_SSA | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS | LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES | LOOPS_HAVE_FALLTHRU_PREHEADERS); loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES); goto loop_fini_done; } gcc_assert (current_loops != NULL); FOR_EACH_LOOP (loop, 0) free_simple_loop_desc (loop); /* Clean up. */ flow_loops_free (current_loops); ggc_free (current_loops); current_loops = NULL; FOR_ALL_BB_FN (bb, cfun) { bb->loop_father = NULL; } loop_fini_done: timevar_pop (TV_LOOP_FINI); }
/* Finalize loop optimizer. */ void loop_optimizer_finalize (struct loops *loops) { unsigned i; if (!loops) return; for (i = 1; i < loops->num; i++) if (loops->parray[i]) free_simple_loop_desc (loops->parray[i]); /* Clean up. */ flow_loops_free (loops); free (loops); /* Checking. */ #ifdef ENABLE_CHECKING verify_flow_info (); #endif }