This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH to include GC files



This patch just adds the `ggc' files to the mainline, and adds
appropriate Makefile targets/dependencies.  They're not yet linked in
to anything, although my next patch will link them in to the C++
front-end.

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

Sat Sep  4 11:19:52 1999  Richard Henderson  <rth@cygnus.com>

	* Makefile.in (GGC, GGC_LIB): New.
	(HOST_RTL): Include ggc-none.o.
	(ggc-simple.o): New target.
	(ggc-none.o): Likewise.
	* tree.h (tree_common): Add gc_mark.
	* rtl.h (struct rtx_def): Steal a bit from code to make gc_mark.
	(struct rtvec_def): Add gc_mark.
	* emit-rtl.c (global_rtl): Update static initializers to contain
	enough initializers.
	* ggc.h, ggc-none.c, ggc-simple.c: New files.
	* toplev.c (gc_time): New variable.
	(all_time): New variable.
	(compile_file): Print gc time.
	(print_time): Calculate percentage of the whole.

Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.286
diff -c -p -r1.286 Makefile.in
*** Makefile.in	1999/09/03 19:13:34	1.286
--- Makefile.in	1999/09/04 18:19:18
*************** CLIB=
*** 316,321 ****
--- 316,327 ----
  # system library.
  OBSTACK=obstack.o
  
+ # The GC method to be used on this system.
+ GGC=ggc-simple.o
+ 
+ # If a supplementary library is being used for the GC.
+ GGC_LIB=
+ 
  # Configure will set these if you need vfprintf and possibly _doprnt support.
  VFPRINTF=@vfprintf@
  DOPRINT=@doprint@
*************** HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HO
*** 572,578 ****
  	    $(HOST_INTLLIBS) $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) \
  	    $(HOST_CLIB)
  
! HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o
  HOST_RTLANAL = $(HOST_PREFIX)rtlanal.o
  HOST_PRINT = $(HOST_PREFIX)print-rtl.o
  HOST_ERRORS = $(HOST_PREFIX)errors.o
--- 578,584 ----
  	    $(HOST_INTLLIBS) $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) \
  	    $(HOST_CLIB)
  
! HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o $(HOST_PREFIX)ggc-none.o
  HOST_RTLANAL = $(HOST_PREFIX)rtlanal.o
  HOST_PRINT = $(HOST_PREFIX)print-rtl.o
  HOST_ERRORS = $(HOST_PREFIX)errors.o
*************** gencheck.o : gencheck.c tree.def $(CONFI
*** 1424,1429 ****
--- 1430,1440 ----
  dumpvers: dumpvers.c
  
  version.o: version.c
+ 
+ ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_BASE_H) $(TREE_H) flags.h ggc.h
+ 
+ ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_BASE_H) ggc.h
+ 
  obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H)
  	rm -f obstack.c
  	$(LN_S) $(srcdir)/../libiberty/obstack.c obstack.c
Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.76
diff -c -p -r1.76 emit-rtl.c
*** emit-rtl.c	1999/09/02 01:22:31	1.76
--- emit-rtl.c	1999/09/04 18:19:26
*************** static int no_line_numbers;
*** 93,109 ****
  
  struct _global_rtl global_rtl =
  {
!   {PC, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI },  /* pc_rtx */
!   {CC0, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* cc0_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* stack_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* frame_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* hard_frame_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* arg_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_incoming_args_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_vars_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_dynamic_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_outgoing_args_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_cfa_rtx */
  };
  
  /* We record floating-point CONST_DOUBLEs in each floating-point mode for
--- 93,109 ----
  
  struct _global_rtl global_rtl =
  {
!   {PC, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI },  /* pc_rtx */
!   {CC0, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* cc0_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* stack_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* frame_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* hard_frame_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* arg_pointer_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_incoming_args_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_vars_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_stack_dynamic_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_outgoing_args_rtx */
!   {REG, VOIDmode, 0, 0, 0, 0, 0, 0, 0, 0, 0 FLDI }, /* virtual_cfa_rtx */
  };
  
  /* We record floating-point CONST_DOUBLEs in each floating-point mode for
Index: ggc-none.c
===================================================================
RCS file: ggc-none.c
diff -N ggc-none.c
*** /dev/null	Sat Dec  5 20:30:03 1998
--- ggc-none.c	Sat Sep  4 11:19:26 1999
***************
*** 0 ****
--- 1,58 ----
+ /* Null garbage collection for the GNU compiler.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+ 
+    This file is part of GNU CC.
+ 
+    GNU CC is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    GNU CC is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GNU CC; see the file COPYING.  If not, write to
+    the Free Software Foundation, 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ /* This version is used by the gen* programs, where we don't really
+    need GC at all.  This prevents problems with pulling in all the
+    tree stuff.  */
+ 
+ /* We are used by gengenrtl, before genrtl.h exists.  But we don't 
+    need it either.  */
+ #define NO_GENRTL_H
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "rtl.h"
+ #include "ggc.h"
+ 
+ rtx
+ ggc_alloc_rtx (nslots)
+      int nslots;
+ {
+   int size = sizeof(struct rtx_def) + (nslots - 1) * sizeof(rtunion);
+   rtx n;
+ 
+   n = (rtx) xmalloc (size);
+   bzero ((char *) n, size);
+ 
+   return n;
+ }
+ 
+ rtvec
+ ggc_alloc_rtvec (nelt)
+      int nelt;
+ {
+   int size = sizeof (struct rtvec_def) + (nelt - 1) * sizeof (rtunion);
+   rtvec v;
+ 
+   v = (rtvec) xmalloc (size);
+   bzero ((char *) v, size);
+ 
+   return v;
+ }
Index: ggc-simple.c
===================================================================
RCS file: ggc-simple.c
diff -N ggc-simple.c
*** /dev/null	Sat Dec  5 20:30:03 1998
--- ggc-simple.c	Sat Sep  4 11:19:27 1999
***************
*** 0 ****
--- 1,714 ----
+ /* Simple garbage collection for the GNU compiler.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+ 
+    This file is part of GNU CC.
+ 
+    GNU CC is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    GNU CC is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GNU CC; see the file COPYING.  If not, write to
+    the Free Software Foundation, 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "rtl.h"
+ #include "tree.h"
+ #include "ggc.h"
+ #include "flags.h"
+ 
+ /* Debugging flags.  */
+ #undef GGC_DUMP
+ #define GGC_POISON
+ 
+ /* Global lists of roots, rtxs, and trees.  */
+ 
+ struct ggc_root
+ {
+   struct ggc_root *next;
+   void *base;
+   int nelt;
+   int size;
+   void (*cb)(void *);
+ };
+ 
+ static struct ggc_root *roots;
+ 
+ struct ggc_rtx
+ {
+   struct ggc_rtx *chain;
+   struct rtx_def rtx;
+ };
+ 
+ static struct ggc_rtx *rtxs;
+ 
+ struct ggc_rtvec
+ {
+   struct ggc_rtvec *chain;
+   struct rtvec_def vec;
+ };
+ 
+ static struct ggc_rtvec *vecs;
+ 
+ struct ggc_tree
+ {
+   struct ggc_tree *chain;
+   union tree_node tree;
+ };
+ 
+ static struct ggc_tree *trees;
+ 
+ struct ggc_string
+ {
+   struct ggc_string *chain;
+   int magic_mark;
+   char string[1];
+ };
+ 
+ #define GGC_STRING_MAGIC	((unsigned int)0xa1b2c3d4)
+ 
+ static struct ggc_string *strings;
+ 
+ /* Some statistics.  */
+ 
+ static int n_rtxs_collected;
+ static int n_vecs_collected;
+ static int n_trees_collected;
+ static int n_strings_collected;
+ static int bytes_alloced_since_gc;
+ extern int gc_time;
+ 
+ #ifdef GGC_DUMP
+ static FILE *dump;
+ #endif
+ 
+ /* Local function prototypes.  */
+ 
+ static void ggc_free_rtx PROTO ((struct ggc_rtx *r));
+ static void ggc_free_tree PROTO ((struct ggc_tree *t));
+ static void ggc_mark_rtx_ptr PROTO ((void *elt));
+ static void ggc_mark_tree_ptr PROTO ((void *elt));
+ 
+ /* These allocators are dreadfully simple, with no caching whatsoever so
+    that Purify-like tools that do allocation versioning can catch errors.
+    This collector is never going to go fast anyway.  */
+ 
+ rtx
+ ggc_alloc_rtx (nslots)
+      int nslots;
+ {
+   struct ggc_rtx *n;
+   int size = sizeof(*n) + (nslots-1) * sizeof(rtunion);
+ 
+   n = (struct ggc_rtx *) xmalloc (size);
+   bzero ((char *) n, size);
+   n->chain = rtxs;
+   rtxs = n;
+ 
+ #ifdef GGC_DUMP
+   fprintf (dump, "alloc rtx %p\n", &n->rtx);
+ #endif
+ 
+   bytes_alloced_since_gc += size;
+ 
+   return &n->rtx;
+ }
+ 
+ rtvec
+ ggc_alloc_rtvec (nelt)
+      int nelt;
+ {
+   struct ggc_rtvec *v;
+   int size = sizeof (*v) + (nelt - 1) * sizeof (rtunion);
+ 
+   v = (struct ggc_rtvec *) xmalloc (size);
+   bzero ((char *) v, size);
+   v->chain = vecs;
+   vecs = v;
+ 
+ #ifdef GGC_DUMP
+   fprintf(dump, "alloc vec %p\n", &v->vec);
+ #endif
+ 
+   bytes_alloced_since_gc += size;
+ 
+   return &v->vec;
+ }
+ 
+ tree
+ ggc_alloc_tree (length)
+      int length;
+ {
+   struct ggc_tree *n;
+   int size = sizeof(*n) - sizeof(n->tree) + length;
+ 
+   n = (struct ggc_tree *) xmalloc (size);
+   bzero ((char *) n, size);
+   n->chain = trees;
+   trees = n;
+ 
+ #ifdef GGC_DUMP
+   fprintf(dump, "alloc tree %p\n", &n->tree);
+ #endif
+ 
+   bytes_alloced_since_gc += size;
+ 
+   return &n->tree;
+ }
+ 
+ char *
+ ggc_alloc_string (contents, length)
+      const char *contents;
+      int length;
+ {
+   struct ggc_string *s;
+   int size;
+ 
+   if (length < 0)
+     {
+       if (contents == NULL)
+ 	return NULL;
+       length = strlen (contents);
+     }
+ 
+   size = (s->string - (char *)s) + length + 1;
+   s = (struct ggc_string *) xmalloc(size);
+   s->chain = strings;
+   s->magic_mark = GGC_STRING_MAGIC;
+   if (contents)
+     bcopy (contents, s->string, length);
+   s->string[length] = 0;
+   strings = s;
+ 
+ #ifdef GGC_DUMP
+   fprintf(dump, "alloc string %p\n", &n->tree);
+ #endif
+ 
+   bytes_alloced_since_gc += size;
+ 
+   return s->string;
+ }
+ 
+ 
+ /* Freeing a bit of rtl isn't quite as simple as calling free, there are
+    a few associated bits that might need freeing as well.  */
+ 
+ static void
+ ggc_free_rtx (r)
+      struct ggc_rtx *r;
+ {
+ #ifdef GGC_DUMP
+   fprintf (dump, "collect rtx %p\n", &r->rtx);
+ #endif
+ #ifdef GGC_POISON
+   memset (r, 0xAA, sizeof(*r));
+ #endif
+ 
+   free (r);
+ }
+ 
+ /* Freeing an rtvec is as simple as calling free.  */
+ 
+ static void
+ ggc_free_rtvec (v)
+      struct ggc_rtvec *v;
+ {
+ #ifdef GGC_DUMP
+   fprintf(dump, "collect vec %p\n", &v->vec);
+ #endif
+ #ifdef GGC_POISON
+   memset (v, 0xBB, sizeof (*v) + ((GET_NUM_ELEM (&v->vec) - 1)
+ 				  * sizeof (rtunion)));
+ #endif
+ 
+   free (v);
+ }
+ 
+ /* Freeing a tree node is almost, but not quite, as simple as calling free.
+    Mostly we need to let the language clean up its lang_specific bits.  */
+ 
+ static void
+ ggc_free_tree (t)
+      struct ggc_tree *t;
+ {
+   switch (TREE_CODE_CLASS (TREE_CODE (&t->tree)))
+     {
+     case 'd': /* A decl node.  */
+     case 't': /* A type node.  */
+       lang_cleanup_tree (&t->tree);
+       break;
+     }
+ 
+ #ifdef GGC_DUMP
+   fprintf (dump, "collect tree %p\n", &t->tree);
+ #endif
+ #ifdef GGC_POISON
+   memset(&t->tree.common, 0xCC, sizeof(t->tree.common));
+ #endif
+ 
+   free (t);
+ }
+ 
+ /* Freeing a string is as simple as calling free.  */
+ 
+ static void
+ ggc_free_string (s)
+      struct ggc_string *s;
+ {
+ #ifdef GGC_DUMP
+   fprintf(dump, "collect string %p\n", s->string);
+ #endif
+ #ifdef GGC_POISON
+   s->magic_mark = 0xDDDDDDDD;
+   s->string[0] = 0xDD;
+ #endif
+ 
+   free (s);
+ }
+ 
+ /* Mark a node.  */
+ 
+ void
+ ggc_mark_rtx (r)
+      rtx r;
+ {
+   const char *fmt;
+   int i;
+ 
+   if (r == NULL_RTX || r->gc_mark)
+     return;
+   r->gc_mark = 1;
+ 
+   /* ??? If (some of) these are really pass-dependant info, do we have
+      any right poking our noses in?  */
+   switch (GET_CODE (r))
+     {
+     case JUMP_INSN:
+       ggc_mark_rtx (JUMP_LABEL (r));
+       break;
+     case CODE_LABEL:
+       ggc_mark_rtx (LABEL_REFS (r));
+       break;
+     case LABEL_REF:
+       ggc_mark_rtx (LABEL_NEXTREF (r));
+       ggc_mark_rtx (CONTAINING_INSN (r));
+       break;
+     case ADDRESSOF:
+       ggc_mark_tree (ADDRESSOF_DECL (r));
+       break;
+     case CONST_DOUBLE:
+       ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
+       break;
+ 
+     default:
+       break;
+     }
+ 
+   for (fmt = GET_RTX_FORMAT (GET_CODE (r)), i = 0; *fmt ; ++fmt, ++i)
+     {
+       switch (*fmt)
+ 	{
+ 	case 'e': case 'u':
+ 	  ggc_mark_rtx (XEXP (r, i));
+ 	  break;
+ 	case 'V': case 'E':
+ 	  ggc_mark_rtvec (XVEC (r, i));
+ 	  break;
+ 	case 'S': case 's':
+ 	  ggc_mark_string (XSTR (r, i));
+ 	  break;
+ 	}
+     }
+ }
+ 
+ void
+ ggc_mark_rtvec (v)
+      rtvec v;
+ {
+   int i;
+ 
+   if (v == NULL || v->gc_mark)
+     return;
+   v->gc_mark = 1;
+ 
+   i = GET_NUM_ELEM (v);
+   while (--i >= 0)
+     ggc_mark_rtx (RTVEC_ELT (v, i));
+ }
+ 
+ void
+ ggc_mark_tree (t)
+      tree t;
+ {
+   if (t == NULL_TREE || t->common.gc_mark)
+     return;
+   t->common.gc_mark = 1;
+ 
+   /* Bits from common.  */
+   ggc_mark_tree (TREE_TYPE (t));
+   ggc_mark_tree (TREE_CHAIN (t));
+ 
+   /* Some nodes require special handling.  */
+   switch (TREE_CODE (t))
+     {
+     case TREE_LIST:
+       ggc_mark_tree (TREE_PURPOSE (t));
+       ggc_mark_tree (TREE_VALUE (t));
+       return;
+ 
+     case TREE_VEC:
+       {
+ 	int i = TREE_VEC_LENGTH (t);
+ 	while (--i >= 0)
+ 	  ggc_mark_tree (TREE_VEC_ELT (t, i));
+ 	return;
+       }
+ 
+     case SAVE_EXPR:
+       ggc_mark_tree (TREE_OPERAND (t, 0));
+       ggc_mark_tree (SAVE_EXPR_CONTEXT (t));
+       ggc_mark_rtx (SAVE_EXPR_RTL (t));
+       return;
+ 
+     case RTL_EXPR:
+       ggc_mark_rtx (RTL_EXPR_SEQUENCE (t));
+       ggc_mark_rtx (RTL_EXPR_RTL (t));
+       return;
+ 
+     case CALL_EXPR:
+       ggc_mark_tree (TREE_OPERAND (t, 0));
+       ggc_mark_tree (TREE_OPERAND (t, 1));
+       ggc_mark_rtx (CALL_EXPR_RTL (t));
+       return;
+ 
+     case COMPLEX_CST:
+       ggc_mark_tree (TREE_REALPART (t));
+       ggc_mark_tree (TREE_IMAGPART (t));
+       break;
+ 
+     case STRING_CST:
+       ggc_mark_string (TREE_STRING_POINTER (t));
+       break;
+ 
+     case PARM_DECL:
+       ggc_mark_rtx (DECL_INCOMING_RTL (t));
+       break;
+ 
+     case IDENTIFIER_NODE:
+       ggc_mark_string (IDENTIFIER_POINTER (t));
+       lang_mark_tree (t);
+       return;
+ 
+     default:
+       break;
+     }
+   
+   /* But in general we can handle them by class.  */
+   switch (TREE_CODE_CLASS (TREE_CODE (t)))
+     {
+     case 'd': /* A decl node.  */
+       ggc_mark_tree (DECL_SIZE (t));
+       ggc_mark_tree (DECL_NAME (t));
+       ggc_mark_tree (DECL_CONTEXT (t));
+       ggc_mark_tree (DECL_ARGUMENTS (t));
+       ggc_mark_tree (DECL_RESULT (t));
+       ggc_mark_tree (DECL_INITIAL (t));
+       ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
+       ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
+       ggc_mark_tree (DECL_SECTION_NAME (t));
+       ggc_mark_tree (DECL_MACHINE_ATTRIBUTES (t));
+       ggc_mark_rtx (DECL_RTL (t));
+       ggc_mark_tree (DECL_VINDEX (t));
+       lang_mark_tree (t);
+       break;
+ 
+     case 't': /* A type node.  */
+       ggc_mark_tree (TYPE_SIZE (t));
+       ggc_mark_tree (TYPE_SIZE_UNIT (t));
+       ggc_mark_tree (TYPE_ATTRIBUTES (t));
+       ggc_mark_tree (TYPE_VALUES (t));
+       ggc_mark_tree (TYPE_POINTER_TO (t));
+       ggc_mark_tree (TYPE_REFERENCE_TO (t));
+       ggc_mark_tree (TYPE_NAME (t));
+       ggc_mark_tree (TYPE_MIN_VALUE (t));
+       ggc_mark_tree (TYPE_MAX_VALUE (t));
+       ggc_mark_tree (TYPE_NEXT_VARIANT (t));
+       ggc_mark_tree (TYPE_MAIN_VARIANT (t));
+       ggc_mark_tree (TYPE_BINFO (t));
+       ggc_mark_tree (TYPE_NONCOPIED_PARTS (t));
+       ggc_mark_tree (TYPE_CONTEXT (t));
+       lang_mark_tree (t);
+       break;
+ 
+     case 'b': /* A lexical block.  */
+       ggc_mark_tree (BLOCK_VARS (t));
+       ggc_mark_tree (BLOCK_TYPE_TAGS (t));
+       ggc_mark_tree (BLOCK_SUBBLOCKS (t));
+       ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
+       ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
+       ggc_mark_rtx (BLOCK_END_NOTE (t));
+       break;
+ 
+     case 'c': /* A constant.  */
+       ggc_mark_rtx (TREE_CST_RTL (t));
+       break;
+ 
+     case 'r': case '<': case '1':
+     case '2': case 'e': case 's': /* Expressions.  */
+       {
+ 	int i = tree_code_length[TREE_CODE (t)];
+ 	while (--i >= 0)
+ 	  ggc_mark_tree (TREE_OPERAND (t, i));
+ 	break;
+       }
+     }
+ }
+ 
+ void
+ ggc_mark_string (s)
+      char *s;
+ {
+   unsigned int *magic = (unsigned int *)s - 1;
+ 
+   if (s == NULL)
+     return;
+ 
+   if ((*magic & ~(unsigned)1) != GGC_STRING_MAGIC)
+     return;   /* abort? */
+   *magic = GGC_STRING_MAGIC | 1;
+ }
+ 
+ /* The top level mark-and-sweep routine.  */
+ 
+ void
+ ggc_collect ()
+ {
+   struct ggc_rtx *r, **rp;
+   struct ggc_rtvec *v, **vp;
+   struct ggc_tree *t, **tp;
+   struct ggc_string *s, **sp;
+   struct ggc_root *x;
+   int time, n_rtxs, n_trees, n_vecs, n_strings;
+ 
+ #ifndef ENABLE_CHECKING
+   /* See if it's even worth our while.  */
+   if (bytes_alloced_since_gc < 64*1024)
+     return;
+ #endif
+ 
+   if (!quiet_flag)
+     fputs (" {GC ", stderr);
+ 
+   time = get_run_time ();
+ 
+   /* Clean out all of the GC marks.  */
+   for (r = rtxs; r != NULL; r = r->chain)
+     r->rtx.gc_mark = 0;
+   for (v = vecs; v != NULL; v = v->chain)
+     v->vec.gc_mark = 0;
+   for (t = trees; t != NULL; t = t->chain)
+     t->tree.common.gc_mark = 0;
+   for (s = strings; s != NULL; s = s->chain)
+     s->magic_mark = GGC_STRING_MAGIC;
+ 
+   /* Mark through all the roots.  */
+   for (x = roots; x != NULL; x = x->next)
+     {
+       char *elt = x->base;
+       int s = x->size, n = x->nelt;
+       void (*cb)(void *) = x->cb;
+       int i;
+ 
+       for (i = 0; i < n; ++i, elt += s)
+ 	(*cb)(elt);
+     }
+ 
+   /* Sweep the resulting dead nodes.  */
+   rp = &rtxs, r = rtxs, n_rtxs = 0;
+   while (r != NULL)
+     {
+       struct ggc_rtx *chain = r->chain;
+       if (!r->rtx.gc_mark)
+         {
+ 	  ggc_free_rtx (r);
+ 	  *rp = chain;
+ 	  n_rtxs++;
+         }
+       else
+ 	rp = &r->chain;
+       r = chain;
+     }
+   *rp = NULL;
+   n_rtxs_collected += n_rtxs;
+ 
+   vp = &vecs, v = vecs, n_vecs = 0;
+   while (v != NULL)
+     {
+       struct ggc_rtvec *chain = v->chain;
+       if (!v->vec.gc_mark)
+         {
+ 	  ggc_free_rtvec (v);
+ 	  *vp = chain;
+ 	  n_vecs++;
+         }
+       else
+ 	vp = &v->chain;
+       v = chain;
+     }
+   *vp = NULL;
+   n_vecs_collected += n_vecs;
+ 
+   tp = &trees, t = trees, n_trees = 0;
+   while (t != NULL)
+     {
+       struct ggc_tree *chain = t->chain;
+       if (!t->tree.common.gc_mark)
+         {
+ 	  ggc_free_tree (t);
+ 	  *tp = chain;
+ 	  n_trees++;
+         }
+       else
+ 	tp = &t->chain;
+       t = chain;
+     }
+   *tp = NULL;
+   n_trees_collected += n_trees;
+ 
+   sp = &strings, s = strings, n_strings = 0;
+   while (s != NULL)
+     {
+       struct ggc_string *chain = s->chain;
+       if (!(s->magic_mark & 1))
+         {
+ 	  ggc_free_string (s);
+ 	  *sp = chain;
+ 	  n_strings++;
+         }
+       else
+ 	sp = &s->chain;
+       s = chain;
+     }
+   *sp = NULL;
+   n_strings_collected += n_strings;
+ 
+   gc_time += time = get_run_time () - time;
+ 
+   if (!quiet_flag)
+     {
+       time = (time + 500) / 1000;
+       fprintf (stderr, "%d,%d,%d,%d %d.%03d}", n_rtxs, n_vecs, n_trees,
+ 	       n_strings, time / 1000, time % 1000);
+     }
+ }
+ 
+ /* Manipulate global roots that are needed between calls to gc.  */
+ 
+ void
+ ggc_add_root (base, nelt, size, cb)
+      void *base;
+      int nelt, size;
+      void (*cb) PROTO ((void *));
+ {
+   struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof(*x));
+ 
+   x->next = roots;
+   x->base = base;
+   x->nelt = nelt;
+   x->size = size;
+   x->cb = cb;
+ 
+   roots = x;
+ }
+ 
+ void
+ ggc_add_rtx_root (base, nelt)
+      rtx *base;
+      int nelt;
+ {
+   ggc_add_root (base, nelt, sizeof(rtx), ggc_mark_rtx_ptr);
+ }
+ 
+ void
+ ggc_add_tree_root (base, nelt)
+      tree *base;
+      int nelt;
+ {
+   ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
+ }
+ 
+ void
+ ggc_del_root (base)
+      void *base;
+ {
+   struct ggc_root *x, **p;
+ 
+   p = &roots, x = roots;
+   while (x)
+     {
+       if (x->base == base)
+ 	{
+ 	  *p = x->next;
+ 	  free (x);
+ 	  return;
+ 	}
+       p = &x->next;
+       x = x->next;
+     }
+ 
+   abort();
+ }
+ 
+ static void
+ ggc_mark_rtx_ptr (elt)
+      void *elt;
+ {
+   ggc_mark_rtx (*(rtx *)elt);
+ }
+ 
+ static void
+ ggc_mark_tree_ptr (elt)
+      void *elt;
+ {
+   ggc_mark_tree (*(tree *)elt);
+ }
+ 
+ #ifdef GGC_DUMP
+ /* Don't enable this unless you want a really really lot of data.  */
+ static void __attribute__((constructor))
+ init(void)
+ {
+   dump = fopen ("zgcdump", "w");
+   setlinebuf (dump);
+ }
+ #endif
+ 
+ #if 0
+ /* GDB really should have a memory search function.  Since this is just
+    for initial debugging, I won't even pretend to get the __data_start
+    to work on any but alpha-dec-linux-gnu.  */
+ static void **
+ search_data(void **start, void *target)
+ {
+   extern void *__data_start[];
+   void **_end = (void **)sbrk(0);
+ 
+   if (start == NULL)
+     start = __data_start;
+   while (start < _end)
+     {
+       if (*start == target)
+         return start;
+       start++;
+     }
+   return NULL;
+ }
+ #endif
Index: ggc.h
===================================================================
RCS file: ggc.h
diff -N ggc.h
*** /dev/null	Sat Dec  5 20:30:03 1998
--- ggc.h	Sat Sep  4 11:19:27 1999
***************
*** 0 ****
--- 1,72 ----
+ /* Garbage collection for the GNU compiler.
+    Copyright (C) 1998 Free Software Foundation, Inc.
+ 
+    This file is part of GNU CC.
+ 
+    GNU CC is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2, or (at your option)
+    any later version.
+ 
+    GNU CC is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with GNU CC; see the file COPYING.  If not, write to
+    the Free Software Foundation, 59 Temple Place - Suite 330,
+    Boston, MA 02111-1307, USA.  */
+ 
+ #include "gansidecl.h"
+ 
+ /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
+    an external gc library that might be linked in.  */
+ 
+ /* Startup */
+ 
+ extern void init_ggc PROTO ((void));
+ 
+ /* Allocation.  */
+ 
+ struct rtx_def *ggc_alloc_rtx PROTO ((int nslots));
+ struct rtvec_def *ggc_alloc_rtvec PROTO ((int nelt));
+ union tree_node *ggc_alloc_tree PROTO ((int length));
+ char *ggc_alloc_string PROTO ((const char *contents, int length));
+ 
+ /* Invoke the collector.  This is really just a hint, but in the case of
+    the simple collector, the only time it will happen.  */
+ 
+ void ggc_collect PROTO ((void));
+ 
+ /* Manipulate global roots that are needed between calls to gc.  */
+ void ggc_add_root PROTO ((void *base, int nelt, int size,
+ 			   void (*)(void *)));
+ void ggc_add_rtx_root PROTO ((struct rtx_def **, int nelt));
+ void ggc_add_tree_root PROTO ((union tree_node **, int nelt));
+ void ggc_del_root PROTO ((void *base));
+ 
+ /* Mark nodes from the gc_add_root callback.  */
+ void ggc_mark_rtx PROTO ((struct rtx_def *));
+ void ggc_mark_rtvec PROTO ((struct rtvec_def *));
+ void ggc_mark_tree PROTO ((union tree_node *));
+ void ggc_mark_string PROTO ((char *));
+ 
+ /* Callbacks to the languages.  */
+ 
+ /* This is the language's opportunity to mark nodes held through
+    the lang_specific hooks in the tree.  */
+ 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 *));
+ 
+ /* 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 *));
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.128
diff -c -p -r1.128 rtl.h
*** rtl.h	1999/09/03 22:54:55	1.128
--- rtl.h	1999/09/04 18:19:28
*************** typedef struct rtx_def
*** 100,112 ****
  {
  #ifdef ONLY_INT_FIELDS
  #ifdef CODE_FIELD_BUG
!   unsigned int code : 16;
  #else
    unsigned short code;
  #endif
  #else
    /* The kind of expression this is.  */
!   enum rtx_code code : 16;
  #endif
    /* The kind of value the expression has.  */
  #ifdef ONLY_INT_FIELDS
--- 100,112 ----
  {
  #ifdef ONLY_INT_FIELDS
  #ifdef CODE_FIELD_BUG
!   unsigned int code : 15;
  #else
    unsigned short code;
  #endif
  #else
    /* The kind of expression this is.  */
!   enum rtx_code code : 15;
  #endif
    /* The kind of value the expression has.  */
  #ifdef ONLY_INT_FIELDS
*************** typedef struct rtx_def
*** 169,174 ****
--- 169,178 ----
       1 in a MEM if the MEM refers to a scalar, rather than a member of
       an aggregate.  */
    unsigned frame_related : 1;
+ 
+   /* Used by the garbage collector.  */
+   unsigned gc_mark : 1;
+ 
    /* The first element of the operands of this rtx.
       The number of operands and their types are controlled
       by the `code' field, according to rtl.def.  */
