PATCH for mark functions
Mark Mitchell
mark@codesourcery.com
Sat Sep 4 19:42:00 GMT 1999
This merges the various GC marking functions from the GC branch into
the mainline. I added comments and prototypes, but the real work is
all Richard and Bernd's.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
Sat Sep 4 19:26:25 1999 Richard Henderson <rth@cygnus.com>
Bernd Schmidt <bernds@cygnus.co.uk>
Mark Mitchell <mark@codesourcery.com>
* Makefile.in (tree.o): Depend on ggc.h.
(varasm.o): Likewise.
(function.o): Likewise.
(stmt.o): Likewise.
(except.o): Likewise.
(optabs.o): Likewise.
(emit-rtl.o): Likewise.
* emit-rtl.c: Include ggc.h.
(sequence_element_free_list): Remove, and all references.
(mark_sequence): New functions.
(mark_emit_state): New function.
* except.c: Include ggc.h.
(mark_eh_node, mark_eh_stack, mark_eh_queue): New functions.
(mark_tree_label_node): New functions.
(mark_eh_state): New function.
* function.c: Include ggc.h.
(mark_temp_slot, mark_function_chain): New functions.
(mark_function_state): New function.
(init_function_once): New function.
* function.h (init_function_once): New function.
* ggc-callbacks.c (lang_mark_false_label_stack): New function.
* ggc.h (label_node): Declare.
(eh_status, emit_status, stmt_status, varasm_status): Likewise.
(lang_mark_false_label_stack): New function.
(mark_temp_slot): Remove declaration.
(mark_function_chain): Likewise.
(mark_eh_state): Adjust prototype.
(mark_stmt_state, mark_emit_state, mark_varasm_state, mark_optab):
Likewise.
* optabs.c: Include ggc.h.
(mark_optab): New function.
(init_optabs): Add gc roots.
* stmt.c: Include ggc.h.
(mark_cond_nesting, mark_loop_nesting): New functions.
(mark_block_nesting, mark_case_nesting, mark_goto_fixup): Likewise.
(mark_stmt_state): New function.
* toplev.c (compile_file): Call init_function_once.
* tree.c: Include ggc.h.
(type_hash): Move declaration earlier in file.
(TYPE_HASH_SIZE, type_hash_table): Likewise.
(init_obstacks): Add gc roots.
(mark_type_hash): New function.
* varasm.c: Include ggc.h.
(mark_pool_constant): New function.
(mark_varasm_state): New function.
Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.289
diff -c -p -r1.289 Makefile.in
*** Makefile.in 1999/09/05 01:06:45 1.289
--- Makefile.in 1999/09/05 02:18:56
*************** prefix.o: prefix.c $(CONFIG_H) system.h
*** 1450,1456 ****
convert.o: convert.c $(CONFIG_H) $(TREE_H) flags.h convert.h toplev.h
! tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h
print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H)
stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
function.h $(EXPR_H) $(RTL_H) toplev.h
--- 1450,1457 ----
convert.o: convert.c $(CONFIG_H) $(TREE_H) flags.h convert.h toplev.h
! tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h \
! ggc.h
print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H)
stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
function.h $(EXPR_H) $(RTL_H) toplev.h
*************** errors.o : errors.c $(CONFIG_H) system.h
*** 1473,1488 ****
varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
function.h defaults.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
! xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h
function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
! insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h
stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \
! loop.h $(RECOG_H) toplev.h output.h varray.h
except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
! insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h
expr.o : expr.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
$(REGS_H) insn-flags.h insn-codes.h $(EXPR_H) insn-config.h $(RECOG_H) \
output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h
--- 1474,1489 ----
varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
function.h defaults.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
! xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h ggc.h
function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
! insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h ggc.h
stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \
! loop.h $(RECOG_H) toplev.h output.h varray.h ggc.h
except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \
! insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h ggc.h
expr.o : expr.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \
$(REGS_H) insn-flags.h insn-codes.h $(EXPR_H) insn-config.h $(RECOG_H) \
output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h
*************** explow.o : explow.c $(CONFIG_H) system.h
*** 1499,1505 ****
insn-codes.h toplev.h
optabs.o : optabs.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h \
! toplev.h
dbxout.o : dbxout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h $(REGS_H) \
insn-config.h reload.h gstab.h xcoffout.h defaults.h output.h dbxout.h \
toplev.h
--- 1500,1506 ----
insn-codes.h toplev.h
optabs.o : optabs.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h \
! toplev.h ggc.h
dbxout.o : dbxout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h $(REGS_H) \
insn-config.h reload.h gstab.h xcoffout.h defaults.h output.h dbxout.h \
toplev.h
*************** dwarf2out.o : dwarf2out.c $(CONFIG_H) sy
*** 1515,1521 ****
xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
flags.h toplev.h output.h dbxout.h
emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
! function.h $(REGS_H) insn-config.h $(RECOG_H) real.h \
$(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h
real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.h
--- 1516,1522 ----
xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
flags.h toplev.h output.h dbxout.h
emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
! function.h $(REGS_H) insn-config.h $(RECOG_H) real.h ggc.h \
$(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h
real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.h
Index: emit-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/emit-rtl.c,v
retrieving revision 1.78
diff -c -p -r1.78 emit-rtl.c
*** emit-rtl.c 1999/09/05 01:06:45 1.78
--- emit-rtl.c 1999/09/05 02:19:01
*************** Boston, MA 02111-1307, USA. */
*** 49,54 ****
--- 49,55 ----
#include "real.h"
#include "obstack.h"
#include "bitmap.h"
+ #include "ggc.h"
/* Commonly used modes. */
*************** static rtx free_insn;
*** 187,192 ****
--- 188,194 ----
static rtx make_jump_insn_raw PROTO((rtx));
static rtx make_call_insn_raw PROTO((rtx));
static rtx find_line_note PROTO((rtx));
+ static void mark_sequence_stack PROTO((struct sequence_stack *));
rtx
gen_rtx_CONST_INT (mode, arg)
*************** init_emit ()
*** 3465,3470 ****
--- 3467,3507 ----
#ifdef INIT_EXPANDERS
INIT_EXPANDERS;
#endif
+ }
+
+ /* Mark SS for GC. */
+
+ static void
+ mark_sequence_stack (ss)
+ struct sequence_stack *ss;
+ {
+ while (ss)
+ {
+ ggc_mark_rtx (ss->first);
+ ggc_mark_tree (ss->sequence_rtl_expr);
+ ss = ss->next;
+ }
+ }
+
+ /* Mark ES for GC. */
+
+ void
+ mark_emit_state (es)
+ struct emit_status *es;
+ {
+ rtx *r;
+ int i;
+
+ if (es == 0)
+ return;
+
+ for (i = es->regno_pointer_flag_length, r = es->x_regno_reg_rtx;
+ i > 0; --i, ++r)
+ ggc_mark_rtx (*r);
+
+ mark_sequence_stack (es->sequence_stack);
+ ggc_mark_tree (es->sequence_rtl_expr);
+ ggc_mark_rtx (es->x_first_insn);
}
/* Create some permanent unique rtl objects shared between all functions.
Index: except.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.90
diff -c -p -r1.90 except.c
*** except.c 1999/09/02 17:29:18 1.90
--- except.c 1999/09/05 02:19:03
*************** Boston, MA 02111-1307, USA. */
*** 408,413 ****
--- 408,414 ----
#include "toplev.h"
#include "intl.h"
#include "obstack.h"
+ #include "ggc.h"
/* One to use setjmp/longjmp method of generating code for exception
handling. */
*************** static void set_insn_eh_region PROTO((rt
*** 467,472 ****
--- 468,477 ----
#ifdef DONT_USE_BUILTIN_SETJMP
static void jumpif_rtx PROTO((rtx, rtx));
#endif
+ static void mark_eh_node PROTO((struct eh_node *));
+ static void mark_eh_stack PROTO((struct eh_stack *));
+ static void mark_eh_queue PROTO((struct eh_queue *));
+ static void mark_tree_label_node PROTO ((struct label_node *));
rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
*************** check_exception_handler_labels ()
*** 2333,2339 ****
}
}
!
/* This group of functions initializes the exception handling data
structures at the start of the compilation, initializes the data
structures at the start of a function, and saves and restores the
--- 2338,2413 ----
}
}
!
! /* Mark the children of NODE for GC. */
!
! static void
! mark_eh_node (node)
! struct eh_node *node;
! {
! while (node)
! {
! if (node->entry)
! {
! ggc_mark_rtx (node->entry->outer_context);
! ggc_mark_rtx (node->entry->exception_handler_label);
! ggc_mark_tree (node->entry->finalization);
! }
! node = node ->chain;
! }
! }
!
! /* Mark S for GC. */
!
! static void
! mark_eh_stack (s)
! struct eh_stack *s;
! {
! if (s)
! mark_eh_node (s->top);
! }
!
! /* Mark Q for GC. */
!
! static void
! mark_eh_queue (q)
! struct eh_queue *q;
! {
! if (q)
! mark_eh_node (q->head);
! }
!
! /* Mark NODE for GC. A label_node contains a union containing either
! a tree or an rtx. This label_node will contain a tree. */
!
! static void
! mark_tree_label_node (node)
! struct label_node *node;
! {
! while (node)
! {
! ggc_mark_tree (node->u.tlabel);
! node = node->chain;
! }
! }
!
! /* Mark EH for GC. */
!
! void
! mark_eh_state (eh)
! struct eh_status *eh;
! {
! mark_eh_stack (&eh->x_ehstack);
! mark_eh_queue (&eh->x_ehqueue);
! ggc_mark_rtx (eh->x_catch_clauses);
!
! lang_mark_false_label_stack (eh->x_false_label_stack);
! mark_tree_label_node (eh->x_caught_return_label_stack);
!
! ggc_mark_tree (eh->x_protect_list);
! ggc_mark_rtx (eh->ehc);
! }
!
/* This group of functions initializes the exception handling data
structures at the start of the compilation, initializes the data
structures at the start of a function, and saves and restores the
Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.103
diff -c -p -r1.103 function.c
*** function.c 1999/09/05 01:06:45 1.103
--- function.c 1999/09/05 02:19:07
*************** Boston, MA 02111-1307, USA. */
*** 57,62 ****
--- 57,63 ----
#include "obstack.h"
#include "toplev.h"
#include "hash.h"
+ #include "ggc.h"
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
*************** static unsigned long insns_for_mem_hash
*** 272,277 ****
--- 273,281 ----
static boolean insns_for_mem_comp PROTO ((hash_table_key, hash_table_key));
static int insns_for_mem_walk PROTO ((rtx *, void *));
static void compute_insns_for_mem PROTO ((rtx, rtx, struct hash_table *));
+ static void mark_temp_slot PROTO ((struct temp_slot *));
+ static void mark_function_state PROTO ((struct function *));
+ static void mark_function_chain PROTO ((void *));
/* Pointer to chain of `struct function' for containing functions. */
*************** reposition_prologue_and_epilogue_notes (
*** 6636,6639 ****
--- 6648,6764 ----
}
}
#endif /* HAVE_prologue or HAVE_epilogue */
+ }
+
+ /* Mark T for GC. */
+
+ static void
+ mark_temp_slot (t)
+ struct temp_slot *t;
+ {
+ while (t)
+ {
+ ggc_mark_rtx (t->slot);
+ ggc_mark_rtx (t->address);
+ ggc_mark_tree (t->rtl_expr);
+
+ t = t->next;
+ }
+ }
+
+ /* Mark P for GC. */
+
+ static void
+ mark_function_state (p)
+ struct function *p;
+ {
+ int i;
+ rtx *r;
+
+ if (p == 0)
+ return;
+
+ ggc_mark_rtx (p->arg_offset_rtx);
+
+ for (i = p->x_max_parm_reg, r = p->x_parm_reg_stack_loc;
+ i > 0; --i, ++r)
+ ggc_mark_rtx (*r);
+
+ ggc_mark_rtx (p->return_rtx);
+ ggc_mark_rtx (p->x_cleanup_label);
+ ggc_mark_rtx (p->x_return_label);
+ ggc_mark_rtx (p->x_save_expr_regs);
+ ggc_mark_rtx (p->x_stack_slot_list);
+ ggc_mark_rtx (p->x_parm_birth_insn);
+ ggc_mark_rtx (p->x_tail_recursion_label);
+ ggc_mark_rtx (p->x_tail_recursion_reentry);
+ ggc_mark_rtx (p->internal_arg_pointer);
+ ggc_mark_rtx (p->x_arg_pointer_save_area);
+ ggc_mark_tree (p->x_rtl_expr_chain);
+ ggc_mark_rtx (p->x_last_parm_insn);
+ ggc_mark_tree (p->x_context_display);
+ ggc_mark_tree (p->x_trampoline_list);
+ ggc_mark_rtx (p->epilogue_delay_list);
+
+ mark_temp_slot (p->x_temp_slots);
+
+ {
+ struct var_refs_queue *q = p->fixup_var_refs_queue;
+ while (q)
+ {
+ ggc_mark_rtx (q->modified);
+ q = q->next;
+ }
+ }
+
+ ggc_mark_rtx (p->x_nonlocal_goto_handler_slots);
+ ggc_mark_rtx (p->x_nonlocal_goto_stack_level);
+ ggc_mark_tree (p->x_nonlocal_labels);
+ }
+
+ /* Mark the function chain ARG (which is really a struct function **)
+ for GC. */
+
+ static void
+ mark_function_chain (arg)
+ void *arg;
+ {
+ struct function *f = *(struct function **) arg;
+
+ for (; f; f = f->next_global)
+ {
+ if (f->can_garbage_collect)
+ continue;
+
+ ggc_mark_tree (f->decl);
+
+ mark_function_state (f);
+ mark_stmt_state (f->stmt);
+ mark_eh_state (f->eh);
+ mark_emit_state (f->emit);
+ mark_varasm_state (f->varasm);
+
+ ggc_mark_rtx (f->expr->x_saveregs_value);
+ ggc_mark_rtx (f->expr->x_apply_args_value);
+ ggc_mark_rtx (f->expr->x_forced_labels);
+
+ if (mark_machine_status)
+ (*mark_machine_status) (f);
+ if (mark_lang_status)
+ (*mark_lang_status) (f);
+
+ if (f->original_arg_vector)
+ ggc_mark_rtvec ((rtvec) f->original_arg_vector);
+ if (f->original_decl_initial)
+ ggc_mark_tree (f->original_decl_initial);
+ }
+ }
+
+ /* Called once, at initialization, to initialize function.c. */
+
+ void
+ init_function_once ()
+ {
+ ggc_add_root (&all_functions, 1, sizeof all_functions,
+ mark_function_chain);
}
Index: function.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.h,v
retrieving revision 1.27
diff -c -p -r1.27 function.h
*** function.h 1999/09/05 01:06:46 1.27
--- function.h 1999/09/05 02:19:08
*************** extern rtx get_first_block_beg PROTO((v
*** 558,563 ****
--- 558,566 ----
extern void init_virtual_regs PROTO((struct emit_status *));
+ /* Called once, at initialization, to initialize function.c. */
+ extern void init_function_once PROTO((void));
+
#ifdef rtx
#undef rtx
#endif
Index: ggc-callbacks.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc-callbacks.c,v
retrieving revision 1.1
diff -c -p -r1.1 ggc-callbacks.c
*** ggc-callbacks.c 1999/09/04 22:34:20 1.1
--- ggc-callbacks.c 1999/09/05 02:19:08
*************** lang_cleanup_tree (t)
*** 41,43 ****
--- 41,52 ----
only included in compilers for languages that don't support GC. */
abort ();
}
+
+ void
+ lang_mark_false_label_stack (l)
+ struct label_node *l ATTRIBUTE_UNUSED;
+ {
+ /* If this function is called, we are doing GC. But, this file is
+ only included in compilers for languages that don't support GC. */
+ abort ();
+ }
Index: ggc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/ggc.h,v
retrieving revision 1.2
diff -c -p -r1.2 ggc.h
*** ggc.h 1999/09/04 18:25:41 1.2
--- ggc.h 1999/09/05 02:19:08
***************
*** 23,28 ****
--- 23,38 ----
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
an external gc library that might be linked in. */
+ /* These structures are defined in various headers throughout the
+ compiler. However, rather than force everyone who includes this
+ header to include all the headers in which they are declared, we
+ just forward-declare them here. */
+ struct label_node;
+ struct eh_status;
+ struct emit_status;
+ struct stmt_status;
+ struct varasm_status;
+
/* Startup */
extern void init_ggc PROTO ((void));
*************** void lang_mark_tree PROTO ((union tree_n
*** 61,72 ****
/* And similarly to free that data when the tree node is released. */
void lang_cleanup_tree PROTO ((union tree_node *));
/* Mark functions for various structs scattered about. */
! void mark_temp_slot PROTO ((void *));
! void mark_function_chain PROTO ((void *));
! void mark_eh_state PROTO ((void *));
! void mark_stmt_state PROTO ((void *));
! void mark_emit_state PROTO ((void *));
! void mark_varasm_state PROTO ((void *));
void mark_optab PROTO ((void *));
--- 71,85 ----
/* And similarly to free that data when the tree node is released. */
void lang_cleanup_tree PROTO ((union tree_node *));
+ /* The FALSE_LABEL_STACK, declared in except.h, has
+ language-dependent semantics. Each front-end should define this
+ function appropriately. */
+ void lang_mark_false_label_stack PROTO ((struct label_node *));
+
/* Mark functions for various structs scattered about. */
! void mark_eh_state PROTO ((struct eh_status *));
! void mark_stmt_state PROTO ((struct stmt_status *));
! void mark_emit_state PROTO ((struct emit_status *));
! void mark_varasm_state PROTO ((struct varasm_status *));
void mark_optab PROTO ((void *));
Index: optabs.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/optabs.c,v
retrieving revision 1.44
diff -c -p -r1.44 optabs.c
*** optabs.c 1999/09/04 22:08:44 1.44
--- optabs.c 1999/09/05 02:19:10
*************** Boston, MA 02111-1307, USA. */
*** 35,40 ****
--- 35,41 ----
#include "expr.h"
#include "recog.h"
#include "reload.h"
+ #include "ggc.h"
/* Each optab contains info on how this target machine
can perform a particular operation
*************** init_floating_libfuncs (optable, opname,
*** 4342,4348 ****
--- 4343,4361 ----
init_libfuncs (optable, SFmode, TFmode, opname, suffix);
}
+ /* Mark ARG (which is really an OPTAB *) for GC. */
+ void
+ mark_optab (arg)
+ void *arg;
+ {
+ optab o = *(optab *) arg;
+ int i;
+
+ for (i = 0; i < NUM_MACHINE_MODES; ++i)
+ ggc_mark_rtx (o->handlers[i].libfunc);
+ }
+
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
*************** init_optabs ()
*** 4679,4684 ****
--- 4692,4701 ----
/* Allow the target to add more libcalls or rename some, etc. */
INIT_TARGET_OPTABS;
#endif
+
+ /* Add these GC roots. */
+ ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
+ ggc_add_rtx_root (libfunc_table, LTI_MAX);
}
#ifdef BROKEN_LDEXP
Index: stmt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/stmt.c,v
retrieving revision 1.83
diff -c -p -r1.83 stmt.c
*** stmt.c 1999/09/03 23:22:49 1.83
--- stmt.c 1999/09/05 02:19:14
*************** Boston, MA 02111-1307, USA. */
*** 52,57 ****
--- 52,58 ----
#include "machmode.h"
#include "toplev.h"
#include "output.h"
+ #include "ggc.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
*************** static void emit_jump_if_reachable PROTO
*** 425,435 ****
--- 426,575 ----
static void emit_case_nodes PROTO((rtx, case_node_ptr, rtx, tree));
static int add_case_node PROTO((tree, tree, tree, tree *));
static struct case_node *case_tree2list PROTO((case_node *, case_node *));
+ static void mark_cond_nesting PROTO((struct nesting *));
+ static void mark_loop_nesting PROTO((struct nesting *));
+ static void mark_block_nesting PROTO((struct nesting *));
+ static void mark_case_nesting PROTO((struct nesting *));
+ static void mark_goto_fixup PROTO((struct goto_fixup *));
+
void
using_eh_for_cleanups ()
{
using_eh_for_cleanups_p = 1;
+ }
+
+ /* Mark N (known to be a cond-nesting) for GC. */
+
+ static void
+ mark_cond_nesting (n)
+ struct nesting *n;
+ {
+ while (n)
+ {
+ ggc_mark_rtx (n->exit_label);
+ ggc_mark_rtx (n->data.cond.endif_label);
+ ggc_mark_rtx (n->data.cond.next_label);
+
+ n = n->next;
+ }
+ }
+
+ /* Mark N (known to be a loop-nesting) for GC. */
+
+ static void
+ mark_loop_nesting (n)
+ struct nesting *n;
+ {
+
+ while (n)
+ {
+ ggc_mark_rtx (n->exit_label);
+ ggc_mark_rtx (n->data.loop.start_label);
+ ggc_mark_rtx (n->data.loop.end_label);
+ ggc_mark_rtx (n->data.loop.alt_end_label);
+ ggc_mark_rtx (n->data.loop.continue_label);
+
+ n = n->next;
+ }
+ }
+
+ /* Mark N (known to be a block-nesting) for GC. */
+
+ static void
+ mark_block_nesting (n)
+ struct nesting *n;
+ {
+ while (n)
+ {
+ struct label_chain *l;
+
+ ggc_mark_rtx (n->exit_label);
+ ggc_mark_rtx (n->data.block.stack_level);
+ ggc_mark_rtx (n->data.block.first_insn);
+ ggc_mark_tree (n->data.block.cleanups);
+ ggc_mark_tree (n->data.block.outer_cleanups);
+
+ for (l = n->data.block.label_chain; l != NULL; l = l->next)
+ ggc_mark_tree (l->label);
+
+ ggc_mark_rtx (n->data.block.last_unconditional_cleanup);
+
+ /* ??? cleanup_ptr never points outside the stack, does it? */
+
+ n = n->next;
+ }
+ }
+
+ /* Mark N (known to be a case-nesting) for GC. */
+
+ static void
+ mark_case_nesting (n)
+ struct nesting *n;
+ {
+ while (n)
+ {
+ struct case_node *node;
+
+ ggc_mark_rtx (n->exit_label);
+ ggc_mark_rtx (n->data.case_stmt.start);
+
+ node = n->data.case_stmt.case_list;
+ while (node)
+ {
+ ggc_mark_tree (node->low);
+ ggc_mark_tree (node->high);
+ ggc_mark_tree (node->code_label);
+ node = node->right;
+ }
+
+ ggc_mark_tree (n->data.case_stmt.default_label);
+ ggc_mark_tree (n->data.case_stmt.index_expr);
+ ggc_mark_tree (n->data.case_stmt.nominal_type);
+
+ n = n->next;
+ }
+ }
+
+ /* Mark G for GC. */
+
+ static void
+ mark_goto_fixup (g)
+ struct goto_fixup *g;
+ {
+ while (g)
+ {
+ ggc_mark_rtx (g->before_jump);
+ ggc_mark_tree (g->target);
+ ggc_mark_tree (g->context);
+ ggc_mark_rtx (g->target_rtl);
+ ggc_mark_rtx (g->stack_level);
+ ggc_mark_tree (g->cleanup_list_list);
+
+ g = g->next;
+ }
+ }
+
+ /* Mark P for GC. */
+
+ void
+ mark_stmt_state (p)
+ struct stmt_status *p;
+ {
+ if (p == 0)
+ return;
+
+ mark_block_nesting (p->x_block_stack);
+ mark_cond_nesting (p->x_cond_stack);
+ mark_loop_nesting (p->x_loop_stack);
+ mark_case_nesting (p->x_case_stack);
+
+ ggc_mark_tree (p->x_last_expr_type);
+ /* last_epxr_value is only valid if last_expr_type is nonzero. */
+ if (p->x_last_expr_type)
+ ggc_mark_rtx (p->x_last_expr_value);
+
+ mark_goto_fixup (p->x_goto_fixup_chain);
}
void
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.206
diff -c -p -r1.206 toplev.c
*** toplev.c 1999/09/05 01:06:46 1.206
--- toplev.c 1999/09/05 02:19:17
*************** compile_file (name)
*** 2935,2940 ****
--- 2935,2941 ----
init_loop ();
init_reload ();
init_alias_once ();
+ init_function_once ();
/* The following initialization functions need to generate rtl, so
provide a dummy function context for them. */
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.c,v
retrieving revision 1.77
diff -c -p -r1.77 tree.c
*** tree.c 1999/09/04 13:09:55 1.77
--- tree.c 1999/09/05 02:19:20
*************** Boston, MA 02111-1307, USA. */
*** 40,45 ****
--- 40,46 ----
#include "function.h"
#include "obstack.h"
#include "toplev.h"
+ #include "ggc.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
*************** int (*lang_get_alias_set) PROTO((tree));
*** 247,255 ****
--- 248,277 ----
codes are made. */
#define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777)
+ /* Each hash table slot is a bucket containing a chain
+ of these structures. */
+
+ struct type_hash
+ {
+ struct type_hash *next; /* Next structure in the bucket. */
+ int hashcode; /* Hash code of this type. */
+ tree type; /* The type recorded here. */
+ };
+
+ /* Now here is the hash table. When recording a type, it is added
+ to the slot whose index is the hash code mod the table size.
+ Note that the hash table is used for several kinds of types
+ (function types, array types and array index range types, for now).
+ While all these live in the same table, they are completely independent,
+ and the hash code is computed differently for each of these. */
+
+ #define TYPE_HASH_SIZE 59
+ struct type_hash *type_hash_table[TYPE_HASH_SIZE];
+
static void set_type_quals PROTO((tree, int));
static void append_random_chars PROTO((char *));
static void build_real_from_int_cst_1 PROTO((PTR));
+ static void mark_type_hash PROTO ((void *));
void gcc_obstack_init ();
*************** init_obstacks ()
*** 284,289 ****
--- 306,316 ----
/* Init the hash table of identifiers. */
bzero ((char *) hash_table, sizeof hash_table);
+
+ ggc_add_tree_root (hash_table, MAX_HASH_TABLE);
+ ggc_add_root (type_hash_table, TYPE_HASH_SIZE,
+ sizeof(struct type_hash *),
+ mark_type_hash);
}
void
*************** build_type_copy (type)
*** 3587,3612 ****
/* Hashing of types so that we don't make duplicates.
The entry point is `type_hash_canon'. */
- /* Each hash table slot is a bucket containing a chain
- of these structures. */
-
- struct type_hash
- {
- struct type_hash *next; /* Next structure in the bucket. */
- int hashcode; /* Hash code of this type. */
- tree type; /* The type recorded here. */
- };
-
- /* Now here is the hash table. When recording a type, it is added
- to the slot whose index is the hash code mod the table size.
- Note that the hash table is used for several kinds of types
- (function types, array types and array index range types, for now).
- While all these live in the same table, they are completely independent,
- and the hash code is computed differently for each of these. */
-
- #define TYPE_HASH_SIZE 59
- struct type_hash *type_hash_table[TYPE_HASH_SIZE];
-
/* Compute a hash code for a list of types (chain of TREE_LIST nodes
with types in the TREE_VALUE slots), by adding the hash codes
of the individual types. */
--- 3614,3619 ----
*************** type_hash_canon (hashcode, type)
*** 3712,3717 ****
--- 3719,3739 ----
type_hash_add (hashcode, type);
return type;
+ }
+
+ /* Mark ARG (which is really a struct type_hash **) for GC. */
+
+ static void
+ mark_type_hash (arg)
+ void *arg;
+ {
+ struct type_hash *t = *(struct type_hash **) arg;
+
+ while (t)
+ {
+ ggc_mark_tree (t->type);
+ t = t->next;
+ }
}
/* Compute a hash code for a list of attributes (chain of TREE_LIST nodes
Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.74
diff -c -p -r1.74 varasm.c
*** varasm.c 1999/09/05 01:06:46 1.74
--- varasm.c 1999/09/05 02:19:22
*************** Boston, MA 02111-1307, USA. */
*** 46,51 ****
--- 46,52 ----
#include "obstack.h"
#include "c-pragma.h"
+ #include "ggc.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
*************** static void asm_output_bss PROTO((FILE
*** 186,191 ****
--- 187,193 ----
static void asm_output_aligned_bss PROTO((FILE *, tree, char *, int, int));
#endif
#endif /* BSS_SECTION_ASM_OP */
+ static void mark_pool_constant PROTO((struct pool_constant *));
static enum in_section { no_section, in_text, in_data, in_named
#ifdef BSS_SECTION_ASM_OP
*************** init_varasm_status (f)
*** 3184,3189 ****
--- 3186,3214 ----
p->x_first_pool = p->x_last_pool = 0;
p->x_pool_offset = 0;
p->x_const_double_chain = 0;
+ }
+
+ /* Mark PC for GC. */
+
+ static void
+ mark_pool_constant (pc)
+ struct pool_constant *pc;
+ {
+ while (pc)
+ {
+ ggc_mark_rtx (pc->constant);
+ pc = pc->next;
+ }
+ }
+
+ /* Mark P for GC. */
+
+ void
+ mark_varasm_state (p)
+ struct varasm_status *p;
+ {
+ mark_pool_constant (p->x_first_pool);
+ ggc_mark_rtx (p->x_const_double_chain);
}
/* Clear out all parts of our state in F that can safely be discarded
More information about the Gcc-patches
mailing list