emit-rtl.c (free_emit_status): Take decl as a parameter.
authorMark Mitchell <mark@codesourcery.com>
Tue, 7 Sep 1999 15:20:58 +0000 (15:20 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 7 Sep 1999 15:20:58 +0000 (15:20 +0000)
* emit-rtl.c (free_emit_status): Take decl as a parameter.
(init_emit_once): Add more GC roots.
* except.c (mark_func_eh_entry): New function.
(mark_eh_node): Mark false_label and rethrow_label.
(init_eh): Add more GC roots.
* function.c (free_after_compilation): Take decl as a paramter.
Call free_stmt_status.
(mark_function_state): Don't assume x_parm_reg_stack_loc is
non-NULL.
* function.h (free_after_compilation): Change prototype.
(free_varasm_status): Likewise.
(free_emit_status): Likewise.
(free_stmt_status): New function.
* ggc-simple.c (rtx, vecs, trees, strings, bytes_alloced_since_gc):
Remove, replacing with ...
(ggc_status): New structure.
(ggc_chain): New variable.
(init_gcc): Define.
(ggc_push_context): New function.
(ggc_pop_context): Likewise.
(ggc_alloc_rtx): Adjust for use of ggc_chain.
(ggc_alloc_rtvec): Likewise.
(ggc_alloc_tree): Likewise.
(ggc_alloc_string): Likewise.
(ggc_mark_rtx): Mark NOTE_SOURCE_FILE and NOTE_RANGE_INFO.
(ggc_mark_tree): Give language-dependent code a chance to mark
`x' nodes.
(ggc_mark_tree_varray): Handle empty arrays.
(ggc_collect): Adjust for use of ggc_chain.  Clear
bytes_alloced_since_last_gc.
* ggc.h (ggc_pop_context): New function.
(ggc_push_context): Likewise.
* print-tree.c (print_node): Don't print obstacks when GC'ing.
* stmt.c (free_stmt_status): New function.
(init_stmt_for_function): Clear last_expr_value.
* toplev.c (rest_of_compilation): Always call free_after_compilation.
Conditionalize call to ggc_collect.
(main): Call init_ggc.
* tree.c (push_obstacks): Do the push, even when GC'ing.
(push_obstacks_nochange): Likewise.
(pop_obstacks): Liekwise.
* varasm.c (free_varasm_status): Take decl as a parameter.

From-SVN: r29170

12 files changed:
gcc/ChangeLog
gcc/emit-rtl.c
gcc/except.c
gcc/function.c
gcc/function.h
gcc/ggc-simple.c
gcc/ggc.h
gcc/print-tree.c
gcc/stmt.c
gcc/toplev.c
gcc/tree.c
gcc/varasm.c

index a2e2ef556c0d2fd27f0e374f1581e6cdfdc7f4fd..5bc407cec5789b40e334c160c270cb43324b560e 100644 (file)
@@ -1,3 +1,48 @@
+Tue Sep  7 00:47:52 1999  Mark Mitchell  <mark@codesourcery.com>
+
+       * emit-rtl.c (free_emit_status): Take decl as a parameter.
+       (init_emit_once): Add more GC roots.
+       * except.c (mark_func_eh_entry): New function.
+       (mark_eh_node): Mark false_label and rethrow_label.
+       (init_eh): Add more GC roots.
+       * function.c (free_after_compilation): Take decl as a paramter.
+       Call free_stmt_status.
+       (mark_function_state): Don't assume x_parm_reg_stack_loc is
+       non-NULL.
+       * function.h (free_after_compilation): Change prototype.
+       (free_varasm_status): Likewise.
+       (free_emit_status): Likewise.
+       (free_stmt_status): New function.
+       * ggc-simple.c (rtx, vecs, trees, strings, bytes_alloced_since_gc): 
+       Remove, replacing with ...
+       (ggc_status): New structure.
+       (ggc_chain): New variable.
+       (init_gcc): Define.
+       (ggc_push_context): New function.
+       (ggc_pop_context): Likewise.
+       (ggc_alloc_rtx): Adjust for use of ggc_chain.
+       (ggc_alloc_rtvec): Likewise.
+       (ggc_alloc_tree): Likewise.
+       (ggc_alloc_string): Likewise.
+       (ggc_mark_rtx): Mark NOTE_SOURCE_FILE and NOTE_RANGE_INFO.
+       (ggc_mark_tree): Give language-dependent code a chance to mark
+       `x' nodes.
+       (ggc_mark_tree_varray): Handle empty arrays.
+       (ggc_collect): Adjust for use of ggc_chain.  Clear
+       bytes_alloced_since_last_gc.
+       * ggc.h (ggc_pop_context): New function.
+       (ggc_push_context): Likewise.
+       * print-tree.c (print_node): Don't print obstacks when GC'ing.
+       * stmt.c (free_stmt_status): New function.
+       (init_stmt_for_function): Clear last_expr_value.
+       * toplev.c (rest_of_compilation): Always call free_after_compilation.
+       Conditionalize call to ggc_collect.
+       (main): Call init_ggc.
+       * tree.c (push_obstacks): Do the push, even when GC'ing.
+       (push_obstacks_nochange): Likewise.
+       (pop_obstacks): Liekwise.
+       * varasm.c (free_varasm_status): Take decl as a parameter.
+       
 Tue Sep  7 08:15:49 1999  Gavin Romig-Koch  <gavin@cygnus.com>
 
        * config/mips/mips.h (MULTILIB_ENDIAN_DEFAULT) : New macro.
@@ -155,7 +200,6 @@ Mon Sep  6 14:30:13 1999  Bernd Schmidt  <bernds@cygnus.co.uk>
        (ix86_mark_machine_status): New function.
        (override_options): Set mark_machine_status.
 
->>>>>>> 1.4290
 Mon Sep  6 15:26:23 1999  Bernd Schmidt  <bernds@cygnus.co.uk>
 
        * tree.c (copy_node): Copy node contents also if doing GC.
@@ -166,7 +210,6 @@ Mon Sep  6 08:42:06 1999  Alexandre Oliva  <oliva@dcc.unicamp.br>
 
 Mon Sep  6 02:42:36 1999  Jeffrey A Law  (law@cygnus.com)
 
->>>>>>> 1.4287
        * collect2.c (scan_libraries): Fix thinko.
 
        * cse.c (delete_trivially_dead_insns): Do not skip the last
index 5a4b5f2f02ae3b8ebea36ad6afb26523f6c5d323..9837b6811b0d3b3b2acf769e25f3d104aa38ca4c 100644 (file)
@@ -1607,13 +1607,19 @@ restore_emit_status (p)
   clear_emit_caches ();
 }
 
