* function.c: Remove all_functions. Make outer_function_chain
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Aug 2001 22:22:02 +0000 (22:22 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 31 Aug 2001 22:22:02 +0000 (22:22 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@45336 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/function.c
gcc/function.h
gcc/ggc-common.c
gcc/integrate.c
gcc/tree.h

index acd4609..77be0dc 100644 (file)
@@ -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.
index 4c87e58..07f9960 100644 (file)
@@ -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 *));
 \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.  */
@@ -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);
 }
 \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");
index 24c99cc..ff8aeb9 100644 (file)
@@ -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));
 
index 049785d..9745001 100644 (file)
@@ -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;
 
index ca8ae0e..232f5fe 100644 (file)
@@ -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;
index 5822f7a..cf6d243 100644 (file)
@@ -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