The following avoids GC collecting during pass execution when a pass calls cgraph::get_body.
Bootstrapped / tested on x86_64-unknown-linux-gnu. OK? Thanks, Richard. 2019-07-03 Richard Biener <rguent...@suse.de> PR ipa/91062 * tree-pass.h (execute_all_ipa_transforms): Add a flag parameter whether to disable GC collection. * passes.c (execute_one_ipa_transform_pass): Likewise, and honor it. (execute_all_ipa_transforms): Likewise and pass it down. * cgraph.c (cgraph_node::get_body): Do not invoke garbage collection from applying IPA transforms. * cgraphunit.c (cgraph_node::expand): Allow garbage collection from applying IPA transforms. Index: gcc/tree-pass.h =================================================================== --- gcc/tree-pass.h (revision 272958) +++ gcc/tree-pass.h (working copy) @@ -632,7 +632,7 @@ extern bool execute_one_pass (opt_pass * extern void execute_pass_list (function *, opt_pass *); extern void execute_ipa_pass_list (opt_pass *); extern void execute_ipa_summary_passes (ipa_opt_pass_d *); -extern void execute_all_ipa_transforms (void); +extern void execute_all_ipa_transforms (bool); extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple **); extern bool pass_init_dump_file (opt_pass *); extern void pass_fini_dump_file (opt_pass *); Index: gcc/passes.c =================================================================== --- gcc/passes.c (revision 272958) +++ gcc/passes.c (working copy) @@ -2182,7 +2182,7 @@ execute_ipa_summary_passes (ipa_opt_pass static void execute_one_ipa_transform_pass (struct cgraph_node *node, - ipa_opt_pass_d *ipa_pass) + ipa_opt_pass_d *ipa_pass, bool do_not_collect) { opt_pass *pass = ipa_pass; unsigned int todo_after = 0; @@ -2228,14 +2228,14 @@ execute_one_ipa_transform_pass (struct c redirect_edge_var_map_empty (); /* Signal this is a suitable GC collection point. */ - if (!(todo_after & TODO_do_not_ggc_collect)) + if (!do_not_collect && !(todo_after & TODO_do_not_ggc_collect)) ggc_collect (); } /* For the current function, execute all ipa transforms. */ void -execute_all_ipa_transforms (void) +execute_all_ipa_transforms (bool do_not_collect) { struct cgraph_node *node; if (!cfun) @@ -2247,7 +2247,8 @@ execute_all_ipa_transforms (void) unsigned int i; for (i = 0; i < node->ipa_transforms_to_apply.length (); i++) - execute_one_ipa_transform_pass (node, node->ipa_transforms_to_apply[i]); + execute_one_ipa_transform_pass (node, node->ipa_transforms_to_apply[i], + do_not_collect); node->ipa_transforms_to_apply.release (); } } Index: gcc/cgraph.c =================================================================== --- gcc/cgraph.c (revision 272958) +++ gcc/cgraph.c (working copy) @@ -3618,7 +3618,7 @@ cgraph_node::get_body (void) set_dump_file (NULL); push_cfun (DECL_STRUCT_FUNCTION (decl)); - execute_all_ipa_transforms (); + execute_all_ipa_transforms (true); cgraph_edge::rebuild_edges (); free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 272958) +++ gcc/cgraphunit.c (working copy) @@ -2184,7 +2184,7 @@ cgraph_node::expand (void) bitmap_obstack_initialize (®_obstack); /* FIXME, only at RTL generation*/ - execute_all_ipa_transforms (); + execute_all_ipa_transforms (false); /* Perform all tree transforms and optimizations. */