This fixes PR56921 in a better way and restores the ability to ggc-collect during RTL loop passes. The patch stores the simple-loop-description in a separate member of struct loop and not its aux field which is not scanned by GC.
Bootstrapped and tested on x86_64-unknown-linux-gnu and powerpc64-linux-gnu, applied. Richard. 2013-04-17 Richard Biener <rguent...@suse.de> PR rtl-optimization/56921 * cfgloop.h (struct loop): Add simple_loop_desc member. (struct niter_desc): Mark with GTY(()). (simple_loop_desc): Do not use aux field but simple_loop_desc. * loop-iv.c (get_simple_loop_desc): Likewise. (free_simple_loop_desc): Likewise. Revert 2013-04-16 Richard Biener <rguent...@suse.de> PR rtl-optimization/56921 * loop-init.c (pass_rtl_move_loop_invariants): Add TODO_do_not_ggc_collect to todo_flags_finish. (pass_rtl_unswitch): Same. (pass_rtl_unroll_and_peel_loops): Same. (pass_rtl_doloop): Same. Index: gcc/cfgloop.h =================================================================== *** gcc/cfgloop.h (revision 198021) --- gcc/cfgloop.h (working copy) *************** struct GTY ((chain_next ("%h.next"))) lo *** 172,177 **** --- 172,180 ---- /* Head of the cyclic list of the exits of the loop. */ struct loop_exit *exits; + + /* Number of iteration analysis data for RTL. */ + struct niter_desc *simple_loop_desc; }; /* Flags for state of loop structure. */ *************** struct rtx_iv *** 372,378 **** /* The description of an exit from the loop and of the number of iterations till we take the exit. */ ! struct niter_desc { /* The edge out of the loop. */ edge out_edge; --- 375,381 ---- /* The description of an exit from the loop and of the number of iterations till we take the exit. */ ! struct GTY(()) niter_desc { /* The edge out of the loop. */ edge out_edge; *************** extern void free_simple_loop_desc (struc *** 425,431 **** static inline struct niter_desc * simple_loop_desc (struct loop *loop) { ! return (struct niter_desc *) loop->aux; } /* Accessors for the loop structures. */ --- 428,434 ---- static inline struct niter_desc * simple_loop_desc (struct loop *loop) { ! return loop->simple_loop_desc; } /* Accessors for the loop structures. */ Index: gcc/loop-iv.c =================================================================== *** gcc/loop-iv.c (revision 198021) --- gcc/loop-iv.c (working copy) *************** get_simple_loop_desc (struct loop *loop) *** 3016,3025 **** /* At least desc->infinite is not always initialized by find_simple_loop_exit. */ ! desc = XCNEW (struct niter_desc); iv_analysis_loop_init (loop); find_simple_exit (loop, desc); ! loop->aux = desc; if (desc->simple_p && (desc->assumptions || desc->infinite)) { --- 3016,3025 ---- /* At least desc->infinite is not always initialized by find_simple_loop_exit. */ ! desc = ggc_alloc_cleared_niter_desc (); iv_analysis_loop_init (loop); find_simple_exit (loop, desc); ! loop->simple_loop_desc = desc; if (desc->simple_p && (desc->assumptions || desc->infinite)) { *************** free_simple_loop_desc (struct loop *loop *** 3069,3074 **** if (!desc) return; ! free (desc); ! loop->aux = NULL; } --- 3069,3074 ---- if (!desc) return; ! ggc_free (desc); ! loop->simple_loop_desc = NULL; } Index: gcc/loop-init.c =================================================================== *** gcc/loop-init.c (revision 198021) --- gcc/loop-init.c (working copy) *************** struct rtl_opt_pass pass_rtl_move_loop_i *** 434,441 **** 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_verify | ! TODO_df_finish | TODO_verify_rtl_sharing ! | TODO_do_not_ggc_collect /* todo_flags_finish */ } }; --- 434,440 ---- 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_df_verify | ! TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */ } }; *************** struct rtl_opt_pass pass_rtl_unswitch = *** 471,478 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing ! | TODO_do_not_ggc_collect /* todo_flags_finish */ } }; --- 470,476 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; *************** struct rtl_opt_pass pass_rtl_unroll_and_ *** 521,528 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing ! | TODO_do_not_ggc_collect /* todo_flags_finish */ } }; --- 519,525 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing, /* todo_flags_finish */ } }; *************** struct rtl_opt_pass pass_rtl_doloop = *** 564,570 **** 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing ! | TODO_do_not_ggc_collect /* todo_flags_finish */ } }; --- 561,566 ---- 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ ! TODO_verify_rtl_sharing /* todo_flags_finish */ } };