Makefile.in (tree.o): Depend on ggc.h.
authorRichard Henderson <rth@cygnus.com>
Sun, 5 Sep 1999 02:41:35 +0000 (19:41 -0700)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sun, 5 Sep 1999 02:41:35 +0000 (02:41 +0000)
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.

Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>
From-SVN: r29119

13 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/emit-rtl.c
gcc/except.c
gcc/function.c
gcc/function.h
gcc/ggc-callbacks.c
gcc/ggc.h
gcc/optabs.c
gcc/stmt.c
gcc/toplev.c
gcc/tree.c
gcc/varasm.c

index a80c0e8d0ba96c9b309c785bfd64db408325ca8c..f9b2e2579fcb0640e972bd1419651717e8859c1e 100644 (file)
@@ -1,3 +1,53 @@
+Sat Sep  4 19:26:25 1999  Richard Henderson  <rth@cygnus.com>
+                         Bernd Schmidt <bernds@cygnus.co.uk>
+                         Mark Mitchell  <mark@codesourcery.com>
+
+       * Makefile.in (tree.o): Depend on ggc.h.
+       (varasm.o): Likewise.
+       (function.o): Likewise.
+       (stmt.o): Likewise.
+       (except.o): Likewise.
+       (optabs.o): Likewise.
+       (emit-rtl.o): Likewise.
+       * emit-rtl.c: Include ggc.h.
+       (sequence_element_free_list): Remove, and all references.
+       (mark_sequence): New functions.
+       (mark_emit_state): New function.
+       * except.c: Include ggc.h.
+       (mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
+       (mark_tree_label_node): New functions.
+       (mark_eh_state): New function.
+       * function.c: Include ggc.h.
+       (mark_temp_slot, mark_function_chain): New functions.
+       (mark_function_state): New function.
+       (init_function_once): New function.
+       * function.h (init_function_once): New function.
+       * ggc-callbacks.c (lang_mark_false_label_stack): New function.
+       * ggc.h (label_node): Declare.
+       (eh_status, emit_status, stmt_status, varasm_status): Likewise.
+       (lang_mark_false_label_stack): New function.
+       (mark_temp_slot): Remove declaration.
+       (mark_function_chain): Likewise.
+       (mark_eh_state): Adjust prototype.
+       (mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
+       Likewise.
+       * optabs.c: Include ggc.h.
+       (mark_optab): New function.
+       (init_optabs): Add gc roots.
+       * stmt.c: Include ggc.h.
+       (mark_cond_nesting, mark_loop_nesting): New functions.
+       (mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
+       (mark_stmt_state): New function.
+       * toplev.c (compile_file): Call init_function_once.
+       * tree.c: Include ggc.h.
+       (type_hash): Move declaration earlier in file.
+       (TYPE_HASH_SIZE, type_hash_table): Likewise.
+       (init_obstacks): Add gc roots.
+       (mark_type_hash): New function.
+       * varasm.c: Include ggc.h.
+       (mark_pool_constant): New function.
+       (mark_varasm_state): New function.
+       
 Sat Sep  4 22:28:56 1999  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * ggc-simple.c (ggc_root, ggc_collect): Wrap prototype with PROTO.
index a358df2cd4adfabb238cb19efaa25dd2ac419fa8..77f2b02462b8aac287327cb2ce88d3213b7a8526 100644 (file)
@@ -1450,7 +1450,8 @@ prefix.o: prefix.c $(CONFIG_H) system.h Makefile prefix.h
 
 convert.o: convert.c $(CONFIG_H) $(TREE_H) flags.h convert.h toplev.h
 
-tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h
+tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h \
+   ggc.h
 print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H)
 stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
    function.h $(EXPR_H) $(RTL_H) toplev.h
@@ -1473,16 +1474,16 @@ errors.o : errors.c $(CONFIG_H) system.h errors.h
 
 varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
    function.h defaults.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
-   xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h
+   xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h ggc.h
 function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
    function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
-   insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h
+   insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h ggc.h
 stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h  \
    insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \
-   loop.h $(RECOG_H) toplev.h output.h varray.h
+   loop.h $(RECOG_H) toplev.h output.h varray.h ggc.h
 except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
    function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
-   insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h
+   insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h ggc.h
 expr.o : expr.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
    $(REGS_H) insn-flags.h insn-codes.h $(EXPR_H) insn-config.h $(RECOG_H) \
    output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h
@@ -1499,7 +1500,7 @@ explow.o : explow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
    insn-codes.h toplev.h
 optabs.o : optabs.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h  \
    insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h \
-   toplev.h
+   toplev.h ggc.h
 dbxout.o : dbxout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h $(REGS_H) \
    insn-config.h reload.h gstab.h xcoffout.h defaults.h output.h dbxout.h \
    toplev.h
@@ -1515,7 +1516,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf2.h \
 xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
    flags.h toplev.h output.h dbxout.h
 emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
-   function.h $(REGS_H) insn-config.h $(RECOG_H) real.h \
+   function.h $(REGS_H) insn-config.h $(RECOG_H) real.h ggc.h \
    $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h
 real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.h
 
index fd04427edbb6ec44473f7245705dd55c82325cdf..a781e2da79d0b0742c93f1635f062721b2b4058f 100644 (file)
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 #include "real.h"
 #include "obstack.h"
 #include "bitmap.h"
+#include "ggc.h"
 
 /* Commonly used modes.  */
 
@@ -187,6 +188,7 @@ static rtx free_insn;
 static rtx make_jump_insn_raw          PROTO((rtx));
 static rtx make_call_insn_raw          PROTO((rtx));
 static rtx find_line_note              PROTO((rtx));
+static void mark_sequence_stack         PROTO((struct sequence_stack *));
 \f
 rtx
 gen_rtx_CONST_INT (mode, arg)
@@ -3467,6 +3469,41 @@ init_emit ()
 #endif
 }
 
+/* Mark SS for GC.  */
+
+static void
+mark_sequence_stack (ss)
+     struct sequence_stack *ss;
+{
+  while (ss)
+    {
+      ggc_mark_rtx (ss->first);
+      ggc_mark_tree (ss->sequence_rtl_expr);
+      ss = ss->next;
+    }
+}
+
+/* Mark ES for GC.  */
+
+void
+mark_emit_state (es)
+     struct emit_status *es;
+{
+  rtx *r;
+  int i;
+
+  if (es == 0)
+    return;
+
+  for (i = es->regno_pointer_flag_length, r = es->x_regno_reg_rtx;
+       i > 0; --i, ++r)
+    ggc_mark_rtx (*r);
+
+  mark_sequence_stack (es->sequence_stack);
+  ggc_mark_tree (es->sequence_rtl_expr);
+  ggc_mark_rtx (es->x_first_insn);
+}
+
 /* Create some permanent unique rtl objects shared between all functions.
    LINE_NUMBERS is nonzero if line numbers are to be generated.  */
 
index 6cc8465903220d270f9c9825cd0243b64ef0e2b2..0a7b9a944df26a381478579570ad94fc635b661a 100644 (file)
@@ -408,6 +408,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "intl.h"
 #include "obstack.h"
+#include "ggc.h"
 
 /* One to use setjmp/longjmp method of generating code for exception
    handling.  */
@@ -467,6 +468,10 @@ static void set_insn_eh_region     PROTO((rtx *, int));
 #ifdef DONT_USE_BUILTIN_SETJMP
 static void jumpif_rtx         PROTO((rtx, rtx));
 #endif
+static void mark_eh_node        PROTO((struct eh_node *));
+static void mark_eh_stack       PROTO((struct eh_stack *));
+static void mark_eh_queue       PROTO((struct eh_queue *));
+static void mark_tree_label_node PROTO ((struct label_node *));
 
 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
 \f
@@ -2333,7 +2338,76 @@ check_exception_handler_labels ()
     }
 
 }