*************** typedef struct rtx_def
*** 200,205 ****
--- 204,210 ----
  
  typedef struct rtvec_def{
    int num_elem;		/* number of elements */
+   int gc_mark;
    struct rtx_def *elem[1];
  } *rtvec;
  
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.203
diff -c -p -r1.203 toplev.c
*** toplev.c	1999/09/02 05:42:04	1.203
--- toplev.c	1999/09/04 18:19:32
*************** Boston, MA 02111-1307, USA.  */
*** 54,59 ****
--- 54,60 ----
  #include "expr.h"
  #include "basic-block.h"
  #include "intl.h"
+ #include "ggc.h"
  
  #ifdef DWARF_DEBUGGING_INFO
  #include "dwarfout.h"
*************** int stack_reg_time;
*** 1350,1355 ****
--- 1351,1358 ----
  int final_time;
  int symout_time;
  int dump_time;
+ int gc_time;
+ int all_time;
  
  /* Return time used so far, in microseconds.  */
  
*************** print_time (str, total)
*** 1429,1436 ****
       int total;
  {
    fprintf (stderr,
! 	   "time in %s: %d.%06d\n",
! 	   str, total / 1000000, total % 1000000);
  }
  
  /* Count an error or warning.  Return 1 if the message should be printed.  */
--- 1432,1440 ----
       int total;
  {
    fprintf (stderr,
! 	   "time in %s: %d.%06d (%.0f%%)\n",
! 	   str, total / 1000000, total % 1000000,
! 	   (double)total / (double)all_time * 100.0);
  }
  
  /* Count an error or warning.  Return 1 if the message should be printed.  */