-/* Clear out all parts of our state in F that can safely be discarded
+/* Clear out all parts of the state in F that can safely be discarded
    after the function has been compiled, to let garbage collection
-   reclaim the memory.  */
+   reclaim the memory.  D is the declaration for the function just
+   compiled.  Its output may have been deferred.  */
+
 void
-free_emit_status (f)
+free_emit_status (f, d)
      struct function *f;
+     tree d;
 {
+  if (DECL_DEFER_OUTPUT (d))
+    return;
+
   free (f->emit->x_regno_reg_rtx);
   free (f->emit->regno_pointer_flag);
   free (f->emit->regno_pointer_align);
@@ -3693,6 +3699,7 @@ init_emit_once (line_numbers)
 
   ggc_add_rtx_root (&const_tiny_rtx[0][0], sizeof(const_tiny_rtx)/sizeof(rtx));
 
+  ggc_add_rtx_root (&const_true_rtx, 1);
   ggc_add_rtx_root (&pic_offset_table_rtx, 1);
   ggc_add_rtx_root (&struct_value_rtx, 1);
   ggc_add_rtx_root (&struct_value_incoming_rtx, 1);
index 0548006777964574280f51d394bc103dfbd0f851..4bb2adb9e705012b43d23b7ab168a94d828ee4ab 100644 (file)
@@ -472,6 +472,7 @@ 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 *));
+static void mark_func_eh_entry PROTO ((void *));
 
 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
 \f