-\f
+
+/* Mark the children of NODE for GC.  */
+
+static void
+mark_eh_node (node)
+     struct eh_node *node;
+{
+  while (node)
+    {
+      if (node->entry)
+       {
+         ggc_mark_rtx (node->entry->outer_context);
+         ggc_mark_rtx (node->entry->exception_handler_label);
+         ggc_mark_tree (node->entry->finalization);
+       }
+      node = node ->chain;
+    }
+}
+
+/* Mark S for GC.  */
+
+static void
+mark_eh_stack (s)
+     struct eh_stack *s;
+{
+  if (s)
+    mark_eh_node (s->top);
+}
+
+/* Mark Q for GC.  */
+
+static void
+mark_eh_queue (q)
+     struct eh_queue *q;
+{
+  if (q)
+    mark_eh_node (q->head);
+}
+
+/* Mark NODE for GC.  A label_node contains a union containing either
+   a tree or an rtx.  This label_node will contain a tree.  */
+
+static void
+mark_tree_label_node (node)
+     struct label_node *node;
+{
+  while (node)
+    {
+      ggc_mark_tree (node->u.tlabel);
+      node = node->chain;
+    }
+}
+
+/* Mark EH for GC.  */
+
+void
+mark_eh_state (eh)
+     struct eh_status *eh;
+{
+  mark_eh_stack (&eh->x_ehstack);
+  mark_eh_queue (&eh->x_ehqueue);
+  ggc_mark_rtx (eh->x_catch_clauses);
+
+  lang_mark_false_label_stack (eh->x_false_label_stack);
+  mark_tree_label_node (eh->x_caught_return_label_stack);
+
+  ggc_mark_tree (eh->x_protect_list);
+  ggc_mark_rtx (eh->ehc);
+}
+
 /* This group of functions initializes the exception handling data
    structures at the start of the compilation, initializes the data
    structures at the start of a function, and saves and restores the
index cb474b2308aa24018262a315102ba52bcb3c068e..b0c27256dab78494d2db3938030c48954e7eb4b4 100644 (file)
@@ -57,6 +57,7 @@ Boston, MA 02111-1307, USA.  */
 #include "obstack.h"
 #include "toplev.h"
 #include "hash.h"
