I've found this useful several times. Note that currently number_of_loops returns loops plus freed ones, the patch prepares to change that, adjusting number_of_loops callers to use vec_safe_length if they really want the maximum allocated loop number.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2016-12-13 Richard Biener <rguent...@suse.de> * cfgloopmanip.c (place_new_loop): Use vec_safe_length to get at the maximum allocated loop number. * loop-init.c (fix_loop_structure): Likewise. * tree-cfg.c (fixup_loop_arrays_after_move): Use place_new_loop. (dump_function_to_file): Dump the number of loops in the function as well as whether they need fixup. Index: gcc/cfgloopmanip.c =================================================================== --- gcc/cfgloopmanip.c (revision 243599) +++ gcc/cfgloopmanip.c (working copy) @@ -430,7 +430,7 @@ remove_path (edge e, bool *irred_invalid void place_new_loop (struct function *fn, struct loop *loop) { - loop->num = number_of_loops (fn); + loop->num = vec_safe_length (loops_for_fn (fn)->larray); vec_safe_push (loops_for_fn (fn)->larray, loop); } Index: gcc/loop-init.c =================================================================== --- gcc/loop-init.c (revision 243599) +++ gcc/loop-init.c (working copy) @@ -253,7 +258,7 @@ fix_loop_structure (bitmap changed_bbs) /* Remember the number of loops so we can return how many new loops flow_loops_find discovered. */ - old_nloops = number_of_loops (cfun); + old_nloops = vec_safe_length (current_loops->larray); /* Re-compute loop structure in-place. */ flow_loops_find (current_loops); @@ -321,7 +327,7 @@ fix_loop_structure (bitmap changed_bbs) timevar_pop (TV_LOOP_INIT); - return number_of_loops (cfun) - old_nloops; + return vec_safe_length (current_loops->larray) - old_nloops; } /* The RTL loop superpass. The actual passes are subpasses. See passes.c for Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c (revision 243597) +++ gcc/tree-cfg.c (working copy) @@ -7095,8 +7095,7 @@ fixup_loop_arrays_after_move (struct fun (*get_loops (fn1))[loop->num] = NULL; /* Place it in the new loop array, assigning it a new number. */ - loop->num = number_of_loops (fn2); - vec_safe_push (loops_for_fn (fn2)->larray, loop); + place_new_loop (fn2, loop); /* Recurse to children. */ for (loop = loop->inner; loop; loop = loop->next) @@ -7561,7 +7560,14 @@ dump_function_to_file (tree fndecl, FILE fprintf (file, " __GIMPLE ()\n%s (", function_name (fun)); } else - fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : ""); + { + if (loops_for_fn (fun)) + fprintf (file, ";; %d loops found%s\n", number_of_loops (fun), + loops_for_fn (fun)->state & LOOPS_NEED_FIXUP + ? " (fixup required)" : ""); + fprintf (file, "%s %s(", function_name (fun), + tmclone ? "[tm-clone] " : ""); + } arg = DECL_ARGUMENTS (fndecl); while (arg)