@@ -2347,6 +2348,8 @@ mark_eh_node (node)
          ggc_mark_rtx (node->entry->outer_context);
          ggc_mark_rtx (node->entry->exception_handler_label);
          ggc_mark_tree (node->entry->finalization);
+         ggc_mark_rtx (node->entry->false_label);
+         ggc_mark_rtx (node->entry->rethrow_label);
        }
       node = node ->chain;
     }
@@ -2405,6 +2408,33 @@ mark_eh_state (eh)
   ggc_mark_rtx (eh->x_eh_return_stub_label);
 }
 
+/* Mark ARG (which is really a struct func_eh_entry**) for GC.  */
+
+static void 
+mark_func_eh_entry (arg)
+     void *arg;
+{
+  struct func_eh_entry *fee;
+  struct handler_info *h;
+  int i;
+
+  fee = *((struct func_eh_entry **) arg);
+
+  for (i = 0; i < current_func_eh_entry; ++i)
+    {
+      ggc_mark_rtx (fee->rethrow_label);
+      for (h = fee->handlers; h; h = h->next)
+       {
+         ggc_mark_rtx (h->handler_label);
+         if (h->type_info != CATCH_ALL_TYPE)
+           ggc_mark_tree ((tree) h->type_info);
+       }
+
+      /* Skip to the next entry in the array.  */
+      ++fee;
+    }
+}
+
 /* 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
@@ -2419,8 +2449,18 @@ init_eh ()
   first_rethrow_symbol = create_rethrow_ref (0);
   final_rethrow = gen_exception_label ();
   last_rethrow_symbol = create_rethrow_ref (CODE_LABEL_NUMBER (final_rethrow));
-}
 
+  ggc_add_rtx_root (&exception_handler_labels, 1);
+  ggc_add_rtx_root (&eh_return_context, 1);
+  ggc_add_rtx_root (&eh_return_stack_adjust, 1);
+  ggc_add_rtx_root (&eh_return_handler, 1);
+  ggc_add_rtx_root (&first_rethrow_symbol, 1);
+  ggc_add_rtx_root (&final_rethrow, 1);
+  ggc_add_rtx_root (&last_rethrow_symbol, 1);
+  ggc_add_root (&function_eh_regions, 1, sizeof (function_eh_regions),
+               mark_func_eh_entry);
+}
+  
 /* Initialize the per-function EH information.  */
 
 void
index b83a7c421d2dee687241abfee339015d17b6c651..4ce2dd5591bbb0f656bf56b77cc934f62a404d6e 100644 (file)
@@ -390,17 +390,23 @@ pop_function_context ()
 
 /* Clear out all parts of the state in F that can safely be discarded
    after the function has been compiled, to let garbage collection
-   reclaim the memory.  */
+   reclaim the memory.  D is the declaration for the function just
+   compiled.  Its output may have been deferred.  */
+
 void
-free_after_compilation (f)
+free_after_compilation (f, d)
      struct function *f;
+     tree d;
 {
-  free_emit_status (f);
-  free_varasm_status (f);
-
-  free (f->x_parm_reg_stack_loc);
+  free_emit_status (f, d);
+  free_varasm_status (f, d);
+  free_stmt_status (f, d);
 
-  f->can_garbage_collect = 1;
+  if (!DECL_DEFER_OUTPUT (d))
+    {
+      free (f->x_parm_reg_stack_loc);
+      f->can_garbage_collect = 1;
+    }
 }
 \f
 /* Allocate fixed slots in the stack frame of the current function.  */
@@ -6682,9 +6688,10 @@ mark_function_state (p)
 
   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);
