2013-02-08 Richard Biener <rguenther@suse.de>
+ * cfgloop.c (verify_loop_structure): Properly handle
+ a loop exiting to another loop header.
+ * ira-int.h (ira_loops): Remove.
+ * ira.c (ira_loops): Remove.
+ (ira): Use loop_optimizer_init and loop_optimizer_finalize.
+ (do_reload): Use loop_optimizer_finalize.
+ * ira-build.c (create_loop_tree_nodes): Use get_loops and
+ number_of_loops to access the loop tree.
+ (more_one_region_p): Likewise.
+ (finish_loop_tree_nodes): Likewise.
+ (rebuild_regno_allocno_maps): Likewise.
+ (mark_loops_for_removal): Likewise.
+ (mark_all_loops_for_removal): Likewise.
+ (remove_unnecessary_regions): Likewise.
+ (ira_build): Likewise.
+ * ira-emit.c (setup_entered_from_non_parent_p): Likewise.
+
+2013-02-08 Richard Biener <rguenther@suse.de>
+
* Makefile.in (tree-tailcall.o): Add $(CFGLOOP_H) dependency.
* ipa-pure-const.c (analyze_function): Avoid calling
mark_irreducible_loops twice.
eloops++;
for (loop = bb->loop_father;
- loop != e->dest->loop_father;
+ loop != e->dest->loop_father
+ /* When a loop exit is also an entry edge which
+ can happen when avoiding CFG manipulations
+ then the last loop exited is the outer loop
+ of the loop entered. */
+ && loop != loop_outer (e->dest->loop_father);
loop = loop_outer (loop))
{
eloops--;
}
ira_loop_nodes = ((struct ira_loop_tree_node *)
ira_allocate (sizeof (struct ira_loop_tree_node)
- * vec_safe_length (ira_loops.larray)));
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
+ * number_of_loops ()));
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), i, loop)
{
- if (loop != ira_loops.tree_root)
+ if (loop_outer (loop) != NULL)
{
ira_loop_nodes[i].regno_allocno_map = NULL;
skip_p = false;
loop_p loop;
if (current_loops != NULL)
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL
&& ira_loop_tree_root != &ira_loop_nodes[i])
return true;
if (current_loops == NULL)
finish_loop_tree_node (&ira_loop_nodes[0]);
else
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), i, loop)
finish_loop_tree_node (&ira_loop_nodes[i]);
ira_free (ira_loop_nodes);
for (i = 0; i < (unsigned int) last_basic_block_before_change; i++)
ira_assert (current_loops != NULL);
max_regno = max_reg_num ();
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, l, loop)
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), l, loop)
if (ira_loop_nodes[l].regno_allocno_map != NULL)
{
ira_free (ira_loop_nodes[l].regno_allocno_map);
ira_assert (current_loops != NULL);
sorted_loops
= (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t)
- * vec_safe_length (ira_loops.larray));
- for (n = i = 0; vec_safe_iterate (ira_loops.larray, i, &loop); i++)
+ * number_of_loops ());
+ for (n = i = 0; vec_safe_iterate (get_loops (), i, &loop); i++)
if (ira_loop_nodes[i].regno_allocno_map != NULL)
{
if (ira_loop_nodes[i].parent == NULL)
loop_p loop;
ira_assert (current_loops != NULL);
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL)
{
if (ira_loop_nodes[i].parent == NULL)
mark_all_loops_for_removal ();
else
mark_loops_for_removal ();
- children_vec.create(last_basic_block + vec_safe_length(ira_loops.larray));
- removed_loop_vec.create(last_basic_block + vec_safe_length(ira_loops.larray));
+ children_vec.create(last_basic_block + number_of_loops ());
+ removed_loop_vec.create(last_basic_block + number_of_loops ());
remove_uneccesary_loop_nodes_from_loop_tree (ira_loop_tree_root);
children_vec.release ();
if (all_p)
}
}
fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n",
- current_loops == NULL ? 1 : vec_safe_length (ira_loops.larray),
+ current_loops == NULL ? 1 : number_of_loops (),
n_basic_blocks, ira_max_point);
fprintf (ira_dump_file,
" allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n",
loop_p loop;
ira_assert (current_loops != NULL);
- FOR_EACH_VEC_SAFE_ELT (ira_loops.larray, i, loop)
+ FOR_EACH_VEC_SAFE_ELT (get_loops (), i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL)
ira_loop_nodes[i].entered_from_non_parent_p
= entered_from_non_parent_p (&ira_loop_nodes[i]);
? REG_FREQ_MAX : (freq * REG_FREQ_MAX / BB_FREQ_MAX) \
? (freq * REG_FREQ_MAX / BB_FREQ_MAX) : 1)
-/* All natural loops. */
-extern struct loops ira_loops;
-
/* A modified value of flag `-fira-verbose' used internally. */
extern int internal_flag_ira_verbose;
function. */
bool ira_use_lra_p;
-/* All natural loops. */
-struct loops ira_loops;
-
/* True if we have allocno conflicts. It is false for non-optimized
mode or when the conflict table is too big. */
bool ira_conflicts_p;
ira_assert (current_loops == NULL);
if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
- {
- flow_loops_find (&ira_loops);
- current_loops = &ira_loops;
- record_loop_exits ();
- }
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS | LOOPS_HAVE_RECORDED_EXITS);
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n");
/* ??? Rebuild the loop tree, but why? Does the loop tree
change if new insns were generated? Can that be handled
by updating the loop tree incrementally? */
- release_recorded_exits ();
- flow_loops_free (&ira_loops);
- flow_loops_find (&ira_loops);
- current_loops = &ira_loops;
- record_loop_exits ();
+ loop_optimizer_finalize ();
+ loop_optimizer_init (AVOID_CFG_MODIFICATIONS
+ | LOOPS_HAVE_RECORDED_EXITS);
if (! ira_use_lra_p)
{
{
if (current_loops != NULL)
{
- release_recorded_exits ();
- flow_loops_free (&ira_loops);
+ loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
}
FOR_ALL_BB (bb)
ira_destroy ();
if (current_loops != NULL)
{
- release_recorded_exits ();
- flow_loops_free (&ira_loops);
+ loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
}
FOR_ALL_BB (bb)