*************** compile_file (name)
*** 3446,3454 ****
  
    if (! quiet_flag)
      {
        fprintf (stderr,"\n");
-       print_time ("parse", parse_time);
  
        print_time ("integration", integration_time);
        print_time ("jump", jump_time);
        print_time ("cse", cse_time);
--- 3450,3460 ----
  
    if (! quiet_flag)
      {
+       all_time = get_run_time ();
+ 
        fprintf (stderr,"\n");
  
+       print_time ("parse", parse_time);
        print_time ("integration", integration_time);
        print_time ("jump", jump_time);
        print_time ("cse", cse_time);
*************** compile_file (name)
*** 3473,3478 ****
--- 3479,3485 ----
        print_time ("varconst", varconst_time);
        print_time ("symout", symout_time);
        print_time ("dump", dump_time);
+       print_time ("gc", gc_time);
      }
  }
  
*************** rest_of_compilation (decl)
*** 3820,3826 ****
    /* See if we have allocated stack slots that are not directly addressable.
       If so, scan all the insns and create explicit address computation
       for all references to such slots.  */
! /*   fixup_stack_slots (); */
  
    /* Find all the EH handlers.  */
    find_exception_handler_labels ();
--- 3827,3833 ----
    /* See if we have allocated stack slots that are not directly addressable.
       If so, scan all the insns and create explicit address computation
       for all references to such slots.  */
!   /* fixup_stack_slots (); */
  
    /* Find all the EH handlers.  */
    find_exception_handler_labels ();
Index: tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.h,v
retrieving revision 1.84
diff -c -p -r1.84 tree.h
*** tree.h	1999/08/31 02:15:46	1.84
--- tree.h	1999/09/04 18:19:33
*************** struct tree_common
*** 194,200 ****
    unsigned lang_flag_4 : 1;
    unsigned lang_flag_5 : 1;
    unsigned lang_flag_6 : 1;
!   /* There is room for three more flags.  */
  };
  
  /* The following table lists the uses of each of the above flags and
--- 194,203 ----
    unsigned lang_flag_4 : 1;
    unsigned lang_flag_5 : 1;
    unsigned lang_flag_6 : 1;
! 
!   unsigned gc_mark : 1;
! 
!   /* There is room for two more flags.  */
  };
  
  /* The following table lists the uses of each of the above flags and


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]