Commit 96fc428c by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/27882 (segfault in ipa-inline.c, if…

re PR tree-optimization/27882 (segfault in ipa-inline.c, if (e->callee->local.disregard_inline_limits)

	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.

From-SVN: r115763
parent 88c4be5e
2006-07-26 Jan Hubicka <jh@suse.cz>
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 <dan@codesourcery.com> 2006-07-26 Daniel Jacobowitz <dan@codesourcery.com>
* dbxout.c (output_types_sort): Add a comment. * dbxout.c (output_types_sort): Add a comment.
......
...@@ -2299,10 +2299,10 @@ ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -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 \ langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h \
tree-flow.h $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) \ tree-flow.h $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) \
diagnostic.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 \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TIMEVAR_H) tree-pass.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) \ 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 \ 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) \ pointer-set.h $(GGC_H) $(C_COMMON_H) $(TREE_GIMPLE_H) \
...@@ -2845,7 +2845,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \ ...@@ -2845,7 +2845,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \ $(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \
$(srcdir)/c-common.h $(srcdir)/c-tree.h $(srcdir)/reload.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)/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)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
$(srcdir)/dojump.c $(srcdir)/tree-profile.c \ $(srcdir)/dojump.c $(srcdir)/tree-profile.c \
$(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.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 \ ...@@ -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-ssanames.h gt-tree-iterator.h gt-gimplify.h \
gt-tree-phinodes.h gt-tree-nested.h \ gt-tree-phinodes.h gt-tree-nested.h \
gt-tree-ssa-operands.h gt-tree-ssa-propagate.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 gt-stringpool.h gt-targhooks.h gt-omp-low.h : s-gtype ; @true
define echo_quoted_to_gtyp define echo_quoted_to_gtyp
......
...@@ -452,6 +452,9 @@ cgraph_remove_node (struct cgraph_node *node) ...@@ -452,6 +452,9 @@ cgraph_remove_node (struct cgraph_node *node)
cgraph_node_remove_callers (node); cgraph_node_remove_callers (node);
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
/* Incremental inlining access removed nodes stored in the postorder list.
*/
node->needed = node->reachable = false;
while (node->nested) while (node->nested)
cgraph_remove_node (node->nested); cgraph_remove_node (node->nested);
if (node->origin) if (node->origin)
...@@ -468,6 +471,8 @@ cgraph_remove_node (struct cgraph_node *node) ...@@ -468,6 +471,8 @@ cgraph_remove_node (struct cgraph_node *node)
cgraph_nodes = node->next; cgraph_nodes = node->next;
if (node->next) if (node->next)
node->next->previous = node->previous; node->next->previous = node->previous;
node->next = NULL;
node->previous = NULL;
slot = htab_find_slot (cgraph_hash, node, NO_INSERT); slot = htab_find_slot (cgraph_hash, node, NO_INSERT);
if (*slot == node) if (*slot == node)
{ {
...@@ -515,6 +520,7 @@ cgraph_remove_node (struct cgraph_node *node) ...@@ -515,6 +520,7 @@ cgraph_remove_node (struct cgraph_node *node)
DECL_STRUCT_FUNCTION (node->decl) = NULL; DECL_STRUCT_FUNCTION (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node; DECL_INITIAL (node->decl) = error_mark_node;
} }
node->decl = NULL;
cgraph_n_nodes--; cgraph_n_nodes--;
/* Do not free the structure itself so the walk over chain can continue. */ /* Do not free the structure itself so the walk over chain can continue. */
} }
......
...@@ -419,11 +419,14 @@ cgraph_reset_node (struct cgraph_node *node) ...@@ -419,11 +419,14 @@ cgraph_reset_node (struct cgraph_node *node)
if (!flag_unit_at_a_time) if (!flag_unit_at_a_time)
{ {
struct cgraph_node *n; struct cgraph_node *n, *next;
for (n = cgraph_nodes; n; n = n->next) for (n = cgraph_nodes; n; n = next)
if (n->global.inlined_to == node) {
cgraph_remove_node (n); next = n->next;
if (n->global.inlined_to == node)
cgraph_remove_node (n);
}
} }
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
...@@ -1009,7 +1012,7 @@ process_function_and_variable_attributes (struct cgraph_node *first, ...@@ -1009,7 +1012,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
void void
cgraph_finalize_compilation_unit (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 /* Keep track of already processed nodes when called multiple times for
intermodule optimization. */ intermodule optimization. */
static struct cgraph_node *first_analyzed; static struct cgraph_node *first_analyzed;
...@@ -1091,9 +1094,10 @@ cgraph_finalize_compilation_unit (void) ...@@ -1091,9 +1094,10 @@ cgraph_finalize_compilation_unit (void)
if (cgraph_dump_file) if (cgraph_dump_file)
fprintf (cgraph_dump_file, "\nReclaiming functions:"); 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; tree decl = node->decl;
next = node->next;
if (node->local.finalized && !DECL_SAVED_TREE (decl)) if (node->local.finalized && !DECL_SAVED_TREE (decl))
cgraph_reset_node (node); cgraph_reset_node (node);
......
...@@ -570,7 +570,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node) ...@@ -570,7 +570,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node)
int probability = PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY); int probability = PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY);
fibheap_t heap; fibheap_t heap;
struct cgraph_edge *e; struct cgraph_edge *e;
struct cgraph_node *master_clone; struct cgraph_node *master_clone, *next;
int depth = 0; int depth = 0;
int n = 0; int n = 0;
...@@ -671,9 +671,12 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node) ...@@ -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 into master clone gets queued just before master clone so we don't
need recursion. */ need recursion. */
for (node = cgraph_nodes; node != master_clone; for (node = cgraph_nodes; node != master_clone;
node = node->next) node = next)
if (node->global.inlined_to == master_clone) {
cgraph_remove_node (node); next = node->next;
if (node->global.inlined_to == master_clone)
cgraph_remove_node (node);
}
cgraph_remove_node (master_clone); cgraph_remove_node (master_clone);
/* FIXME: Recursive inlining actually reduces number of calls of the /* FIXME: Recursive inlining actually reduces number of calls of the
function. At this place we should probably walk the function and function. At this place we should probably walk the function and
...@@ -1150,6 +1153,12 @@ struct tree_opt_pass pass_ipa_inline = ...@@ -1150,6 +1153,12 @@ struct tree_opt_pass pass_ipa_inline =
0 /* letter */ 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 /* Do inlining of small functions. Doing so early helps profiling and other
passes to be somewhat more effective and avoids some code duplication in passes to be somewhat more effective and avoids some code duplication in
later real inlining pass for testcases with very many function calls. */ later real inlining pass for testcases with very many function calls. */
...@@ -1157,9 +1166,6 @@ static unsigned int ...@@ -1157,9 +1166,6 @@ static unsigned int
cgraph_early_inlining (void) cgraph_early_inlining (void)
{ {
struct cgraph_node *node; struct cgraph_node *node;
int nnodes;
struct cgraph_node **order =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
int i; int i;
if (sorrycount || errorcount) if (sorrycount || errorcount)
...@@ -1169,6 +1175,7 @@ cgraph_early_inlining (void) ...@@ -1169,6 +1175,7 @@ cgraph_early_inlining (void)
gcc_assert (!node->aux); gcc_assert (!node->aux);
#endif #endif
order = ggc_alloc (sizeof (*order) * cgraph_n_nodes);
nnodes = cgraph_postorder (order); nnodes = cgraph_postorder (order);
for (i = nnodes - 1; i >= 0; i--) for (i = nnodes - 1; i >= 0; i--)
{ {
...@@ -1186,7 +1193,9 @@ cgraph_early_inlining (void) ...@@ -1186,7 +1193,9 @@ cgraph_early_inlining (void)
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
gcc_assert (!node->global.inlined_to); gcc_assert (!node->global.inlined_to);
#endif #endif
free (order); ggc_free (order);
order = NULL;
nnodes = 0;
return 0; return 0;
} }
...@@ -1213,3 +1222,5 @@ struct tree_opt_pass pass_early_ipa_inline = ...@@ -1213,3 +1222,5 @@ struct tree_opt_pass pass_early_ipa_inline =
TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */ TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
0 /* letter */ 0 /* letter */
}; };
#include "gt-ipa-inline.h"
...@@ -97,7 +97,7 @@ bool ...@@ -97,7 +97,7 @@ bool
cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
{ {
struct cgraph_node *first = (void *) 1; struct cgraph_node *first = (void *) 1;
struct cgraph_node *node; struct cgraph_node *node, *next;
bool changed = false; bool changed = false;
int insns = 0; int insns = 0;
...@@ -151,8 +151,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -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 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 of code. Body of such functions is released via remove_node once the
inline clones are eliminated. */ 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) if (!node->aux)
{ {
int local_insns; int local_insns;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment