+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>
* dbxout.c (output_types_sort): Add a comment.
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) \
$(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 \
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
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)
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)
{
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. */
}
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);
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;
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);
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;
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
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. */
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)
gcc_assert (!node->aux);
#endif
+ order = ggc_alloc (sizeof (*order) * cgraph_n_nodes);
nnodes = cgraph_postorder (order);
for (i = nnodes - 1; i >= 0; i--)
{
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;
}
TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
0 /* letter */
};
+
+#include "gt-ipa-inline.h"
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;
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;