mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-16 13:00:09 +08:00
function.c: Remove all_functions.
* 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. From-SVN: r45336
This commit is contained in:
parent
7a95ae6b51
commit
eb3ae3e105
@ -1,3 +1,33 @@
|
||||
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.
|
||||
|
112
gcc/function.c
112
gcc/function.c
@ -145,9 +145,6 @@ tree inline_function_decl;
|
||||
/* 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;
|
||||
@ -305,13 +302,13 @@ static int insns_for_mem_walk PARAMS ((rtx *, void *));
|
||||
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 *));
|
||||
|
||||
/* 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. */
|
||||
@ -322,7 +319,7 @@ find_function_data (decl)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -339,21 +336,24 @@ void
|
||||
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;
|
||||
|
||||
@ -381,7 +381,7 @@ pop_function_context_from (context)
|
||||
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;
|
||||
@ -487,6 +487,8 @@ free_after_compilation (f)
|
||||
f->original_decl_initial = NULL;
|
||||
f->inl_last_parm_insn = NULL;
|
||||
f->epilogue_delay_list = NULL;
|
||||
|
||||
free (f);
|
||||
}
|
||||
|
||||
/* Allocate fixed slots in the stack frame of the current function. */
|
||||
@ -1346,10 +1348,13 @@ put_var_into_stack (decl)
|
||||
/* 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;
|
||||
|
||||
@ -5523,12 +5528,7 @@ fix_lexical_addr (addr, var)
|
||||
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);
|
||||
@ -5612,7 +5612,7 @@ trampoline_address (function)
|
||||
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)
|
||||
{
|
||||
@ -5628,9 +5628,7 @@ trampoline_address (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). */
|
||||
@ -6227,10 +6225,6 @@ init_function_start (subr, filename, line)
|
||||
{
|
||||
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;
|
||||
|
||||
@ -6595,7 +6589,6 @@ expand_dummy_function_end ()
|
||||
|
||||
free_after_parsing (cfun);
|
||||
free_after_compilation (cfun);
|
||||
free (cfun);
|
||||
cfun = 0;
|
||||
}
|
||||
|
||||
@ -7672,36 +7665,44 @@ mark_function_status (p)
|
||||
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);
|
||||
if (f == 0)
|
||||
return;
|
||||
|
||||
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);
|
||||
ggc_mark_struct_function (f);
|
||||
}
|
||||
|
||||
if (mark_machine_status)
|
||||
(*mark_machine_status) (f);
|
||||
if (mark_lang_status)
|
||||
(*mark_lang_status) (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);
|
||||
|
||||
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);
|
||||
}
|
||||
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. */
|
||||
@ -7709,8 +7710,9 @@ mark_function_chain (arg)
|
||||
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");
|
||||
|
@ -178,9 +178,6 @@ struct expr_status
|
||||
|
||||
struct function
|
||||
{
|
||||
struct function *next_global;
|
||||
struct function *next;
|
||||
|
||||
struct eh_status *eh;
|
||||
struct stmt_status *stmt;
|
||||
struct expr_status *expr;
|
||||
@ -195,6 +192,9 @@ struct function
|
||||
/* Points to the FUNCTION_DECL of this function. */
|
||||
tree decl;
|
||||
|
||||
/* Function containing this function, if any. */
|
||||
struct function *outer;
|
||||
|
||||
/* Number of bytes of args popped by function being compiled on its return.
|
||||
Zero if no bytes are to be popped.
|
||||
May affect compilation of return insn or of function epilogue. */
|
||||
@ -482,9 +482,6 @@ struct function
|
||||
/* The function currently being compiled. */
|
||||
extern struct function *cfun;
|
||||
|
||||
/* A list of all functions we have compiled so far. */
|
||||
extern struct function *all_functions;
|
||||
|
||||
/* Nonzero if we've already converted virtual regs to hard regs. */
|
||||
extern int virtuals_instantiated;
|
||||
|
||||
@ -553,9 +550,6 @@ extern tree inline_function_decl;
|
||||
return the `struct function' for it. */
|
||||
struct function *find_function_data PARAMS ((tree));
|
||||
|
||||
/* Pointer to chain of `struct function' for containing functions. */
|
||||
extern struct function *outer_function_chain;
|
||||
|
||||
/* Set NOTE_BLOCK for each block note in the current function. */
|
||||
extern void identify_blocks PARAMS ((void));
|
||||
|
||||
|
@ -381,6 +381,8 @@ ggc_mark_trees ()
|
||||
ggc_mark_tree (DECL_VINDEX (t));
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (t))
|
||||
ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
|
||||
if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_INSNS (t))
|
||||
ggc_mark_struct_function (DECL_SAVED_INSNS (t));
|
||||
lang_mark_tree (t);
|
||||
break;
|
||||
|
||||
|
@ -2902,9 +2902,10 @@ output_inline_function (fndecl)
|
||||
/* Compile this function all the way down to assembly code. */
|
||||
rest_of_compilation (fndecl);
|
||||
|
||||
/* We can't inline this anymore. */
|
||||
f->inlinable = 0;
|
||||
/* We can't inline this anymore; rest_of_compilation destroyed the
|
||||
data structures describing the function. */
|
||||
DECL_INLINE (fndecl) = 0;
|
||||
DECL_SAVED_INSNS (fndecl) = 0;
|
||||
|
||||
cfun = old_cfun;
|
||||
current_function_decl = old_cfun ? old_cfun->decl : 0;
|
||||
|
@ -1682,6 +1682,8 @@ struct tree_type
|
||||
argument's depth. */
|
||||
#define DECL_POINTER_DEPTH(DECL) (DECL_CHECK (DECL)->decl.pointer_depth)
|
||||
|
||||
struct function;
|
||||
|
||||
struct tree_decl
|
||||
{
|
||||
struct tree_common common;
|
||||
@ -2803,6 +2805,7 @@ extern void push_function_context PARAMS ((void));
|
||||
extern void pop_function_context PARAMS ((void));
|
||||
extern void push_function_context_to PARAMS ((tree));
|
||||
extern void pop_function_context_from PARAMS ((tree));
|
||||
extern void ggc_mark_struct_function PARAMS ((struct function *));
|
||||
|
||||
/* In print-rtl.c */
|
||||
#ifdef BUFSIZ
|
||||
|
Loading…
Reference in New Issue
Block a user