summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog47
-rw-r--r--gcc/emit-rtl.c13
-rw-r--r--gcc/except.c42
-rw-r--r--gcc/function.c27
-rw-r--r--gcc/function.h11
-rw-r--r--gcc/ggc-simple.c186
-rw-r--r--gcc/ggc.h7
-rw-r--r--gcc/print-tree.c3
-rw-r--r--gcc/stmt.c17
-rw-r--r--gcc/toplev.c11
-rw-r--r--gcc/tree.c9
-rw-r--r--gcc/varasm.c17
12 files changed, 317 insertions, 73 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a2e2ef556c0..5bc407cec57 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 5a4b5f2f02a..9837b6811b0 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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);
diff --git a/gcc/except.c b/gcc/except.c
index 05480067779..4bb2adb9e70 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -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));
@@ -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
diff --git a/gcc/function.c b/gcc/function.c
index b83a7c421d2..4ce2dd5591b 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
+ }
}
/* 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);
diff --git a/gcc/function.h b/gcc/function.h
index 966b3f74e47..76ee362734d 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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 *));
diff --git a/gcc/ggc-simple.c b/gcc/ggc-simple.c
index 60da127e7f2..41363bc6d30 100644
--- a/gcc/ggc-simple.c
+++ b/gcc/ggc-simple.c
@@ -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)
{
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 5acf3e9c7eb..785e25bf80f 100644
--- 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));
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 81219e77de3..df653371326 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -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);
}
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 92050e97305..aef2b70ef2e 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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 ();
}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 68c7458390a..73a77bca838 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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);
diff --git a/gcc/tree.c b/gcc/tree.c
index 47db9b0ee9d..f79512311fe 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 3d18899ebd2..8c0b5a16fab 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -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);