PATCH cgraphunit.c: Don't revisit SAVE_EXPR nodes
Jeff Sturm
jsturm@one-point.com
Wed Sep 3 05:16:00 GMT 2003
I discovered a pathological tree while building libjava with
-funit-at-a-time that consists of many nested compounds with SAVE_EXPR
nodes shared on both sides. Seemingly this can cause an exponential
slowdown in cgraph_create_edges (or "virtual memory exhausted" in my
case).
walk_tree_without_duplicates would take care of the duplication, except
when called recursively, as happens at a CALL_EXPR node.
Following is my attempt at a fix. Bootstrapped on mainline
for i686-pc-linux-gnu.
Jeff
2003-09-03 Jeff Sturm <jsturm@one-point.com>
* cgraphunit.c (visited_save_exprs): New static variable.
(record_call_1): Remember visited SAVE_EXPR nodes.
(cgraph_create_edges): Setup/teardown visited_save_exprs.
--- cgraphunit.c 2003-09-02 16:30:37.000000000 -0400
+++ cgraphunit.c.new 2003-09-02 16:20:43.000000000 -0400
@@ -54,6 +54,8 @@ static int nfunctions_inlined;
static int initial_insns;
static int overall_insns;
+static htab_t visited_save_exprs;
+
/* Analyze function once it is parsed. Set up the local information
available - create cgraph edges for function calls via BODY. */
@@ -127,6 +129,19 @@ record_call_1 (tree *tp, int *walk_subtr
*walk_subtrees = 0;
}
}
+ else if (TREE_CODE (*tp) == SAVE_EXPR)
+ {
+ void **slot;
+
+ /* Ensure we don't visit a SAVE_EXPR node more than once.
+ In spite of walk_tree_without_duplicates, this may happen
+ e.g. when a SAVE_EXPR appears in a parameter list. */
+ slot = htab_find_slot (visited_save_exprs, *tp, INSERT);
+ if (*slot)
+ *walk_subtrees = 0;
+ else
+ *slot = *tp;
+ }
/* Save some cycles by not walking types and declaration as we won't find anything
usefull there anyway. */
if (DECL_P (*tp) || TYPE_P (*tp))
@@ -141,7 +156,11 @@ cgraph_create_edges (tree decl, tree bod
{
/* The nodes we're interested in are never shared, so walk
the tree ignoring duplicates. */
+ visited_save_exprs = htab_create (37, htab_hash_pointer,
+ htab_eq_pointer, NULL);
walk_tree_without_duplicates (&body, record_call_1, decl);
+ htab_delete (visited_save_exprs);
+ visited_save_exprs = NULL;
}
/* Analyze the function scheduled to be output. */
More information about the Gcc-patches
mailing list