* emit-rtl.c (free_emit_status): Don't check DECL_DEFER_OUTPUT.
Free the struct.
(mark_emit_status): Renamed from mark_emit_state.
* except.c (mark_eh_status): Renamed from mark_eh_state.
Check not null before marking.
(free_eh_status): New.
* expr.c (mark_expr_status, free_expr_status): New.
* function.c (free_machine_status): New.
(free_after_parsing): New.
(free_after_compilation): Move bits to free_after_parsing; call
free_eh_status, free_expr_status; zero the marked members of the
function state.
(prepare_function_start): No can_garbage_collect.
Call init_eh_for_function.
(expand_dummy_function_end): Free up current_function state.
(mark_function_status): Renamed from mark_function_state.
(mark_function_chain): No can_garbage_collect. Call mark_expr_status.
* function.h (struct function): No can_garbage_collect.
(free_machine_status, free_after_parsing): Declare.
(free_eh_status, free_expr_status): Declare.
* ggc.h (mark_expr_status): Declare.
* stmt.c (free_stmt_status): Free the struct.
(mark_stmt_status): Renamed from mark_stmt_state.
(init_stmt): Don't call init_eh.
(init_stmt_for_function): Don't call init_eh_for_function.
* toplev.c (compile_file): Call init_eh.
(rest_of_compilation): Free basic block info before ggc_collect.
Call free_after_parsing; conditionally call free_after_compilation.
* varasm.c (mark_varasm_status): Renamed from mark_varasm_state.
Check not null before marking.
From-SVN: r29448
+Wed Sep 15 17:56:00 1999 Richard Henderson <rth@cygnus.com>
+
+ * emit-rtl.c (free_emit_status): Don't check DECL_DEFER_OUTPUT.
+ Free the struct.
+ (mark_emit_status): Renamed from mark_emit_state.
+ * except.c (mark_eh_status): Renamed from mark_eh_state.
+ Check not null before marking.
+ (free_eh_status): New.
+ * expr.c (mark_expr_status, free_expr_status): New.
+ * function.c (free_machine_status): New.
+ (free_after_parsing): New.
+ (free_after_compilation): Move bits to free_after_parsing; call
+ free_eh_status, free_expr_status; zero the marked members of the
+ function state.
+ (prepare_function_start): No can_garbage_collect.
+ Call init_eh_for_function.
+ (expand_dummy_function_end): Free up current_function state.
+ (mark_function_status): Renamed from mark_function_state.
+ (mark_function_chain): No can_garbage_collect. Call mark_expr_status.
+ * function.h (struct function): No can_garbage_collect.
+ (free_machine_status, free_after_parsing): Declare.
+ (free_eh_status, free_expr_status): Declare.
+ * ggc.h (mark_expr_status): Declare.
+ * stmt.c (free_stmt_status): Free the struct.
+ (mark_stmt_status): Renamed from mark_stmt_state.
+ (init_stmt): Don't call init_eh.
+ (init_stmt_for_function): Don't call init_eh_for_function.
+ * toplev.c (compile_file): Call init_eh.
+ (rest_of_compilation): Free basic block info before ggc_collect.
+ Call free_after_parsing; conditionally call free_after_compilation.
+ * varasm.c (mark_varasm_status): Renamed from mark_varasm_state.
+ Check not null before marking.
+ (free_varasm_status): Don't check DECL_DEFER_OUTPUT. Free the struct.
+
Wed Sep 15 17:53:16 1999 Richard Henderson <rth@cygnus.com>
* c-lex.c (yylex): Initialize warn.
free_emit_status (f)
struct function *f;
{
- if (DECL_DEFER_OUTPUT (f->decl))
- return;
-
free (f->emit->x_regno_reg_rtx);
free (f->emit->regno_pointer_flag);
free (f->emit->regno_pointer_align);
- f->emit->x_regno_reg_rtx = 0;
+ free (f->emit);
+ f->emit = NULL;
}
\f
/* Go through all the RTL insn bodies and copy any invalid shared structure.
/* Mark ES for GC. */
void
-mark_emit_state (es)
+mark_emit_status (es)
struct emit_status *es;
{
rtx *r;
/* Mark EH for GC. */
void
-mark_eh_state (eh)
+mark_eh_status (eh)
struct eh_status *eh;
{
+ if (eh == 0)
+ return;
+
mark_eh_stack (&eh->x_ehstack);
mark_eh_stack (&eh->x_catchstack);
mark_eh_queue (&eh->x_ehqueue);
void
init_eh_for_function ()
{
- current_function->eh = (struct eh_status *) xmalloc (sizeof (struct eh_status));
+ current_function->eh
+ = (struct eh_status *) xmalloc (sizeof (struct eh_status));
ehstack.top = 0;
catchstack.top = 0;
eh_return_handler = NULL_RTX;
eh_return_stub_label = NULL_RTX;
}
+
+void
+free_eh_status (f)
+ struct function *f;
+{
+ free (f->eh);
+ f->eh = NULL;
+}
\f
/* This section is for the exception handling specific optimization
pass. First are the internal routines, and then the main
forced_labels = 0;
}
+void
+mark_expr_status (p)
+ struct expr_status *p;
+{
+ if (p == NULL)
+ return;
+
+ ggc_mark_rtx (p->x_saveregs_value);
+ ggc_mark_rtx (p->x_apply_args_value);
+ ggc_mark_rtx (p->x_forced_labels);
+}
+
+void
+free_expr_status (f)
+ struct function *f;
+{
+ free (f->expr);
+ f->expr = NULL;
+}
+
/* Small sanity check that the queue is empty at the end of a function. */
void
finish_expr_for_function ()
void (*save_machine_status) PROTO((struct function *));
void (*restore_machine_status) PROTO((struct function *));
void (*mark_machine_status) PROTO((struct function *));
+void (*free_machine_status) PROTO((struct function *));
/* Likewise, but for language-specific data. */
void (*init_lang_status) PROTO((struct function *));
static int insns_for_mem_walk PROTO ((rtx *, void *));
static void compute_insns_for_mem PROTO ((rtx, rtx, struct hash_table *));
static void mark_temp_slot PROTO ((struct temp_slot *));
-static void mark_function_state PROTO ((struct function *));
+static void mark_function_status PROTO ((struct function *));
static void mark_function_chain PROTO ((void *));
\f
pop_function_context_from (current_function_decl);
}
+/* Clear out all parts of the state in F that can safely be discarded
+ after the function has been parsed, but not compiled, to let
+ garbage collection reclaim the memory. */
+
+void
+free_after_parsing (f)
+ struct function *f;
+{
+ /* f->expr->forced_labels is used by code generation. */
+ /* f->emit->regno_reg_rtx is used by code generation. */
+ /* f->varasm is used by code generation. */
+ /* f->eh->eh_return_stub_label is used by code generation. */
+
+ if (free_lang_status)
+ (*free_lang_status) (f);
+ free_stmt_status (f);
+}
+
/* Clear out all parts of the state in F that can safely be discarded
after the function has been compiled, to let garbage collection
reclaim the memory. */
free_after_compilation (f)
struct function *f;
{
+ free_eh_status (f);
+ free_expr_status (f);
free_emit_status (f);
free_varasm_status (f);
- free_stmt_status (f);
- if (free_lang_status)
- (*free_lang_status) (f);
- if (!DECL_DEFER_OUTPUT (f->decl))
- {
- free (f->x_parm_reg_stack_loc);
- f->can_garbage_collect = 1;
- }
+ if (free_machine_status)
+ (*free_machine_status) (f);
+
+ free (f->x_parm_reg_stack_loc);
+
+ f->arg_offset_rtx = NULL;
+ f->return_rtx = NULL;
+ f->internal_arg_pointer = NULL;
+ f->x_nonlocal_labels = NULL;
+ f->x_nonlocal_goto_handler_slots = NULL;
+ f->x_nonlocal_goto_handler_labels = NULL;
+ f->x_nonlocal_goto_stack_level = NULL;
+ f->x_cleanup_label = NULL;
+ f->x_return_label = NULL;
+ f->x_save_expr_regs = NULL;
+ f->x_stack_slot_list = NULL;
+ f->x_rtl_expr_chain = NULL;
+ f->x_tail_recursion_label = NULL;
+ f->x_tail_recursion_reentry = NULL;
+ f->x_arg_pointer_save_area = NULL;
+ f->x_context_display = NULL;
+ f->x_trampoline_list = NULL;
+ f->x_parm_birth_insn = NULL;
+ f->x_last_parm_insn = NULL;
+ f->x_parm_reg_stack_loc = NULL;
+ f->x_temp_slots = NULL;
+ f->fixup_var_refs_queue = NULL;
+ f->original_arg_vector = NULL;
+ f->original_decl_initial = NULL;
+ f->inl_last_parm_insn = NULL;
+ f->epilogue_delay_list = NULL;
}
+
\f
/* Allocate fixed slots in the stack frame of the current function. */
prepare_function_start ()
{
current_function = (struct function *) xcalloc (1, sizeof (struct function));
- current_function->can_garbage_collect = 0;
init_stmt_for_function ();
+ init_eh_for_function ();
cse_not_expected = ! optimize;
/* Outside function body, can't compute type's actual size
until next function's body starts. */
+
+ free_after_parsing (current_function);
+ free_after_compilation (current_function);
+ free (current_function);
current_function = 0;
}
/* Mark P for GC. */
static void
-mark_function_state (p)
+mark_function_status (p)
struct function *p;
{
int i;
for (; f; f = f->next_global)
{
- if (f->can_garbage_collect)
- continue;
-
ggc_mark_tree (f->decl);
- mark_function_state (f);
- mark_stmt_state (f->stmt);
- mark_eh_state (f->eh);
- mark_emit_state (f->emit);
- mark_varasm_state (f->varasm);
-
- ggc_mark_rtx (f->expr->x_saveregs_value);
- ggc_mark_rtx (f->expr->x_apply_args_value);
- ggc_mark_rtx (f->expr->x_forced_labels);
+ mark_function_status (f);
+ mark_eh_status (f->eh);
+ mark_stmt_status (f->stmt);
+ mark_expr_status (f->expr);
+ mark_emit_status (f->emit);
+ mark_varasm_status (f->varasm);
if (mark_machine_status)
(*mark_machine_status) (f);
struct emit_status *emit;
struct varasm_status *varasm;
- /* Nonzero if we are done compiling this function. */
- int can_garbage_collect;
-
/* For function.c. */
/* Name of this function. */
extern void (*mark_machine_status) PROTO((struct function *));
extern void (*save_machine_status) PROTO((struct function *));
extern void (*restore_machine_status) PROTO((struct function *));
+extern void (*free_machine_status) PROTO((struct function *));
/* Likewise, but for language-specific data. */
extern void (*init_lang_status) PROTO((struct function *));
extern void save_tree_status PROTO((struct function *));
extern void restore_tree_status PROTO((struct function *));
extern void restore_emit_status PROTO((struct function *));
+extern void free_after_parsing PROTO((struct function *));
extern void free_after_compilation PROTO((struct function *));
extern void init_varasm_status PROTO((struct function *));
extern void free_varasm_status PROTO((struct function *));
extern void free_emit_status PROTO((struct function *));
extern void free_stmt_status PROTO((struct function *));
+extern void free_eh_status PROTO((struct function *));
+extern void free_expr_status PROTO((struct function *));
+
extern rtx get_first_block_beg PROTO((void));
extern void init_virtual_regs PROTO((struct emit_status *));
just forward-declare them here. */
struct eh_status;
struct emit_status;
+struct expr_status;
struct hash_table;
struct label_node;
struct rtvec_def;
/* Mark functions for various structs scattered about. */
-void mark_eh_state PROTO ((struct eh_status *));
-void mark_stmt_state PROTO ((struct stmt_status *));
-void mark_emit_state PROTO ((struct emit_status *));
-void mark_varasm_state PROTO ((struct varasm_status *));
+void mark_eh_status PROTO ((struct eh_status *));
+void mark_emit_status PROTO ((struct emit_status *));
+void mark_expr_status PROTO ((struct expr_status *));
+void mark_stmt_status PROTO ((struct stmt_status *));
+void mark_varasm_status PROTO ((struct varasm_status *));
void mark_optab PROTO ((void *));
/* We're about to free the function obstack. If we hold pointers to
things allocated there, then we'll try to mark them when we do
GC. So, we clear them out here explicitly. */
- f->stmt->x_goto_fixup_chain = 0;
+
+ free (f->stmt);
+ f->stmt = NULL;
}
/* Mark P for GC. */
void
-mark_stmt_state (p)
+mark_stmt_status (p)
struct stmt_status *p;
{
if (p == 0)
init_stmt ()
{
gcc_obstack_init (&stmt_obstack);
- init_eh ();
}
void
expr_stmts_for_value = 0;
last_expr_type = 0;
last_expr_value = NULL_RTX;
-
- init_eh_for_function ();
}
\f
/* Return nonzero if anything is pushed on the loop, condition, or case
init_decl_processing ();
init_optabs ();
init_stmt ();
+ init_eh ();
init_loop ();
init_reload ();
init_alias_once ();
/* Show no temporary slots allocated. */
init_temp_slots ();
+
+ free_basic_block_vars (0);
});
/* Make sure volatile mem refs aren't considered valid operands for
init_recog_no_volatile ();
/* We're done with this function. Free up memory if we can. */
- free_after_compilation (current_function);
-
+ free_after_parsing (current_function);
+ if (! DECL_DEFER_OUTPUT (decl))
+ free_after_compilation (current_function);
current_function = 0;
if (ggc_p)
*except* what is spent in this function. */
parse_time -= get_run_time () - start_time;
-
- /* Reset global variables. */
- free_basic_block_vars (0);
}
\f
static void
/* Mark P for GC. */
void
-mark_varasm_state (p)
- struct varasm_status *p;
+mark_varasm_status (p)
+ struct varasm_status *p;
{
+ if (p == NULL)
+ return;
+
mark_pool_constant (p->x_first_pool);
mark_pool_sym_hash_table (p->x_const_rtx_sym_hash_table);
ggc_mark_rtx (p->x_const_double_chain);
{
struct varasm_status *p;
- if (DECL_DEFER_OUTPUT (f->decl))
- return;
-
p = f->varasm;
free (p->x_const_rtx_hash_table);
free (p->x_const_rtx_sym_hash_table);
-
- p->x_first_pool = p->x_last_pool = 0;
- p->x_const_rtx_hash_table = 0;
- p->x_const_rtx_sym_hash_table = 0;
- p->x_const_double_chain = 0;
+ free (p);
+ f->varasm = NULL;
}
\f
enum kind { RTX_DOUBLE, RTX_INT };