+  if (p->x_parm_reg_stack_loc)
+    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);
index 966b3f74e4788dc877ce0b71e93478c2f78ed81c..76ee362734d490fcdecbcb6b5a8e6874fb3249a4 100644 (file)
@@ -549,11 +549,16 @@ extern void (*restore_lang_status)        PROTO((struct function *));
 extern void save_tree_status           PROTO((struct function *));
 extern void restore_tree_status                PROTO((struct function *));
 extern void restore_emit_status                PROTO((struct function *));
-extern void free_after_compilation     PROTO((struct function *));
+extern void free_after_compilation     PROTO((struct function *,
+                                              tree));
 
 extern void init_varasm_status         PROTO((struct function *));
-extern void free_varasm_status         PROTO((struct function *));
-extern void free_emit_status           PROTO((struct function *));
+extern void free_varasm_status         PROTO((struct function *,
+                                              tree));
+extern void free_emit_status           PROTO((struct function *,
+                                              tree));
+extern void free_stmt_status            PROTO((struct function *,
+                                              tree));
 extern rtx get_first_block_beg         PROTO((void));
 
 extern void init_virtual_regs          PROTO((struct emit_status *));
index 60da127e7f24d1f34b2e0fe3eac7d1b7edca3e4f..41363bc6d309abba29ffddc6a08b520376193326 100644 (file)
@@ -50,24 +50,18 @@ struct ggc_rtx
   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;
@@ -77,7 +71,19 @@ struct ggc_string
 
 #define GGC_STRING_MAGIC       ((unsigned int)0xa1b2c3d4)
 
-static struct ggc_string *strings;
+struct ggc_status
+{
+  struct ggc_status *next;
+  struct ggc_rtx *rtxs;
+  struct ggc_rtvec *vecs;
+  struct ggc_tree *trees;
+  struct ggc_string *strings;
+  size_t bytes_alloced_since_gc;
+};
+
+/* A chain of GGC contexts.  The currently active context is at the
+   front of the chain.  */
+static struct ggc_status *ggc_chain;
 
 /* Some statistics.  */
 
@@ -85,7 +91,6 @@ 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
@@ -103,6 +108,81 @@ static void ggc_mark_tree_hash_table_ptr PROTO ((void *elt));
 static boolean ggc_mark_tree_hash_table_entry PROTO ((struct hash_entry *,
                                                      hash_table_key));
 
+/* Called once to initialize the garbage collector.  */
+
+void 
+init_ggc PROTO ((void))
+{
+  /* Initialize the global context.  */
+  ggc_push_context ();
+}
+
+/* Start a new GGC context.  Memory allocated in previous contexts
+   will not be collected while the new context is active.  */
+
+void
+ggc_push_context PROTO ((void))
+{
+  struct ggc_status *gs = (struct ggc_status *) xmalloc (sizeof (*gs));
+  bzero (gs, sizeof (*gs));
+  gs->next = ggc_chain;
+  ggc_chain = gs;
+}
+
+/* Finish a GC context.  Any uncollected memory in the new context
+   will be merged with the old context.  */
+
+void 
+ggc_pop_context PROTO ((void))
+{
+  struct ggc_rtx *r;
+  struct ggc_rtvec *v;
+  struct ggc_tree *t;
+  struct ggc_string *s;
+  struct ggc_status *gs;
+
+  gs = ggc_chain;
+
+  r = gs->rtxs;
+  if (r)
+    {
+      while (r->chain)
+       r = r->chain;
+      r->chain = gs->next->rtxs;
+      gs->next->rtxs = gs->rtxs;
+    }
+      
+  v = gs->vecs;
+  if (v)
+    {
+      while (v->chain)
+       v = v->chain;
+      v->chain = gs->next->vecs;
+      gs->next->vecs = gs->vecs;
+    }
+
+  t = gs->trees;
+  if (t)
+    {
+      while (t->chain)
+       t = t->chain;
+      t->chain = gs->next->trees;
+      gs->next->trees = gs->trees;
+    }
+
+  s = gs->strings;
+  if (s)
+    {
+      while (s->chain)
+       s = s->chain;
+      s->chain = gs->next->strings;
+      gs->next->strings = gs->strings;
+    }
+
+  ggc_chain = gs->next;
+  free (gs);
+}
+
 /* 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.  */