+#include "ggc.h"
 
 #ifndef TRAMPOLINE_ALIGNMENT
 #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
@@ -272,6 +273,9 @@ static unsigned long insns_for_mem_hash PROTO ((hash_table_key));
 static boolean insns_for_mem_comp PROTO ((hash_table_key, hash_table_key));
 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_chain PROTO ((void *));
 
 \f
 /* Pointer to chain of `struct function' for containing functions.  */
@@ -5630,7 +5634,7 @@ init_function_start (subr, filename, line)
   /* Remember this function for later.  */
   current_function->next_global = all_functions;
   all_functions = current_function;
-
+  
   current_function_name = (*decl_printable_name) (subr, 2);
 
   /* Nonzero if this is a nested function that uses a static chain.  */
@@ -6637,3 +6641,116 @@ reposition_prologue_and_epilogue_notes (f)
     }
 #endif /* HAVE_prologue or HAVE_epilogue */
 }
+
+/* Mark T for GC.  */
+
+static void
+mark_temp_slot (t)
+  struct temp_slot *t;
+{
+  while (t)
+    {
+      ggc_mark_rtx (t->slot);
+      ggc_mark_rtx (t->address);
+      ggc_mark_tree (t->rtl_expr);
+
+      t = t->next;
+    }
+}
+
+/* Mark P for GC.  */
+
+static void
+mark_function_state (p)
+     struct function *p;
+{
+  int i;
+  rtx *r;
+
+  if (p == 0)
+    return;
+
+  ggc_mark_rtx (p->arg_offset_rtx);
+
+  for (i = p->x_max_parm_reg, r = p->x_parm_reg_stack_loc;
+       i > 0; --i, ++r)
+    ggc_mark_rtx (*r);
+
+  ggc_mark_rtx (p->return_rtx);
+  ggc_mark_rtx (p->x_cleanup_label);
+  ggc_mark_rtx (p->x_return_label);
+  ggc_mark_rtx (p->x_save_expr_regs);
+  ggc_mark_rtx (p->x_stack_slot_list);
+  ggc_mark_rtx (p->x_parm_birth_insn);
+  ggc_mark_rtx (p->x_tail_recursion_label);
+  ggc_mark_rtx (p->x_tail_recursion_reentry);
+  ggc_mark_rtx (p->internal_arg_pointer);
+  ggc_mark_rtx (p->x_arg_pointer_save_area);
+  ggc_mark_tree (p->x_rtl_expr_chain);
+  ggc_mark_rtx (p->x_last_parm_insn);
+  ggc_mark_tree (p->x_context_display);
+  ggc_mark_tree (p->x_trampoline_list);
+  ggc_mark_rtx (p->epilogue_delay_list);
+
+  mark_temp_slot (p->x_temp_slots);
+
+  {
+    struct var_refs_queue *q = p->fixup_var_refs_queue;
+    while (q)
+      {
+       ggc_mark_rtx (q->modified);
+       q = q->next;
+      }
+  }
+
+  ggc_mark_rtx (p->x_nonlocal_goto_handler_slots);
+  ggc_mark_rtx (p->x_nonlocal_goto_stack_level);
+  ggc_mark_tree (p->x_nonlocal_labels);
+}
+
+/* Mark the function chain ARG (which is really a struct function **)
+   for GC.  */
+
+static void
+mark_function_chain (arg)
+     void *arg;
+{
+  struct function *f = *(struct function **) arg;
+
+  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);
+
+      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);
+}
index 0b6eb66b68d5325d83f17e4f08efdf3dfa74c873..966b3f74e4788dc877ce0b71e93478c2f78ed81c 100644 (file)
@@ -558,6 +558,9 @@ extern rtx get_first_block_beg              PROTO((void));
 
 extern void init_virtual_regs          PROTO((struct emit_status *));
 
