PATCH for mark functions

Mark Mitchell mark@codesourcery.com
Sat Sep 4 19:42:00 GMT 1999


This merges the various GC marking functions from the GC branch into
the mainline.  I added comments and prototypes, but the real work is
all Richard and Bernd's.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

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.
	
Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.289
diff -c -p -r1.289 Makefile.in
*** Makefile.in	1999/09/05 01:06:45	1.289
--- Makefile.in	1999/09/05 02:18:56
*************** prefix.o: prefix.c $(CONFIG_H) system.h 
*** 1450,1456 ****
  
  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
  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
--- 1450,1457 ----
  
  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 \
!    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
*************** errors.o : errors.c $(CONFIG_H) system.h
*** 1473,1488 ****
  
  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
  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
  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
  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
  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
--- 1474,1489 ----
  
  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 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 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 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 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
*************** explow.o : explow.c $(CONFIG_H) system.h
*** 1499,1505 ****
     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
  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
--- 1500,1506 ----
     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 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
*************** dwarf2out.o : dwarf2out.c $(CONFIG_H) sy
*** 1515,1521 ****
  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 \
     $(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
  
--- 1516,1522 ----
  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 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: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.78
diff -c -p -r1.78 emit-rtl.c
*** emit-rtl.c	1999/09/05 01:06:45	1.78
--- emit-rtl.c	1999/09/05 02:19:01
*************** Boston, MA 02111-1307, USA.  */
*** 49,54 ****
--- 49,55 ----
  #include "real.h"
  #include "obstack.h"
  #include "bitmap.h"
+ #include "ggc.h"
  
  /* Commonly used modes.  */
  
*************** static rtx free_insn;
*** 187,192 ****
--- 188,194 ----
  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 *));
  
  rtx
  gen_rtx_CONST_INT (mode, arg)
*************** init_emit ()
*** 3465,3470 ****
--- 3467,3507 ----
  #ifdef INIT_EXPANDERS
    INIT_EXPANDERS;
  #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.
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.90
diff -c -p -r1.90 except.c
*** except.c	1999/09/02 17:29:18	1.90
--- except.c	1999/09/05 02:19:03
*************** Boston, MA 02111-1307, USA.  */
*** 408,413 ****
--- 408,414 ----
  #include "toplev.h"
  #include "intl.h"
  #include "obstack.h"
+ #include "ggc.h"
  
  /* One to use setjmp/longjmp method of generating code for exception
     handling.  */
*************** static void set_insn_eh_region	PROTO((rt
*** 467,472 ****
--- 468,477 ----
  #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));
  
*************** check_exception_handler_labels ()
*** 2333,2339 ****
      }
  
  }
! 
  /* 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
--- 2338,2413 ----
      }
  
  }
! 
! /* 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: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.103
diff -c -p -r1.103 function.c
*** function.c	1999/09/05 01:06:45	1.103
--- function.c	1999/09/05 02:19:07
*************** Boston, MA 02111-1307, USA.  */
*** 57,62 ****
--- 57,63 ----
  #include "obstack.h"
  #include "toplev.h"
  #include "hash.h"
+ #include "ggc.h"
  
  #ifndef TRAMPOLINE_ALIGNMENT
  #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
*************** static unsigned long insns_for_mem_hash 
*** 272,277 ****
--- 273,281 ----
  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 *));
  
  
  /* Pointer to chain of `struct function' for containing functions.  */
*************** reposition_prologue_and_epilogue_notes (
*** 6636,6639 ****
--- 6648,6764 ----
  	}
      }
  #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: function.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.h,v