@@ -116,14 +196,14 @@ ggc_alloc_rtx (nslots)
 
   n = (struct ggc_rtx *) xmalloc (size);
   bzero ((char *) n, size);
-  n->chain = rtxs;
-  rtxs = n;
+  n->chain = ggc_chain->rtxs;
+  ggc_chain->rtxs = n;
 
 #ifdef GGC_DUMP
   fprintf (dump, "alloc rtx %p\n", &n->rtx);
 #endif
 
-  bytes_alloced_since_gc += size;
+  ggc_chain->bytes_alloced_since_gc += size;
 
   return &n->rtx;
 }
@@ -137,14 +217,14 @@ ggc_alloc_rtvec (nelt)
 
   v = (struct ggc_rtvec *) xmalloc (size);
   bzero ((char *) v, size);
-  v->chain = vecs;
-  vecs = v;
+  v->chain = ggc_chain->vecs;
+  ggc_chain->vecs = v;
 
 #ifdef GGC_DUMP
   fprintf(dump, "alloc vec %p\n", &v->vec);
 #endif
 
-  bytes_alloced_since_gc += size;
+  ggc_chain->bytes_alloced_since_gc += size;
 
   return &v->vec;
 }
@@ -158,14 +238,14 @@ ggc_alloc_tree (length)
 
   n = (struct ggc_tree *) xmalloc (size);
   bzero ((char *) n, size);
-  n->chain = trees;
-  trees = n;
+  n->chain = ggc_chain->trees;
+  ggc_chain->trees = n;
 
 #ifdef GGC_DUMP
   fprintf(dump, "alloc tree %p\n", &n->tree);
 #endif
 
-  bytes_alloced_since_gc += size;
+  ggc_chain->bytes_alloced_since_gc += size;
 
   return &n->tree;
 }
@@ -187,18 +267,18 @@ ggc_alloc_string (contents, length)
 
   size = (s->string - (char *)s) + length + 1;
   s = (struct ggc_string *) xmalloc(size);
-  s->chain = strings;
+  s->chain = ggc_chain->strings;
   s->magic_mark = GGC_STRING_MAGIC;
   if (contents)
     bcopy (contents, s->string, length);
   s->string[length] = 0;
-  strings = s;
+  ggc_chain->strings = s;
 
 #ifdef GGC_DUMP
   fprintf(dump, "alloc string %p\n", &s->string);
 #endif
 
-  bytes_alloced_since_gc += size;
+  ggc_chain->bytes_alloced_since_gc += size;
 
   return s->string;
 }
@@ -313,6 +393,21 @@ ggc_mark_rtx (r)
     case CONST_DOUBLE:
       ggc_mark_rtx (CONST_DOUBLE_CHAIN (r));
       break;
+    case NOTE:
+      switch (NOTE_LINE_NUMBER (r))
+       {
+       case NOTE_INSN_RANGE_START:
+       case NOTE_INSN_RANGE_END:
+       case NOTE_INSN_LIVE:
+         ggc_mark_rtx (NOTE_RANGE_INFO (r));
+         break;
+
+       default:
+         if (NOTE_LINE_NUMBER (r) >= 0)
+           ggc_mark_string (NOTE_SOURCE_FILE (r));
+         break;
+       }
+      break;
 
     default:
       break;
@@ -475,6 +570,10 @@ ggc_mark_tree (t)
          ggc_mark_tree (TREE_OPERAND (t, i));
        break;
       }
+
+    case 'x':
+      lang_mark_tree (t);
+      break;
     }
 }
 
@@ -486,8 +585,9 @@ ggc_mark_tree_varray (v)
 {
   int i;
 
-  for (i = v->num_elements - 1; i >= 0; --i) 
-    ggc_mark_tree (VARRAY_TREE (v, i));
+  if (v)
+    for (i = v->num_elements - 1; i >= 0; --i) 
+      ggc_mark_tree (VARRAY_TREE (v, i));
 }
 
 /* Mark the hash table-entry HE.  It's key field is really a tree.  */