+/* Called once, at initialization, to initialize function.c.  */
+extern void init_function_once          PROTO((void));
+
 #ifdef rtx
 #undef rtx
 #endif
index 851f8dd0a265592fc30e3f62d216dc410777ba5e..1b19579e914392e19a0b70b0f93ea583d8cde896 100644 (file)
@@ -41,3 +41,12 @@ lang_cleanup_tree (t)
      only included in compilers for languages that don't support GC.  */
   abort ();
 }
+
+void
+lang_mark_false_label_stack (l)
+     struct label_node *l ATTRIBUTE_UNUSED;
+{
+  /* If this function is called, we are doing GC.  But, this file is
+     only included in compilers for languages that don't support GC.  */
+  abort ();
+}
index bb0be13623e9c4a72cd8f8396924282b2347f811..6967900cb8aa9dc14ee1d961cc329d072364bf2a 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
 /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
    an external gc library that might be linked in.  */
 
+/* These structures are defined in various headers throughout the
+   compiler.  However, rather than force everyone who includes this
+   header to include all the headers in which they are declared, we
+   just forward-declare them here.  */
+struct label_node;
+struct eh_status;
+struct emit_status;
+struct stmt_status;
+struct varasm_status;
+
 /* Startup */
 
 extern void init_ggc PROTO ((void));
@@ -61,12 +71,15 @@ void lang_mark_tree PROTO ((union tree_node *));
 /* And similarly to free that data when the tree node is released.  */
 void lang_cleanup_tree PROTO ((union tree_node *));
 
+/* The FALSE_LABEL_STACK, declared in except.h, has
+   language-dependent semantics.  Each front-end should define this
+   function appropriately.  */
+void lang_mark_false_label_stack PROTO ((struct label_node *));
+
 /* Mark functions for various structs scattered about.  */
 
