+2001-08-31 Zack Weinberg <zack@codesourcery.com>
+
+ * function.c: Remove all_functions. Make outer_function_chain
+ static.
+ (init_function_start): Don't add new function structure to
+ all_functions.
+ (find_function_data, push_function_context_to,
+ pop_function_context_from, put_var_into_stack,
+ trampoline_address): Update for changed structure element names.
+ (push_function_context_to): Disentangle.
+ (free_after_compilation): Also free F.
+ (expand_dummy_function_end): Don't free cfun here.
+ (put_var_into_stack): Comment why we can't use find_function_data here.
+ (fix_lexical_addr, trampoline_address, ): Use find_function_data.
+ (mark_function_chain): Split into maybe_mark_struct_function and
+ ggc_mark_struct_function. Export the latter.
+ (init_function_once): Mark from cfun and outer_function_chain;
+ not all_functions.
+
+ * function.h (struct function): Kill next_global. Rename next
+ to outer. All users updated to match.
+ (all_functions, outer_function_chain): Don't declare.
+
+ * ggc-common.c (ggc_mark_trees): Mark DECL_SAVED_INSNS.
+ * integrate.c (output_inline_function): Clear DECL_SAVED_INSNS,
+ don't touch f->inlinable, after calling rest_of_compilation.
+
+ * tree.h: Forward-declare struct function. Prototype
+ ggc_mark_struct_function.
+
2001-08-31 Kazu Hirata <kazu@hxi.com>
* config/h8300/h8300.md (*andorhi3): Fix typos.
/* The currently compiled function. */
struct function *cfun = 0;
-/* Global list of all compiled functions. */
-struct function *all_functions = 0;
-
/* These arrays record the INSN_UIDs of the prologue and epilogue insns. */
static varray_type prologue;
static varray_type epilogue;
static void compute_insns_for_mem PARAMS ((rtx, rtx, struct hash_table *));
static void mark_temp_slot PARAMS ((struct temp_slot *));
static void mark_function_status PARAMS ((struct function *));
-static void mark_function_chain PARAMS ((void *));
+static void maybe_mark_struct_function PARAMS ((void *));
static void prepare_function_start PARAMS ((void));
static void do_clobber_return_reg PARAMS ((rtx, void *));
static void do_use_return_reg PARAMS ((rtx, void *));
\f
/* Pointer to chain of `struct function' for containing functions. */
-struct function *outer_function_chain;
+static struct function *outer_function_chain;
/* Given a function decl for a containing function,
return the `struct function' for it. */
{
struct function *p;
- for (p = outer_function_chain; p; p = p->next)
+ for (p = outer_function_chain; p; p = p->outer)
if (p->decl == decl)
return p;
push_function_context_to (context)
tree context;
{
- struct function *p, *context_data;
+ struct function *p;
if (context)
{
- context_data = (context == current_function_decl
- ? cfun
- : find_function_data (context));
- context_data->contains_functions = 1;
+ if (context == current_function_decl)
+ cfun->contains_functions = 1;
+ else
+ {
+ struct function *containing = find_function_data (context);
+ containing->contains_functions = 1;
+ }
}
if (cfun == 0)
init_dummy_function_start ();
p = cfun;
- p->next = outer_function_chain;
+ p->outer = outer_function_chain;
outer_function_chain = p;
p->fixup_var_refs_queue = 0;
struct var_refs_queue *next;
cfun = p;
- outer_function_chain = p->next;
+ outer_function_chain = p->outer;
current_function_decl = p->decl;
reg_renumber = 0;
f->original_decl_initial = NULL;
f->inl_last_parm_insn = NULL;
f->epilogue_delay_list = NULL;
+
+ free (f);
}
\f
/* Allocate fixed slots in the stack frame of the current function. */
/* Get the mode it's actually stored in. */
promoted_mode = GET_MODE (reg);
- /* If this variable comes from an outer function,
- find that function's saved context. */
+ /* If this variable comes from an outer function, find that
+ function's saved context. Don't use find_function_data here,
+ because it might not be in any active function.
+ FIXME: Is that really supposed to happen?
+ It does in ObjC at least. */
if (context != current_function_decl && context != inline_function_decl)
- for (function = outer_function_chain; function; function = function->next)
+ for (function = outer_function_chain; function; function = function->outer)
if (function->decl == context)
break;
if (context == current_function_decl || context == inline_function_decl)
return addr;
- for (fp = outer_function_chain; fp; fp = fp->next)
- if (fp->decl == context)
- break;
-
- if (fp == 0)
- abort ();
+ fp = find_function_data (context);
if (GET_CODE (addr) == ADDRESSOF && GET_CODE (XEXP (addr, 0)) == MEM)
addr = XEXP (XEXP (addr, 0), 0);
return
adjust_trampoline_addr (XEXP (RTL_EXPR_RTL (TREE_VALUE (link)), 0));
- for (fp = outer_function_chain; fp; fp = fp->next)
+ for (fp = outer_function_chain; fp; fp = fp->outer)
for (link = fp->x_trampoline_list; link; link = TREE_CHAIN (link))
if (TREE_PURPOSE (link) == function)
{
fn_context = decl_function_context (function);
if (fn_context != current_function_decl
&& fn_context != inline_function_decl)
- for (fp = outer_function_chain; fp; fp = fp->next)
- if (fp->decl == fn_context)
- break;
+ fp = find_function_data (fn_context);
/* Allocate run-time space for this trampoline
(usually in the defining function's stack frame). */
{
prepare_function_start ();
- /* Remember this function for later. */
- cfun->next_global = all_functions;
- all_functions = cfun;
-
current_function_name = (*decl_printable_name) (subr, 2);
cfun->decl = subr;
free_after_parsing (cfun);
free_after_compilation (cfun);
- free (cfun);
cfun = 0;
}
mark_hard_reg_initial_vals (p);
}
-/* Mark the function chain ARG (which is really a struct function **)
- for GC. */
-
+/* Mark the struct function pointed to by *ARG for GC, if it is not
+ NULL. This is used to mark the current function and the outer
+ function chain. */
static void
-mark_function_chain (arg)
+maybe_mark_struct_function (arg)
void *arg;
{
struct function *f = *(struct function **) arg;
- for (; f; f = f->next_global)
- {
- ggc_mark_tree (f->decl);
-
- 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);
- if (mark_lang_status)
- (*mark_lang_status) (f);
-
- if (f->original_arg_vector)
- ggc_mark_rtvec ((rtvec) f->original_arg_vector);
- if (f->original_decl_initial)
- ggc_mark_tree (f->original_decl_initial);
- }
+ if (f == 0)
+ return;
+
+ ggc_mark_struct_function (f);
+}
+
+/* Mark a struct function * for GC. This is called from ggc-common.c. */
+void
+ggc_mark_struct_function (f)
+ struct function *f;
+{
+ ggc_mark_tree (f->decl);
+
+ 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);
+ if (mark_lang_status)
+ (*mark_lang_status) (f);
+
+ if (f->original_arg_vector)
+ ggc_mark_rtvec ((rtvec) f->original_arg_vector);
+ if (f->original_decl_initial)
+ ggc_mark_tree (f->original_decl_initial);
}
/* Called once, at initialization, to initialize function.c. */
void
init_function_once ()
{
- ggc_add_root (&all_functions, 1, sizeof all_functions,
- mark_function_chain);
+ ggc_add_root (&cfun, 1, sizeof cfun, maybe_mark_struct_function);
+ ggc_add_root (&outer_function_chain, 1, sizeof outer_function_chain,
+ maybe_mark_struct_function);
VARRAY_INT_INIT (prologue, 0, "prologue");
VARRAY_INT_INIT (epilogue, 0, "epilogue");