diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 73fd11fe98b..602f2e7e328 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2007-01-04 Jan Hubicka + + * cgraph.c (cgraph_release_function_body): New function. + (cgraph_remove_node): Use it. + * cgraph.h (cgraph_release_function_body): Declare. + * cgraphunit.c (cgraph_expand_function): Use it. + * ipa.c (cgraph_remove_unreahchable_nodes): Use it. + * tree-ssa.c (delete_tree_ssa): Allow to be called before aliasing + is initialized and while compilation of other function is running. + * tree-optimize.c (execute_free_cfg_annotations): Move code to clear + statement CFG annotations from here to ... + * tree-cfg.c (delete_tree_cfg_annotations): ... here. + 2007-01-04 Zdenek Dvorak * cfgloop.h (enum li_flags): Make the constants powers of two. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 1baed252439..8914569b395 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -468,6 +468,27 @@ cgraph_node_remove_callers (struct cgraph_node *node) node->callers = NULL; } +/* Release memory used to represent body of function NODE. */ + +void +cgraph_release_function_body (struct cgraph_node *node) +{ + if (DECL_STRUCT_FUNCTION (node->decl) + && DECL_STRUCT_FUNCTION (node->decl)->gimple_df) + { + tree old_decl = current_function_decl; + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); + current_function_decl = node->decl; + delete_tree_ssa (); + delete_tree_cfg_annotations (); + current_function_decl = old_decl; + pop_cfun(); + } + DECL_SAVED_TREE (node->decl) = NULL; + DECL_STRUCT_FUNCTION (node->decl) = NULL; + DECL_INITIAL (node->decl) = error_mark_node; +} + /* Remove the node from cgraph. */ void @@ -541,11 +562,7 @@ cgraph_remove_node (struct cgraph_node *node) } if (kill_body && flag_unit_at_a_time) - { - DECL_SAVED_TREE (node->decl) = NULL; - DECL_STRUCT_FUNCTION (node->decl) = NULL; - DECL_INITIAL (node->decl) = error_mark_node; - } + cgraph_release_function_body (node); node->decl = NULL; if (node->call_site_hash) { diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 6f2d3be9a90..4a33d5d45cb 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -281,6 +281,7 @@ void dump_cgraph_node (FILE *, struct cgraph_node *); void cgraph_insert_node_to_hashtable (struct cgraph_node *node); void cgraph_remove_edge (struct cgraph_edge *); void cgraph_remove_node (struct cgraph_node *); +void cgraph_release_function_body (struct cgraph_node *); void cgraph_node_remove_callees (struct cgraph_node *node); struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_node *, diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 4cbb75f0c72..b1c5c8b461f 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1179,9 +1179,7 @@ cgraph_expand_function (struct cgraph_node *node) current_function_decl = NULL; if (!cgraph_preserve_function_body_p (node->decl)) { - DECL_SAVED_TREE (node->decl) = NULL; - DECL_STRUCT_FUNCTION (node->decl) = NULL; - DECL_INITIAL (node->decl) = error_mark_node; + cgraph_release_function_body (node); /* Eliminate all call edges. This is important so the call_expr no longer points to the dead function body. */ cgraph_node_remove_callees (node); diff --git a/gcc/ipa.c b/gcc/ipa.c index b78709bc166..f45c0583876 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -186,9 +186,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) break; if (!clone) { - DECL_SAVED_TREE (node->decl) = NULL; - DECL_STRUCT_FUNCTION (node->decl) = NULL; - DECL_INITIAL (node->decl) = error_mark_node; + cgraph_release_function_body (node); node->analyzed = false; } cgraph_node_remove_callees (node); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 4358c7e7b3e..69b4b4bb0a5 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2651,6 +2651,17 @@ disband_implicit_edges (void) void delete_tree_cfg_annotations (void) { + basic_block bb; + block_stmt_iterator bsi; + + /* Remove annotations from every tree in the function. */ + FOR_EACH_BB (bb) + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + { + tree stmt = bsi_stmt (bsi); + ggc_free (stmt->base.ann); + stmt->base.ann = NULL; + } label_to_block_map = NULL; } diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 5be07cb07c5..75df4cc54e6 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -241,21 +241,9 @@ struct tree_opt_pass pass_free_datastructures = static unsigned int execute_free_cfg_annotations (void) { - basic_block bb; - block_stmt_iterator bsi; - /* Emit gotos for implicit jumps. */ disband_implicit_edges (); - /* Remove annotations from every tree in the function. */ - FOR_EACH_BB (bb) - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) - { - tree stmt = bsi_stmt (bsi); - ggc_free (stmt->base.ann); - stmt->base.ann = NULL; - } - /* And get rid of annotations we no longer need. */ delete_tree_cfg_annotations (); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 644a7976402..a4231083d01 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -846,10 +846,13 @@ delete_tree_ssa (void) cfun->gimple_df->call_clobbered_vars = NULL; cfun->gimple_df->addressable_vars = NULL; cfun->gimple_df->modified_noreturn_calls = NULL; + if (gimple_aliases_computed_p (cfun)) + { + delete_alias_heapvars (); + gcc_assert (!need_ssa_update_p ()); + } cfun->gimple_df->aliases_computed_p = false; - delete_alias_heapvars (); - gcc_assert (!need_ssa_update_p ()); cfun->gimple_df = NULL; }