diff options
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/gcc/function.c b/gcc/function.c index 4c87e58..07f9960 100644 --- a/gcc/function.c +++ b/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); - - 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. */ @@ -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"); |