diff options
-rw-r--r-- | gcc/ChangeLog | 47 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 13 | ||||
-rw-r--r-- | gcc/except.c | 42 | ||||
-rw-r--r-- | gcc/function.c | 27 | ||||
-rw-r--r-- | gcc/function.h | 11 | ||||
-rw-r--r-- | gcc/ggc-simple.c | 186 | ||||
-rw-r--r-- | gcc/ggc.h | 7 | ||||
-rw-r--r-- | gcc/print-tree.c | 3 | ||||
-rw-r--r-- | gcc/stmt.c | 17 | ||||
-rw-r--r-- | gcc/toplev.c | 11 | ||||
-rw-r--r-- | gcc/tree.c | 9 | ||||
-rw-r--r-- | gcc/varasm.c | 17 |
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); |