-void mark_temp_slot PROTO ((void *));
-void mark_function_chain PROTO ((void *));
-void mark_eh_state PROTO ((void *));
-void mark_stmt_state PROTO ((void *));
-void mark_emit_state PROTO ((void *));
-void mark_varasm_state PROTO ((void *));
+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_optab PROTO ((void *));
index ae6a6ff999be59ac0d25c235e1d9ac1be7bd6208..d82eb2ee6fa4fee63efd79d13e2174a7dadbe47c 100644 (file)
@@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA.  */
 #include "expr.h"
 #include "recog.h"
 #include "reload.h"
+#include "ggc.h"
 
 /* Each optab contains info on how this target machine
    can perform a particular operation
@@ -4342,6 +4343,18 @@ init_floating_libfuncs (optable, opname, suffix)
   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
 }
 
+/* Mark ARG (which is really an OPTAB *) for GC.  */
+
+void
+mark_optab (arg)
+     void *arg;
+{
+  optab o = *(optab *) arg;
+  int i;
+
+  for (i = 0; i < NUM_MACHINE_MODES; ++i)
+    ggc_mark_rtx (o->handlers[i].libfunc);
+}
 
 /* Call this once to initialize the contents of the optabs
    appropriately for the current target machine.  */
@@ -4679,6 +4692,10 @@ init_optabs ()
   /* Allow the target to add more libcalls or rename some, etc.  */
   INIT_TARGET_OPTABS;
 #endif
+
+  /* Add these GC roots.  */
+  ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
+  ggc_add_rtx_root (libfunc_table, LTI_MAX);
 }
 \f
 #ifdef BROKEN_LDEXP
index 255d635fbbbd38ff10d471c29885ad484b063a7f..a9f859237c262f7837c46e5c11b23fd00ba3bea0 100644 (file)
@@ -52,6 +52,7 @@ Boston, MA 02111-1307, USA.  */
 #include "machmode.h"
 #include "toplev.h"
 #include "output.h"
+#include "ggc.h"
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
@@ -425,6 +426,12 @@ static void emit_jump_if_reachable PROTO((rtx));
 static void emit_case_nodes            PROTO((rtx, case_node_ptr, rtx, tree));
 static int add_case_node               PROTO((tree, tree, tree, tree *));
 static struct case_node *case_tree2list        PROTO((case_node *, case_node *));
+static void mark_cond_nesting           PROTO((struct nesting *));
+static void mark_loop_nesting           PROTO((struct nesting *));
+static void mark_block_nesting          PROTO((struct nesting *));
+static void mark_case_nesting           PROTO((struct nesting *));
+static void mark_goto_fixup             PROTO((struct goto_fixup *));
+
 \f
 void
 using_eh_for_cleanups ()
@@ -432,6 +439,139 @@ using_eh_for_cleanups ()
   using_eh_for_cleanups_p = 1;
 }
 