@@ -534,11 +634,12 @@ ggc_collect ()
   struct ggc_tree *t, **tp;
   struct ggc_string *s, **sp;
   struct ggc_root *x;
+  struct ggc_status *gs;
   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)
+  if (ggc_chain->bytes_alloced_since_gc < 64*1024)
     return;
 #endif
 
@@ -548,14 +649,17 @@ ggc_collect ()
   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;
+  for (gs = ggc_chain; gs; gs = gs->next)
+    {
+      for (r = gs->rtxs; r != NULL; r = r->chain)
+       r->rtx.gc_mark = 0;
+      for (v = gs->vecs; v != NULL; v = v->chain)
+       v->vec.gc_mark = 0;
+      for (t = gs->trees; t != NULL; t = t->chain)
+       t->tree.common.gc_mark = 0;
+      for (s = gs->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)
@@ -570,7 +674,9 @@ ggc_collect ()
     }
 
   /* Sweep the resulting dead nodes.  */
-  rp = &rtxs, r = rtxs, n_rtxs = 0;
+  rp = &ggc_chain->rtxs;
+  r = ggc_chain->rtxs;
+  n_rtxs = 0;
   while (r != NULL)
     {
       struct ggc_rtx *chain = r->chain;
@@ -587,7 +693,9 @@ ggc_collect ()
   *rp = NULL;
   n_rtxs_collected += n_rtxs;
 
-  vp = &vecs, v = vecs, n_vecs = 0;
+  vp = &ggc_chain->vecs;
+  v = ggc_chain->vecs;
+  n_vecs = 0;
   while (v != NULL)
     {
       struct ggc_rtvec *chain = v->chain;
@@ -604,7 +712,9 @@ ggc_collect ()
   *vp = NULL;
   n_vecs_collected += n_vecs;
 
-  tp = &trees, t = trees, n_trees = 0;
+  tp = &ggc_chain->trees;
+  t = ggc_chain->trees;
+  n_trees = 0;
   while (t != NULL)
     {
       struct ggc_tree *chain = t->chain;
@@ -621,7 +731,9 @@ ggc_collect ()
   *tp = NULL;
   n_trees_collected += n_trees;
 
-  sp = &strings, s = strings, n_strings = 0;
+  sp = &ggc_chain->strings;
+  s = ggc_chain->strings;
+  n_strings = 0;
   while (s != NULL)
     {
       struct ggc_string *chain = s->chain;
@@ -637,8 +749,10 @@ ggc_collect ()
     }
   *sp = NULL;
   n_strings_collected += n_strings;
+  ggc_chain->bytes_alloced_since_gc = 0;
 
-  gc_time += time = get_run_time () - time;
+  time = get_run_time () - time;
+  gc_time += time;
 
   if (!quiet_flag)
     {
index 5acf3e9c7eb21c910ebaa26aca68b40607d6bc1f..785e25bf80fd2725ee796628da9b6d5320480c00 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -43,6 +43,13 @@ struct hash_table;
 
 extern void init_ggc PROTO ((void));
 
+/* Start a new GGC context.  Memory allocated in previous contexts
+   will not be collected while the new context is active.  */
+extern void ggc_pop_context PROTO ((void));
+/* Finish a GC context.  Any uncollected memory in the new context
+   will be merged with the old context.  */
+extern void ggc_push_context PROTO ((void));
+
 /* Allocation.  */
 
 struct rtx_def *ggc_alloc_rtx PROTO ((int nslots));
index 81219e77de33a62309ef6fa31685708304645e12..df653371326161cbe98007b15da605cffbe158d2 100644 (file)
@@ -270,7 +270,8 @@ print_node (file, prefix, node, indent)
       if (TREE_TYPE (node))
        indent_to (file, indent + 3);
 
-      print_obstack_name ((char *) node, file, "");
+      if (!ggc_p)
+       print_obstack_name ((char *) node, file, "");
       indent_to (file, indent + 3);
     }
 
index 92050e9730576aa2eda48ccf8227d793c0abab62..aef2b70ef2e5b65be24ca3530ddee952543202bc 100644 (file)
@@ -550,6 +550,22 @@ mark_goto_fixup (g)
     }
 }
 
+/* Clear out all parts of the state in F that can safely be discarded
+   after the function has been compiled, to let garbage collection
+   reclaim the memory.  D is the declaration for the function just
+   compiled.  Its output may have been deferred.  */
+
+void
+free_stmt_status (f, d)
+     struct function *f;
+     tree d ATTRIBUTE_UNUSED;
+{
+  /* We're about to free the function obstack.  If we hold pointers to
+     things allocated there, then we'll try to mark them when we do
+     GC.  So, we clear them out here explicitly.  */
+  f->stmt->x_goto_fixup_chain = 0;
+}
+
 /* Mark P for GC.  */
 
 void
@@ -602,6 +618,7 @@ init_stmt_for_function ()
   /* We are not processing a ({...}) grouping.  */
   expr_stmts_for_value = 0;
   last_expr_type = 0;
+  last_expr_value = NULL_RTX;
 
   init_eh_for_function ();
 }
