From f4ec5ce196a540fee89c85fb94d8a0027455274c Mon Sep 17 00:00:00 2001 From: hubicka Date: Wed, 26 Jul 2006 20:17:32 +0000 Subject: [PATCH] PR tree-optimization/27882 * cgraph.c (cgraph_remove_node): Clear needed, reachable, next, previous and decl fields. * cgraphunit.c (cgraph_reset_node): Expect cgraph_remove_node to kill next pointer (cgraph_analyze_compilation_unit): Likewise. * ipa.c (cgraph_remove_unreachable_nodes): Likewise. * ipa-inline.c (cgraph_decide_recursive_inlining): Likewise. (cgraph_early_inlinine): Make order garbage collected. * Makefile.in (gt-ipa-inline): New garbagecollected file. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115763 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 13 +++++++++++++ gcc/Makefile.in | 8 ++++---- gcc/cgraph.c | 6 ++++++ gcc/cgraphunit.c | 16 ++++++++++------ gcc/ipa-inline.c | 27 +++++++++++++++++++-------- gcc/ipa.c | 5 +++-- 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0709007a8e..228a358e159 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2006-07-26 Jan Hubicka + + PR tree-optimization/27882 + * cgraph.c (cgraph_remove_node): Clear needed, reachable, next, previous + and decl fields. + * cgraphunit.c (cgraph_reset_node): Expect cgraph_remove_node to kill + next pointer + (cgraph_analyze_compilation_unit): Likewise. + * ipa.c (cgraph_remove_unreachable_nodes): Likewise. + * ipa-inline.c (cgraph_decide_recursive_inlining): Likewise. + (cgraph_early_inlinine): Make order garbage collected. + * Makefile.in (gt-ipa-inline): New garbagecollected file. + 2006-07-26 Daniel Jacobowitz * dbxout.c (output_types_sort): Add a comment. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 7dd40980527..f65a5fbbb72 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2299,10 +2299,10 @@ ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h \ tree-flow.h $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) \ diagnostic.h -ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ +ipa-inline.o : ipa-inline.c gt-ipa-inline.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \ $(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TIMEVAR_H) tree-pass.h \ - $(COVERAGE_H) $(HASHTAB_H) + $(COVERAGE_H) $(HASHTAB_H) ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ pointer-set.h $(GGC_H) $(C_COMMON_H) $(TREE_GIMPLE_H) \ @@ -2845,7 +2845,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \ $(srcdir)/c-common.h $(srcdir)/c-tree.h $(srcdir)/reload.h \ $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \ - $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c\ + $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c \ $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \ $(srcdir)/dojump.c $(srcdir)/tree-profile.c \ $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \ @@ -2899,7 +2899,7 @@ gt-tree-profile.h gt-tree-ssa-address.h \ gt-tree-ssanames.h gt-tree-iterator.h gt-gimplify.h \ gt-tree-phinodes.h gt-tree-nested.h \ gt-tree-ssa-operands.h gt-tree-ssa-propagate.h \ -gt-tree-ssa-structalias.h \ +gt-tree-ssa-structalias.h gt-ipa-inline.h \ gt-stringpool.h gt-targhooks.h gt-omp-low.h : s-gtype ; @true define echo_quoted_to_gtyp diff --git a/gcc/cgraph.c b/gcc/cgraph.c index e20c8d5336e..8d841b46e0d 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -452,6 +452,9 @@ cgraph_remove_node (struct cgraph_node *node) cgraph_node_remove_callers (node); cgraph_node_remove_callees (node); + /* Incremental inlining access removed nodes stored in the postorder list. + */ + node->needed = node->reachable = false; while (node->nested) cgraph_remove_node (node->nested); if (node->origin) @@ -468,6 +471,8 @@ cgraph_remove_node (struct cgraph_node *node) cgraph_nodes = node->next; if (node->next) node->next->previous = node->previous; + node->next = NULL; + node->previous = NULL; slot = htab_find_slot (cgraph_hash, node, NO_INSERT); if (*slot == node) { @@ -515,6 +520,7 @@ cgraph_remove_node (struct cgraph_node *node) DECL_STRUCT_FUNCTION (node->decl) = NULL; DECL_INITIAL (node->decl) = error_mark_node; } + node->decl = NULL; cgraph_n_nodes--; /* Do not free the structure itself so the walk over chain can continue. */ } diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index db44cb8c242..606cd75ef92 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -419,11 +419,14 @@ cgraph_reset_node (struct cgraph_node *node) if (!flag_unit_at_a_time) { - struct cgraph_node *n; + struct cgraph_node *n, *next; - for (n = cgraph_nodes; n; n = n->next) - if (n->global.inlined_to == node) - cgraph_remove_node (n); + for (n = cgraph_nodes; n; n = next) + { + next = n->next; + if (n->global.inlined_to == node) + cgraph_remove_node (n); + } } cgraph_node_remove_callees (node); @@ -1009,7 +1012,7 @@ process_function_and_variable_attributes (struct cgraph_node *first, void cgraph_finalize_compilation_unit (void) { - struct cgraph_node *node; + struct cgraph_node *node, *next; /* Keep track of already processed nodes when called multiple times for intermodule optimization. */ static struct cgraph_node *first_analyzed; @@ -1091,9 +1094,10 @@ cgraph_finalize_compilation_unit (void) if (cgraph_dump_file) fprintf (cgraph_dump_file, "\nReclaiming functions:"); - for (node = cgraph_nodes; node != first_analyzed; node = node->next) + for (node = cgraph_nodes; node != first_analyzed; node = next) { tree decl = node->decl; + next = node->next; if (node->local.finalized && !DECL_SAVED_TREE (decl)) cgraph_reset_node (node); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d2cdce2b0ea..6bbfcf0c00e 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -570,7 +570,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node) int probability = PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY); fibheap_t heap; struct cgraph_edge *e; - struct cgraph_node *master_clone; + struct cgraph_node *master_clone, *next; int depth = 0; int n = 0; @@ -671,9 +671,12 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node) into master clone gets queued just before master clone so we don't need recursion. */ for (node = cgraph_nodes; node != master_clone; - node = node->next) - if (node->global.inlined_to == master_clone) - cgraph_remove_node (node); + node = next) + { + next = node->next; + if (node->global.inlined_to == master_clone) + cgraph_remove_node (node); + } cgraph_remove_node (master_clone); /* FIXME: Recursive inlining actually reduces number of calls of the function. At this place we should probably walk the function and @@ -1150,6 +1153,12 @@ struct tree_opt_pass pass_ipa_inline = 0 /* letter */ }; +/* Because inlining might remove no-longer reachable nodes, we need to + keep the array visible to garbage collector to avoid reading collected + out nodes. */ +static int nnodes; +static GTY ((length ("nnodes"))) struct cgraph_node **order; + /* Do inlining of small functions. Doing so early helps profiling and other passes to be somewhat more effective and avoids some code duplication in later real inlining pass for testcases with very many function calls. */ @@ -1157,9 +1166,6 @@ static unsigned int cgraph_early_inlining (void) { struct cgraph_node *node; - int nnodes; - struct cgraph_node **order = - XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); int i; if (sorrycount || errorcount) @@ -1169,6 +1175,7 @@ cgraph_early_inlining (void) gcc_assert (!node->aux); #endif + order = ggc_alloc (sizeof (*order) * cgraph_n_nodes); nnodes = cgraph_postorder (order); for (i = nnodes - 1; i >= 0; i--) { @@ -1186,7 +1193,9 @@ cgraph_early_inlining (void) for (node = cgraph_nodes; node; node = node->next) gcc_assert (!node->global.inlined_to); #endif - free (order); + ggc_free (order); + order = NULL; + nnodes = 0; return 0; } @@ -1213,3 +1222,5 @@ struct tree_opt_pass pass_early_ipa_inline = TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */ 0 /* letter */ }; + +#include "gt-ipa-inline.h" diff --git a/gcc/ipa.c b/gcc/ipa.c index 44b045654da..b78709bc166 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -97,7 +97,7 @@ bool cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) { struct cgraph_node *first = (void *) 1; - struct cgraph_node *node; + struct cgraph_node *node, *next; bool changed = false; int insns = 0; @@ -151,8 +151,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) unanalyzed nodes so they look like for true extern functions to the rest of code. Body of such functions is released via remove_node once the inline clones are eliminated. */ - for (node = cgraph_nodes; node; node = node->next) + for (node = cgraph_nodes; node; node = next) { + next = node->next; if (!node->aux) { int local_insns; -- 2.11.0