+/* Mark N (known to be a cond-nesting) for GC.  */
+
+static void
+mark_cond_nesting (n)
+     struct nesting *n;
+{
+  while (n)
+    {
+      ggc_mark_rtx (n->exit_label);
+      ggc_mark_rtx (n->data.cond.endif_label);
+      ggc_mark_rtx (n->data.cond.next_label);
+
+      n = n->next;
+    }
+}
+
+/* Mark N (known to be a loop-nesting) for GC.  */
+
+static void
+mark_loop_nesting (n)
+     struct nesting *n;
+{
+
+  while (n)
+    {
+      ggc_mark_rtx (n->exit_label);
+      ggc_mark_rtx (n->data.loop.start_label);
+      ggc_mark_rtx (n->data.loop.end_label);
+      ggc_mark_rtx (n->data.loop.alt_end_label);
+      ggc_mark_rtx (n->data.loop.continue_label);
+
+      n = n->next;
+    }
+}
+
+/* Mark N (known to be a block-nesting) for GC.  */
+
+static void
+mark_block_nesting (n)
+     struct nesting *n;
+{
+  while (n)
+    {
+      struct label_chain *l;
+
+      ggc_mark_rtx (n->exit_label);
+      ggc_mark_rtx (n->data.block.stack_level);
+      ggc_mark_rtx (n->data.block.first_insn);
+      ggc_mark_tree (n->data.block.cleanups);
+      ggc_mark_tree (n->data.block.outer_cleanups);
+
+      for (l = n->data.block.label_chain; l != NULL; l = l->next)
+       ggc_mark_tree (l->label);
+
+      ggc_mark_rtx (n->data.block.last_unconditional_cleanup);
+
+      /* ??? cleanup_ptr never points outside the stack, does it?  */
+
+      n = n->next;
+    }
+}
+
+/* Mark N (known to be a case-nesting) for GC.  */
+
+static void
+mark_case_nesting (n)
+     struct nesting *n;
+{
+  while (n)
+    {
+      struct case_node *node;
+
+      ggc_mark_rtx (n->exit_label);
+      ggc_mark_rtx (n->data.case_stmt.start);
+
+      node = n->data.case_stmt.case_list;
+      while (node)
+       {
+         ggc_mark_tree (node->low);
+         ggc_mark_tree (node->high);
+         ggc_mark_tree (node->code_label);
+         node = node->right;
+       }
+
+      ggc_mark_tree (n->data.case_stmt.default_label);
+      ggc_mark_tree (n->data.case_stmt.index_expr);
+      ggc_mark_tree (n->data.case_stmt.nominal_type);
+
+      n = n->next;
+    }
+}
+
+/* Mark G for GC.  */
+
+static void
+mark_goto_fixup (g)
+     struct goto_fixup *g;
+{
+  while (g)
+    {
+      ggc_mark_rtx (g->before_jump);
+      ggc_mark_tree (g->target);
+      ggc_mark_tree (g->context);
+      ggc_mark_rtx (g->target_rtl);
+      ggc_mark_rtx (g->stack_level);
+      ggc_mark_tree (g->cleanup_list_list);
+
+      g = g->next;
+    }
+}
+
+/* Mark P for GC.  */
+
+void
+mark_stmt_state (p)
+     struct stmt_status *p;
+{
+  if (p == 0)
+    return;
+
+  mark_block_nesting (p->x_block_stack);
+  mark_cond_nesting (p->x_cond_stack);
+  mark_loop_nesting (p->x_loop_stack);
+  mark_case_nesting (p->x_case_stack);
+
+  ggc_mark_tree (p->x_last_expr_type);
+  /* last_epxr_value is only valid if last_expr_type is nonzero.  */
+  if (p->x_last_expr_type)
+    ggc_mark_rtx (p->x_last_expr_value);
+
+  mark_goto_fixup (p->x_goto_fixup_chain);
+}
+
 void
 init_stmt ()
 {
index e654146e2c4ef48daa848013f34004c7d2b18f3a..eaa013eda7833c21fea686e67cf93a748fdc2b82 100644 (file)
@@ -2935,6 +2935,7 @@ compile_file (name)
   init_loop ();
   init_reload ();
   init_alias_once ();
+  init_function_once ();
 
   /* The following initialization functions need to generate rtl, so
      provide a dummy function context for them.  */
index e280190fcd5bf371c97ccab686b7e24a5dd71365..1d0f27377da6a24cd6b4750a956186d45a64b259 100644 (file)
@@ -40,6 +40,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "obstack.h"
 #include "toplev.h"
+#include "ggc.h"
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
@@ -247,9 +248,30 @@ int (*lang_get_alias_set) PROTO((tree));
    codes are made.  */
 #define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
 
+/* Each hash table slot is a bucket containing a chain
+   of these structures.  */
+
+struct type_hash
+{
+  struct type_hash *next;      /* Next structure in the bucket.  */
+  int hashcode;                        /* Hash code of this type.  */
+  tree type;                   /* The type recorded here.  */
+};
+
+/* Now here is the hash table.  When recording a type, it is added
+   to the slot whose index is the hash code mod the table size.
+   Note that the hash table is used for several kinds of types
+   (function types, array types and array index range types, for now).
+   While all these live in the same table, they are completely independent,
+   and the hash code is computed differently for each of these.  */
+
+#define TYPE_HASH_SIZE 59
+struct type_hash *type_hash_table[TYPE_HASH_SIZE];
+
 static void set_type_quals PROTO((tree, int));
 static void append_random_chars PROTO((char *));
 static void build_real_from_int_cst_1 PROTO((PTR));
+static void mark_type_hash PROTO ((void *));
 
 void gcc_obstack_init ();
 
@@ -284,6 +306,11 @@ init_obstacks ()
 
   /* Init the hash table of identifiers.  */
   bzero ((char *) hash_table, sizeof hash_table);
+
+  ggc_add_tree_root (hash_table, MAX_HASH_TABLE);
+  ggc_add_root (type_hash_table, TYPE_HASH_SIZE, 
+               sizeof(struct type_hash *),
+               mark_type_hash);
 }
 
 void