index 68c7458390a48954d72d8e7084ddcadba9ede2f1..73a77bca838588e9e07f41e73e1539e80984b070 100644 (file)
@@ -4466,13 +4466,13 @@ rest_of_compilation (decl)
 
   init_recog_no_volatile ();
 
-  /* We're done with this function.  */
-  if (! DECL_DEFER_OUTPUT (decl))
-    free_after_compilation (current_function);
+  /* We're done with this function.  Free up memory if we can.  */
+  free_after_compilation (current_function, decl);
 
   current_function = 0;
 
-  ggc_collect ();
+  if (ggc_p)
+    ggc_collect ();
 
   /* The parsing time is all the time spent in yyparse
      *except* what is spent in this function.  */
@@ -4793,6 +4793,9 @@ main (argc, argv)
   flag_short_enums = DEFAULT_SHORT_ENUMS;
 #endif
 
+  /* Initialize the garbage-collector.  */
+  if (ggc_p)
+    init_ggc ();
   ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
                &mark_file_stack);
 
index 47db9b0ee9d68c624363cfcd6b20a3cb99e21c0a..f79512311fed6779ca672fb59215cedc7a44c81d 100644 (file)
@@ -476,9 +476,6 @@ push_obstacks (current, saveable)
 {
   struct obstack_stack *p;
 
-  if (ggc_p)
-    return;
-
   p = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
                                              (sizeof (struct obstack_stack)));
 
@@ -501,9 +498,6 @@ push_obstacks_nochange ()
 {
   struct obstack_stack *p;
   
-  if (ggc_p)
-    return;
-
   p = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
                                              (sizeof (struct obstack_stack)));
 
@@ -522,9 +516,6 @@ pop_obstacks ()
 {
   struct obstack_stack *p;
 
-  if (ggc_p)
-    return;
-
   p = obstack_stack;
   obstack_stack = p->next;
 
index 3d18899ebd2c07497e33b68f9ff111d6e64e9917..8c0b5a16faba24d4906669dda9a95e3c3ce71219 100644 (file)
@@ -3210,13 +3210,22 @@ mark_varasm_state (p)
   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.  */
+/* Clear out all parts of the state in F that can safely be discarded
+   after the function has been compiled, to let garbage collection
+   reclaim the memory.  D is the declaration for the function just
+   compiled.  Its output may have been deferred.  */
+
 void
-free_varasm_status (f)
+free_varasm_status (f, d)
      struct function *f;
+     tree d;
 {
-  struct varasm_status *p = f->varasm;
+  struct varasm_status *p;
+
+  if (DECL_DEFER_OUTPUT (d))
+    return;
+
+  p = f->varasm;
   free (p->x_const_rtx_hash_table);
   free (p->x_const_rtx_sym_hash_table);