retrieving revision 1.27
diff -c -p -r1.27 function.h
*** function.h	1999/09/05 01:06:46	1.27
--- function.h	1999/09/05 02:19:08
*************** extern rtx get_first_block_beg		PROTO((v
*** 558,563 ****
--- 558,566 ----
  
  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: ggc-callbacks.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc-callbacks.c,v
retrieving revision 1.1
diff -c -p -r1.1 ggc-callbacks.c
*** ggc-callbacks.c	1999/09/04 22:34:20	1.1
--- ggc-callbacks.c	1999/09/05 02:19:08
*************** lang_cleanup_tree (t)
*** 41,43 ****
--- 41,52 ----
       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: ggc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc.h,v
retrieving revision 1.2
diff -c -p -r1.2 ggc.h
*** ggc.h	1999/09/04 18:25:41	1.2
--- ggc.h	1999/09/05 02:19:08
***************
*** 23,28 ****
--- 23,38 ----
  /* 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));
*************** void lang_mark_tree PROTO ((union tree_n
*** 61,72 ****
  /* And similarly to free that data when the tree node is released.  */
  void lang_cleanup_tree PROTO ((union tree_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_optab PROTO ((void *));
--- 71,85 ----
  /* 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_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: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.44
diff -c -p -r1.44 optabs.c
*** optabs.c	1999/09/04 22:08:44	1.44
--- optabs.c	1999/09/05 02:19:10
*************** Boston, MA 02111-1307, USA.  */
*** 35,40 ****
--- 35,41 ----
  #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
*************** init_floating_libfuncs (optable, opname,
*** 4342,4348 ****
--- 4343,4361 ----
    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.  */
  
*************** init_optabs ()
*** 4679,4684 ****
--- 4692,4701 ----
    /* 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);
  }
  
  #ifdef BROKEN_LDEXP
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.83
diff -c -p -r1.83 stmt.c
*** stmt.c	1999/09/03 23:22:49	1.83
--- stmt.c	1999/09/05 02:19:14
*************** Boston, MA 02111-1307, USA.  */
*** 52,57 ****
--- 52,58 ----
  #include "machmode.h"
  #include "toplev.h"
  #include "output.h"
+ #include "ggc.h"
  
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free free
*************** static void emit_jump_if_reachable	PROTO
*** 425,435 ****
--- 426,575 ----
  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 *));
+ 
  
  void
  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
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.206
diff -c -p -r1.206 toplev.c
*** toplev.c	1999/09/05 01:06:46	1.206
--- toplev.c	1999/09/05 02:19:17
*************** compile_file (name)
*** 2935,2940 ****
--- 2935,2941 ----
    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: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.c,v
retrieving revision 1.77
diff -c -p -r1.77 tree.c
*** tree.c	1999/09/04 13:09:55	1.77
--- tree.c	1999/09/05 02:19:20
*************** Boston, MA 02111-1307, USA.  */
*** 40,45 ****
--- 40,46 ----
  #include "function.h"
  #include "obstack.h"
  #include "toplev.h"
+ #include "ggc.h"
  
  #define obstack_chunk_alloc xmalloc
  #define obstack_chunk_free free
*************** int (*lang_get_alias_set) PROTO((tree));
*** 247,255 ****
--- 248,277 ----
     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 ();
  
*************** init_obstacks ()
*** 284,289 ****
--- 306,316 ----
  
    /* 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
*************** build_type_copy (type)
*** 3587,3612 ****
  /* 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.  */
--- 3614,3619 ----
*************** type_hash_canon (hashcode, type)
*** 3712,3717 ****
--- 3719,3739 ----
      type_hash_add (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
Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.74
diff -c -p -r1.74 varasm.c
*** varasm.c	1999/09/05 01:06:46	1.74
--- varasm.c	1999/09/05 02:19:22
*************** Boston, MA 02111-1307, USA.  */
*** 46,51 ****
--- 46,52 ----
  
  #include "obstack.h"
  #include "c-pragma.h"
+ #include "ggc.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
  #include "xcoffout.h"
*************** static void asm_output_bss		PROTO((FILE 
*** 186,191 ****
--- 187,193 ----
  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 *));
  
  static enum in_section { no_section, in_text, in_data, in_named
  #ifdef BSS_SECTION_ASM_OP
*************** init_varasm_status (f)
*** 3184,3189 ****
--- 3186,3214 ----
    p->x_first_pool = p->x_last_pool = 0;
    p->x_pool_offset = 0;
    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


More information about the Gcc-patches mailing list