@@ -3587,26 +3614,6 @@ build_type_copy (type)
 /* Hashing of types so that we don't make duplicates.
    The entry point is `type_hash_canon'.  */
 
-/* Each hash table slot is a bucket containing a chain
-   of these structures.  */
-
-struct type_hash
-{
-  struct type_hash *next;      /* Next structure in the bucket.  */
-  int hashcode;                        /* Hash code of this type.  */
-  tree type;                   /* The type recorded here.  */
-};
-
-/* Now here is the hash table.  When recording a type, it is added
-   to the slot whose index is the hash code mod the table size.
-   Note that the hash table is used for several kinds of types
-   (function types, array types and array index range types, for now).
-   While all these live in the same table, they are completely independent,
-   and the hash code is computed differently for each of these.  */
-
-#define TYPE_HASH_SIZE 59
-struct type_hash *type_hash_table[TYPE_HASH_SIZE];
-
 /* Compute a hash code for a list of types (chain of TREE_LIST nodes
    with types in the TREE_VALUE slots), by adding the hash codes
    of the individual types.  */
@@ -3714,6 +3721,21 @@ type_hash_canon (hashcode, type)
   return type;
 }
 
+/* Mark ARG (which is really a struct type_hash **) for GC.  */
+
+static void
+mark_type_hash (arg)
+     void *arg;
+{
+  struct type_hash *t = *(struct type_hash **) arg;
+
+  while (t)
+    {
+      ggc_mark_tree (t->type);
+      t = t->next;
+    }
+}
+
 /* Compute a hash code for a list of attributes (chain of TREE_LIST nodes
    with names in the TREE_PURPOSE slots and args in the TREE_VALUE slots),
    by adding the hash codes of the individual attributes.  */
index 3f25a982929e3b15b8de87277cafddd4bc43da4b..33b16fe87bd1c261fc817d86499d2997e68f75b8 100644 (file)
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA.  */
 
 #include "obstack.h"
 #include "c-pragma.h"
+#include "ggc.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
@@ -186,6 +187,7 @@ static void asm_output_bss          PROTO((FILE *, tree, char *, int, int));
 static void asm_output_aligned_bss     PROTO((FILE *, tree, char *, int, int));
 #endif
 #endif /* BSS_SECTION_ASM_OP */
+static void mark_pool_constant          PROTO((struct pool_constant *));
 \f
 static enum in_section { no_section, in_text, in_data, in_named
 #ifdef BSS_SECTION_ASM_OP
@@ -3186,6 +3188,29 @@ init_varasm_status (f)
   p->x_const_double_chain = 0;
 }
 
+/* Mark PC for GC.  */
+
+static void 
+mark_pool_constant (pc)
+     struct pool_constant *pc;
+{
+  while (pc)
+    {
+      ggc_mark_rtx (pc->constant);
+      pc = pc->next;
+    }
+}
+
+/* Mark P for GC.  */
+
+void
+mark_varasm_state (p)
+  struct varasm_status *p;
+{
+  mark_pool_constant (p->x_first_pool);
+  ggc_mark_rtx (p->x_const_double_chain);
+}
+
 /* Clear out all parts of our state in F that can safely be discarded
    after the function has been compiled.  */
 void