cgraph.c (cgraph_release_function_body): Plug memory leak on ipa_transforms_to_apply and CFG...
* cgraph.c (cgraph_release_function_body): Plug memory leak on ipa_transforms_to_apply and CFG; ggc_free gimple df and struct function so we are sure we do not dangle it forever. * function.c (outer_function_chain, find_function_data): Remove. (function_context_stack): New. (push_function_context, pop_function_context): Update. * function.h (struct function): Remove pointer outer. (outer_function_chain, find_function_data): Remove. * stmt.c (force_label_rtx): Remove dead call of find_function_data. From-SVN: r140285
This commit is contained in:
parent
b1d0a338a7
commit
936fc9bad2
@ -1,3 +1,15 @@
|
||||
2008-09-11 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.c (cgraph_release_function_body): Plug memory leak on
|
||||
ipa_transforms_to_apply and CFG; ggc_free gimple df and struct function
|
||||
so we are sure we do not dangle it forever.
|
||||
* function.c (outer_function_chain, find_function_data): Remove.
|
||||
(function_context_stack): New.
|
||||
(push_function_context, pop_function_context): Update.
|
||||
* function.h (struct function): Remove pointer outer.
|
||||
(outer_function_chain, find_function_data): Remove.
|
||||
* stmt.c (force_label_rtx): Remove dead call of find_function_data.
|
||||
|
||||
2008-09-11 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR middle-end/37448
|
||||
|
31
gcc/cgraph.c
31
gcc/cgraph.c
@ -846,21 +846,34 @@ cgraph_node_remove_callers (struct cgraph_node *node)
|
||||
void
|
||||
cgraph_release_function_body (struct cgraph_node *node)
|
||||
{
|
||||
if (DECL_STRUCT_FUNCTION (node->decl)
|
||||
&& DECL_STRUCT_FUNCTION (node->decl)->gimple_df)
|
||||
if (DECL_STRUCT_FUNCTION (node->decl))
|
||||
{
|
||||
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 ();
|
||||
cfun->eh = NULL;
|
||||
gimple_set_body (node->decl, NULL);
|
||||
current_function_decl = old_decl;
|
||||
if (cfun->gimple_df)
|
||||
{
|
||||
current_function_decl = node->decl;
|
||||
delete_tree_ssa ();
|
||||
delete_tree_cfg_annotations ();
|
||||
cfun->eh = NULL;
|
||||
current_function_decl = old_decl;
|
||||
}
|
||||
if (cfun->cfg)
|
||||
{
|
||||
gcc_assert (dom_computed[0] == DOM_NONE);
|
||||
gcc_assert (dom_computed[1] == DOM_NONE);
|
||||
clear_edges ();
|
||||
}
|
||||
pop_cfun();
|
||||
gimple_set_body (node->decl, NULL);
|
||||
VEC_free (ipa_opt_pass, heap,
|
||||
DECL_STRUCT_FUNCTION (node->decl)->ipa_transforms_to_apply);
|
||||
/* Struct function hangs a lot of data that would leak if we didn't
|
||||
removed all pointers to it. */
|
||||
ggc_free (DECL_STRUCT_FUNCTION (node->decl));
|
||||
DECL_STRUCT_FUNCTION (node->decl) = NULL;
|
||||
}
|
||||
DECL_SAVED_TREE (node->decl) = NULL;
|
||||
DECL_STRUCT_FUNCTION (node->decl) = NULL;
|
||||
DECL_INITIAL (node->decl) = error_mark_node;
|
||||
}
|
||||
|
||||
|
@ -208,23 +208,14 @@ static void do_clobber_return_reg (rtx, void *);
|
||||
static void do_use_return_reg (rtx, void *);
|
||||
static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
|
||||
|
||||
/* Pointer to chain of `struct function' for containing functions. */
|
||||
struct function *outer_function_chain;
|
||||
/* Stack of nested functions. */
|
||||
/* Keep track of the cfun stack. */
|
||||
|
||||
/* Given a function decl for a containing function,
|
||||
return the `struct function' for it. */
|
||||
typedef struct function *function_p;
|
||||
|
||||
struct function *
|
||||
find_function_data (tree decl)
|
||||
{
|
||||
struct function *p;
|
||||
|
||||
for (p = outer_function_chain; p; p = p->outer)
|
||||
if (p->decl == decl)
|
||||
return p;
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
DEF_VEC_P(function_p);
|
||||
DEF_VEC_ALLOC_P(function_p,heap);
|
||||
static VEC(function_p,heap) *function_context_stack;
|
||||
|
||||
/* Save the current context for compilation of a nested function.
|
||||
This is called from language-specific code. */
|
||||
@ -235,8 +226,7 @@ push_function_context (void)
|
||||
if (cfun == 0)
|
||||
allocate_struct_function (NULL, false);
|
||||
|
||||
cfun->outer = outer_function_chain;
|
||||
outer_function_chain = cfun;
|
||||
VEC_safe_push (function_p, heap, function_context_stack, cfun);
|
||||
set_cfun (NULL);
|
||||
}
|
||||
|
||||
@ -246,10 +236,8 @@ push_function_context (void)
|
||||
void
|
||||
pop_function_context (void)
|
||||
{
|
||||
struct function *p = outer_function_chain;
|
||||
|
||||
struct function *p = VEC_pop (function_p, function_context_stack);
|
||||
set_cfun (p);
|
||||
outer_function_chain = p->outer;
|
||||
current_function_decl = p->decl;
|
||||
|
||||
/* Reset variables that have known state during rtx generation. */
|
||||
@ -3905,13 +3893,6 @@ set_cfun (struct function *new_cfun)
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep track of the cfun stack. */
|
||||
|
||||
typedef struct function *function_p;
|
||||
|
||||
DEF_VEC_P(function_p);
|
||||
DEF_VEC_ALLOC_P(function_p,heap);
|
||||
|
||||
/* Initialized with NOGC, making this poisonous to the garbage collector. */
|
||||
|
||||
static VEC(function_p,heap) *cfun_stack;
|
||||
|
@ -495,9 +495,6 @@ struct function GTY(())
|
||||
/* Points to the FUNCTION_DECL of this function. */
|
||||
tree decl;
|
||||
|
||||
/* Function containing this function, if any. */
|
||||
struct function *outer;
|
||||
|
||||
/* A PARM_DECL that should contain the static chain for this function.
|
||||
It will be initialized at the beginning of the function. */
|
||||
tree static_chain_decl;
|
||||
@ -610,9 +607,6 @@ extern GTY(()) struct function *cfun;
|
||||
push_cfun or set_cfun. */
|
||||
#define cfun (cfun + 0)
|
||||
|
||||
/* Pointer to chain of `struct function' for containing functions. */
|
||||
extern GTY(()) struct function *outer_function_chain;
|
||||
|
||||
/* Nonzero if we've already converted virtual regs to hard regs. */
|
||||
extern int virtuals_instantiated;
|
||||
|
||||
@ -633,10 +627,6 @@ extern void instantiate_decl_rtl (rtx x);
|
||||
#define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree)
|
||||
#define VALUE_HISTOGRAMS(fun) (fun)->value_histograms
|
||||
|
||||
/* Given a function decl for a containing function,
|
||||
return the `struct function' for it. */
|
||||
struct function *find_function_data (tree);
|
||||
|
||||
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
|
||||
and create duplicate blocks. */
|
||||
extern void reorder_blocks (void);
|
||||
|
@ -151,15 +151,9 @@ force_label_rtx (tree label)
|
||||
{
|
||||
rtx ref = label_rtx (label);
|
||||
tree function = decl_function_context (label);
|
||||
struct function *p;
|
||||
|
||||
gcc_assert (function);
|
||||
|
||||
if (function != current_function_decl)
|
||||
p = find_function_data (function);
|
||||
else
|
||||
p = cfun;
|
||||
|
||||
forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref, forced_labels);
|
||||
return ref;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user