]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Merge from pch-branch up to tag pch-commit-20020603.
authorGeoffrey Keating <geoffk@redhat.com>
Tue, 4 Jun 2002 07:11:05 +0000 (07:11 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Tue, 4 Jun 2002 07:11:05 +0000 (07:11 +0000)
From-SVN: r54232

182 files changed:
gcc/.cvsignore
gcc/ChangeLog
gcc/Makefile.in
gcc/ada/ChangeLog
gcc/ada/Make-lang.in
gcc/ada/ada-tree.h
gcc/ada/config-lang.in
gcc/ada/decl.c
gcc/ada/gigi.h
gcc/ada/gnat_rm.texi
gcc/ada/misc.c
gcc/ada/prj-makr.adb
gcc/ada/prj-makr.ads
gcc/ada/prj-pp.adb
gcc/ada/prj-pp.ads
gcc/ada/trans.c
gcc/ada/utils.c
gcc/ada/utils2.c
gcc/alias.c
gcc/basic-block.h
gcc/bitmap.c
gcc/bitmap.h
gcc/c-common.c
gcc/c-common.h
gcc/c-decl.c
gcc/c-lang.c
gcc/c-objc-common.c
gcc/c-parse.in
gcc/c-pragma.c
gcc/c-tree.h
gcc/config/alpha/alpha.c
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/c4x/c4x-protos.h
gcc/config/c4x/c4x.c
gcc/config/cris/cris.c
gcc/config/cris/t-cris
gcc/config/d30v/d30v-protos.h
gcc/config/d30v/d30v.c
gcc/config/d30v/d30v.h
gcc/config/darwin-protos.h
gcc/config/darwin.c
gcc/config/dsp16xx/dsp16xx.c
gcc/config/dsp16xx/dsp16xx.h
gcc/config/i386/i386.c
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/m68hc11/m68hc11-protos.h
gcc/config/m68hc11/m68hc11.c
gcc/config/mcore/mcore-protos.h
gcc/config/mcore/mcore.c
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.h
gcc/config/mn10200/mn10200.c
gcc/config/mn10200/mn10200.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/t-darwin
gcc/config/sh/sh.c
gcc/config/sh/t-sh
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/xtensa/t-xtensa
gcc/config/xtensa/xtensa.c
gcc/configure
gcc/configure.in
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/config-lang.in
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl.h
gcc/cp/decl2.c
gcc/cp/lex.c
gcc/cp/lex.h
gcc/cp/mangle.c
gcc/cp/parse.y
gcc/cp/pt.c
gcc/cp/repo.c
gcc/cp/search.c
gcc/cp/semantics.c
gcc/cp/spew.c
gcc/cp/tree.c
gcc/cselib.c
gcc/cselib.h
gcc/dependence.c
gcc/doc/gccint.texi
gcc/doc/gty.texi [new file with mode: 0644]
gcc/doc/tm.texi
gcc/dwarf2asm.c
gcc/dwarf2out.c
gcc/emit-rtl.c
gcc/except.c
gcc/explow.c
gcc/expr.c
gcc/expr.h
gcc/f/ChangeLog
gcc/f/Make-lang.in
gcc/f/com.c
gcc/f/com.h
gcc/f/config-lang.in
gcc/f/ste.c
gcc/f/where.c
gcc/final.c
gcc/fold-const.c
gcc/function.c
gcc/function.h
gcc/gcse.c
gcc/gengtype-lex.l [new file with mode: 0644]
gcc/gengtype-yacc.y [new file with mode: 0644]
gcc/gengtype.c [new file with mode: 0644]
gcc/gengtype.h [new file with mode: 0644]
gcc/ggc-common.c
gcc/ggc-none.c
gcc/ggc.h
gcc/hash.c [deleted file]
gcc/hash.h [deleted file]
gcc/hashtable.h
gcc/insn-addr.h
gcc/integrate.c
gcc/integrate.h
gcc/java/ChangeLog
gcc/java/Make-lang.in
gcc/java/builtins.c
gcc/java/check-init.c
gcc/java/class.c
gcc/java/config-lang.in
gcc/java/constants.c
gcc/java/decl.c
gcc/java/expr.c
gcc/java/java-tree.h
gcc/java/jcf-parse.c
gcc/java/jcf-write.c
gcc/java/lang.c
gcc/java/mangle.c
gcc/java/parse.y
gcc/langhooks-def.h
gcc/langhooks.h
gcc/libfuncs.h
gcc/lists.c
gcc/mkconfig.sh
gcc/objc/Make-lang.in
gcc/objc/config-lang.in
gcc/objc/objc-act.c
gcc/objc/objc-act.h
gcc/objc/objc-lang.c
gcc/optabs.c
gcc/optabs.h
gcc/output.h
gcc/profile.c
gcc/real.h
gcc/reg-stack.c
gcc/regclass.c
gcc/rtl.h
gcc/sdbout.c
gcc/ssa-dce.c
gcc/ssa.c
gcc/ssa.h
gcc/stmt.c
gcc/stor-layout.c
gcc/stringpool.c
gcc/system.h
gcc/tlink.c
gcc/toplev.c
gcc/tree-inline.c
gcc/tree.c
gcc/tree.h
gcc/varasm.c
gcc/varray.c
gcc/varray.h
include/ChangeLog
include/hashtab.h
libiberty/ChangeLog
libiberty/hashtab.c

index 85d00a50a0c4b6f0a64eb1ab78d940fb648d6756..f8fdbf661ae637b94f4633bf53576072e847d45d 100644 (file)
@@ -4,3 +4,6 @@ c-parse.c
 tradcif.c
 cscope.files
 cscope.out
+gengtype-lex.c
+gengtype-yacc.c
+gengtype-yacc.h
index db487f90ccb67d0295c712de219adb0f4a26dbea..ea60f963b3cec1042b236dc6fd5dbd0aa1bd501d 100644 (file)
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       Merge from pch-branch:
+       
+       * gengtype.h (UNION_OR_STRUCT_P): New macro.
+       * gengtype.c (write_gc_structure_fields): Use it.
+       (write_gc_root): Use it here too.
+
+       * gengtype.c (write_gc_structure_fields): Assume that lengths
+       of typenames fit into an 'int'; don't pass a size_t to "%d" in
+       printf.
+       (write_gc_marker_routine_for_structure): Likewise.
+       (write_gc_types): Likewise.
+       (write_gc_root): Likewise.
+
+       * varray.h (VARRAY_CLEAR): New.
+       (varray_clear): Prototype.
+       * varray.c (varray_clear): New.
+       * cselib.c (reg_values_old): New.
+       (used_regs_old): New.
+       (cselib_init): Use cached varrays if available to avoid
+       generating large amounts of garbage.
+       (cselib_finish): Don't throw away old varrays.
+
+       * final.c (insn_addresses_): Move out of ifdef.
+
+       * varray.c (uses_ggc): Make more varray kinds GCable.
+       * varray.h (union varray_data_tag): Let gengtype see
+       fields 'generic' and 'te'.
+       * reg-stack.c: Include gt-reg-stack.h, ggc.h.
+       (stack_regs_mentioned_data): Move out of ifdef; mark with gengtype.
+       (reg_to_stack): Don't call VARRAY_FREE.
+       * insn-addr.h (INSN_ADDRESSES_FREE): Don't use VARRAY_FREE.
+       (insn_addresses_): Use gengtype to mark.
+       * gengtype.c (write_gc_structure_fields): Handle arrays of generic
+       pointers; handle generic pointers in unused union fields.
+       (get_output_file_with_visibility): Include cselib.h,
+       insn-addr.h in gtype-desc.c.
+       * function.c (prologue): Use gengtype to mark.
+       (epilogue): Likewise.
+       (sibcall_epilogue): Likewise.
+       * dependence.c: Include gt-dependence.h, ggc.h.
+       (struct def_use): Use gengtype to mark.
+       (struct loop): Likewise.
+       (struct induction): Likewise.
+       (struct dependence): Likewise.
+       (def_use_chain): Likewise.
+       (dep_chain): Likewise.
+       (loop_chain): Likewise.
+       (induction_chain): Likewise.
+       (init_dependence_analysis): Don't free anything, just clear pointers.
+       (build_def_use): Use GGC to allocate def_use.
+       (add_loop): Use GGC to allocate loop.
+       (find_induction_variable): Use GGC to allocate induction.
+       (check_node_dependence): Use GGC to allocate induction, dependence.
+       (dump_node_dependence): Don't free varrays.
+       (end_dependence_analysis): Likewise.
+       * cselib.h (struct cselib_val_struct): Use gengtype to mark.
+       (struct elt_loc_list): Likewise.
+       (struct elt_list): Likewise.
+       * cselib.c: Don't include obstack.h.
+       (hash_table): Use gengtype to mark.
+       (reg_values): Use gengtype to mark.
+       (used_regs): Use gengtype to mark.
+       (cselib_obstack): Delete.
+       (cselib_startobj): Delete.
+       (empty_vals): Mark as deletable.
+       (empty_elt_lists): Mark as deletable.
+       (empty_elt_loc_lists): Mark as deletable.
+       (new_elt_list): Use GGC to allocate struct elt_list.
+       (new_elt_loc_list): Use GGC to allocate struct elt_loc_list.
+       (clear_table): Don't delete obstack; don't unnecessarily clear
+       deletable variables.
+       (new_cselib_val): Use GGC to allocate struct cselib_val.
+       (cselib_init): Don't set up obstacks.  Use GGC to allocate
+       hash table.
+       (cselib_finish): Just clear variables, don't free anything.
+       * Makefile.in (cselib.o): Remove dependency on $(OBSTACK_H).
+       (reg-stack.o): Add dependency on gt-reg-stack.h, $(GGC_H).
+       (dependence.o): Add dependency on gt-dependence.h, $(GGC_H).
+       (GTFILES): Add insn-addr.h, cselib.h, dependence.c, reg-stack.c.
+       (gt-reg-stack.h): New rule.
+       (gt-dependence.h): New rule.
+       (gtype-desc.o): Add cselib.h, insn-addr.h.
+
+       * varray.c: Use only necessary headers.
+       (element_size): New.
+       (uses_ggc): New.
+       (varray_init): Take type, not size.  Use GGC if appropriate.
+       (varray_grow): Update for change to struct varray_head_tag.
+       Use GGC if appropriate.
+       * varray.h (struct const_equiv_data): Use gengtype.
+       (enum varray_data_enum): New.
+       (union varray_data_tag): Use gengtype.
+       (struct varray_head_tag): Use gengtype.  Replace size field with
+       enum varray_data_enum.
+       (varray_init): Update prototype.
+       (VARRAY_SCHED_INIT): Delete.
+       (VARRAY_*_INIT): Update for change to varray_init.
+       (VARRAY_SCHED): Delete.
+       (VARRAY_PUSH_SCHED): Delete.
+       (VARRAY_TOP_SCHED): Delete.
+       * tree.h: Update for change to length specifier.
+       * tree-inline.c (optimize_inline_calls): Don't use VARRAY_FREE.
+       (clone_body): Likewise.
+       * ssa.h (ssa_definition): Use gengtype to mark.
+       * ssa.c (convert_from_ssa): Don't use VARRAY_FREE.
+       * ssa-dce.c (ssa_eliminate_dead_code): Don't use VARRAY_FREE.
+       * rtl.h (struct rtvec_def): Update for change to length specifier.
+       * integrate.c (expand_inline_function): Don't use VARRAY_FREE.
+       (struct initial_value_struct): Update for change to length specifier.
+       * ggc.h (ggc_add_rtx_varray_root): Delete prototype.
+       (ggc_add_tree_varray_root): Delete prototype.
+       (ggc_mark_rtx_varray): Delete prototype.
+       (ggc_mark_tree_varray): Delete prototype.
+       * ggc-common.c (ggc_add_rtx_varray_root): Delete.
+       (ggc_add_tree_varray_root): Delete.
+       (ggc_mark_rtx_varray): Delete.
+       (ggc_mark_tree_varray): Delete.
+       (ggc_mark_rtx_varray_ptr): Delete.
+       (ggc_mark_tree_varray_ptr): Delete.
+       * gengtype.h (enum typekind): Remove TYPE_VARRAY.
+       (create_varray): Delete prototype.
+       * gengtype.c (varrays): Delete.
+       (create_varray): Delete.
+       (adjust_field_type): Detect array of string pointers.
+       (process_gc_options): Remove code to handle varray_type option.
+       (set_gc_used_type): Remove TYPE_VARRAY case.
+       (output_escaped_param): New.
+       (write_gc_structure_fields): Use output_escaped_param on all
+       parameters.  Handle 'skip' with 'use_param' option.  Handle
+       arrays of strings.  Remove TYPE_VARRAY handling.
+       (write_gc_roots): Use boolean to detect 'length' option.
+       * gengtype-yacc.y (VARRAY_TYPE): Delete token.
+       (struct_fields): Call adjust_field_type on array fields.
+       (type): Remove VARRAY_TYPE case.
+       (type_option): Likewise.
+       * gengtype-lex.l: Don't consider varray_type a keyword.
+       * function.h: Update for change to length specifier.
+       (free_eh_status): Delete prototype.
+       * function.c (free_after_compilation): Don't call free_eh_status.
+       (reorder_blocks): Don't use VARRAY_FREE.
+       * except.c (struct eh_status): Update for change to length specifier.
+       remove varray_type specifier.
+       (free_eh_status): Delete.
+       * dwarf2out.c: Include gt-dwarf2out.h.
+       (used_rtx_varray): Use gengtype to mark, move
+       outside ifdefs.
+       (incomplete_types): Likewise.
+       (decl_scope_table): Likewise.
+       (dwarf2out_init): Don't call ggc_add_tree_varray_root.  
+       * cfglayout.c (scope_to_insns_finalize): Don't use VARRAY_FREE.
+       * c-tree.h (struct lang_type): Update for change to length specifier.
+       * c-parse.in (yylexstring): Don't use VARRAY_FREE.
+       * c-objc-common.c: Include gt-c-objc-common.h.
+       (deferred_fns): Mark for gengtype.
+       (c_objc_common_init): Don't call ggc_add_tree_varray_root.
+       (expand_deferred_fns): Just set deferred_fns to 0 to free it.
+       * Makefile.in (c-objc-common.o): Add gt-c-objc-common.h.
+       (gtype-desc.o): Update dependencies.
+       (dwarf2out.o): Add gt-dwarf2out.h.
+       (varray.o): Update dependencies.
+       (GTFILES): Add varray.h, ssa.h, dwarf2out.c, c-objc-common.c.
+       (gt-c-objc-common.h): New rule.
+       (gt-dwarf2out.h): New rule.
+       * objc/objc-act.c (build_objc_string_object): Don't use VARRAY_FREE.
+
+       * doc/gty.texi (GTY Options): Correct spelling.
+       (GGC Roots): Likewise.
+       * Makefile.in (TEXI_CPP_FILES): New.
+       (TEXI_GCC_FILES): New.
+       (TEXI_GCCINT_FILES): New.
+       (TEXI_CPPINT_FILES): New.
+       ($(docdir)/cpp.info): Use new macros.
+       ($(docdir)/gcc.info): Likewise.
+       ($(docdir)/gccint.info): Likewise.
+       ($(docdir)/cppinternals.info): Likewise.
+       (cpp.dvi): Likewise.
+       (gcc.dvi): Likewise.
+       (gccint.dvi): Likewise.
+       (cppinternals.dvi): Likewise.
+
+       * Makefile.in ($(docdir)/gccint.info): Depend on gty.texi.
+       * doc/gccint.texi (Top): Include gty.texi.
+       * doc/gty.texi: New file.
+
+       * bitmap.c: Include ggc.h, gt-bitmap.h.
+       (bitmap_ggc_free): New.
+       (bitmap_elem_to_freelist): New.
+       (bitmap_element_free): Use bitmap_elem_to_freelist.
+       (bitmap_element_allocate): Allow use of GGC.
+       (bitmap_clear): Use bitmap_elem_to_freelist.
+       (bitmap_copy): Update for change to bitmap_element_allocate.
+       (bitmap_set_bit): Likewise.
+       (bitmap_operation): Update for changes elsewhere.
+       (bitmap_initialize): Allow to create bitmaps that will use GGC.
+       * bitmap.h (struct bitmap_element_def): Use gengtype.
+       (struct bitmap_head_def): Likewise.  Also add 'using_obstack' field.
+       (bitmap_initialize): Add extra parameter.
+       (BITMAP_OBSTACK_ALLOC): Update for change to bitmap_initialize.
+       (BITMAP_ALLOCA): Delete.
+       (BITMAP_XMALLOC): Update for change to bitmap_initialize.
+       (BITMAP_GGC_ALLOC): New.
+       * Makefile.in (gtype-desc.o): Add bitmap.h.
+       (bitmap.o): Add gt-bitmap.h, $(GGC_H).
+       (GTFILES): Add bitmap.c.
+       (gt-bitmap.h): New rule.
+       ($(HOST_PREFIX_1)bitmap.o): Add gt-bitmap.h.
+       * basic-block.h: Update for changes to bitmap_initialize.
+       * except.c (exception_handler_label_map): Move into...
+       (struct eh_status): Here.
+       (struct eh_region): Make 'aka' GCable.
+       (free_eh_status): Don't need to specially handle
+       exception_handler_label_map.
+       (add_ehl_entry): Update for changes to exception_handler_label_map.
+       (find_exception_handler_labels): Likewise.
+       (remove_exception_handler_label): Likewise.
+       (maybe_remove_eh_handler): Likewise.
+       (for_each_eh_label): Likewise.
+       (remove_eh_handler): Allocate 'aka' using GGC.
+       * gengtype.c (get_output_file_with_visibility): Add bitmap.h
+       to list of includes.
+
+       * gengtype.c (write_gc_marker_routine_for_structure): Name
+       the routines 'gt_ggc_mx_*' instead of 'gt_ggc_m_*'.  
+       (write_gc_types): Arrange for the tests with NULL to be inlined.
+       (write_gc_roots): Update uses of procedure pointers.
+       * ggc-common.c (gt_ggc_mx_rtx_def): Rename from gt_ggc_m_rtx_def.
+
+       * Makefile.in (explow.o): Add dependency on gt-explow.h.
+       (sdbout.o): Add dependency on gt-sdbout.h.
+
+       * emit-rtl.c (const_int_htab): Use gengtype to clear unused entries.
+       (mem_attrs_htab): Likewise.
+       (init_emit_once): Don't call ggc_add_deletable_htab.
+       * fold-const.c (size_htab): Use gengtype to clear unused entries.
+       (size_int_type_wide): Don't call ggc_add_deletable_htab.
+       * gengtype.c (finish_root_table): Add LASTNAME and TNAME
+       parameters, use them, change callers.
+       (write_gc_root): Add IF_MARKED parameter, use it, change callers.
+       (write_gc_roots): Handle 'if_marked' option.
+       (main): Don't need to call set_gc_used_type any more.
+       * ggc.h (ggc_htab_marked_p): Delete.
+       (ggc_htab_mark): Delete.
+       (struct ggc_cache_tab): New.
+       (gt_ggc_cache_rtab): New declaration.
+       * ggc-common.c (struct d_htab_root): Delete.
+       (d_htab_roots): Delete.
+       (ggc_add_deletable_htab): Delete.
+       (ggc_htab_delete): Handle new htab-deleting mechanism.
+       (ggc_mark_roots): Use new htab-deleting mechanism.
+       * tree.c (type_hash_table): Use gengtype to clear unused entries.
+       Make static.
+       (init_obstacks): Don't call ggc_add_deletable_htab.
+
+       * objc/objc-act.h (struct hashed_attribute): Use gengtype.
+       (struct hashed_entry): Likewise.
+       (nst_method_hash_list): Likewise.
+       (cls_method_hash_list): Likewise.
+       (HASH_ALLOC_LIST_SIZE): Delete.
+       (ATTR_ALLOC_LIST_SIZE): Delete.
+       * objc/objc-act.c (hash_init): Use ggc to allocate
+       nst_method_hash_list, cls_method_hash_list.
+       (hash_enter): Use ggc to allocate; allocate one entry at a time.
+       (hash_add_attr): Likewise.
+       (ggc_mark_hash_table): Delete.
+       (objc_act_parse_init): Delete.
+       (objc_init): Delete reference to objc_act_parse_init.
+       * tlink.c: Replace hash.h with hashtab.h.  Explicitly include
+       obstack.h.  Replace references to 'struct hash_table' with htab_t.
+       (struct symbol_hash_entry): Replace hash header with key field.
+       (struct file_hash_entry): Replace hash header with key field.
+       (struct demangled_hash_entry): Replace hash header with key field.
+       (hash_string_eq): New.
+       (hash_string_hash): New.
+       (symbol_hash_newfunc): Delete.
+       (symbol_hash_lookup): Modify to use htab_t.
+       (file_hash_newfunc): Delete.
+       (file_hash_lookup): Modify to use htab_t.
+       (demangled_hash_newfunc): Delete.
+       (demangled_hash_lookup): Modify to use htab_t.
+       (tlink_init): Modify to use htab_t.
+       * hash.h: Delete.
+       * hash.c: Delete.
+       * ggc.h: Delete forward structure declarations.
+       Delete prototypes for deleted functions.
+       * ggc-common.c: Don't include hash.h.
+       (ggc_add_tree_hash_table_root): Delete.
+       (ggc_mark_tree_hash_table_entry): Delete.
+       (ggc_mark_tree_hash_table): Delete.
+       (ggc_mark_tree_hash_table_ptr): Delete.
+       * gengtype.c (write_gc_structure_fields): Allow param_is option.
+       (write_gc_marker_routine_for_structure): Use visibility of
+       the parameter if there is one.
+       * function.c: Replace hash.h with hashtab.h.  Replace references
+       to 'struct hash_table *' with htab_t.
+       (struct insns_for_mem_entry): Include a plain key.
+       (fixup_var_refs_insns_with_hash): Update to use htab_t.
+       (insns_for_mem_newfunc): Delete.
+       (insns_for_mem_hash): Update to use htab_t.
+       (insns_for_mem_comp): Likewise.
+       (insns_for_mem_walk): Likewise.
+       * c-lang.c: Include ggc.h.
+       * Makefile.in (OBJS): Remove hash.o.
+       (c-lang.o): Add GGC_H.
+       (COLLECT2_OBJS): Remove hash.o.
+       (tlink.o): Remove hash.h, add HASHTAB_H and OBSTACK_H.
+       (ggc-common.o): Remove hash.h.
+       (function.o): Remove hash.h, add HASHTAB_H.
+       (genautomata.o): Remove hash.h, add HASHTAB_H.
+
+       * varasm.c (mark_const_str_htab_1): Delete.
+       (mark_const_str_htab): Delete.
+       (const_str_htab_del): Delete.
+       (const_str_htab): Use gengtype to mark.
+       (init_varasm_once): Use gengtype to mark hashtables.  Use GC to
+       allocate them.
+       * tree.c (mark_tree_hashtable_entry): Delete.
+       (mark_tree_hashtable): Delete.
+       * tree.h (mark_tree_hashtable): Delete prototype.
+       * ggc.h (ggc_test_and_set_mark): Treat (void *)1 like NULL.
+       (ggc_mark): Likewise.
+       (ggc_calloc): New.
+       (htab_create_ggc): New.
+       * ggc-common.c (ggc_calloc): New.
+       * gengtype.h (enum typekind): Add TYPE_PARAM_STRUCT.
+       (struct type): Add param_struct structure.
+       * gengtype.c (param_structs): New.
+       (adjust_field_type): Handle param_is option.
+       (set_gc_used_type): Handle TYPE_PARAM_STRUCT.
+       (get_output_file_with_visibility): Include hashtab.h in gtype-desc.c.
+       (write_gc_structure_fields): Add new PARAM parameter.  Update
+       callers.  Handle use_param option.  Handle TYPE_PARAM_STRUCT.
+       (write_gc_marker_routine_for_structure): Add new PARAM parameter.
+       Use it to generate function name.  Update callers.
+       (write_gc_types): Add new PARAM_STRUCTS parameter.  Update callers.
+       Process them.
+       (write_gc_roots): Handle TYPE_PARAM_STRUCT.  Allow param_is
+       option.
+       (main): Define PTR as pointer-to-scalar.  Don't specially
+       mark deferred_string or ehl_map_entry.
+       * gengtype-yacc.y (PARAM_IS): Add new token.
+       (externstatic): Use adjust_field_type.
+       (type_option): Add PARAM_IS.
+       * gengtype-lex.l: Add rule for typedef of function pointers.
+       Add rule for PARAM_IS.
+       (IWORD): Add size_t.
+       * except.c (exception_handler_label_map): Use gengtype to mark.
+       (type_to_runtime_map): Likewise.
+       (mark_ehl_map_entry): Delete.
+       (mark_ehl_map): Delete.
+       (init_eh): Use gengtype for roots; use GC to allocate hash tables.
+       (t2r_mark_1): Delete.
+       (t2r_mark): Delete.
+       * Makefile.in (gtype-desc.o): Correct dependencies.
+       (GTFILES): Add hashtab.h.
+       (genautomata.o): Actually uses hashtab.h.
+
+       * Makefile.in (stringpool.o): Add $(GGC_H).
+       (dwarf2asm.o): Likewise.
+       (GTFILES): Add hashtable.h.
+       * c-common.h (struct c_common_identifier): Use gengtype.
+       * c-decl.h (c_mark_tree): Delete.
+       * c-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+       * c-tree.h (struct lang_identifier): Use gengtype.
+       (union lang_tree_node): New.
+       (c_mark_tree): Delete prototype.
+       * dwarf2out.c [!DWARF2_DEBUGGING_INFO]: Define dummy 
+       dwarf2_debug_hooks.
+       * gengtype-lex.l (IWORD): Allow 'bool'.
+       (ptr_alias): Match.
+       * gengtype-yacc.y (ALIAS): New token.
+       (type_option): New rule.
+       (option): Use type_option.
+       * gengtype.c (process_gc_options): New.
+       (set_gc_used_type): Use it.
+       (write_gc_structure_fields): Add 'bitmap' parameter, change callers.
+       Add new variable 't' to hold the type of the field being processed.
+       Add more error checking.  Use UNION_P when looking at 'desc' option.
+       Handle language-specific structures containing other
+       language-specific structures.
+       (write_gc_types): Handle 'ptr_alias' option.
+       (main): Don't need to specially output lang_type, lang_decl, lang_id2.
+       * ggc-common.c (ggc_pending_trees): Delete.
+       (ggc_mark_roots): Don't manipulate ggc_pending_trees.
+       (ggc_mark_trees): Delete.
+       (gt_ggc_m_tree_node): Delete.
+       * ggc.h (ggc_pending_trees): Delete.
+       (ggc_mark_tree): Make alias of gt_ggc_m_tree_node.
+       * hashtable.h (ht_identifier): Use gengtype.
+       * langhooks-def.h (LANG_HOOKS_MARK_TREE): Delete.
+       * langhooks.h (struct lang_hooks): Delete mark_tree.
+       * sdbout.c [! SDB_DEBUGGING_INFO]: Define dummy sdb_debug_hooks
+       anyway.
+       * system.h: Poison LANG_HOOKS_MARK_TREE.
+       * tree.c (tree_node_structure): New.
+       * tree.h (struct tree_common): Use gengtype.
+       (struct tree_int_cst): Likewise.
+       (struct tree_real_cst): Likewise.
+       (struct tree_string): Likewise.
+       (struct tree_complex): Likewise.
+       (struct tree_vector): Likewise.
+       (struct tree_identifier): Likewise.
+       (struct tree_list): Likewise.
+       (struct tree_vec): Likewise.
+       (struct tree_exp): Likewise.
+       (struct tree_block): Likewise.
+       (struct tree_type): Likewise.
+       (struct tree_decl): Likewise.
+       (enum tree_structure_enum): New.
+       (union tree_node): Use gengtype, with an alias.
+       (tree_node_structure): Prototype.
+       * objc/objc-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+
+       Merge to tag pch-merge-20020430.  The LANG_HOOKS_FUNCTION_MARK
+       macro was deleted.  The LANG_HOOKS_FUNCTION_FREE macro was renamed
+       to LANG_HOOKS_FUNCTION_FINAL.
+       * Makefile.in (GTFILES): Add bitmap.h.
+       * except.c (struct eh_region): Mark field 'aka' to be skipped.
+
+       * config/alpha/alpha.c [TARGET_ABI_UNICOSMK]
+       (alpha_init_machine_status): Give proper type.
+       * Makefile.in (c-lang.o): Depend on gtype-c.h.
+       (optabs.o): Depend on gt-optabs.h.
+       (GTFILES): Add optabs.o.
+       (gt-optabs.h): Add rule.
+       * optabs.c: Include gt-optabs.h.
+
+       * gengtype.c (set_gc_used_type): Correct some errors in last change.
+       (write_gc_structure_fields): If a field which should be NULL is
+       not, abort.
+       * c-pragma.c: Move struct align_stack and variable alignment_stack
+       out from the ifdef.
+
+       * config/xtensa/t-xtensa: Add dependencies for gt-xtensa.h.
+       * config/xtensa/xtensa.c: Include gt-cris.h.
+       (struct machine_function): Use gengtype to mark.
+       * config/mmix/mmix.h (struct machine_function): Use gengtype
+       to mark.
+       * config/cris/t-cris: Add dependencies for gt-cris.h.
+       * config/cris/cris.c: Include gt-cris.h.
+       (struct machine_function): Use gengtype to mark.
+       * config/rs6000/rs6000.h (struct machine_function): Use gengtype
+       to mark.
+       * doc/tm.texi (Per-Function Data): Delete references to
+       mark_machine_status.
+       * config/ia64/ia64.c (ia64_override_options): Don't set
+       mark_machine_status.
+       * config/i386/i386.c (override_options): Likewise.
+       * config/d30v/d30v.c (d30v_init_expanders): Likewise.
+       * config/arm/arm.c (arm_init_expanders): Likewise.
+       * config/alpha/alpha.c (override_options): Likewise.
+       * gengtype.h (enum gc_used_enum): Add GC_MAYBE_POINTED_TO. 
+       * gengtype.c (set_gc_used_type): Handle 'maybe_null' option.
+       (write_gc_structure_fields): Don't handle 'really' option.
+       Handle 'maybe_null' option.
+       (write_gc_types): Handle 'maybe_null' option.
+       * function.h (struct function): Don't use "really".
+       (mark_machine_status): Delete declaration.
+       (mark_lang_status): Delete declaration.
+       (gt_ggc_mr_machine_function): Delete prototype.
+       (gt_ggc_mr_language_function): Delete prototype.
+       * function.c (mark_machine_status): Delete.
+       (mark_lang_status): Delete.
+       (gt_ggc_mr_machine_function): Delete.
+       (gt_ggc_mr_language_function): Delete.
+       * c-tree.h (mark_c_function_context): Delete prototype.
+       * c-objc-common.c (c_objc_common_init): Don't set mark_lang_status.
+       * c-decl.c (struct language_function): Rename from struct
+       c_language_function.  Update uses.  Use gengtype to mark.
+       (mark_c_function_context): Delete.
+       * c-common.h (struct c_language_function): Rename from struct
+       language_function.
+       (mark_stmt_tree): Delete prototype.
+       (c_mark_lang_decl): Delete prototype.
+       (mark_c_language_function): Delete prototype.
+       * c-common.c (mark_stmt_tree): Delete.
+       (c_mark_lang_decl): Delete.
+       (mark_c_language_function): Delete.
+
+       * gengtype.h (enum typekind): Add TYPE_LANG_STRUCT.
+       (lang_bitmap): New typedef.  Use where appropriate.
+       (struct type): Add gc_used field, lang_struct field.
+       (UNION_P): New macro.
+       (new_structure): New prototype.
+       (find_structure): Remove 'pos' parameter.  Change all callers.
+       * gengtype-lex.l: Update for changes to find_structure.
+       * gengtype-yacc.y (typedef_struct): Use new_structure.
+       (yacc_ids): Suppress warning.
+       (type): Use new_structure.
+       * gengtype.c (string_type): Update for changes to struct type.
+       (find_structure): Just find a structure, don't worry about
+       creating one.
+       (new_structure): New.
+       (note_yacc_type): Use new_structure.
+       (set_gc_used_type): New.
+       (set_gc_used): New.
+       (write_gc_structure_fields): Allow for pointers to TYPE_LANG_STRUCT.
+       (write_gc_types): Handle TYPE_LANG_STRUCT.
+       (write_gc_marker_routine_for_structure): New.
+       (main): Call set_gc_used.  Add some calls to set_gc_used_type
+       for places where GCC doesn't use gengtype properly yet.
+       * ggc.h (gt_ggc_m_rtx_def): Don't prototype.
+       (gt_ggc_m_tree_node): Likewise.
+
+       * varasm.c (copy_constant): Call expand_constant if we hit
+       something we can't recognise.
+
+       * ggc-common.c (ggc_mark_rtvec_children): Delete.
+       (ggc_mark_rtx_children): Use generic name for ggc_mark_rtvec.
+       (lang_mark_false_label_stack): Delete.
+       * rtl.h (struct rtvec_def): Use gengtype to mark.
+       * ggc.h (ggc_mark_rtvec): Delete.
+       (gt_ggc_m_rtvec_def): Delete.
+       (ggc_mark_nonnull_tree): Delete.
+       (ggc_mark_rtvec_children): Delete prototype.
+       (lang_mark_false_label_stack): Delete declaration.
+
+       * gengtype.h (note_yacc_type): Add prototype.
+       * gengtype.c (note_yacc_type): New function.
+       * gengtype-lex.l: Add lexer support for yacc files.
+       * gengtype-yacc.y (start): Extract union from yacc files.
+       (yacc_union): New rule.
+       (yacc_typematch): New rule.
+       (yacc_ids): New rule.
+       (enum_items): Tweak for efficiency.
+       (optionseq): Likewise.
+
+       * c-common.h (struct language_function): Use gengtype.
+       (struct c_lang_decl): Likewise.
+       * c-tree.h (struct lang_decl): Likewise.
+       (struct lang_type): Likewise.
+       * c-decl.c (lang_mark_tree): Use generated marker routines to mark
+       tree language substructures.
+
+       * stringpool.c (mark_ident): Replace ggc_mark_nonnull_tree with
+       ggc_mark_tree.
+       * dwarf2asm.c (mark_indirect_pool_entry): Likewise.
+
+       * varasm.c (struct rtx_const): Remove 'skip' tags for scalar arrays.
+
+       * stmt.c (struct nesting): Add discriminator.  Use gengtype to
+       mark. Remove 'data.block.cleanup_ptr' field.
+       (struct stmt_status): Use usual technique to mark struct nesting.
+       (gt_ggc_mr_nesting_cond): Delete.
+       (gt_ggc_mr_nesting_loop): Delete.
+       (gt_ggc_mr_nesting_block): Delete.
+       (gt_ggc_mr_nesting_case_stmt): Delete.
+       (expand_start_cond): Set discriminator.
+       (expand_start_loop): Likewise.
+       (expand_start_null_loop): Likewise.
+       (expand_start_bindings_and_block): Set discriminator.  Don't set
+       deleted fields.
+       (expand_decl_cleanup): Replace 'cleanup_ptr' with
+       &thisblock->data.block.cleanups.
+       (expand_start_case): Set discriminator.
+       (expand_start_case_dummy): Set discriminator.
+
+       * ggc-callbacks.c: Remove.
+
+       * gengtype.h (struct type): Add 'u.s.bitmap' field.
+       (find_structure): Add 'pos' parameter.
+       * gengtype-lex.l: Update callers to find_structure.
+       * gengtype-yacc.y: Likewise.
+       * gengtype.c (find_structure): Allow for structures to be defined
+       in multiple language backends.
+       (get_output_file_with_visibility): Include debug.h in gtype-desc.c.
+       (counter): Rename to gc_counter.
+       (write_gc_structure_fields): Fail when writing out fields for
+       an incomplete structure.  Ignore arrays of scalars.  Handle
+       'tree_vec' special.
+       (write_gc_types): Reset counter for each procedure written.
+
+       * stmt.c (add_case_node): Use GGC to allocate struct case_node.
+       (free_case_nodes): Delete.
+       (expand_end_case_type): Delete call to free_case_nodes.
+
+       * Makefile.in (cselib.o): Include gt-<filename>.h.
+       (gcse.o): Likewise.
+       (profile.o): Likewise.
+       (alias.o): Likewise.
+       (GTFILES): Add alias.c, cselib.c, gcse.c, profile.c, and
+       alphabetize backend files.
+       (gt-alias.h, gt-cselib.h, gt-gcse.h, gt-profile.h): New rules.
+       * alias.c: Use gengtype for roots.
+       * c-common.h (struct stmt_tree_s): Use gengtype.
+       * c-decl.c: Use gengtype for roots.
+       * cselib.c: Use gengtype for roots.
+       * expr.c: Use gengtype for roots.
+       * fold-const.c: Use gengtype for roots.
+       * gcse.c: Use gengtype for roots.
+       * gengtype-lex.l: Handle typedefs of function types.
+       Allow for empty array bounds.
+       Allow processing to stop on initialisers.
+       * gengtype-yacc.y (externstatic): Stop processing on initialisers.
+       (semiequal): New rule.
+       * gengtype.c (create_file): Tidy output files.
+       (get_output_file_with_visibility): Fix paren warning.  Fix bug
+       involving multiple input files mapping to one output file.
+       (write_gc_structure_fields): Skip arrays of scalars.
+       (write_gc_types): Tidy output files.
+       (write_gc_root): New function.
+       (write_gc_roots): Fix bugs, add support for roots that are
+       structures.
+       * ggc-common.c (ggc_mark_rtx_ptr): Delete.
+       (ggc_mark_tree_ptr): Delete.
+       (ggc_add_rtx_root): Delete.
+       (ggc_add_tree_root): Delete.
+       (ggc_del_root): Delete.
+       * integrate.c (get_func_hard_reg_initial_val): Use ggc_alloc to
+       allocate struct initial_value_struct.
+       * profile.c: Use gengtype for roots.
+       * sdbout.c: Use gengtype for roots.
+       * varasm.c (mark_weak_decls): Delete unused prototype.
+       (mark_const_hash_entry): Delete unused function.
+       * config/darwin-protos.h: Use gengtype for roots.
+       (machopic_add_gc_roots): Delete.
+       * config/arm/arm.c: Use gengtype for roots.
+       * config/arm/arm.h: Use gengtype for roots.
+       * config/c4x/c4x-protos.h: Use gengtype for roots.
+       * config/c4x/c4x.c (c4x_add_gc_roots): Delete.
+       * config/d30v/d30v-protos.h: Use gengtype for roots.
+       * config/d30v/d30v.c (d30v_add_gc_roots): Delete.
+       * config/dsp16xx/dsp16xx.c (override_options): Use gengtype for roots.
+       * config/dsp16xx/dsp16xx.h: Use gengtype for roots.
+       * config/ia64/ia64-protos.h: Use gengtype for roots.
+       * config/ia64/ia64.c (ia64_add_gc_roots): Delete.
+       * config/m68hc11/m68hc11-protos.h: Use gengtype for roots.
+       * config/m68hc11/m68hc11.c (z_reg): Make global.
+       (z_reg_qi): Make global.
+       (m68hc11_add_gc_roots): Delete.
+       * config/mcore/mcore-protos.h: Use gengtype for roots.
+       * config/mcore/mcore.c (mcore_add_gc_roots): Delete.
+       * config/mips/mips.c (mips_add_gc_roots): Delete.
+       * config/mips/mips.h: Use gengtype for roots.
+       * config/mmix/mmix.c (override_options): Use gengtype for roots.
+       * config/mmix/mmix.h: Use gengtype for roots.
+       * config/mn10200/mn10200.c (asm_file_start): Use gengtype for roots.
+       * config/mn10200/mn10200.h: Use gengtype for roots.
+       * config/pa/pa.c: Use gengtype for roots, marking.
+       (struct deferred_plabel): Use GGC, gengtype.
+       (pa_add_gc_roots): Delete.
+       (mark_deferred_plabels): Delete.
+       * config/pj/pj-protos.h: Use gengtype for roots.
+       * config/pj/pj.h (OVERRIDE_OPTIONS): Don't define.
+       * config/rs6000/rs6000.c: Use gengtype for roots.  Don't call
+       machopic_add_gc_roots.
+       * config/rs6000/rs6000.h: Use gengtype for roots.
+       * config/rs6000/t-darwin (darwin.o): Add dependency on gt-darwin.h.
+       (gt-darwin.h): Add rule.
+       * config/sh/sh.c: Use gengtype for roots.
+       * config/sh/t-sh ($(out_object_file)): Add dependency on gt-sh.h.
+       (gt-sh.h): Add rule.
+       * config/sparc/sparc.c: Use gengtype for roots.
+       (sparc_add_gc_roots): Delete.
+       (struct ultrasparc_pipeline_state): Use GGC, gengtype.
+       (mark_ultrasparc_pipeline_state): Delete.
+       * config/sparc/sparc.h: Use gengtype for roots.
+
+       * Makefile.in (c-parse.o): Update dependencies.
+       (c-common.o): Likewise.
+       (GTFILES): Add c-common.h, c-tree.h, c-common.c, c-parse.in.
+       Add dependencies for the files they generate.
+       * c-common.c: Replace ggc_add_* uses with GTY annotations.
+       * c-common.h: Likewise.
+       * c-decl.c: Likewise.
+       (gt_ggc_mp_binding_level): Delete.
+       * c-lang.c: Include gtype-c.h.
+       * c-parse.in: Replace ggc_add_* uses with GTY annotations.  Include
+       gt-c-parse.h.
+       * c-pragma.h: Replace ggc_add_* uses with GTY annotations.
+       (gt_ggc_mp_align_stack): Delete.
+       * c-tree.h: Replace ggc_add_* uses with GTY annotations.
+       * function.c: Replace ggc_add_* uses with GTY annotations.
+       (gt_ggc_mp_function): Delete.
+       * function.h: Replace ggc_add_* uses with GTY annotations.
+       * gengtype.c (lang_names): New.
+       (NUM_BASE_FILES): New.
+       (open_base_files): Create language base files.
+       (startswith): New.
+       (get_file_basename): New.
+       (get_base_file_bitmap): New.
+       (get_output_file_with_visibility): Rename from get_output_file.
+       Add more mappings for various C/Objc filenames.
+       (finish_root_table): New.
+       (write_gc_roots): Handle dependencies and scoping properly.
+       * gengtype.h: Add prototypes for new functions.
+       * ggc-common.c (struct deletable_root): Delete.
+       (deletables): Delete.
+       (ggc_add_deletable_root): Delete.
+       (ggc_mark_roots): No need to deal with deleted functionality.
+       * ggc.h (ggc_add_deletable_root): Delete prototype.
+       * objc/Make-lang.in (objc-act.o): Add gtype-objc.h dependency.
+       (gtype-objc.h): Add rule to create.
+       * objc/config-lang.in (gtfiles): New.
+       * objc/objc-act.c: Allocate imp_list using GGC.  Replace uses of
+       ggc_add_* with GTY markers.  Include gtype-objc.h.
+       (ggc_mark_imp_list): Delete.
+       * objc/objc-act.h: Replace uses of ggc_add_* with GTY markers.
+       * objc/objc-lang.c: Random Whitespace Change.
+
+       * except.h (exception_handler_labels): Delete.
+       (get_exception_handler_labels): New.
+       * except.c (exception_handler_labels): Delete.
+       (struct eh_status): Add exception_handler_labels field.
+       (doing_eh): Don't add exception_handler_labels as root.
+       (free_eh_status): Don't need to free exception_handler_labels.
+       (get_exception_handler_labels): New.
+       (find_exception_handler_labels): Update for move of
+       exception_handler_labels.
+       (remove_exception_handler_label): Likewise.
+       * cfgrtl.c (can_delete_label_p): Use get_exception_handler_labels.
+       * jump.c (rebuild_jump_labels): Likewise.
+       * loop.c (find_and_verify_loops): Likewise.
+       * sched-rgn.c (is_cfg_nonregular): Likewise.
+
+       * gengtype.c (write_gc_structure_fields): Handle variable-length
+       TYPE_ARRAYs.
+
+       * varasm.c (struct weak_syms): Use GGC, gengtype.
+       (mark_weak_decls): Delete.
+       (weak_decls): Likewise.
+       (add_weak): Likewise.
+       (remove_from_pending_weak_list): Likewise.
+       (init_varasm_once): Likewise.
+
+       * Makefile.in (gtype-desc.o): Add libfuncs.h dependency.
+       (GTFILES): Add tree.h, libfuncs.h, emit-rtl.c, explow.c,
+       stor-layout.c, regclass.c, and lists.c.
+       Add dependencies of gt-emit-rtl.h gt-explow.h gt-stor-layout.h
+       gt-regclass.h and gt-lists.h on s-gtype.
+       * emit-rtl.c: Use gengtype for roots.  Include gt-emit-rtl.h.
+       * except.c: Use gengtype for roots.
+       * explow.c: Use gengtype for roots.  Include gt-explow.h.
+       * expr.h (init_stor_layout_once): Delete prototype.
+       * function.c: Use gengtype for roots.
+       * gengtype-lex.l: Add ENT_EXTERNSTATIC lexing.
+       * gengtype-yacc.y (start): Can also be an externstatic.
+       (externstatic): New production.
+       (struct_fields): Correct array bounds inversion for 2-d arrays.
+       * gengtype.c (variables): New variable.
+       (note_variable): New function.
+       (get_output_file): Include libfuncs.h into gtype-desc.c.
+       (get_output_file_name): New function.
+       (write_gc_structure_fields): Suppress warnings.
+       (write_gc_types): Make static.
+       (put_mangled_filename): New function.
+       (write_gc_roots): New function.
+       (main): Call write_gc_roots.
+       * gengtype.h (note_variable): Prototype.
+       (get_output_file_name): Prototype.
+       (write_gc_types): Delete prototype.
+       * ggc.h: Clean up unnecessary structure predefinitions.
+       (struct ggc_root_tab): Define.
+       (gt_ggc_m_rtx_def): Make function, not macro.
+       (gt_ggc_m_tree_node): Likewise.
+       * libfuncs.h: Use gengtype for roots.
+       * lists.c: Use gengtype for roots.  Include gt-lists.h.
+       (init_EXPR_INSN_LIST_cache): Delete.
+       * optabs.c: Use gengtype for roots.
+       (gt_ggc_mp_optab): Delete.
+       * optabs.h: Use gengtype for roots.
+       * regclass.c: Use gengtype for roots.  Include gt-regclass.h.
+       * rtl.h: Use gengtype for roots.
+       (init_EXPR_INSN_LIST_cache): Delete prototype.
+       * stor-layout.c: Use gengtype for roots.
+       Include gt-stor-layout.h.
+       (init_stor_layout_once): Delete.
+       * toplev.c: Use gengtype for roots.  Delete calls to deleted
+       routines.
+       * tree.c: Use gengtype for roots.
+       * tree.h: Use gengtype for roots.
+       * varasm.c: Use gengtype for roots.
+       
+       * Makefile.in (GTFILES): Add @all_gtfiles@.
+       * configure: Regenerate.
+       * configure.in: Construct all_gtfiles from the gtfiles definitions
+       in config-lang.in.
+       * gengtype-yacc.y (type): Warn about duplicate structure names.
+       * gengtype.c (get_output_file): Handle .c files in language
+       subdirectories.
+
+       * Makefile.in (GTFILES): Run gengtype on all the config files
+       and on the target .c file.
+       * except.c (mark_eh_region): Delete.
+       (init_eh_for_function): Use GGC on struct eh_status.
+       (mark_eh_status): Delete.
+       (free_eh_status): Use GGC.
+       (expand_eh_region_start): Use GGC to
+       (collect_eh_region_array): Allocate last_region_number using GGC.
+       (duplicate_eh_region_1): Use GGC to allocate struct eh_region.
+       (remove_eh_handler): Let GGC free struct eh_region.
+       (add_call_site): Use GGC to reallocate call_site_record array.
+       * function.c (init_machine_status): Update calling sequence.
+       (mark_machine_status): Likewise.
+       (mark_lang_status): Likewise.
+       (prepare_function_start): Update init_machine_status call.
+       (mark_function_status): Delete.
+       (maybe_mark_struct_function): Delete.
+       (ggc_mark_struct_function): Delete.
+       (gt_ggc_mp_function): New.
+       (gt_ggc_mr_machine_function): New.
+       (gt_ggc_mr_language_function): New.
+       (init_function_once): Use canonical names.
+       * function.h (struct function): Use gengtype.
+       (init_machine_status): Return the structure.
+       (mark_machine_status): Take a 'void *'.
+       (mark_lang_status): Likewise.
+       * ggc-common.c (ggc_mark_trees): Use canonical name for
+       ggc_mark_struct_function.
+       * tree.h (ggc_mark_struct_function): Delete prototype.
+       * config/alpha/alpha.c (alpha_mark_machine_status): Delete.
+       (alpha_init_machine_status): Likewise.
+       (override_options): Use canonical name for alpha_mark_machine_status.
+       * config/alpha/unicosmk.h (struct machine_function): Use gengtype.
+       * config/arm/arm.h (struct machine_function): Use gengtype.
+       * config/arm/arm.c (arm_mark_machine_status): Delete.
+       (arm_init_machine_status): Update calling sequence.
+       (arm_init_expanders): Use canonical name for arm_mark_machine_status.
+       * config/cris/cris.c (cris_init_machine_status): Update 
+       calling sequence.
+       * config/d30v/d30v.h (struct machine_function): Use gengtype.
+       * config/d30v/d30v.c (d30v_init_machine_status): Update 
+       calling sequence.
+       (d30v_mark_machine_status): Delete.
+       * config/i386/i386.c: Include gt-i386.h.
+       (struct machine_function): Use gengtype.
+       (ix86_init_machine_status): Update calling sequence.
+       (ix86_mark_machine_status): Delete.
+       (override_options): Use canonical namke for ix86_mark_machine_status.
+       * config/ia64/ia64.h (struct machine_function): Use gengtype.
+       * config/ia64/ia64.c (ia64_init_machine_status): Update calling 
+       sequence.
+       (ia64_mark_machine_status): Delete.
+       (ia64_override_options): Use canonical name for 
+       ia64_mark_machine_status.
+       * config/mmix/mmix.c (mmix_init_machine_status): Update calling 
+       sequence.
+       * config/rs6000/rs6000.c (rs6000_init_machine_status): Likewise.
+       * config/xtensa/xtensa.c (xtensa_init_machine_status): Likewise.
+       * gengtype.c (get_output_file): Fix warning.
+       (main): Add prototype to suppress warning.
+       * tree.c: Remove tree_hash_mark prototype.
+
+       * tree.h (init_stmt): Delete prototype.
+       * toplev.c (lang_independent_init): Don't call init_stmt.
+       * stmt.c (ALLOC_NESTING): Use GGC for 'struct nesting'.
+       (stmt_obstack): Delete.
+       (POPSTACK): No need to free 'struct nesting'.
+       (gt_ggc_mr_nesting_cond): Use canonical names.
+       (gt_ggc_mr_nesting_loop): Use canonical names.
+       (gt_ggc_mr_nesting_block): Use canonical names.
+       (gt_ggc_mr_nesting_case_stmt): Use canonical names.
+       (mark_stmt_status): Delete.
+       (init_stmt): Delete.
+       (clear_last_expr): Clear both last_expr_type and last_expr_value.
+       Use it everywhere that last_expr_type was cleared.
+       * lists.c (init_EXPR_INSN_LIST_cache): Use ggc_add_deletable_root.
+       (zap_lists): Delete.
+       * ggc.h (ggc_add_deletable_root): Prototype.
+       (mark_stmt_status): Remove prototype.
+       * ggc-common.c (ggc_add_deletable_root): New.
+       (ggc_mark_roots): Handle deletable roots.
+       * function.c (ggc_mark_struct_function): Use canonical name
+       for mark_stmt_status.
+       * emit-rtl.c (free_sequence_stack): New.
+       (start_sequence): Use a freelist for sequences.
+       (end_sequence): Likewise.
+       (init_emit_once): Add free_sequence_stack as a deleteable root.
+       * c-pragma.c Include gt-c-pragma.h.
+       (struct align_stack): Use gengtype.
+       (push_alignment): Use GGC for struct align_stack.
+       (mark_align_stack): Delete.
+       (gt_ggc_mp_align_stack): New.
+       (init_pragma): Use canonical name for mark_align_stack.
+       * c-decl.c: Include gt-c-decl.h.
+       (struct binding_level): Use gengtype.
+       (make_binding_level): Use GGC; handle the freelist here.
+       (pop_binding_level): New.
+       (pushlevel): Move code into make_binding_level.
+       (push_label_level): Likewise.
+       (poplevel): Move code into pop_binding_level.
+       (pop_label_level): Likewise.
+       (mark_binding_level): Delete.
+       (gt_ggc_mp_binding_level): New.
+       (c_init_decl_processing): Use canonical name for mark_binding_level.
+       Add free_binding_level as deletable root.
+       (mark_c_function_context): Use canonical name for mark_binding_level.
+       * Makefile.in (c-decl.o): Add gt-c-decl.h.
+       (c-pragma.o): Add gt-c-pragma.h.
+       (GTFILES): Add c-decl.c and c-pragma.c.
+       (gt-c-decl.h, gt-c-pragma.h): Create using gengtype.
+
+       * tree.c (struct type_hash): Use gengtype.
+       (init_obstacks): Use canonical name for type_hash_mark.
+       (type_hash_mark): Delete.
+       Include gt-tree.h.
+       * rtl.h (struct mem_attrs): Use gengtype.
+       * optabs.h (struct optab): Use gengtype.
+       * optabs.c (expand_binop): Squish signed/unsigned warning.
+       (mark_optab): Make local, use canonical name, use autogenerated
+       marker procedure.
+       (init_optabs): Use canonical name for mark_optab.
+       (new_optab): Use GGC to allocate optabs.
+       * ggc.h: Delete mark_optab prototype.
+       * ggc-common.c (ggc_mark_rtx_children): Use canonical name for
+       mem_attrs marker procedure.
+       * gengtype.c (get_output_file): Include headers in gtype-desc.c
+       explicitly rather than deducing them from file names.
+       (write_gc_structure_fields): Handle arrays of structures.
+       (main): Return non-zero exit code if errors occur during output.
+       * emit-rtl.c (mem_attrs_mark): Delete.
+       (init_emit_once): Use canonical name for mem_attrs marker procedure.
+       * Makefile.in (gtype-desc.o): Explicitly name dependencies.
+       (tree.o): Depend on gt-tree.h.
+       (GTFILES): Add rtl.h, optabs.h, tree.c.
+       (gt-tree.h): Add it to s-gtype rule.
+
+       * .cvsignore: Ignore gengtype flex/bison generated files.
+       * Makefile.in (GGC_H): Add gtype-desc.h.
+       (OBJS): Add gtype-desc.o.
+       (GEN): Add gengtype.
+       (STAGESTUFF): Add gengtype.
+       (varasm.o): Add gt-varasm.h.
+       (stmt.o): Add gt-stmt.h.
+       (except.o): Add gt-except.h.
+       (integrate.o): Add gt-integrate.h.
+       (GTFILES): New.
+       Add new rules for new files.
+       * configure: Regenerate.
+       * configure.in: Correct defaults.h paths.
+       * emit-rtl.c (mark_sequence_stack): Delete.
+       (mark_emit_status): Delete.
+       (start_sequence): Allocate sequence structures using GGC.
+       (end_sequence): Allocate sequence structures using GGC.
+       * except.c: Use gengtype for various structures.  Include
+       gt-except.h.
+       * expr.c (mark_expr_status): Delete.
+       * function.c: Use gengtype for various structures.  Include
+       gt-function.h.
+       (mark_function_status): Use standard gt_ggc names for marker functions.
+       (ggc_mark_struct_function): Likewise.
+       * function.h: Use gengtype for various structures.
+       * gengtype-lex.l: New file.
+       * gengtype-yacc.y: New file.
+       * gengtype.c: New file.
+       * gengtype.h: New file.
+       * ggc.h: Include gtype-desc.h.  Alias some marker procedures to
+       the standard names.  Remove some now-unnecessary prototypes.
+       * integrate.c: Use gengtype for various structures.  Include
+       gt-integrate.h.
+       (mark_hard_reg_initial_vals): Delete.
+       * integrate.h (mark_hard_reg_initial_vals): Delete.
+       * stmt.c: Use gengtype for various structures.  Include
+       gt-stmt.h.
+       (mark_case_node): Delete.
+       (mark_goto_fixup): Delete.
+       (mark_stmt_status): Use standard gt_ggc names for marker functions.
+       * system.h: Define GTY to empty.   In flex/bison files,
+       don't poison malloc or realloc, instead just define them to
+       xmalloc and xrealloc.
+       * varasm.c: Use gengtype for various structures.  Include
+       gt-varasm.h.  Use standard gt_ggc names for marker functions.
+       (mark_pool_constant): Delete.
+       (mark_varasm_status): Delete.
+       (decode_rtx_const): #if 0 out non-typesafe hack.
+
+       * function.h (free_lang_status): Mark as obsolete.
+       * function.c (free_lang_status): Mark as obsolete.
+       * c-decl.c (push_c_function_context): Use GC to allocate and free
+       struct language_function.
+       (pop_c_function_context): Likewise.
+       * c-common.c (mark_c_language_function): Mark struct
+       language_function.
+
+       * doc/tm.texi (Per-Function Data): Don't document free_machine_status.
+       Document that the machine_function structures must be allocated
+       using GC.  Update mark_machine_status documentation.
+       * function.h: Don't declare free_machine_status.
+       * function.c (free_machine_status): Don't define. 
+       (free_after_compilation): Don't call free_machine_status.
+       (ggc_mark_struct_function): Mark f->machine.  Call
+       mark_machine_status only on non-NULL pointers.
+       * system.h: Poison free_machine_status.
+       * config/xtensa/xtensa.c (xtensa_init_machine_status): Use GC on
+       struct machine_function.
+       (xtensa_free_machine_status): Delete.
+       (override_options): Don't set free_machine_status.
+       * config/rs6000/rs6000.c (rs6000_override_options): Don't set
+       free_machine_status.
+       (rs6000_init_machine_status): Use GC on struct machine_function.
+       (rs6000_free_machine_status): Delete.
+       * config/ia64/ia64.c (ia64_init_machine_status): Use GC on struct
+       machine_function.
+       (ia64_mark_machine_status): Likewise.
+       (ia64_free_machine_status): Delete.
+       (ia64_override_options): Don't set free_machine_status.
+       * config/i386/i386.c (override_options): Don't set
+       free_machine_status.
+       (ix86_init_machine_status): Use GC on struct machine_function.
+       (ix86_mark_machine_status): Likewise.
+       (ix86_free_machine_status): Delete.
+       * config/d30v/d30v.c: (d30v_init_machine_status): Use GC on struct
+       machine_function.
+       (d30v_mark_machine_status): Likewise.
+       (d30v_free_machine_status): Delete.
+       (d30v_init_expanders): Don't set free_machine_status.
+       * config/arm/arm.c (arm_mark_machine_status): Use GC on struct
+       machine_function.
+       (arm_init_machine_status): Likewise.
+       (arm_free_machine_status): Delete.
+       (arm_init_expanders): Don't set free_machine_status.
+       * config/alpha/alpha.c (override_options): Don't set
+       free_machine_status.
+       (alpha_init_machine_status): Use GC on struct machine_function.
+       (alpha_mark_machine_status): Likewise.
+       (alpha_free_machine_status): Delete.
+
+       * varasm.c (compare_constant): Fix typo.
+
+       * varasm.c: Don't include obstack.h.
+       (struct varasm_status): x_const_rtx_hash_table is a hash of rtxes.
+       (struct rtx_const): Give substructures names, improve formatting.
+       (struct constant_descriptor): Delete.
+       (struct constant_descriptor_tree): New, based on constant_descriptor.
+       (const_hash_table): Is a hash table of trees.
+       (mark_const_hash_entry): Is used for hashes of trees.  Mark
+       constant_descriptor_tree structure.
+       (mark_const_str_htab_1): Mark deferred_string structure.
+       (compare_constant): Rewrite to compare trees.
+       (compare_constant_1): Delete.
+       (record_constant): Delete.
+       (record_constant_1): Delete.
+       (output_constant_def): Use struct constant_descriptor_tree.
+       Don't duplicate trees twice.
+       (struct constant_descriptor_rtx): New.
+       (struct pool_constant): Used for rtx constants.
+       (init_varasm_status): Update for change to struct varasm_status.
+       (mark_varasm_status): Likewise.
+       (free_varasm_status): Delete.
+       (compare_constant_rtx): Rewrite to handle constant_descriptor_rtx.
+       (record_constant_rtx): Likewise.
+       (mem_for_const_double): Update to use struct constant_descriptor_rtx.
+       (force_const_mem): Likewise.
+       * Makefile.in (varasm.o): Doesn't depend on obstack.h.
+       * function.c (free_after_compilation): Don't use free_varasm_status.
+       * function.h: Don't prototype free_varasm_status.
+
+       * ggc-common.c (ggc_realloc): Handle X being NULL.
+
+       * ggc-common.c (ggc_realloc): New function.
+       * ggc.h: Prototype it.
+       * emit-rtl.c (free_emit_status): Delete.
+       (init_emit): Allocate emit subarrays using GC.
+       (gen_reg_rtx): Reallocate subarrays using GC.
+       (init_emit): Use GC to allocate 'struct emit_status' and its
+       subarrays.
+       (mark_emit_status): Mark structure and its subarrays.
+       * stmt.c (free_stmt_status): Delete.
+       * expr.c (free_expr_status): Delete.
+       * function.h: Remove prototypes for deleted functions.
+       * function.c (free_after_compilation): Don't use deleted functions.
+       Don't call free() on x_parm_reg_stack_loc.
+       (free_after_parsing): Don't use free_stmt_status.
+       (assign_parms): Use GC to allocate and resize x_parm_reg_stack_loc.
+       (mark_function_status): Mark x_parm_reg_stack_loc.
+
+       * varasm.c (init_varasm_status): Use GC to allocate
+       'struct varasm_status' and its fields x_const_rtx_hash_table
+       and x_const_rtx_sym_hash_table.
+       (mark_varasm_status): Mark them.
+       (free_varasm_status): Use GC to free them.
+       * expr.c (init_expr): Use GC to allocate 'struct expr_status'.
+       (mark_expr_status): Mark the structure itself.
+       (free_expr_status): Use GC to free the structure.
+       * stmt.c (free_stmt_status): Use GC to free 'struct stmt_status'.
+       (mark_stmt_status): Mark the 'struct stmt_status' itself.
+       (init_stmt_for_function): Allocate the structure for GC.
+
+       * dwarf2out.c (lookup_type_die): Use TYPE_SYMTAB_DIE.
+       (equate_type_number_to_die): Likewise.
+       * tree.h (TYPE_SYMTAB_DIE): New macro.
+       (struct die_struct): Predeclare.
+       (struct tree_type): Add field symtab.die.   Add a tag
+       to the union type of field symtab.
+
+       * varray.h (VARRAY_RTVEC_INIT): A varray of rtvec contains
+       'struct rtvec_def *', not 'struct rtvec_def'.
+
+       * function.h (original_arg_vector): Make a real rtvec.
+       * function.c (ggc_mark_struct_function): Adjust.
+       * integrate.c (expand_inline_function): Adjust.
+
 2002-06-04  Jason Thorpe  <thorpej@wasabisystems.com>
 
        * config.gcc (sh5-*-netbsd*, sh5l*-*-netbsd*)
index f9487583d554cba4004f8d8194e981450f69f450..10ba33ffd1ac76233be3ec7bb96689346f000e96 100644 (file)
@@ -562,7 +562,7 @@ REGS_H = regs.h varray.h $(MACHMODE_H)
 INTEGRATE_H = integrate.h varray.h
 LOOP_H = loop.h varray.h bitmap.h
 GCC_H = gcc.h version.h
-GGC_H = ggc.h varray.h
+GGC_H = ggc.h varray.h gtype-desc.h
 TIMEVAR_H = timevar.h timevar.def
 INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
 C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
@@ -718,20 +718,21 @@ C_OBJS = c-parse.o c-lang.o $(C_AND_OBJC_OBJS)
 
 # Language-independent object files.
 
-OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o  \
- cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o cfgrtl.o \
- combine.o conflict.o convert.o cse.o cselib.o dbxout.o debug.o dependence.o \
- df.o diagnostic.o doloop.o dominance.o dwarf2asm.o dwarf2out.o dwarfout.o \
- emit-rtl.o except.o explow.o expmed.o expr.o final.o flow.o           \
- fold-const.o function.o gcse.o genrtl.o ggc-common.o global.o graph.o \
- haifa-sched.o hash.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
- insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o   \
- integrate.o intl.o jump.o  langhooks.o lcm.o lists.o local-alloc.o    \
- loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o  \
- profile.o real.o recog.o reg-stack.o regclass.o regmove.o regrename.o \
- reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o     \
- sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o   \
- sibcall.o simplify-rtx.o ssa.o ssa-ccp.o ssa-dce.o stmt.o     \
+OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o     \
+ cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o            \
+ cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o          \
+ debug.o dependence.o df.o diagnostic.o doloop.o dominance.o              \
+ dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o          \
+ expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o            \
+ genrtl.o ggc-common.o global.o graph.o gtype-desc.o                      \
+ haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o     \
+ insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o      \
+ integrate.o intl.o jump.o  langhooks.o lcm.o lists.o local-alloc.o       \
+ loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o     \
+ profile.o real.o recog.o reg-stack.o regclass.o regmove.o regrename.o    \
+ reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o        \
+ sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o      \
+ sibcall.o simplify-rtx.o ssa.o ssa-ccp.o ssa-dce.o stmt.o                \
  stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
  tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
  $(GGC) $(out_object_file) $(EXTRA_OBJS)
@@ -744,7 +745,8 @@ BACKEND = main.o libbackend.a
 GEN= genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
  genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext)   \
  genconfig$(build_exeext) genpeep$(build_exeext) gengenrtl$(build_exeext)    \
- gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext)
+ gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
+ gengtype$(build_exeext)
 
 # Files to be copied away after each stage in building.
 STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
@@ -759,6 +761,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
  genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
  genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
  gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
+ gengtype$(build_exeext) \
  genrtl.c genrtl.h \
  xgcc$(exeext) cpp$(exeext) cc1$(exeext) $(EXTRA_PASSES) \
  $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) cc1obj$(exeext) \
@@ -1141,7 +1144,8 @@ s-crt0:   $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
 c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) flags.h \
     diagnostic.h $(TM_P_H)
 c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) $(GGC_H) intl.h \
-    $(C_TREE_H) input.h flags.h $(SYSTEM_H) toplev.h output.h $(CPPLIB_H)
+    $(C_TREE_H) input.h flags.h $(SYSTEM_H) toplev.h output.h $(CPPLIB_H) \
+    gt-c-parse.h
        $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
               -c $(srcdir)/c-parse.c $(OUTPUT_OPTION)
 
@@ -1164,11 +1168,12 @@ $(srcdir)/c-parse.y: c-parse.in
 
 c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
     $(GGC_H) $(TARGET_H) flags.h function.h output.h $(EXPR_H) \
-    debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h
+    debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h \
+    gt-c-decl.h
 c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
     $(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
 c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
-    langhooks.h $(LANGHOOKS_DEF_H) c-common.h
+    $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) c-common.h gtype-c.h
 c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
     debug.h $(C_TREE_H) c-common.h real.h \
     c-pragma.h input.h intl.h flags.h toplev.h output.h \
@@ -1176,20 +1181,20 @@ c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
 c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
     $(C_TREE_H) $(RTL_H) insn-config.h integrate.h $(EXPR_H) $(C_TREE_H) \
     flags.h toplev.h tree-inline.h diagnostic.h integrate.h $(VARRAY_H) \
-    langhooks.h $(GGC_H)
+    langhooks.h $(GGC_H) gt-c-objc-common.h
 c-aux-info.o : c-aux-info.c  $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
     flags.h toplev.h
 c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h \
     $(C_COMMON_H)
 c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
-    c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H)
+    c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
 mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
 graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
     function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
 sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
     $(BASIC_BLOCK_H)
 
-COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o
+COLLECT2_OBJS = collect2.o tlink.o intl.o underscore.o version.o
 COLLECT2_LIBS = @COLLECT2_LIBS@
 collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
 # Don't try modifying collect2 (aka ld) in place--it might be linking this.
@@ -1203,9 +1208,8 @@ collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) gstab.h intl.h \
        -DTARGET_MACHINE=\"$(target_alias)\" \
        -c $(srcdir)/collect2.c $(OUTPUT_OPTION)
 
-tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) $(SYSTEM_H) collect2.h intl.h
-hash.o: hash.c hash.h $(SYSTEM_H) toplev.h $(GCONFIG_H)
-       $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) \
+    $(OBSTACK_H) collect2.h intl.h
 
 underscore.c: s-under ; @true
 
@@ -1227,7 +1231,7 @@ s-under: $(GCC_PASSES)
 c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
        $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
        $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
-       diagnostic.h tree-inline.h except.h real.h
+       diagnostic.h tree-inline.h except.h gt-c-common.h real.h
 
 # A file used by all variants of C and some other languages.
 
@@ -1314,8 +1318,13 @@ dumpvers: dumpvers.c
 
 version.o: version.c version.h
 
+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) varray.h $(HASHTAB_H) \
+       $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
+       libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
+       ssa.h cselib.h insn-addr.h
+
 ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-       flags.h $(GGC_H) varray.h hash.h $(HASHTAB_H) $(TM_P_H) langhooks.h
+       flags.h $(GGC_H) varray.h $(HASHTAB_H) $(TM_P_H) langhooks.h
 
 ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
        $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H)
@@ -1324,7 +1333,7 @@ ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
        toplev.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H)
 
 stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
-       flags.h toplev.h
+       flags.h toplev.h $(GGC_H)
 
 hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
 
@@ -1345,7 +1354,8 @@ langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
    tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h \
    $(LANGHOOKS_DEF_H) flags.h
 tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
-   $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h real.h
+   $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
+   real.h gt-tree.h
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
    flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
    $(EXPR_H) $(SPLAY_TREE_H) tree-dump.h
@@ -1392,21 +1402,22 @@ errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h
        $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
 
 varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
-   function.h $(EXPR_H) hard-reg-set.h $(REGS_H) $(OBSTACK_H) \
+   function.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
    output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
-   $(HASHTAB_H) $(TARGET_H) langhooks.h
+   $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h
 function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
-   insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) \
-   $(TM_P_H) langhooks.h
+   insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
+   $(TM_P_H) langhooks.h gt-function.h
 stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h  \
    insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
    $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
-   langhooks.h $(PREDICT_H)
+   langhooks.h $(PREDICT_H) gt-stmt.h
 except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    except.h function.h $(EXPR_H) libfuncs.h integrate.h langhooks.h \
    insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
-   dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H)
+   dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) \
+   gt-except.h
 expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
    $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h insn-attr.h insn-config.h \
    $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
@@ -1423,10 +1434,10 @@ expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h  \
    toplev.h $(TM_P_H) langhooks.h
 explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
-   toplev.h function.h ggc.h $(TM_P_H)
+   toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
 optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h  \
    insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
-   toplev.h $(GGC_H) real.h $(TM_P_H) except.h
+   toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h
 dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
     $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
    insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
@@ -1434,16 +1445,16 @@ debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H)
 sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
    function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) real.h \
    insn-config.h $(OBSTACK_H) xcoffout.h c-pragma.h ggc.h \
-   sdbout.h toplev.h $(TM_P_H) except.h debug.h langhooks.h
+   sdbout.h toplev.h $(TM_P_H) except.h debug.h langhooks.h gt-sdbout.h
 dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \
    flags.h insn-config.h reload.h output.h toplev.h $(TM_P_H) \
    debug.h langhooks.h
 dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf2.h \
    debug.h flags.h insn-config.h reload.h output.h diagnostic.h real.h \
    hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
-   $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h
+   $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h gt-dwarf2out.h
 dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
-   output.h dwarf2asm.h $(TM_P_H)
+   output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
 vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
    output.h vmsdbg.h debug.h langhooks.h
 xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) xcoffout.h \
@@ -1456,7 +1467,7 @@ real.o : real.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h $(TM_P_H)
 integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    debug.h $(INTEGRATE_H) insn-config.h $(EXPR_H) real.h $(REGS_H) \
    intl.h function.h output.h $(RECOG_H) except.h toplev.h $(LOOP_H) \
-   $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h
+   $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h gt-integrate.h
 jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
    insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
    toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H)
@@ -1466,13 +1477,13 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
    output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H)
 cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
    hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
-   output.h function.h cselib.h $(GGC_H) $(OBSTACK_H) $(TM_P_H)
+   output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h
 cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
    real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h \
    $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H)
 gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h \
    flags.h real.h insn-config.h ggc.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
-   function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) except.h
+   function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h
 sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) function.h \
    hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
 resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
@@ -1497,7 +1508,7 @@ conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H) $(HASHTAB_H) \
 profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    insn-config.h output.h $(REGS_H) $(EXPR_H) function.h \
    gcov-io.h toplev.h $(GGC_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TARGET_H) \
-   langhooks.h profile.h libfuncs.h
+   langhooks.h profile.h libfuncs.h gt-profile.h
 loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
    insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \
    real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h \
@@ -1537,14 +1548,13 @@ regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h flags.h
 local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
    $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
    output.h function.h $(INSN_ATTR_H) toplev.h  except.h $(TM_P_H)
-bitmap.o : bitmap.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(BASIC_BLOCK_H) \
-   $(REGS_H)
+bitmap.o : bitmap.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
+   $(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
        $(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
 global.o : global.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h reload.h function.h \
    $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h toplev.h \
    $(TM_P_H)
-varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) varray.h $(RTL_H) $(TREE_H) bitmap.h \
-   errors.h
+varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) varray.h $(GGC_H) errors.h
 reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h output.h \
    $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) hard-reg-set.h insn-config.h \
    $(REGS_H) function.h real.h toplev.h $(TM_P_H)
@@ -1560,7 +1570,8 @@ reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) conditions.h hard-reg-set.h \
    $(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H)
 alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
    $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h $(EXPR_H) \
-   $(GGC_H) function.h cselib.h $(TREE_H) $(TM_P_H) langhooks.h $(TARGET_H)
+   $(GGC_H) function.h cselib.h $(TREE_H) $(TM_P_H) langhooks.h $(TARGET_H) \
+   gt-alias.h
 regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
    $(RECOG_H) output.h $(REGS_H) hard-reg-set.h flags.h function.h \
    $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
@@ -1588,7 +1599,7 @@ recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \
    $(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
 reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \
    $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
-   varray.h function.h $(TM_P_H)
+   varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h
 predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
    insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
    $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H) real.h \
@@ -1610,7 +1621,7 @@ ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
    flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
    output.h except.h $(TM_P_H)
 dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
-   $(C_COMMON_H) flags.h varray.h $(EXPR_H)
+   $(C_COMMON_H) flags.h varray.h $(EXPR_H) $(GGC_H) gt-dependence.h
 params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
 hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) $(HOOKS_H)
 
@@ -1793,6 +1804,38 @@ s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
        $(SHELL) $(srcdir)/move-if-change tmp-preds.h tm-preds.h
        $(STAMP) s-preds
 
+GTFILES = $(GCONFIG_H) \
+  $(HASHTAB_H) \
+  $(srcdir)/bitmap.h $(srcdir)/function.h  $(srcdir)/rtl.h $(srcdir)/optabs.h \
+  $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h $(srcdir)/real.h \
+  $(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h $(srcdir)/cselib.h \
+  $(srcdir)/c-common.h $(srcdir)/c-tree.h \
+  $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c \
+  $(srcdir)/dependence.c $(srcdir)/dwarf2out.c $(srcdir)/emit-rtl.c \
+  $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
+  $(srcdir)/fold-const.c $(srcdir)/function.c \
+  $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
+  $(srcdir)/profile.c $(srcdir)/regclass.c $(srcdir)/reg-stack.c \
+  $(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
+  $(srcdir)/tree.c $(srcdir)/varasm.c \
+  $(srcdir)/c-objc-common.c $(srcdir)/c-common.c $(srcdir)/c-parse.in \
+  $(out_file) \
+  $(srcdir)/c-decl.c $(srcdir)/c-pragma.c \
+  @all_gtfiles@
+
+gtype-desc.h gtype-desc.c gt-except.h gt-function.h : s-gtype; @true
+gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h gt-emit-rtl.h : s-gtype; @true
+gt-explow.h gt-stor-layout.h gt-regclass.h gt-lists.h : s-gtype; @true
+gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h gt-profile.h : s-gtype; @true
+gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dwarf2out.h : s-gtype ; @true
+gt-reg-stack.h gt-dependence.h : s-gtype ; @true
+gt-c-common.h gt-c-decl.h gt-c-parse.h gt-c-pragma.h : s-gtype; @true
+gt-c-objc-common.h gtype-c.h : s-gtype ; @true
+
+s-gtype: gengtype$(build_exeext) $(GTFILES)
+       ./gengtype $(GTFILES)
+       $(STAMP) s-gtype
+
 #\f
 # Compile the programs that generate insn-* from the machine description.
 # They are compiled with $(HOST_CC), and associated libraries,
@@ -1899,7 +1942,7 @@ genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(OUTPUT_OPTION)
 
 genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
-  $(SYSTEM_H) errors.h varray.h hash.h genattrtab.h
+  $(SYSTEM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
 
 genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
@@ -1924,6 +1967,33 @@ genpreds$(build_exeext) : genpreds.o $(HOST_LIBDEPS)
 genpreds.o : genpreds.c $(RTL_BASE_H) $(HCONFIG_H) $(SYSTEM_H)
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpreds.c $(OUTPUT_OPTION)
 
+gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \
+  $(HOST_LIBDEPS)
+       $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
+        gengtype.o gengtype-lex.o gengtype-yacc.o $(HOST_LIBS)
+
+gengtype.o : gengtype.c gengtype.h $(HCONFIG_H) $(SYSTEM_H) real.h
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+         $(srcdir)/gengtype.c $(OUTPUT_OPTION)
+
+gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.c \
+  $(HCONFIG_H) $(SYSTEM_H)
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+         $(srcdir)/gengtype-lex.c $(OUTPUT_OPTION)
+
+gengtype-yacc.o : gengtype-yacc.c gengtype.h $(HCONFIG_H) $(SYSTEM_H)
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+         $(srcdir)/gengtype-yacc.c $(OUTPUT_OPTION)
+
+$(srcdir)/gengtype-lex.c : $(srcdir)/gengtype-lex.l
+       $(FLEX) $(FLEXFLAGS) -o$@ $(srcdir)/gengtype-lex.l \
+        || ( rm -f $@ && false )
+
+$(srcdir)/gengtype-yacc.c: $(srcdir)/gengtype-yacc.y
+       (cd $(srcdir) && \
+        $(BISON) $(BISONFLAGS) -d -o gengtype-yacc.c gengtype-yacc.y || \
+        ( rm -f $@ && false ) )
+
 #\f
 # Compile the libraries to be used by gen*.
 # If we are not cross-building, gen* use the same .o's that cc1 will use,
@@ -1941,8 +2011,8 @@ $(BUILD_PREFIX_1)print-rtl.o: $(srcdir)/print-rtl.c $(HCONFIG_H) \
        sed -e 's/config[.]h/hconfig.h/' $(srcdir)/print-rtl.c > $(BUILD_PREFIX)print-rtl.c
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)print-rtl.c $(OUTPUT_OPTION)
 
-$(BUILD_PREFIX_1)bitmap.o: $(srcdir)/bitmap.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
-  flags.h $(BASIC_BLOCK_H) $(REGS_H)
+$(BUILD_PREFIX_1)bitmap.o: $(srcdir)/bitmap.c $(HCONFIG_H) $(SYSTEM_H) \
+  $(RTL_H) flags.h $(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
        rm -f $(BUILD_PREFIX)bitmap.c
        sed -e 's/config[.]h/hconfig.h/' $(srcdir)/bitmap.c > $(BUILD_PREFIX)bitmap.c
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)bitmap.c $(OUTPUT_OPTION)
@@ -2303,11 +2373,10 @@ docdir = $(srcdir)/doc
 doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug
 info: $(docdir)/cpp.info $(docdir)/gcc.info $(docdir)/gccint.info lang.info $(docdir)/cppinternals.info
 
-$(docdir)/cpp.info: $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
+TEXI_CPP_FILES = $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
   $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-       cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cpp.info doc/cpp.texi
 
-$(docdir)/gcc.info: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
+TEXI_GCC_FILES = $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
         $(docdir)/frontends.texi $(docdir)/standards.texi \
         $(docdir)/invoke.texi $(docdir)/extend.texi $(docdir)/md.texi \
         $(docdir)/objc.texi $(docdir)/gcov.texi $(docdir)/trouble.texi \
@@ -2316,9 +2385,8 @@ $(docdir)/gcc.info: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
         $(docdir)/include/funding.texi $(docdir)/gnu.texi \
         $(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
         $(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-       cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gcc.info doc/gcc.texi
 
-$(docdir)/gccint.info: $(docdir)/gccint.texi \
+TEXI_GCCINT_FILES = $(docdir)/gccint.texi \
         $(docdir)/include/gcc-common.texi $(docdir)/contribute.texi \
         $(docdir)/makefile.texi $(docdir)/configterms.texi \
         $(docdir)/portability.texi $(docdir)/interface.texi \
@@ -2329,46 +2397,37 @@ $(docdir)/gccint.info: $(docdir)/gccint.texi \
         $(docdir)/headerdirs.texi $(docdir)/include/funding.texi \
         $(docdir)/gnu.texi $(docdir)/include/gpl.texi \
         $(docdir)/include/fdl.texi $(docdir)/contrib.texi \
-        $(docdir)/languages.texi $(docdir)/sourcebuild.texi
+        $(docdir)/languages.texi $(docdir)/sourcebuild.texi \
+        $(docdir)/gty.texi
+
+TEXI_CPPINT_FILES = $(docdir)/cppinternals.texi
+
+$(docdir)/cpp.info: $(TEXI_CPP_FILES)
+       cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cpp.info doc/cpp.texi
+
+$(docdir)/gcc.info: $(TEXI_GCC_FILES)
+       cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gcc.info doc/gcc.texi
+
+$(docdir)/gccint.info: $(TEXI_GCCINT_FILES)
        cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gccint.info doc/gccint.texi
 
-$(docdir)/cppinternals.info: $(docdir)/cppinternals.texi
+$(docdir)/cppinternals.info: $(TEXI_CPPINT_FILES)
        cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cppinternals.info \
                doc/cppinternals.texi
 
 dvi: gcc.dvi gccint.dvi cpp.dvi lang.dvi cppinternals.dvi
 
 # This works with GNU Make's default rule.
-cpp.dvi: $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
-       $(docdir)/cppenv.texi $(docdir)/cppopts.texi
+cpp.dvi: $(TEXI_CPP_FILES)
        $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cpp.texi
 
-gcc.dvi: $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
-        $(docdir)/frontends.texi $(docdir)/standards.texi \
-        $(docdir)/invoke.texi $(docdir)/extend.texi $(docdir)/md.texi \
-        $(docdir)/objc.texi $(docdir)/gcov.texi $(docdir)/trouble.texi \
-        $(docdir)/bugreport.texi $(docdir)/service.texi \
-        $(docdir)/contribute.texi $(docdir)/vms.texi \
-        $(docdir)/include/funding.texi $(docdir)/gnu.texi \
-        $(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
-        $(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
+gcc.dvi: $(TEXI_GCC_FILES)
        $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gcc.texi
 
-gccint.dvi: $(docdir)/gccint.texi \
-        $(docdir)/include/gcc-common.texi $(docdir)/contribute.texi \
-        $(docdir)/makefile.texi $(docdir)/configterms.texi \
-        $(docdir)/portability.texi $(docdir)/interface.texi \
-        $(docdir)/passes.texi $(docdir)/c-tree.texi \
-        $(docdir)/rtl.texi $(docdir)/md.texi $(docdir)/tm.texi \
-        $(docdir)/hostconfig.texi $(docdir)/fragments.texi \
-        $(docdir)/configfiles.texi $(docdir)/collect2.texi \
-        $(docdir)/headerdirs.texi $(docdir)/include/funding.texi \
-        $(docdir)/gnu.texi $(docdir)/include/gpl.texi \
-        $(docdir)/include/fdl.texi $(docdir)/contrib.texi \
-        $(docdir)/languages.texi $(docdir)/sourcebuild.texi
+gccint.dvi: $(TEXI_GCCINT_FILES)
        $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gccint.texi
 
-cppinternals.dvi: $(docdir)/cppinternals.texi
+cppinternals.dvi: $(TEXI_CPPINT_FILES)
        $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cppinternals.texi
 
 generated-manpages: $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1 \
index a17ab0357985ebea87d4dd9fe6d2225f28a7eb7a..0f28390b3ceb2bade1e155e411dc5f17bc274417 100644 (file)
@@ -1,3 +1,58 @@
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       Merge from pch-branch:
+
+       * config-lang.in (gtfiles): Add ada-tree.h.
+       * ada-tree.h (SET_TYPE_CI_CO_LIST): New.
+       (SET_TYPE_MODULUS): New.
+       (SET_TYPE_INDEX): New.
+       (SET_TYPE_DIGITS_VALUE): New.
+       (SET_TYPE_RM_SIZE): New.
+       (SET_TYPE_UNCONSTRAINED_ARRAY): New.
+       (SET_TYPE_ADA_SIZE): New.
+       (SET_TYPE_ACTUAL_BOUNDS): New.
+       (SET_DECL_CONST_CORRESPONDING_VAR): New.
+       (SET_DECL_ORIGINAL_FIELD): New.
+       (TREE_LOOP_ID): Correct typo.
+       * decl.c: Use new macros.
+       * utils.c: Include debug.h, use new macros.
+       * utils2.c: Use new macros.     
+
+       * ada-tree.h: Update all macros for new tree description.
+       (struct tree_loop_id): New.
+       (union lang_tree_node): New.
+       (struct lang_decl): New.
+       (struct lang_type): New.
+       * misc.c (gnat_mark_tree): Delete.
+       (LANG_HOOKS_MARK_TREE): Delete.
+       * trans.c (tree_transform): No longer any need to cast
+       for TREE_LOOP_ID.
+
+       * utils.c (struct language_function): New dummy structure.
+
+       * Makefile.in (decl.o): gt-ada-<filename.h> is in objdir, not srcdir.
+       (misc.o): Likewise.
+       (utils.o): Likewise; also gtype-ada.h.
+       * Make-lang.in (gnat1): Add dependency on s-gtype.
+       (gnatbind): Add dependency on $(CONFIG_H).
+       * utils.c: Correct last #include.
+       (stuct e_stack): Remove unnecessary 'static'.
+       (mark_e_stack): Remove unused prototype.
+
+       * scn-nlit.adb: Remove whitespace after version number to
+       keep lines under 80 chars.
+       * snames.adb: Likewise.
+       * treepr.ads: Likewise.
+       
+       * Makefile.in (decl.o): Include gt-ada-<filename>.h.
+       (misc.o): Likewise.
+       (utils.o): Include gt-ada-<filename>.h and gtype-ada.h.
+       * config-lang.in (gtfiles): New.
+       * decl.c: Use gengtype for roots.
+       * gigi.h: Use gengtype for roots.
+       * trans.c: Use gengtype for roots.
+       * utils.c: Use gengtype for roots, marking.  Include gtype-ada.h.
+
 2002-06-02  Gabriel Dos Reis  <gdr@codesourcery.com>
 
        * misc.c (gnat_init): Adjust setting of internal_error_function.
index 67a52df542c2e6265cec52bebcd74fbec12246e9..af91c3228262bb6760dc5148e0693c1b53185d0d 100644 (file)
@@ -205,10 +205,6 @@ gnat1$(exeext): $(TARGET_ADA_SRCS) $(GNAT1_OBJS) $(ADA_BACKEND) $(LIBDEPS)
                $(SYSLIBS)
        $(RM) stamp-gnatlib2 stamp-tools
 
-gnatbind$(exeext): ada/b_gnatb.o $(GNATBIND_OBJS)
-       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ ada/b_gnatb.o $(GNATBIND_OBJS) \
-             $(LIBIBERTY) $(LIBS)
-
 # use target-gcc target-gnatmake target-gnatbind target-gnatlink 
 gnattools: $(GCC_PARTS) $(CONFIG_H) prefix.o force
        $(MAKE) -C ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
@@ -272,6 +268,9 @@ gnatlib_and_tools: gnatlib gnattools
 # use cross-gcc
 gnat-cross: force
        $(MAKE) -C ada $(FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) gnat-cross
+
+gt-ada-decl.h gt-ada-trans.h gt-ada-utils.h gtype-ada.h : s-gtype ; @true
+
 \f
 # Build hooks:
 
@@ -1002,7 +1001,8 @@ ada/cuintp.o : ada/cuintp.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) ada/ada.h \
 ada/decl.o : ada/decl.c $(CONFIG_H) $(TREE_H) $(srcdir)/flags.h \
    $(srcdir)/toplev.h $(srcdir)/convert.h ada/ada.h ada/types.h ada/atree.h \
    ada/nlists.h ada/elists.h ada/uintp.h ada/sinfo.h ada/einfo.h ada/snames.h \
-   ada/namet.h ada/stringt.h ada/repinfo.h ada/fe.h $(ADA_TREE_H) ada/gigi.h
+   ada/namet.h ada/stringt.h ada/repinfo.h ada/fe.h $(ADA_TREE_H) ada/gigi.h \
+   gt-ada-decl.h
 
 ada/misc.o : ada/misc.c $(CONFIG_H) $(TREE_H) $(RTL_H) $(srcdir)/expr.h \
    insn-codes.h insn-flags.h insn-config.h $(srcdir)/recog.h \
@@ -1020,12 +1020,13 @@ ada/targtyps.o : ada/targtyps.c $(CONFIG_H) ada/ada.h ada/types.h ada/atree.h \
 ada/trans.o : ada/trans.c $(CONFIG_H) $(TREE_H) $(RTL_H) $(srcdir)/flags.h \
    ada/ada.h $(srcdir)/except.h ada/types.h ada/atree.h ada/nlists.h \
    ada/elists.h ada/uintp.h ada/sinfo.h ada/einfo.h ada/namet.h ada/snames.h \
-   ada/stringt.h ada/urealp.h ada/fe.h $(ADA_TREE_H) ada/gigi.h
+   ada/stringt.h ada/urealp.h ada/fe.h $(ADA_TREE_H) ada/gigi.h gt-ada-trans.h
 
 ada/utils.o : ada/utils.c $(CONFIG_H) $(TREE_H) $(srcdir)/flags.h \
    $(srcdir)/expr.h $(srcdir)/convert.h $(srcdir)/defaults.h ada/ada.h \
    ada/types.h ada/atree.h ada/nlists.h ada/elists.h ada/sinfo.h ada/einfo.h \
-   ada/namet.h ada/stringt.h ada/uintp.h ada/fe.h $(ADA_TREE_H) ada/gigi.h
+   ada/namet.h ada/stringt.h ada/uintp.h ada/fe.h $(ADA_TREE_H) ada/gigi.h \
+   gt-ada-utils.h gtype-ada.h
 
 ada/utils2.o : ada/utils2.c $(CONFIG_H) $(TREE_H) $(srcdir)/flags.h ada/ada.h \
    ada/types.h ada/atree.h ada/nlists.h ada/elists.h ada/sinfo.h ada/einfo.h \
index 40435d723939c16e9d352c5c01e6eeb97cd368c4..b22f081bb6a5ee73188ff2a67907fdfa2a2c652d 100644 (file)
@@ -34,6 +34,35 @@ enum gnat_tree_code {
 };
 #undef DEFTREECODE
 
+/* A tree to hold a loop ID.  */
+struct tree_loop_id GTY(()) 
+{
+  struct tree_common common;
+  struct nesting *loop_id;
+};
+
+/* The language-specific tree.  */
+union lang_tree_node 
+  GTY((desc ("TREE_CODE (&%h.generic) == GNAT_LOOP_ID")))
+{
+  union tree_node GTY ((tag ("0"), 
+                       desc ("tree_node_structure (&%h)"))) 
+    generic;
+  struct tree_loop_id GTY ((tag ("1"))) loop_id;
+};
+
+/* Ada uses the lang_decl and lang_type fields to hold more trees.  */
+struct lang_decl GTY(()) 
+{
+  union lang_tree_node 
+    GTY((desc ("TREE_CODE (&%h.generic) == GNAT_LOOP_ID"))) t;
+};
+struct lang_type GTY(())
+{
+  union lang_tree_node 
+    GTY((desc ("TREE_CODE (&%h.generic) == GNAT_LOOP_ID"))) t;
+};
+
 /* Flags added to GCC type nodes.  */
 
 /* For RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE, nonzero if this is a
@@ -129,29 +158,39 @@ enum gnat_tree_code {
    by copy in copy out.  It is a CONSTRUCTOR.  For a full description of the
    cico parameter passing mechanism refer to the routine gnat_to_gnu_entity. */
 #define TYPE_CI_CO_LIST(NODE)   \
-  (tree) TYPE_LANG_SPECIFIC (FUNCTION_TYPE_CHECK (NODE))
+  (&TYPE_LANG_SPECIFIC (FUNCTION_TYPE_CHECK (NODE))->t.generic)
+#define SET_TYPE_CI_CO_LIST(NODE, X)   \
+  (TYPE_LANG_SPECIFIC (FUNCTION_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 /* For an INTEGER_TYPE with TYPE_MODULAR_P, this is the value of the
    modulus. */
 #define TYPE_MODULUS(NODE)  \
-  (tree) TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE))
+  (&TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE))->t.generic)
+#define SET_TYPE_MODULUS(NODE, X)  \
+  (TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 /* For an INTEGER_TYPE that is the TYPE_DOMAIN of some ARRAY_TYPE, points to
    the type corresponding to the Ada index type.  */
 #define TYPE_INDEX_TYPE(NODE)  \
-  (tree) TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE))
+  (&TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE))->t.generic)
+#define SET_TYPE_INDEX_TYPE(NODE, X)   \
+  (TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 /* For an INTEGER_TYPE with TYPE_VAX_FLOATING_POINT_P, stores the
    Digits_Value.  */
 #define TYPE_DIGITS_VALUE(NODE)  \
-  (long) TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE))
+  ((long) TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE)))
+#define SET_TYPE_DIGITS_VALUE(NODE, X)  \
+  (TYPE_LANG_SPECIFIC (INTEGER_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 /* For INTEGER_TYPE, stores the RM_Size of the type.  */
 #define TYPE_RM_SIZE_INT(NODE) TYPE_VALUES (INTEGER_TYPE_CHECK (NODE))
 
 /* Likewise for ENUMERAL_TYPE.  */
 #define TYPE_RM_SIZE_ENUM(NODE)        \
-  (tree) TYPE_LANG_SPECIFIC (ENUMERAL_TYPE_CHECK (NODE))
+  (&TYPE_LANG_SPECIFIC (ENUMERAL_TYPE_CHECK (NODE))->t.generic)
+#define SET_TYPE_RM_SIZE_ENUM(NODE, X) \
+  (TYPE_LANG_SPECIFIC (ENUMERAL_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 #define TYPE_RM_SIZE(NODE)                                     \
   (TREE_CODE (NODE) == ENUMERAL_TYPE ? TYPE_RM_SIZE_ENUM (NODE)        \
@@ -162,17 +201,23 @@ enum gnat_tree_code {
    unconstrained object.  Likewise for a RECORD_TYPE that is pointed
    to by a thin pointer.  */
 #define TYPE_UNCONSTRAINED_ARRAY(NODE)  \
-  (tree) TYPE_LANG_SPECIFIC (RECORD_TYPE_CHECK (NODE))
+  (&TYPE_LANG_SPECIFIC (RECORD_TYPE_CHECK (NODE))->t.generic)
+#define SET_TYPE_UNCONSTRAINED_ARRAY(NODE, X)  \
+  (TYPE_LANG_SPECIFIC (RECORD_TYPE_CHECK (NODE)) = (struct lang_type *)(X))
 
 /* For other RECORD_TYPEs and all UNION_TYPEs and QUAL_UNION_TYPEs, the Ada
    size of the object.  This differs from the GCC size in that it does not
    include any rounding up to the alignment of the type.  */
-#define TYPE_ADA_SIZE(NODE)    (tree) TYPE_LANG_SPECIFIC (NODE)
+#define TYPE_ADA_SIZE(NODE)    (&TYPE_LANG_SPECIFIC (NODE)->t.generic)
+#define SET_TYPE_ADA_SIZE(NODE, X) \
+  (TYPE_LANG_SPECIFIC (NODE) = (struct lang_type *)(X))
 
 /* For an INTEGER_TYPE with TYPE_HAS_ACTUAL_BOUNDS_P or an ARRAY_TYPE, this is
    the index type that should be used when the actual bounds are required for
    a template.  This is used in the case of packed arrays.  */
-#define TYPE_ACTUAL_BOUNDS(NODE)   (tree) TYPE_LANG_SPECIFIC (NODE)
+#define TYPE_ACTUAL_BOUNDS(NODE)   (&TYPE_LANG_SPECIFIC (NODE)->t.generic)
+#define SET_TYPE_ACTUAL_BOUNDS(NODE, X) \
+  (TYPE_LANG_SPECIFIC (NODE) = (struct lang_type *)(X))
 
 /* In an UNCONSTRAINED_ARRAY_TYPE, points to the record containing both
    the template and object.  */
@@ -211,12 +256,16 @@ enum gnat_tree_code {
    memory.  Used when a scalar constant is aliased or has its
    address taken.  */
 #define DECL_CONST_CORRESPONDING_VAR(NODE) \
-  (tree) DECL_LANG_SPECIFIC (CONST_DECL_CHECK (NODE))
+  (&DECL_LANG_SPECIFIC (CONST_DECL_CHECK (NODE))->t.generic)
+#define SET_DECL_CONST_CORRESPONDING_VAR(NODE, X) \
+  (DECL_LANG_SPECIFIC (CONST_DECL_CHECK (NODE)) = (struct lang_decl *)(X))
 
 /* In a FIELD_DECL, points to the FIELD_DECL that was the ultimate
    source of the decl.  */
 #define DECL_ORIGINAL_FIELD(NODE) \
-  (tree) DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE))
+  (&DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE))->t.generic)
+#define SET_DECL_ORIGINAL_FIELD(NODE, X) \
+  (DECL_LANG_SPECIFIC (FIELD_DECL_CHECK (NODE)) = (struct lang_decl *)(X))
 
 /* In a FIELD_DECL corresponding to a discriminant, contains the
    discriminant number.  */
@@ -224,4 +273,5 @@ enum gnat_tree_code {
 
 /* This is a horrible kludge to store the loop_id of a loop into a tree
    node.  We need to find some other place to store it!  */
-#define TREE_LOOP_ID(NODE) (TREE_CHECK (NODE, GNAT_LOOP_ID)->real_cst.rtl)
+#define TREE_LOOP_ID(NODE) \
+  (((union lang_tree_node *)TREE_CHECK (NODE, GNAT_LOOP_ID))->loop_id.loop_id)
index d9029c14b8db5dac35dd0975ed2c16ec83952d5f..b0fe156af131d2c0d08887c1c326c07b815e88c0 100644 (file)
@@ -35,6 +35,8 @@ compilers="gnat1\$(exeext)"
 
 stagestuff="gnatbind\$(exeext) gnat1\$(exeext)"
 
+gtfiles="\$(srcdir)/ada/ada-tree.h \$(srcdir)/ada/gigi.h \$(srcdir)/ada/decl.c \$(srcdir)/ada/trans.c \$(srcdir)/ada/utils.c"
+
 diff_excludes="-x ada/a-einfo.h -x ada/a-sinfo.h -x ada/nmake.adb -x ada/nmake.ads -x ada/treeprs.ads -x ada/sysid.ads"
 
 outputs=ada/Makefile
index adf1d35744bd9d9d3bfe3f0df1ac90bc76f43bf9..fbced93ffd1aafad71d75cd4b293334ad0aa4a35 100644 (file)
@@ -1044,10 +1044,10 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
                || Address_Taken (gnat_entity)
                || Is_Aliased (gnat_entity)
                || Is_Aliased (Etype (gnat_entity))))
-         DECL_CONST_CORRESPONDING_VAR (gnu_decl)
-           = create_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
+         SET_DECL_CONST_CORRESPONDING_VAR (gnu_decl, 
+             create_var_decl (gnu_entity_id, gnu_ext_name, gnu_type,
                               gnu_expr, 0, Is_Public (gnat_entity), 0,
-                              static_p, 0);
+                              static_p, 0));
 
        /* If this is declared in a block that contains an block with an
           exception handler, we must force this variable in memory to
@@ -1184,7 +1184,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
        if (! integer_zerop (gnu_modulus))
          {
            TYPE_MODULAR_P (gnu_type) = 1;
-           TYPE_MODULUS (gnu_type) = gnu_modulus;
+           SET_TYPE_MODULUS (gnu_type, gnu_modulus);
            gnu_high = fold (build (MINUS_EXPR, gnu_type, gnu_modulus,
                                    convert (gnu_type, integer_one_node)));
          }
@@ -1308,7 +1308,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
                                         gnu_field_type, gnu_type, 1, 0, 0, 1),
          finish_record_type (gnu_type, gnu_field, 0, 0);
          TYPE_LEFT_JUSTIFIED_MODULAR_P (gnu_type) = 1;
-         TYPE_ADA_SIZE (gnu_type) = bitsize_int (esize);
+         SET_TYPE_ADA_SIZE (gnu_type, bitsize_int (esize));
        }
 
       break;
@@ -1320,8 +1320,8 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
        {
          gnu_type = make_signed_type (esize);
          TYPE_VAX_FLOATING_POINT_P (gnu_type) = 1;
-         TYPE_DIGITS_VALUE (gnu_type)
-           = UI_To_Int (Digits_Value (gnat_entity));
+         SET_TYPE_DIGITS_VALUE (gnu_type, 
+                                UI_To_Int (Digits_Value (gnat_entity)));
          break;
        }
 
@@ -1619,7 +1619,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
          = TYPE_REFERENCE_TO (gnu_type) = gnu_fat_type;
        TYPE_MODE (gnu_type) = BLKmode;
        TYPE_ALIGN (gnu_type) = TYPE_ALIGN (tem);
-       TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type) = gnu_type;
+       SET_TYPE_UNCONSTRAINED_ARRAY (gnu_fat_type, gnu_type);
 
        /* If the maximum size doesn't overflow, use it.  */
        if (TREE_CODE (gnu_max_size) == INTEGER_CST
@@ -1647,7 +1647,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
        DECL_FIELD_OFFSET (TREE_CHAIN (TYPE_FIELDS (tem))) = size_zero_node;
        DECL_FIELD_BIT_OFFSET (TREE_CHAIN (TYPE_FIELDS (tem)))
          = bitsize_zero_node;
-       TYPE_UNCONSTRAINED_ARRAY (tem) = gnu_type;
+       SET_TYPE_UNCONSTRAINED_ARRAY (tem, gnu_type);
        TYPE_OBJECT_RECORD_TYPE (gnu_type) = tem;
 
        /* Give the thin pointer type a name.  */
@@ -2066,18 +2066,18 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
                  TYPE_HAS_ACTUAL_BOUNDS_P (gnu_inner_type) = 1;
                }
 
-             TYPE_ACTUAL_BOUNDS (gnu_inner_type) = NULL_TREE;
+             SET_TYPE_ACTUAL_BOUNDS (gnu_inner_type, NULL_TREE);
 
              for (gnat_index = First_Index (gnat_entity);
                   Present (gnat_index); gnat_index = Next_Index (gnat_index))
-               TYPE_ACTUAL_BOUNDS (gnu_inner_type)
-                 = tree_cons (NULL_TREE,
+               SET_TYPE_ACTUAL_BOUNDS (gnu_inner_type,
+                   tree_cons (NULL_TREE,
                               get_unpadded_type (Etype (gnat_index)),
-                              TYPE_ACTUAL_BOUNDS (gnu_inner_type));
+                              TYPE_ACTUAL_BOUNDS (gnu_inner_type)));
 
              if (Convention (gnat_entity) != Convention_Fortran)
-               TYPE_ACTUAL_BOUNDS (gnu_inner_type)
-                 = nreverse (TYPE_ACTUAL_BOUNDS (gnu_inner_type));
+               SET_TYPE_ACTUAL_BOUNDS (gnu_inner_type,
+                   nreverse (TYPE_ACTUAL_BOUNDS (gnu_inner_type)));
 
              if (TREE_CODE (gnu_type) == RECORD_TYPE
                  && TYPE_LEFT_JUSTIFIED_MODULAR_P (gnu_type))
@@ -2577,9 +2577,10 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
 
                    DECL_INTERNAL_P (gnu_field)
                      = DECL_INTERNAL_P (gnu_old_field);
-                   DECL_ORIGINAL_FIELD (gnu_field)
-                     = DECL_ORIGINAL_FIELD (gnu_old_field) != 0
-                       ? DECL_ORIGINAL_FIELD (gnu_old_field) : gnu_old_field;
+                   SET_DECL_ORIGINAL_FIELD (gnu_field,
+                       (DECL_ORIGINAL_FIELD (gnu_old_field) != 0
+                        ? DECL_ORIGINAL_FIELD (gnu_old_field) 
+                        : gnu_old_field));
                    DECL_DISCRIMINANT_NUMBER (gnu_field)
                      = DECL_DISCRIMINANT_NUMBER (gnu_old_field);
                    TREE_THIS_VOLATILE (gnu_field)
@@ -2598,7 +2599,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
              TYPE_ALIGN (gnu_type) = TYPE_ALIGN (gnu_base_type);
              TYPE_SIZE (gnu_type) = TYPE_SIZE (gnu_base_type);
              TYPE_SIZE_UNIT (gnu_type) = TYPE_SIZE_UNIT (gnu_base_type);
-             TYPE_ADA_SIZE (gnu_type) = TYPE_ADA_SIZE (gnu_base_type);
+             SET_TYPE_ADA_SIZE (gnu_type, TYPE_ADA_SIZE (gnu_base_type));
 
              if (TREE_CODE (TYPE_SIZE (gnu_type)) != INTEGER_CST
                  && contains_placeholder_p (TYPE_SIZE (gnu_type)))
@@ -2623,10 +2624,10 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
                  && contains_placeholder_p (TYPE_ADA_SIZE (gnu_type)))
                for (gnu_temp = gnu_subst_list;
                     gnu_temp; gnu_temp = TREE_CHAIN (gnu_temp))
-                 TYPE_ADA_SIZE (gnu_type)
-                   = substitute_in_expr (TYPE_ADA_SIZE (gnu_type),
+                 SET_TYPE_ADA_SIZE (gnu_type,
+                     substitute_in_expr (TYPE_ADA_SIZE (gnu_type),
                                          TREE_PURPOSE (gnu_temp),
-                                         TREE_VALUE (gnu_temp));
+                                         TREE_VALUE (gnu_temp)));
 
              /* Recompute the mode of this record type now that we know its
                 actual size.  */
@@ -2816,7 +2817,7 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
            if (gnu_type == 0)
              {
                gnu_type = make_node (RECORD_TYPE);
-               TYPE_UNCONSTRAINED_ARRAY (gnu_type) = gnu_old;
+               SET_TYPE_UNCONSTRAINED_ARRAY (gnu_type, gnu_old);
                TYPE_POINTER_TO (gnu_old) = gnu_type;
 
                set_lineno (gnat_entity, 0);
@@ -3670,11 +3671,14 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
          if (TREE_CODE (gnu_type) == RECORD_TYPE
              && operand_equal_p (TYPE_ADA_SIZE (gnu_type),
                                  TYPE_SIZE (gnu_type), 0))
-           TYPE_ADA_SIZE (gnu_type) = TYPE_SIZE (gnu_type)
-             = elaborate_expression_1 (gnat_entity, gnat_entity,
-                                       TYPE_SIZE (gnu_type),
-                                       get_identifier ("SIZE"),
-                                       definition, 0);
+           {
+             TYPE_SIZE (gnu_type)
+               = elaborate_expression_1 (gnat_entity, gnat_entity,
+                                         TYPE_SIZE (gnu_type),
+                                         get_identifier ("SIZE"),
+                                         definition, 0);
+             SET_TYPE_ADA_SIZE (gnu_type, TYPE_SIZE (gnu_type));
+           }
          else
            {
              TYPE_SIZE (gnu_type)
@@ -3699,11 +3703,11 @@ gnat_to_gnu_entity (gnat_entity, gnu_expr, definition)
                   size_int (TYPE_ALIGN (gnu_type) / BITS_PER_UNIT));
 
              if (TREE_CODE (gnu_type) == RECORD_TYPE)
-               TYPE_ADA_SIZE (gnu_type)
-                 = elaborate_expression_1 (gnat_entity, gnat_entity,
+               SET_TYPE_ADA_SIZE (gnu_type,
+                   elaborate_expression_1 (gnat_entity, gnat_entity,
                                            TYPE_ADA_SIZE (gnu_type),
                                            get_identifier ("RM_SIZE"),
-                                           definition, 0);
+                                           definition, 0));
            }
        }
 
@@ -4040,7 +4044,7 @@ substitution_list (gnat_subtype, gnat_type, gnu_list, definition)
 /* For the following two functions: for each GNAT entity, the GCC
    tree node used as a dummy for that entity, if any.  */
 
-static tree *dummy_node_table;
+static GTY((length ("max_gnat_nodes"))) tree * dummy_node_table;
 
 /* Initialize the above table.  */
 
@@ -4049,8 +4053,7 @@ init_dummy_type ()
 {
   Node_Id gnat_node;
 
-  dummy_node_table = (tree *) xmalloc (max_gnat_nodes * sizeof (tree));
-  ggc_add_tree_root (dummy_node_table, max_gnat_nodes);
+  dummy_node_table = (tree *) ggc_alloc (max_gnat_nodes * sizeof (tree));
 
   for (gnat_node = 0; gnat_node < max_gnat_nodes; gnat_node++)
     dummy_node_table[gnat_node] = NULL_TREE;
@@ -4447,9 +4450,9 @@ make_packable_type (type)
                             ! DECL_NONADDRESSABLE_P (old_field));
 
       DECL_INTERNAL_P (new_field) = DECL_INTERNAL_P (old_field);
-      DECL_ORIGINAL_FIELD (new_field)
-       = (DECL_ORIGINAL_FIELD (old_field) != 0
-          ? DECL_ORIGINAL_FIELD (old_field) : old_field);
+      SET_DECL_ORIGINAL_FIELD (new_field,
+         (DECL_ORIGINAL_FIELD (old_field) != 0
+          ? DECL_ORIGINAL_FIELD (old_field) : old_field));
       TREE_CHAIN (new_field) = field_list;
       field_list = new_field;
     }
@@ -4583,7 +4586,7 @@ maybe_pad_type (type, size, align, gnat_entity, name_trailer,
 
   /* Keep the RM_Size of the padded record as that of the old record
      if requested.  */
-  TYPE_ADA_SIZE (record) = same_rm_size ? size : rm_size (type);
+  SET_TYPE_ADA_SIZE (record, same_rm_size ? size : rm_size (type));
 
   /* Unless debugging information isn't being written for the input type,
      write a record that shows what we are a subtype of and also make a
@@ -5696,12 +5699,12 @@ set_rm_size (uint_size, gnu_type, gnat_entity)
       && Is_Discrete_Or_Fixed_Point_Type (gnat_entity))
     TYPE_RM_SIZE_INT (gnu_type) = size;
   else if (TREE_CODE (gnu_type) == ENUMERAL_TYPE)
-    TYPE_RM_SIZE_ENUM (gnu_type) = size;
+    SET_TYPE_RM_SIZE_ENUM (gnu_type, size);
   else if ((TREE_CODE (gnu_type) == RECORD_TYPE
            || TREE_CODE (gnu_type) == UNION_TYPE
            || TREE_CODE (gnu_type) == QUAL_UNION_TYPE)
           && ! TYPE_IS_FAT_POINTER_P (gnu_type))
-    TYPE_ADA_SIZE (gnu_type) = size;
+    SET_TYPE_ADA_SIZE (gnu_type, size);
 }
 \f
 /* Given a type TYPE, return a new type whose size is appropriate for SIZE.
@@ -5935,8 +5938,8 @@ gnat_substitute_in_type (t, f, r)
 
          new = build_range_type (TREE_TYPE (t), low, high);
          if (TYPE_INDEX_TYPE (t))
-           TYPE_INDEX_TYPE (new)
-             = gnat_substitute_in_type (TYPE_INDEX_TYPE (t), f, r);
+           SET_TYPE_INDEX_TYPE (new, 
+               gnat_substitute_in_type (TYPE_INDEX_TYPE (t), f, r));
          return new;
        }
 
@@ -6056,9 +6059,9 @@ gnat_substitute_in_type (t, f, r)
              }
 
            DECL_CONTEXT (new_field) = new;
-           DECL_ORIGINAL_FIELD (new_field)
-             DECL_ORIGINAL_FIELD (field) != 0
-               ? DECL_ORIGINAL_FIELD (field) : field;
+           SET_DECL_ORIGINAL_FIELD (new_field,
+              (DECL_ORIGINAL_FIELD (field) != 0
+               ? DECL_ORIGINAL_FIELD (field) : field));
 
            /* If the size of the old field was set at a constant,
               propagate the size in case the type's size was variable.
@@ -6121,7 +6124,7 @@ gnat_substitute_in_type (t, f, r)
          {
            TYPE_SIZE (new) = TYPE_SIZE (t);
            TYPE_SIZE_UNIT (new) = TYPE_SIZE_UNIT (t);
-           TYPE_ADA_SIZE (new) = TYPE_ADA_SIZE (t);
+           SET_TYPE_ADA_SIZE (new, TYPE_ADA_SIZE (t));
          }
 
        return new;
@@ -6209,3 +6212,5 @@ concat_id_with_name (gnu_id, suffix)
   strcpy (Name_Buffer + len, suffix);
   return get_identifier (Name_Buffer);
 }
+
+#include "gt-ada-decl.h"
index 44b5937d7c17ed7a3a43751ba0135ac2ef0508fc..586b1fee9cf952bb33d7db7e39b273ae94485979 100644 (file)
@@ -159,7 +159,7 @@ extern const char *ref_filename;
 /* List of TREE_LIST nodes representing a block stack.  TREE_VALUE
    of each gives the variable used for the setjmp buffer in the current
    block, if any.  */
-extern tree gnu_block_stack;
+extern GTY(()) tree gnu_block_stack;
 
 /* This is the main program of the back-end.  It sets up all the table
    structures and then generates code.  */
@@ -348,8 +348,8 @@ enum standard_datatypes
   ADT_raise_nodefer_decl,
   ADT_LAST};
 
-extern tree gnat_std_decls[(int) ADT_LAST];
-extern tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
+extern GTY(()) tree gnat_std_decls[(int) ADT_LAST];
+extern GTY(()) tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
 
 #define longest_float_type_node gnat_std_decls[(int) ADT_longest_float_type]
 #define void_type_decl_node gnat_std_decls[(int) ADT_void_type_decl]
index b80f66683b6d5b85aabe1f82eb8e44d79f64aa1c..d1df13cc409da4c4302fa168432ebd1e8b4f2a0b 100644 (file)
@@ -8,7 +8,7 @@
 @c                                                                            o
 @c                              G N A T _ RM                                  o
 @c                                                                            o
-@c                            $Revision: 1.6 $
+@c                            $Revision: 1.3.8.1 $
 @c                                                                            o
 @c              Copyright (C) 1995-2002 Free Software Foundation              o
 @c                                                                            o
index 3bc01d303aae16ee54db23e1ca0a2b073c63babc..a03a216d78d1eebf098971f3358dcd0cf44f58fa 100644 (file)
@@ -86,7 +86,6 @@ static const char *gnat_printable_name        PARAMS  ((tree, int));
 static tree gnat_eh_runtime_type       PARAMS ((tree));
 static int gnat_eh_type_covers         PARAMS ((tree, tree));
 static void gnat_parse_file            PARAMS ((int));
-static void gnat_mark_tree             PARAMS ((tree));
 static rtx gnat_expand_expr            PARAMS ((tree, rtx, enum machine_mode,
                                                 int));
 
@@ -104,8 +103,6 @@ static rtx gnat_expand_expr         PARAMS ((tree, rtx, enum machine_mode,
 #define LANG_HOOKS_DECODE_OPTION       gnat_decode_option
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE          gnat_parse_file
-#undef LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE           gnat_mark_tree
 #undef LANG_HOOKS_HONOR_READONLY
 #define LANG_HOOKS_HONOR_READONLY      1
 #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
@@ -289,53 +286,6 @@ gnat_init_options ()
   gnat_argc = 1;
 }
 
-static void
-gnat_mark_tree (t)
-     tree t;
-{
-  switch (TREE_CODE (t))
-    {
-    case FUNCTION_TYPE:
-      ggc_mark_tree (TYPE_CI_CO_LIST (t));
-      return;
-
-    case INTEGER_TYPE:
-      if (TYPE_MODULAR_P (t))
-       ggc_mark_tree (TYPE_MODULUS (t));
-      else if (TYPE_VAX_FLOATING_POINT_P (t))
-       ;
-      else if (TYPE_HAS_ACTUAL_BOUNDS_P (t))
-       ggc_mark_tree (TYPE_ACTUAL_BOUNDS (t));
-      else
-       ggc_mark_tree (TYPE_INDEX_TYPE (t));
-      return;
-
-    case ENUMERAL_TYPE:
-      ggc_mark_tree (TYPE_RM_SIZE_ENUM (t));
-      return;
-
-    case ARRAY_TYPE:
-      ggc_mark_tree (TYPE_ACTUAL_BOUNDS (t));
-      return;
-
-    case RECORD_TYPE:  case UNION_TYPE:  case QUAL_UNION_TYPE:
-      /* This is really TYPE_UNCONSTRAINED_ARRAY for fat pointers.  */
-      ggc_mark_tree (TYPE_ADA_SIZE (t));
-      return;
-
-    case CONST_DECL:
-      ggc_mark_tree (DECL_CONST_CORRESPONDING_VAR (t));
-      return;
-
-    case FIELD_DECL:
-      ggc_mark_tree (DECL_ORIGINAL_FIELD (t));
-      return;
-
-    default:
-      return;
-    }
-}
-
 /* Here is the function to handle the compiler error processing in GCC.  */
 
 static void
index b74b5664d49b8596f9e31f7853fd852215f75a53..4cb9f02dc54e2d03bac46fa1e5afd19ecd1782a2 100644 (file)
@@ -6,7 +6,6 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision$
 --                                                                          --
 --          Copyright (C) 2001-2002 Free Software Foundation, Inc.          --
 --                                                                          --
index 4bba35c6cc3de83c209f1d6ee47e0f3c716209ed..7d0279858c82d30d1c6e8c81eb3903061a280a3c 100644 (file)
@@ -6,7 +6,6 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                            $Revision$
 --                                                                          --
 --             Copyright (C) 2001-2002 Free Software Foundation, Inc.       --
 --                                                                          --
index 707417b0e0fcefd6c5190d35ce95e1115b94d4b6..143eefa8d8851489a31bbc1087d00ec1679246e5 100644 (file)
@@ -6,7 +6,6 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision$
 --                                                                          --
 --             Copyright (C) 2001-2002 Free Software Foundation, Inc.       --
 --                                                                          --
index b70ff47262467342edbed794e5ee822f763f0f20..ef859cf674b355e9d4447bc41190d397b79bfbe8 100644 (file)
@@ -6,7 +6,6 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                            $Revision$
 --                                                                          --
 --             Copyright (C) 2001 Free Software Foundation, Inc.            --
 --                                                                          --
index 63aafe4a62eb72dd7ed02fcc6f6015a44abbaf21..2fafd48de8ef100c46eb1c7cdc4234cd58235459 100644 (file)
@@ -86,7 +86,7 @@ tree gnu_block_stack;
    variables.  TREE_VALUE is the VAR_DECL that stores the address of
    the raised exception.  Nonzero means we are in an exception
    handler.  Not used in the zero-cost case.  */
-static tree gnu_except_ptr_stack;
+static GTY(()) tree gnu_except_ptr_stack;
 
 /* Map GNAT tree codes to GCC tree codes for simple expressions.  */
 static enum tree_code gnu_codes[Number_Node_Kinds];
@@ -96,7 +96,7 @@ Node_Id error_gnat_node;
 
 /* Variable that stores a list of labels to be used as a goto target instead of
    a return in some functions.  See processing for N_Subprogram_Body.  */
-static tree gnu_return_label_stack;
+static GTY(()) tree gnu_return_label_stack;
 
 static tree tree_transform             PARAMS((Node_Id));
 static void elaborate_all_entities     PARAMS((Node_Id));
@@ -188,9 +188,6 @@ gigi (gnat_root, max_gnat_node, number_name, nodes_ptr, next_node_ptr,
   save_gnu_tree (Base_Type (standard_integer),
                 TYPE_NAME (integer_type_node), 0);
 
-  ggc_add_tree_root (&gnu_block_stack, 1);
-  ggc_add_tree_root (&gnu_except_ptr_stack, 1);
-  ggc_add_tree_root (&gnu_return_label_stack, 1);
   gnu_except_ptr_stack = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
 
   dconstp5 = REAL_VALUE_ATOF ("0.5", DFmode);
@@ -2318,7 +2315,7 @@ tree_transform (gnat_node)
          {
            tree gnu_loop_id = make_node (GNAT_LOOP_ID);
 
-           TREE_LOOP_ID (gnu_loop_id) = (rtx) loop_id;
+           TREE_LOOP_ID (gnu_loop_id) = loop_id;
            save_gnu_tree (Entity (Identifier (gnat_node)), gnu_loop_id, 1);
          }
 
@@ -2407,8 +2404,7 @@ tree_transform (gnat_node)
 
        if (Present (Name (gnat_node)))
          loop_id
-           = (struct nesting *)
-             TREE_LOOP_ID (get_gnu_tree (Entity (Name (gnat_node))));
+           = TREE_LOOP_ID (get_gnu_tree (Entity (Name (gnat_node))));
 
        if (Present (Condition (gnat_node)))
          gnu_cond = invert_truthvalue (gnat_truthvalue_conversion
@@ -5589,3 +5585,5 @@ init_code_table ()
   gnu_codes[N_Op_Shift_Right] = RSHIFT_EXPR;
   gnu_codes[N_Op_Shift_Right_Arithmetic] = RSHIFT_EXPR;
 }
+
+#include "gt-ada-trans.h"
index 292efd33650c9549186edc3cf472d7e2659b3c0d..11cee7568d46911a6e1d5cf51e2dec3c79523dc7 100644 (file)
@@ -33,6 +33,7 @@
 #include "toplev.h"
 #include "output.h"
 #include "ggc.h"
+#include "debug.h"
 #include "convert.h"
 
 #include "ada.h"
@@ -69,18 +70,22 @@ tree gnat_raise_decls[(int) LAST_REASON_CODE + 1];
 /* Associates a GNAT tree node to a GCC tree node. It is used in
    `save_gnu_tree', `get_gnu_tree' and `present_gnu_tree'. See documentation
    of `save_gnu_tree' for more info.  */
-static tree *associate_gnat_to_gnu;
+static GTY((length ("max_gnat_nodes"))) tree *associate_gnat_to_gnu;
 
 /* This listhead is used to record any global objects that need elaboration.
    TREE_PURPOSE is the variable to be elaborated and TREE_VALUE is the
    initial value to assign.  */
 
-static tree pending_elaborations;
+static GTY(()) tree pending_elaborations;
 
 /* This stack allows us to momentarily switch to generating elaboration
    lists for an inner context.  */
 
-static struct e_stack {struct e_stack *next; tree elab_list; } *elist_stack;
+struct e_stack GTY(()) {
+  struct e_stack *next; 
+  tree elab_list; 
+};
+static GTY(()) struct e_stack *elist_stack;
 
 /* This variable keeps a table for types for each precision so that we only 
    allocate each of them once. Signed and unsigned types are kept separate.
@@ -88,10 +93,10 @@ static struct e_stack {struct e_stack *next; tree elab_list; } *elist_stack;
    Note that these types are only used when fold-const requests something
    special.  Perhaps we should NOT share these types; we'll see how it
    goes later.  */
-static tree signed_and_unsigned_types[2 * MAX_BITS_PER_WORD + 1][2];
+static GTY(()) tree signed_and_unsigned_types[2 * MAX_BITS_PER_WORD + 1][2];
 
 /* Likewise for float types, but record these by mode.  */
-static tree float_types[NUM_MACHINE_MODES];
+static GTY(()) tree float_types[NUM_MACHINE_MODES];
 
 /* For each binding contour we allocate a binding_level structure which records
    the entities defined or declared in that contour. Contours include:
@@ -102,7 +107,7 @@ static tree float_types[NUM_MACHINE_MODES];
 
    Binding contours are used to create GCC tree BLOCK nodes.  */
 
-struct binding_level
+struct binding_level GTY(())
 {
   /* A chain of ..._DECL nodes for all variables, constants, functions,
      parameters and type declarations.  These ..._DECL nodes are chained
@@ -121,10 +126,10 @@ struct binding_level
 };
 
 /* The binding level currently in effect.  */
-static struct binding_level *current_binding_level = NULL;
+static GTY(()) struct binding_level *current_binding_level;
 
 /* A chain of binding_level structures awaiting reuse.  */
-static struct binding_level *free_binding_level = NULL;
+static GTY((deletable (""))) struct binding_level *free_binding_level;
 
 /* The outermost binding level. This binding level is created when the
    compiler is started and it will exist through the entire compilation.  */
@@ -133,6 +138,11 @@ static struct binding_level *global_binding_level;
 /* Binding level structures are initialized by copying this one.  */
 static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL};
 
+struct language_function GTY(())
+{
+  int unused;
+};
+
 static tree merge_sizes                        PARAMS ((tree, tree, tree, int, int));
 static tree compute_related_constant   PARAMS ((tree, tree));
 static tree split_plus                 PARAMS ((tree, tree *));
@@ -142,8 +152,6 @@ static tree convert_to_fat_pointer  PARAMS ((tree, tree));
 static tree convert_to_thin_pointer    PARAMS ((tree, tree));
 static tree make_descriptor_field      PARAMS ((const char *,tree, tree,
                                                 tree));
-static void mark_binding_level         PARAMS ((PTR));
-static void mark_e_stack               PARAMS ((PTR));
 \f
 /* Initialize the association of GNAT nodes to GCC trees.  */
 
@@ -152,22 +160,12 @@ init_gnat_to_gnu ()
 {
   Node_Id gnat_node;
 
-  associate_gnat_to_gnu = (tree *) xmalloc (max_gnat_nodes * sizeof (tree));
-  ggc_add_tree_root (associate_gnat_to_gnu, max_gnat_nodes);
+  associate_gnat_to_gnu = (tree *) ggc_alloc (max_gnat_nodes * sizeof (tree));
 
   for (gnat_node = 0; gnat_node < max_gnat_nodes; gnat_node++)
     associate_gnat_to_gnu[gnat_node] = NULL_TREE;
 
   pending_elaborations = build_tree_list (NULL_TREE, NULL_TREE);
-  ggc_add_tree_root (&pending_elaborations, 1);
-  ggc_add_root ((PTR) &elist_stack, 1, sizeof (struct e_stack), mark_e_stack);
-  ggc_add_tree_root (&signed_and_unsigned_types[0][0],
-                    (sizeof signed_and_unsigned_types
-                     / sizeof signed_and_unsigned_types[0][0]));
-  ggc_add_tree_root (float_types, ARRAY_SIZE (float_types));
-
-  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
-               mark_binding_level);
 }
 
 /* GNAT_ENTITY is a GNAT tree node for an entity.   GNU_DECL is the GCC tree
@@ -260,7 +258,7 @@ pushlevel (ignore)
     }
   else
     newlevel
-      = (struct binding_level *) xmalloc (sizeof (struct binding_level));
+      = (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
 
   *newlevel = clear_binding_level;
 
@@ -680,9 +678,6 @@ init_gigi_decls (long_long_float_type, exception_type)
   DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;
 
   main_identifier_node = get_identifier ("main");
-
-  ggc_add_tree_root (gnat_std_decls, ARRAY_SIZE (gnat_std_decls));
-  ggc_add_tree_root (gnat_raise_decls, ARRAY_SIZE (gnat_raise_decls));
 }
 \f
 /* This function is called indirectly from toplev.c to handle incomplete 
@@ -849,7 +844,7 @@ finish_record_type (record_type, fieldlist, has_rep, defer_debug)
   /* Now set any of the values we've just computed that apply.  */
   if (! TYPE_IS_FAT_POINTER_P (record_type)
       && ! TYPE_CONTAINS_TEMPLATE_P (record_type))
-    TYPE_ADA_SIZE (record_type) = ada_size;
+    SET_TYPE_ADA_SIZE (record_type, ada_size);
 
 #ifdef ROUND_TYPE_SIZE
   size = ROUND_TYPE_SIZE (record_type, size, TYPE_ALIGN (record_type));
@@ -1159,7 +1154,7 @@ create_subprog_type (return_type, param_decl_list, cico_list,
       || TYPE_RETURNS_BY_REF_P (type) != returns_by_ref)
     type = copy_type (type);
 
-  TYPE_CI_CO_LIST (type) = cico_list;
+  SET_TYPE_CI_CO_LIST (type, cico_list);
   TYPE_RETURNS_UNCONSTRAINED_P (type) = returns_unconstrained;
   TYPE_RETURNS_STACK_DEPRESSED (type) = returns_with_dsp;
   TYPE_RETURNS_BY_REF_P (type) = returns_by_ref;
@@ -1207,7 +1202,7 @@ create_index_type (min, max, index)
   else if (TYPE_INDEX_TYPE (type) != 0)
     type = copy_type (type);
 
-  TYPE_INDEX_TYPE (type) = index;
+  SET_TYPE_INDEX_TYPE (type, index);
   return type;
 }
 \f
@@ -1598,37 +1593,6 @@ get_pending_elaborations ()
   return result;
 }
 
-/* Mark the binding level stack.  */
-
-static void
-mark_binding_level (arg)
-     PTR arg;
-{
-  struct binding_level *level = *(struct binding_level **) arg;
-
-  for (; level != 0; level = level->level_chain)
-    {
-      ggc_mark_tree (level->names);
-      ggc_mark_tree (level->blocks);
-      ggc_mark_tree (level->this_block);
-    }
-}
-
-/* Mark the pending elaboration list.  */
-
-static void
-mark_e_stack (data)
-     PTR data;
-{
-  struct e_stack *p = *((struct e_stack **) data);
-
-  if (p != 0)
-    {
-      ggc_mark_tree (p->elab_list);
-      mark_e_stack (&p->next);
-    }
-}
-
 /* Return nonzero if there are pending elaborations.  */
 
 int
@@ -1643,7 +1607,7 @@ pending_elaborations_p ()
 void
 push_pending_elaborations ()
 {
-  struct e_stack *p = (struct e_stack *) xmalloc (sizeof (struct e_stack));
+  struct e_stack *p = (struct e_stack *) ggc_alloc (sizeof (struct e_stack));
 
   p->next = elist_stack;
   p->elab_list = pending_elaborations;
@@ -1660,7 +1624,6 @@ pop_pending_elaborations ()
 
   pending_elaborations = p->elab_list;
   elist_stack = p->next;
-  free (p);
 }
 
 /* Return the current position in pending_elaborations so we can insert
@@ -2666,7 +2629,7 @@ update_pointer_to (old_type, new_type)
                                  TREE_CHAIN (TYPE_FIELDS (ptr)), new_ref));
 
       for (var = TYPE_MAIN_VARIANT (ptr); var; var = TYPE_NEXT_VARIANT (var))
-       TYPE_UNCONSTRAINED_ARRAY (var) = new_type;
+       SET_TYPE_UNCONSTRAINED_ARRAY (var, new_type);
 
       TYPE_POINTER_TO (new_type) = TYPE_REFERENCE_TO (new_type)
        = TREE_TYPE (new_type) = ptr;
@@ -3366,3 +3329,6 @@ unchecked_convert (type, expr)
 
   return expr;
 }
+
+#include "gt-ada-utils.h"
+#include "gtype-ada.h"
index 6d76a4149ce2ce9fb68e3f79d58f4c398d564128..e3627a28e5e47ddf75d6886923d0c2af39f16be0 100644 (file)
@@ -514,7 +514,7 @@ nonbinary_modular_operation (op_code, type, lhs, rhs)
       /* Copy the node so we ensure it can be modified to make it modular.  */
       op_type = copy_node (gnat_type_for_size (precision, unsignedp));
       modulus = convert (op_type, modulus);
-      TYPE_MODULUS (op_type) = modulus;
+      SET_TYPE_MODULUS (op_type, modulus);
       TYPE_MODULAR_P (op_type) = 1;
       lhs = convert (op_type, lhs);
       rhs = convert (op_type, rhs);
@@ -530,7 +530,7 @@ nonbinary_modular_operation (op_code, type, lhs, rhs)
     {
       tree div_type = copy_node (gnat_type_for_size (needed_precision, 1));
       modulus = convert (div_type, modulus);
-      TYPE_MODULUS (div_type) = modulus;
+      SET_TYPE_MODULUS (div_type, modulus);
       TYPE_MODULAR_P (div_type) = 1;
       result = convert (op_type,
                        fold (build (TRUNC_MOD_EXPR, div_type,
index e3dd16008cfb2485548fcd1cc10635a9c56360fb..c528fcf15520a6d7c29fea5d06a944041d41e154 100644 (file)
@@ -152,7 +152,7 @@ static int nonlocal_set_p               PARAMS ((rtx));
    current function performs nonlocal memory memory references for the
    purposes of marking the function as a constant function.  */
 
-static rtx *reg_base_value;
+static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
 static rtx *new_reg_base_value;
 static unsigned int reg_base_value_size; /* size of reg_base_value array */
 
@@ -2663,8 +2663,8 @@ init_alias_analysis ()
      optimization.  Loop unrolling can create a large number of
      registers.  */
   reg_base_value_size = maxreg * 2;
-  reg_base_value = (rtx *) xcalloc (reg_base_value_size, sizeof (rtx));
-  ggc_add_rtx_root (reg_base_value, reg_base_value_size);
+  reg_base_value = (rtx *) ggc_alloc_cleared (reg_base_value_size
+                                             * sizeof (rtx));
 
   new_reg_base_value = (rtx *) xmalloc (reg_base_value_size * sizeof (rtx));
   reg_seen = (char *) xmalloc (reg_base_value_size);
@@ -2878,12 +2878,7 @@ end_alias_analysis ()
   reg_known_value_size = 0;
   free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
   reg_known_equiv_p = 0;
-  if (reg_base_value)
-    {
-      ggc_del_root (reg_base_value);
-      free (reg_base_value);
-      reg_base_value = 0;
-    }
+  reg_base_value = 0;
   reg_base_value_size = 0;
   if (alias_invariant)
     {
@@ -2891,3 +2886,5 @@ end_alias_analysis ()
       alias_invariant = 0;
     }
 }
+
+#include "gt-alias.h"
index 3f015a83434b40fbdb2ccfd3c12cbeac906e9dde..7de4c7c088a8524cff77a7fb163d013c20f15dfa 100644 (file)
@@ -33,7 +33,7 @@ typedef bitmap_head regset_head;
 typedef bitmap regset;
 
 /* Initialize a new regset.  */
-#define INIT_REG_SET(HEAD) bitmap_initialize (HEAD)
+#define INIT_REG_SET(HEAD) bitmap_initialize (HEAD, 1)
 
 /* Clear a register set by freeing up the linked list.  */
 #define CLEAR_REG_SET(HEAD) bitmap_clear (HEAD)
@@ -99,7 +99,7 @@ do {                                                                  \
 #define OBSTACK_ALLOC_REG_SET(OBSTACK) BITMAP_OBSTACK_ALLOC (OBSTACK)
 
 /* Initialize a register set.  Returns the new register set.  */
-#define INITIALIZE_REG_SET(HEAD) bitmap_initialize (&HEAD)
+#define INITIALIZE_REG_SET(HEAD) bitmap_initialize (&HEAD, 1)
 
 /* Do any cleanup needed on a regset when it is no longer used.  */
 #define FREE_REG_SET(REGSET) BITMAP_FREE(REGSET)
index 189c06edc7010ec9839c5e44f11ed01bf220250c..e22a524ce17fee65597d782f613e00b89f6d3e73 100644 (file)
@@ -23,6 +23,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtl.h"
 #include "flags.h"
 #include "obstack.h"
+#include "ggc.h"
 #include "bitmap.h"
 
 /* Obstack to allocate bitmap elements from.  */
@@ -40,13 +41,33 @@ static int bitmap_obstack_init = FALSE;
 /* Global data */
 bitmap_element bitmap_zero_bits;       /* An element of all zero bits.  */
 static bitmap_element *bitmap_free;    /* Freelist of bitmap elements.  */
+static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
 
+static void bitmap_elem_to_freelist    PARAMS ((bitmap, bitmap_element *));
 static void bitmap_element_free                PARAMS ((bitmap, bitmap_element *));
-static bitmap_element *bitmap_element_allocate PARAMS ((void));
+static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
 static int bitmap_element_zerop                PARAMS ((bitmap_element *));
 static void bitmap_element_link                PARAMS ((bitmap, bitmap_element *));
 static bitmap_element *bitmap_find_bit PARAMS ((bitmap, unsigned int));
 \f
+/* Add ELEM to the appropriate freelist.  */
+static INLINE void
+bitmap_elem_to_freelist (head, elt)
+     bitmap head;
+     bitmap_element *elt;
+{
+  if (head->using_obstack)
+    {
+      elt->next = bitmap_free;
+      bitmap_free = elt;
+    }
+  else
+    {
+      elt->next = bitmap_ggc_free;
+      bitmap_ggc_free = elt;
+    }
+}
+
 /* Free a bitmap element.  Since these are allocated off the
    bitmap_obstack, "free" actually means "put onto the freelist".  */
 
@@ -75,56 +96,68 @@ bitmap_element_free (head, elt)
       if (head->current)
        head->indx = head->current->indx;
     }
-
-  elt->next = bitmap_free;
-  bitmap_free = elt;
+  bitmap_elem_to_freelist (head, elt);
 }
 \f
 /* Allocate a bitmap element.  The bits are cleared, but nothing else is.  */
 
 static INLINE bitmap_element *
-bitmap_element_allocate ()
+bitmap_element_allocate (head)
+     bitmap head;
 {
   bitmap_element *element;
 
-  if (bitmap_free != 0)
-    {
-      element = bitmap_free;
-      bitmap_free = element->next;
-    }
-  else
+  if (head->using_obstack)
     {
-      /* We can't use gcc_obstack_init to initialize the obstack since
-        print-rtl.c now calls bitmap functions, and bitmap is linked
-        into the gen* functions.  */
-      if (!bitmap_obstack_init)
+      if (bitmap_free != 0)
        {
-         bitmap_obstack_init = TRUE;
-
-         /* Let particular systems override the size of a chunk.  */
+         element = bitmap_free;
+         bitmap_free = element->next;
+       }
+      else
+       {
+         /* We can't use gcc_obstack_init to initialize the obstack since
+            print-rtl.c now calls bitmap functions, and bitmap is linked
+            into the gen* functions.  */
+         if (!bitmap_obstack_init)
+           {
+             bitmap_obstack_init = TRUE;
+             
+             /* Let particular systems override the size of a chunk.  */
 #ifndef OBSTACK_CHUNK_SIZE
 #define OBSTACK_CHUNK_SIZE 0
 #endif
-         /* Let them override the alloc and free routines too.  */
+             /* Let them override the alloc and free routines too.  */
 #ifndef OBSTACK_CHUNK_ALLOC
 #define OBSTACK_CHUNK_ALLOC xmalloc
 #endif
 #ifndef OBSTACK_CHUNK_FREE
 #define OBSTACK_CHUNK_FREE free
 #endif
-
+             
 #if !defined(__GNUC__) || (__GNUC__ < 2)
 #define __alignof__(type) 0
 #endif
-
-         obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
-                                     __alignof__ (bitmap_element),
-                                     (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
-                                     (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+             
+             obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
+                                         __alignof__ (bitmap_element),
+                                         (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
+                                         (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+           }
+         
+         element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
+                                                     sizeof (bitmap_element));
        }
-
-      element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
-                                                 sizeof (bitmap_element));
+    }
+  else
+    {
+      if (bitmap_ggc_free != NULL)
+       {
+          element = bitmap_ggc_free;
+          bitmap_ggc_free = element->next;
+       }
+      else
+       element = ggc_alloc (sizeof (bitmap_element));
     }
 
   memset (element->bits, 0, sizeof (element->bits));
@@ -232,8 +265,7 @@ bitmap_clear (head)
   for (element = head->first; element != 0; element = next)
     {
       next = element->next;
-      element->next = bitmap_free;
-      bitmap_free = element;
+      bitmap_elem_to_freelist (head, element);
     }
 
   head->first = head->current = 0;
@@ -256,7 +288,7 @@ bitmap_copy (to, from)
   /* Copy elements in forward direction one at a time */
   for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
     {
-      bitmap_element *to_elt = bitmap_element_allocate ();
+      bitmap_element *to_elt = bitmap_element_allocate (to);
 
       to_elt->indx = from_ptr->indx;
 
@@ -363,7 +395,7 @@ bitmap_set_bit (head, bit)
 
   if (ptr == 0)
     {
-      ptr = bitmap_element_allocate ();
+      ptr = bitmap_element_allocate (head);
       ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
       ptr->bits[word_num] = bit_val;
       bitmap_element_link (head, ptr);
@@ -594,8 +626,7 @@ bitmap_operation (to, from1, from2, operation)
          changed = 1;
          to_tmp = to_ptr;
          to_ptr = to_ptr->next;
-         to_tmp->next = bitmap_free;
-         bitmap_free = to_tmp;
+         bitmap_elem_to_freelist (to, to_tmp);
        }
       if (to_ptr && to_ptr->indx == indx)
        {
@@ -603,7 +634,7 @@ bitmap_operation (to, from1, from2, operation)
          to_ptr = to_ptr->next;
        }
       else
-       to_tmp = bitmap_element_allocate ();
+       to_tmp = bitmap_element_allocate (to);
 
       /* Do the operation, and if any bits are set, link it into the
         linked list.  */
@@ -638,8 +669,7 @@ bitmap_operation (to, from1, from2, operation)
        }
       else
        {
-         to_tmp->next = bitmap_free;
-         bitmap_free = to_tmp;
+         bitmap_elem_to_freelist (to, to_tmp);
        }
     }
 
@@ -649,8 +679,16 @@ bitmap_operation (to, from1, from2, operation)
       changed = 1;
       for (to_tmp = to_ptr; to_tmp->next ; to_tmp = to_tmp->next)
        continue;
-      to_tmp->next = bitmap_free;
-      bitmap_free = to_ptr;
+      if (to->using_obstack)
+       {
+         to_tmp->next = bitmap_free;
+         bitmap_free = to_ptr;
+       }
+      else
+       {
+         to_tmp->next = bitmap_ggc_free;
+         bitmap_ggc_free = to_ptr;
+       }
     }
 
 #undef DOIT
@@ -715,10 +753,15 @@ bitmap_union_of_diff (dst, a, b, c)
 /* Initialize a bitmap header.  */
 
 bitmap
-bitmap_initialize (head)
+bitmap_initialize (head, using_obstack)
      bitmap head;
+     int using_obstack;
 {
+  if (head == NULL && ! using_obstack)
+    head = ggc_alloc (sizeof (*head));
+  
   head->first = head->current = 0;
+  head->using_obstack = using_obstack;
 
   return head;
 }
@@ -800,3 +843,5 @@ bitmap_print (file, head, prefix, suffix)
                            });
   fputs (suffix, file);
 }
+
+#include "gt-bitmap.h"
index c2dcb9df30eb4460c8ab483dff9519ae446ec031..ed402990f11d94f2da17fdcc2e17c28ca91ec8da 100644 (file)
@@ -40,7 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    having to realloc and copy a giant bit array.  The `prev' field is
    undefined for an element on the free list.  */
 
-typedef struct bitmap_element_def
+typedef struct bitmap_element_def GTY(())
 {
   struct bitmap_element_def *next;             /* Next element.  */
   struct bitmap_element_def *prev;             /* Previous element.  */
@@ -49,12 +49,14 @@ typedef struct bitmap_element_def
 } bitmap_element;
 
 /* Head of bitmap linked list.  */
-typedef struct bitmap_head_def {
+typedef struct bitmap_head_def GTY(()) {
   bitmap_element *first;       /* First element in linked list.  */
   bitmap_element *current;     /* Last element looked at.  */
   unsigned int indx;           /* Index of last element looked at.  */
-
-} bitmap_head, *bitmap;
+  int using_obstack;           /* Are we using an obstack or ggc for
+                                   allocation?  */
+} bitmap_head;
+typedef struct bitmap_head_def *bitmap;
 
 /* Enumeration giving the various operations we support.  */
 enum bitmap_bits {
@@ -100,10 +102,12 @@ extern void debug_bitmap_file PARAMS ((FILE *, bitmap));
 /* Print a bitmap */
 extern void bitmap_print PARAMS ((FILE *, bitmap, const char *, const char *));
 
-/* Initialize a bitmap header.  */
-extern bitmap bitmap_initialize PARAMS ((bitmap));
+/* Initialize a bitmap header.  If HEAD is NULL, a new header will be
+   allocated.  USING_OBSTACK indicates how elements should be allocated.  */
+extern bitmap bitmap_initialize PARAMS ((bitmap head, 
+                                        int using_obstack));
 
-/* Release all memory held by bitmaps.  */
+/* Release all memory used by the bitmap obstack.  */
 extern void bitmap_release_memory PARAMS ((void));
 
 /* A few compatibility/functions macros for compatibility with sbitmaps */
@@ -117,22 +121,15 @@ extern int bitmap_last_set_bit PARAMS((bitmap));
 
 /* Allocate a bitmap with oballoc.  */
 #define BITMAP_OBSTACK_ALLOC(OBSTACK)                          \
-  bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)))
-
-/* Allocate a bitmap with alloca.  Note alloca cannot be passed as an
-   argument to a function, so we set a temporary variable to the value
-   returned by alloca and pass that variable to bitmap_initialize().
-   PTR is then set to the value returned from bitmap_initialize() to
-   avoid having it appear more than once in case it has side effects.  */
-#define BITMAP_ALLOCA(PTR) \
-do { \
-  bitmap temp_bitmap_ = (bitmap) alloca (sizeof (bitmap_head)); \
-  (PTR) = bitmap_initialize (temp_bitmap_); \
-} while (0)
+  bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
+
+/* Allocate a bitmap with ggc_alloc.  */
+#define BITMAP_GGC_ALLOC()                     \
+  bitmap_initialize (NULL, 0)
 
 /* Allocate a bitmap with xmalloc.  */
 #define BITMAP_XMALLOC()                                        \
-  bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)))
+  bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)), 1)
 
 /* Do any cleanup needed on a bitmap when it is no longer used.  */
 #define BITMAP_FREE(BITMAP)                    \
index 995fc0c3f8c1c61c022692101fbea8af07f6e3ae..eaa812d587fdde270ad41c7a095cd1947438d5cf 100644 (file)
@@ -3750,41 +3750,6 @@ finish_label_address_expr (label)
   return result;
 }
 
-/* Mark P (a stmt_tree) for GC.  The use of a `void *' for the
-   parameter allows this function to be used as a GC-marking
-   function.  */
-
-void
-mark_stmt_tree (p)
-     void *p;
-{
-  stmt_tree st = (stmt_tree) p;
-
-  ggc_mark_tree (st->x_last_stmt);
-  ggc_mark_tree (st->x_last_expr_type);
-}
-
-/* Mark LD for GC.  */
-
-void
-c_mark_lang_decl (c)
-     struct c_lang_decl *c ATTRIBUTE_UNUSED;
-{
-}
-
-/* Mark F for GC.  */
-
-void
-mark_c_language_function (f)
-     struct language_function *f;
-{
-  if (!f)
-    return;
-
-  mark_stmt_tree (&f->x_stmt_tree);
-  ggc_mark_tree (f->x_scope_stmt_stack);
-}
-
 /* Hook used by expand_expr to expand language-specific tree codes.  */
 
 rtx
@@ -4288,7 +4253,7 @@ enum built_in_attribute
   ATTR_LAST
 };
 
-static tree built_in_attributes[(int) ATTR_LAST];
+static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
 
 static bool c_attrs_initialized = false;
 
@@ -4570,7 +4535,6 @@ c_init_attributes ()
 #undef DEF_ATTR_IDENT
 #undef DEF_ATTR_TREE_LIST
 #undef DEF_FN_ATTR
-  ggc_add_tree_root (built_in_attributes, (int) ATTR_LAST);
   c_attrs_initialized = true;
 }
 
@@ -5938,3 +5902,5 @@ check_function_arguments_recurse (callback, ctx, param, param_num)
 
   (*callback) (ctx, param, param_num);
 }
+
+#include "gt-c-common.h"
index aab0e33253eabea7684f77ee6a65d2c753e34861..d0523a50051992ca1ac6edc7fb6cc7c063030626 100644 (file)
@@ -183,10 +183,10 @@ enum c_tree_index
 
 /* Identifier part common to the C front ends.  Inherits from
    tree_identifier, despite appearances.  */
-struct c_common_identifier
+struct c_common_identifier GTY(())
 {
   struct tree_common common;
-  struct cpp_hashnode node;
+  struct cpp_hashnode GTY ((skip (""))) node;
 };
 
 #define wchar_type_node                        c_global_trees[CTI_WCHAR_TYPE]
@@ -231,7 +231,7 @@ struct c_common_identifier
 /* A node for `((void) 0)'.  */
 #define void_zero_node                  c_global_trees[CTI_VOID_ZERO]
 
-extern tree c_global_trees[CTI_MAX];
+extern GTY(()) tree c_global_trees[CTI_MAX];
 
 /* Mark which labels are explicitly declared.
    These may be shadowed, and may be referenced from nested functions.  */
@@ -252,7 +252,7 @@ c_language_kind;
 
 /* Information about a statement tree.  */
 
-struct stmt_tree_s {
+struct stmt_tree_s GTY(()) {
   /* The last statement added to the tree.  */
   tree x_last_stmt;
   /* The type of the last expression statement.  (This information is
@@ -282,7 +282,7 @@ typedef struct stmt_tree_s *stmt_tree;
 /* Global state pertinent to the current function.  Some C dialects
    extend this structure with additional fields.  */
 
-struct language_function {
+struct c_language_function GTY(()) {
   /* While we are parsing the function, this contains information
      about the statement-tree that we are building.  */
   struct stmt_tree_s x_stmt_tree;
@@ -344,7 +344,6 @@ extern tree walk_stmt_tree                  PARAMS ((tree *,
                                                         void *));
 extern void prep_stmt                           PARAMS ((tree));
 extern void expand_stmt                         PARAMS ((tree));
-extern void mark_stmt_tree                      PARAMS ((void *));
 extern void shadow_warning                     PARAMS ((const char *,
                                                         tree, tree));
 extern tree c_begin_if_stmt                    PARAMS ((void));
@@ -357,7 +356,7 @@ extern void c_finish_while_stmt_cond                PARAMS ((tree, tree));
    structure for FUNCTION_DECLs; all other DECLs have a NULL
    DECL_LANG_SPECIFIC field.  */
 
-struct c_lang_decl {
+struct c_lang_decl GTY(()) {
   unsigned declared_inline : 1;
 };
 
@@ -368,8 +367,6 @@ struct c_lang_decl {
 #define DECL_NUM_STMTS(NODE) \
   (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
 
-extern void c_mark_lang_decl                    PARAMS ((struct c_lang_decl *));
-
 /* The variant of the C language being processed.  Each C language
    front-end defines this variable.  */
 
@@ -869,8 +866,6 @@ extern tree boolean_increment                       PARAMS ((enum tree_code,
    after entering or leaving a header file.  */
 extern void extract_interface_info             PARAMS ((void));
 
-extern void mark_c_language_function            PARAMS ((struct language_function *));
-
 extern int case_compare                         PARAMS ((splay_tree_key,
                                                         splay_tree_key));
 
index 7e3309edf8b6680eafc852aea147d670c193bfea..6c16801e4e24126666b1ad958f3e3896196cab1e 100644 (file)
@@ -103,21 +103,21 @@ static int current_function_prototype_line;
 
 /* The current statement tree.  */
 
-static struct stmt_tree_s c_stmt_tree;
+static GTY(()) struct stmt_tree_s c_stmt_tree;
 
 /* The current scope statement stack.  */
 
-static tree c_scope_stmt_stack;
+static GTY(()) tree c_scope_stmt_stack;
 
 /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
    that have names.  Here so we can clear out their names' definitions
    at the end of the function.  */
 
-static tree named_labels;
+static GTY(()) tree named_labels;
 
 /* A list of LABEL_DECLs from outer contexts that are currently shadowed.  */
 
-static tree shadowed_labels;
+static GTY(()) tree shadowed_labels;
 
 /* Nonzero when store_parm_decls is called indicates a varargs function.
    Value not meaningful after store_parm_decls.  */
@@ -164,7 +164,7 @@ static int current_extern_inline;
 /* Note that the information in the `names' component of the global contour
    is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
 
-struct binding_level
+struct binding_level GTY(())
   {
     /* A chain of _DECL nodes for all variables, constants, functions,
        and typedef types.  These are in the reverse of the order supplied.
@@ -229,17 +229,17 @@ struct binding_level
 
 /* The binding level currently in effect.  */
 
-static struct binding_level *current_binding_level;
+static GTY(()) struct binding_level *current_binding_level;
 
 /* A chain of binding_level structures awaiting reuse.  */
 
-static struct binding_level *free_binding_level;
+static GTY((deletable (""))) struct binding_level *free_binding_level;
 
 /* The outermost binding level, for names of file scope.
    This is created when the compiler is started and exists
    through the entire run.  */
 
-static struct binding_level *global_binding_level;
+static GTY(()) struct binding_level *global_binding_level;
 
 /* Binding level structures are initialized by copying this one.  */
 
@@ -262,7 +262,7 @@ static int keep_next_if_subblocks;
    saved values of named_labels and shadowed_labels for
    a label binding level outside the current one.  */
 
-static struct binding_level *label_level_chain;
+static GTY(()) struct binding_level *label_level_chain;
 
 /* Functions called automatically at the beginning and end of execution.  */
 
@@ -271,7 +271,7 @@ tree static_ctors, static_dtors;
 /* Forward declarations.  */
 
 static struct binding_level * make_binding_level       PARAMS ((void));
-static void mark_binding_level         PARAMS ((void *));
+static void pop_binding_level          PARAMS ((struct binding_level **));
 static void clear_limbo_values         PARAMS ((tree));
 static int duplicate_decls             PARAMS ((tree, tree, int));
 static int redeclaration_error_message PARAMS ((tree, tree));
@@ -755,13 +755,33 @@ c_finish_incomplete_decl (decl)
     }
 }
 \f
-/* Create a new `struct binding_level'.  */
+/* Reuse or create a struct for this binding level.  */
 
 static struct binding_level *
 make_binding_level ()
 {
-  /* NOSTRICT */
-  return (struct binding_level *) xmalloc (sizeof (struct binding_level));
+  if (free_binding_level)
+    {
+      struct binding_level *result = free_binding_level;
+      free_binding_level = result->level_chain;
+      return result;
+    }
+  else
+    return (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
+}
+
+/* Remove a binding level from a list and add it to the level chain.  */
+
+static void
+pop_binding_level (lp)
+     struct binding_level **lp;
+{
+  struct binding_level *l = *lp;
+  *lp = l->level_chain;
+  
+  memset (l, 0, sizeof (struct binding_level));
+  l->level_chain = free_binding_level;
+  free_binding_level = l;
 }
 
 /* Nonzero if we are currently in the global binding level.  */
@@ -829,17 +849,7 @@ pushlevel (tag_transparent)
       named_labels = 0;
     }
 
-  /* Reuse or create a struct for this binding level.  */
-
-  if (free_binding_level)
-    {
-      newlevel = free_binding_level;
-      free_binding_level = free_binding_level->level_chain;
-    }
-  else
-    {
-      newlevel = make_binding_level ();
-    }
+  newlevel = make_binding_level ();
 
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
@@ -1060,13 +1070,7 @@ poplevel (keep, reverse, functionbody)
 
   /* Pop the current level, and free the structure for reuse.  */
 
-  {
-    struct binding_level *level = current_binding_level;
-    current_binding_level = current_binding_level->level_chain;
-
-    level->level_chain = free_binding_level;
-    free_binding_level = level;
-  }
+  pop_binding_level (&current_binding_level);
 
   /* Dispose of the block that we just made inside some higher level.  */
   if (functionbody)
@@ -1145,17 +1149,7 @@ push_label_level ()
 {
   struct binding_level *newlevel;
 
-  /* Reuse or create a struct for this binding level.  */
-
-  if (free_binding_level)
-    {
-      newlevel = free_binding_level;
-      free_binding_level = free_binding_level->level_chain;
-    }
-  else
-    {
-      newlevel = make_binding_level ();
-    }
+  newlevel = make_binding_level ();
 
   /* Add this level to the front of the chain (stack) of label levels.  */
 
@@ -1217,9 +1211,7 @@ pop_label_level ()
   shadowed_labels = level->shadowed;
 
   /* Pop the current level, and free the structure for reuse.  */
-  label_level_chain = label_level_chain->level_chain;
-  level->level_chain = free_binding_level;
-  free_binding_level = level;
+  pop_binding_level (&label_level_chain);
 }
 \f
 /* Push a definition or a declaration of struct, union or enum tag "name".
@@ -2864,26 +2856,6 @@ lookup_name_current_level (name)
   return t;
 }
 \f
-/* Mark ARG for GC.  */
-
-static void
-mark_binding_level (arg)
-     void *arg;
-{
-  struct binding_level *level = *(struct binding_level **) arg;
-
-  for (; level != 0; level = level->level_chain)
-    {
-      ggc_mark_tree (level->names);
-      ggc_mark_tree (level->tags);
-      ggc_mark_tree (level->shadowed);
-      ggc_mark_tree (level->blocks);
-      ggc_mark_tree (level->this_block);
-      ggc_mark_tree (level->parm_order);
-      ggc_mark_tree (level->incomplete_list);
-    }
-}
-
 /* Create the predefined scalar types of C,
    and some nodes representing standard constants (0, 1, (void *) 0).
    Initialize the global binding level.
@@ -2937,20 +2909,6 @@ c_init_decl_processing ()
 
   make_fname_decl = c_make_fname_decl;
   start_fname_decls ();
-
-  /* Record our roots.  */
-
-  ggc_add_tree_root (c_global_trees, CTI_MAX);
-  ggc_add_root (&c_stmt_tree, 1, sizeof c_stmt_tree, mark_stmt_tree);
-  ggc_add_tree_root (&c_scope_stmt_stack, 1);
-  ggc_add_tree_root (&named_labels, 1);
-  ggc_add_tree_root (&shadowed_labels, 1);
-  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
-               mark_binding_level);
-  ggc_add_root (&label_level_chain, 1, sizeof label_level_chain,
-               mark_binding_level);
-  ggc_add_tree_root (&static_ctors, 1);
-  ggc_add_tree_root (&static_dtors, 1);
 }
 
 /* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
@@ -7045,9 +7003,9 @@ check_for_loop_decls ()
    that keep track of the progress of compilation of the current function.
    Used for nested functions.  */
 
-struct c_language_function
+struct language_function GTY(())
 {
-  struct language_function base;
+  struct c_language_function base;
   tree named_labels;
   tree shadowed_labels;
   int returns_value;
@@ -7065,10 +7023,10 @@ void
 c_push_function_context (f)
      struct function *f;
 {
-  struct c_language_function *p;
-  p = ((struct c_language_function *)
-       xmalloc (sizeof (struct c_language_function)));
-  f->language = (struct language_function *) p;
+  struct language_function *p;
+  p = ((struct language_function *)
+       ggc_alloc (sizeof (struct language_function)));
+  f->language = p;
 
   p->base.x_stmt_tree = c_stmt_tree;
   p->base.x_scope_stmt_stack = c_scope_stmt_stack;
@@ -7088,8 +7046,7 @@ void
 c_pop_function_context (f)
      struct function *f;
 {
-  struct c_language_function *p
-    = (struct c_language_function *) f->language;
+  struct language_function *p = f->language;
   tree link;
 
   /* Bring back all the labels that were shadowed.  */
@@ -7119,26 +7076,7 @@ c_pop_function_context (f)
   current_extern_inline = p->extern_inline;
   current_binding_level = p->binding_level;
 
-  free (p);
-  f->language = 0;
-}
-
-/* Mark the language specific parts of F for GC.  */
-
-void
-c_mark_function_context (f)
-     struct function *f;
-{
-  struct c_language_function *p
-    = (struct c_language_function *) f->language;
-
-  if (p == 0)
-    return;
-
-  mark_c_language_function (&p->base);
-  ggc_mark_tree (p->shadowed_labels);
-  ggc_mark_tree (p->named_labels);
-  mark_binding_level (&p->binding_level);
+  f->language = NULL;
 }
 
 /* Copy the DECL_LANG_SPECIFIC data associated with DECL.  */
@@ -7158,32 +7096,6 @@ c_dup_lang_specific_decl (decl)
   DECL_LANG_SPECIFIC (decl) = ld;
 }
 
-/* Mark the language specific bits in T for GC.  */
-
-void
-c_mark_tree (t)
-     tree t;
-{
-  if (TREE_CODE (t) == IDENTIFIER_NODE)
-    {
-      struct lang_identifier *i = (struct lang_identifier *) t;
-      ggc_mark_tree (i->global_value);
-      ggc_mark_tree (i->local_value);
-      ggc_mark_tree (i->label_value);
-      ggc_mark_tree (i->implicit_decl);
-      ggc_mark_tree (i->error_locus);
-      ggc_mark_tree (i->limbo_value);
-    }
-  else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
-    ggc_mark (TYPE_LANG_SPECIFIC (t));
-  else if (DECL_P (t) && DECL_LANG_SPECIFIC (t))
-    {
-      ggc_mark (DECL_LANG_SPECIFIC (t));
-      c_mark_lang_decl (&DECL_LANG_SPECIFIC (t)->base);
-      ggc_mark_tree (DECL_LANG_SPECIFIC (t)->pending_sizes);
-    }
-}
-
 /* The functions below are required for functionality of doing
    function at once processing in the C front end. Currently these
    functions are not called from anywhere in the C front end, but as
@@ -7319,3 +7231,5 @@ make_pointer_declarator (type_quals_attrs, target)
     itarget = tree_cons (attrs, target, NULL_TREE);
   return build1 (INDIRECT_REF, quals, itarget);
 }
+
+#include "gt-c-decl.h"
index 07a60d0fb0f88b474efb210a043036f275d99aa4..60588fbd82d78bc075f9c7d9a00b109a35dafaa8 100644 (file)
@@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree.h"
 #include "c-tree.h"
 #include "c-common.h"
+#include "ggc.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
 
@@ -49,8 +50,6 @@ static void c_init_options PARAMS ((void));
 #define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
 #undef LANG_HOOKS_SAFE_FROM_P
 #define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
-#undef LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE c_mark_tree
 #undef LANG_HOOKS_EXPAND_EXPR
 #define LANG_HOOKS_EXPAND_EXPR c_expand_expr
 #undef LANG_HOOKS_MARK_ADDRESSABLE
@@ -75,8 +74,6 @@ static void c_init_options PARAMS ((void));
 #define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
 #undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
 #define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
-#undef LANG_HOOKS_FUNCTION_MARK
-#define LANG_HOOKS_FUNCTION_MARK c_mark_function_context
 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
 
@@ -224,3 +221,5 @@ finish_file ()
 {
   c_objc_common_finish_file ();
 }
+
+#include "gtype-c.h"
index df16be1f491a58fa0f7b2d1580b3b4fa85f9dcbd..1ff2668bed4a075851f32ce140861c6ecc9681e7 100644 (file)
@@ -41,7 +41,7 @@ static void expand_deferred_fns PARAMS ((void));
 static tree start_cdtor        PARAMS ((int));
 static void finish_cdtor PARAMS ((tree));
 
-static varray_type deferred_fns;
+static GTY(()) varray_type deferred_fns;
 
 int
 c_missing_noreturn_ok_p (decl)
@@ -253,7 +253,6 @@ c_objc_common_init (filename)
     }
 
   VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
-  ggc_add_tree_varray_root (&deferred_fns, 1);
 
   return filename;
 }
@@ -291,7 +290,7 @@ expand_deferred_fns ()
        }
     }
 
-  VARRAY_FREE (deferred_fns);
+  deferred_fns = 0;
 }
 
 static tree
@@ -413,3 +412,5 @@ c_tree_printer (buffer)
       return 0;
     }
 }
+
+#include "gt-c-objc-common.h"
index 78a53869dd76aba35f88041aabafc2e596b81a9b..c5c499cf0488dccf9a876642ecbaf2e15b22f26e 100644 (file)
@@ -266,17 +266,17 @@ static const char *if_stmt_file;
 static int if_stmt_line;
 
 /* List of types and structure classes of the current declaration.  */
-static tree current_declspecs = NULL_TREE;
-static tree prefix_attributes = NULL_TREE;
+static GTY(()) tree current_declspecs;
+static GTY(()) tree prefix_attributes;
 
 /* List of all the attributes applying to the identifier currently being
    declared; includes prefix_attributes and possibly some more attributes
    just after a comma.  */
-static tree all_prefix_attributes = NULL_TREE;
+static GTY(()) tree all_prefix_attributes;
 
 /* Stack of saved values of current_declspecs, prefix_attributes and
    all_prefix_attributes.  */
-static tree declspec_stack;
+static GTY(()) tree declspec_stack;
 
 /* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK
    should be called from the productions making use of setspecs.  */
@@ -341,16 +341,11 @@ static inline int _yylex  PARAMS ((void));
 static int  yylex        PARAMS ((void));
 static void init_reswords PARAMS ((void));
 
-/* Add GC roots for variables local to this file.  */
+  /* Initialisation routine for this file.  */
 void
 c_parse_init ()
 {
   init_reswords ();
-
-  ggc_add_tree_root (&declspec_stack, 1);
-  ggc_add_tree_root (&current_declspecs, 1);
-  ggc_add_tree_root (&prefix_attributes, 1);
-  ggc_add_tree_root (&all_prefix_attributes, 1);
 }
 
 %}
@@ -3730,8 +3725,6 @@ end ifc
             || (next_type == CPP_NAME && yylexname () == STRING));
 
       yylval.ttype = combine_strings (strings);
-
-      VARRAY_FREE (strings);
     }
   else
     yylval.ttype = orig;
@@ -3943,3 +3936,5 @@ free_parser_stacks ()
       free (malloced_yyvs);
     }
 }
+
+#include "gt-c-parse.h"
index 1a016b8b2201982498daaf658cb5217ba73a29db..df9e1bf3c3403b97de4b8d88261791a6f4930f00 100644 (file)
@@ -36,11 +36,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define GCC_BAD(msgid) do { warning (msgid); return; } while (0)
 #define GCC_BAD2(msgid, arg) do { warning (msgid, arg); return; } while (0)
 
-#ifdef HANDLE_PRAGMA_PACK
-static void handle_pragma_pack PARAMS ((cpp_reader *));
-
-#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
-typedef struct align_stack
+typedef struct align_stack GTY(())
 {
   int                  alignment;
   unsigned int         num_pushes;
@@ -48,8 +44,12 @@ typedef struct align_stack
   struct align_stack * prev;
 } align_stack;
 
-static struct align_stack * alignment_stack = NULL;
+static GTY(()) struct align_stack * alignment_stack;
+
+#ifdef HANDLE_PRAGMA_PACK
+static void handle_pragma_pack PARAMS ((cpp_reader *));
 
+#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
 /* If we have a "global" #pragma pack(<n>) in effect when the first
    #pragma pack(push,<n>) is encountered, this stores the value of 
    maximum_field_alignment in effect.  When the final pop_alignment() 
@@ -61,7 +61,6 @@ static int default_alignment;
 
 static void push_alignment PARAMS ((int, tree));
 static void pop_alignment  PARAMS ((tree));
-static void mark_align_stack PARAMS ((void *));
 
 /* Push an alignment value onto the stack.  */
 static void
@@ -75,7 +74,7 @@ push_alignment (alignment, id)
     {
       align_stack * entry;
 
-      entry = (align_stack *) xmalloc (sizeof (* entry));
+      entry = (align_stack *) ggc_alloc (sizeof (* entry));
 
       entry->alignment  = alignment;
       entry->num_pushes = 1;
@@ -137,24 +136,9 @@ pop_alignment (id)
       else
        maximum_field_alignment = entry->alignment;
 
-      free (alignment_stack);
-
       alignment_stack = entry;
     }
 }
-
-static void
-mark_align_stack (p)
-    void *p;
-{
-  align_stack *a = *(align_stack **) p;
-
-  while (a)
-    {
-      ggc_mark_tree (a->id);
-      a = a->prev;
-    }
-}
 #else  /* not HANDLE_PRAGMA_PACK_PUSH_POP */
 #define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
 #define push_alignment(ID, N) \
@@ -272,12 +256,12 @@ handle_pragma_pack (dummy)
 }
 #endif  /* HANDLE_PRAGMA_PACK */
 
+static GTY(()) tree pending_weaks;
+
 #ifdef HANDLE_PRAGMA_WEAK
 static void apply_pragma_weak PARAMS ((tree, tree));
 static void handle_pragma_weak PARAMS ((cpp_reader *));
 
-static tree pending_weaks;
-
 static void
 apply_pragma_weak (decl, value)
      tree decl, value;
@@ -363,11 +347,11 @@ maybe_apply_pragma_weak (decl)
 }
 #endif /* HANDLE_PRAGMA_WEAK */
 
+static GTY(()) tree pending_redefine_extname;
+
 #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
 static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
 
-static tree pending_redefine_extname;
-
 /* #pragma redefined_extname oldname newname */
 static void
 handle_pragma_redefine_extname (dummy)
@@ -404,11 +388,11 @@ handle_pragma_redefine_extname (dummy)
 }
 #endif
 
+static GTY(()) tree pragma_extern_prefix;
+
 #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
 static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
 
-static tree pragma_extern_prefix;
-
 /* #pragma extern_prefix "prefix" */
 static void
 handle_pragma_extern_prefix (dummy)
@@ -500,25 +484,19 @@ init_pragma ()
 #endif
 #ifdef HANDLE_PRAGMA_WEAK
   cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
-  ggc_add_tree_root (&pending_weaks, 1);
 #endif
 #ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
   cpp_register_pragma (parse_in, 0, "redefine_extname",
                       handle_pragma_redefine_extname);
-  ggc_add_tree_root (&pending_redefine_extname, 1);
 #endif
 #ifdef HANDLE_PRAGMA_EXTERN_PREFIX
   cpp_register_pragma (parse_in, 0, "extern_prefix",
                       handle_pragma_extern_prefix);
-  ggc_add_tree_root (&pragma_extern_prefix, 1);
 #endif
 
 #ifdef REGISTER_TARGET_PRAGMAS
   REGISTER_TARGET_PRAGMAS (parse_in);
 #endif
-
-#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
-  ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack),
-               mark_align_stack);
-#endif
 }
+
+#include "gt-c-pragma.h"
index 77eeb3e4c54c93f87e0463e7ad75f6400966c982..aff8800d2a5f0a6b98ed7f0b28ccb334a4e50b7a 100644 (file)
@@ -34,16 +34,31 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    lang_identifier nodes, because some keywords are only special in a
    particular context.  */
 
-struct lang_identifier
+struct lang_identifier GTY(())
 {
-  struct c_common_identifier ignore;
-  tree global_value, local_value, label_value, implicit_decl;
-  tree error_locus, limbo_value;
+  struct c_common_identifier common_id;
+  tree global_value;
+  tree local_value;
+  tree label_value;
+  tree implicit_decl;
+  tree error_locus;
+  tree limbo_value;
+};
+
+/* The resulting tree type.  */
+
+union lang_tree_node 
+  GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
+{
+  union tree_node GTY ((tag ("0"), 
+                       desc ("tree_node_structure (&%h)"))) 
+    generic;
+  struct lang_identifier GTY ((tag ("1"))) identifier;
 };
 
 /* Language-specific declaration information.  */
 
-struct lang_decl
+struct lang_decl GTY(())
 {
   struct c_lang_decl base;
   /* The return types and parameter types may have variable size.
@@ -107,10 +122,10 @@ struct lang_decl
   (DECL_LANG_SPECIFIC (NODE)->base.declared_inline)
 
 /* In a RECORD_TYPE, a sorted array of the fields of the type.  */
-struct lang_type
+struct lang_type GTY(())
 {
   int len;
-  tree elts[1];
+  tree GTY((length ("%h.len"))) elts[1];
 };
 
 /* Record whether a type or decl was written with nonconstant size.
@@ -178,7 +193,6 @@ extern void c_insert_default_attributes             PARAMS ((tree));
 extern void c_init_decl_processing             PARAMS ((void));
 extern void c_dup_lang_specific_decl           PARAMS ((tree));
 extern void c_print_identifier                 PARAMS ((FILE *, tree, int));
-extern void c_mark_tree                                PARAMS ((tree));
 extern tree build_array_declarator              PARAMS ((tree, tree, int, int));
 extern tree build_enumerator                    PARAMS ((tree, tree));
 extern int  c_decode_option                     PARAMS ((int, char **));
@@ -205,7 +219,6 @@ extern tree lookup_name                         PARAMS ((tree));
 extern tree lookup_name_current_level          PARAMS ((tree));
 extern void parmlist_tags_warning               PARAMS ((void));
 extern void pending_xref_error                  PARAMS ((void));
-extern void c_mark_function_context             PARAMS ((struct function *));
 extern void c_push_function_context             PARAMS ((struct function *));
 extern void c_pop_function_context              PARAMS ((struct function *));
 extern void pop_label_level                     PARAMS ((void));
@@ -384,7 +397,7 @@ extern int mesg_implicit_function_declaration;
 /* In c-decl.c */
 extern void c_finish_incomplete_decl PARAMS ((tree));
 
-extern tree static_ctors;
-extern tree static_dtors;
+extern GTY(()) tree static_ctors;
+extern GTY(()) tree static_dtors;
 
 #endif /* ! GCC_C_TREE_H */
index ab02990241543ff0b77aef3865ff5a4d03122359..0d13840d0324658db84a4afd94dc673728d166e1 100644 (file)
@@ -188,12 +188,8 @@ static void alpha_elf_select_rtx_section
   PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
 #endif
 
-static void alpha_init_machine_status
-  PARAMS ((struct function *p));
-static void alpha_mark_machine_status
-  PARAMS ((struct function *p));
-static void alpha_free_machine_status
-  PARAMS ((struct function *p));
+static struct machine_function * alpha_init_machine_status
+  PARAMS ((void));
 
 static void unicosmk_output_deferred_case_vectors PARAMS ((FILE *));
 static void unicosmk_gen_dsib PARAMS ((unsigned long *imaskP));
@@ -562,8 +558,6 @@ override_options ()
 
   /* Set up function hooks.  */
   init_machine_status = alpha_init_machine_status;
-  mark_machine_status = alpha_mark_machine_status;
-  free_machine_status = alpha_free_machine_status;
 }
 \f
 /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
@@ -5311,9 +5305,9 @@ alpha_multipass_dfa_lookahead ()
 \f
 /* Machine-specific function data.  */
 
-struct machine_function
+struct machine_function GTY(())
 {
-#if TARGET_ABI_UNICOSMK
+  /* For unicosmk. */
   /* List of call information words for calls from this function.  */
   struct rtx_def *first_ciw;
   struct rtx_def *last_ciw;
@@ -5321,58 +5315,18 @@ struct machine_function
 
   /* List of deferred case vectors.  */
   struct rtx_def *addr_list;
-#else
-#if TARGET_ABI_OSF
+
+  /* For OSF. */
   const char *some_ld_name;
-#else
-  /* Non-empty struct.  */
-  char dummy;
-#endif
-#endif
 };
 
-/* Register global variables and machine-specific functions with the
-   garbage collector.  */
+/* How to allocate a 'struct machine_function'.  */
 
-static void
-alpha_init_machine_status (p)
-     struct function *p;
+static struct machine_function *
+alpha_init_machine_status ()
 {
-  p->machine =
-    (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
-
-#if TARGET_ABI_UNICOSMK
-  p->machine->first_ciw = NULL_RTX;
-  p->machine->last_ciw = NULL_RTX;
-  p->machine->ciw_count = 0;
-  p->machine->addr_list = NULL_RTX;
-#endif
-#if TARGET_ABI_OSF
-  p->machine->some_ld_name = NULL;
-#endif
-}
-
-static void
-alpha_mark_machine_status (p)
-     struct function *p;
-{
-  struct machine_function *machine = p->machine;
-
-  if (machine)
-    {
-#if TARGET_ABI_UNICOSMK
-      ggc_mark_rtx (machine->first_ciw);
-      ggc_mark_rtx (machine->addr_list);
-#endif
-    }
-}
-
-static void
-alpha_free_machine_status (p)
-     struct function *p;
-{
-  free (p->machine);
-  p->machine = NULL;
+  return ((struct machine_function *) 
+               ggc_alloc_cleared (sizeof (struct machine_function)));
 }
 
 /* Functions to save and restore alpha_return_addr_rtx.  */
@@ -9913,3 +9867,6 @@ unicosmk_need_dex (x)
 }
 
 #endif /* TARGET_ABI_UNICOSMK */
+
+#include "gt-alpha.h"
+
index 111884d234b63776f1dd04bb54e9fcfe039d6f6a..4d1b467dd4966d53e7f583300df6997c6b78103d 100644 (file)
@@ -82,9 +82,7 @@ static Ccstar    output_multi_immediate               PARAMS ((rtx *, Ccstar, Ccstar, int, Hi
 static void      print_multi_reg               PARAMS ((FILE *, Ccstar, int, int));
 static Mmode     select_dominance_cc_mode      PARAMS ((rtx, rtx, Hint));
 static Ccstar    shift_op                      PARAMS ((rtx, Hint *));
-static void      arm_init_machine_status       PARAMS ((struct function *));
-static void      arm_mark_machine_status        PARAMS ((struct function *));
-static void      arm_free_machine_status        PARAMS ((struct function *));
+static struct machine_function * arm_init_machine_status PARAMS ((void));
 static int       number_of_first_bit_set        PARAMS ((int));
 static void      replace_symbols_in_block       PARAMS ((tree, rtx, rtx));
 static void      thumb_exit                     PARAMS ((FILE *, int, rtx));
@@ -772,10 +770,6 @@ arm_override_options ()
 static void
 arm_add_gc_roots ()
 {
-  ggc_add_rtx_root (&arm_compare_op0, 1);
-  ggc_add_rtx_root (&arm_compare_op1, 1);
-  ggc_add_rtx_root (&arm_target_insn, 1); /* Not sure this is really a root.  */
-
   gcc_obstack_init(&minipool_obstack);
   minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
 }
@@ -10091,37 +10085,16 @@ thumb_unexpanded_epilogue ()
 
 /* Functions to save and restore machine-specific function data.  */
 
-static void
-arm_mark_machine_status (p)
-     struct function * p;
-{
-  machine_function *machine = p->machine;
-
-  if (machine)
-    ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
-}
-
-static void
-arm_init_machine_status (p)
-     struct function * p;
+static struct machine_function *
+arm_init_machine_status ()
 {
-  p->machine =
-    (machine_function *) xcalloc (1, sizeof (machine_function));
+  struct machine_function *machine;
+  machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
 
-#if ARM_FT_UNKNOWWN != 0  
-  ((machine_function *) p->machine)->func_type = ARM_FT_UNKNOWN;
+#if ARM_FT_UNKNOWN != 0  
+  machine->func_type = ARM_FT_UNKNOWN;
 #endif
-}
-
-static void
-arm_free_machine_status (p)
-     struct function * p;
-{
-  if (p->machine)
-    {
-      free (p->machine);
-      p->machine = NULL;
-    }
+  return machine;
 }
 
 /* Return an RTX indicating where the return address to the
@@ -10152,8 +10125,6 @@ arm_init_expanders ()
 {
   /* Arrange to initialize and mark the machine per-function status.  */
   init_machine_status = arm_init_machine_status;
-  mark_machine_status = arm_mark_machine_status;
-  free_machine_status = arm_free_machine_status;
 }
 
 /* Generate the rest of a function's prologue.  */
@@ -10851,10 +10822,11 @@ arm_strip_name_encoding (const char * name)
   return name;
 }
 
+rtx aof_pic_label;
+
 #ifdef AOF_ASSEMBLER
 /* Special functions only needed when producing AOF syntax assembler.  */
 
-rtx aof_pic_label = NULL_RTX;
 struct pic_chain
 {
   struct pic_chain * next;
@@ -10872,10 +10844,6 @@ aof_pic_entry (x)
 
   if (aof_pic_label == NULL_RTX)
     {
-      /* We mark this here and not in arm_add_gc_roots() to avoid
-        polluting even more code with ifdefs, and because it never
-        contains anything useful until we assign to it here.  */
-      ggc_add_rtx_root (&aof_pic_label, 1);
       aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
     }
 
index 3a3e6bad6810fa2d994044c70d7297d85a843746..1b1b7dbe77c08b4994fb95d6a1d669ced5aa9a14 100644 (file)
@@ -107,21 +107,22 @@ extern arm_cc arm_current_cc;
 
 extern int arm_target_label;
 extern int arm_ccfsm_state;
-extern struct rtx_def * arm_target_insn;
+extern GTY(()) rtx arm_target_insn;
 /* Run-time compilation parameters selecting different hardware subsets.  */
 extern int target_flags;
 /* The floating point instruction architecture, can be 2 or 3 */
 extern const char * target_fp_name;
 /* Define the information needed to generate branch insns.  This is
-   stored from the compare operation.  Note that we can't use "rtx" here
-   since it hasn't been defined!  */
-extern struct rtx_def * arm_compare_op0;
-extern struct rtx_def * arm_compare_op1;
+   stored from the compare operation.  */
+extern GTY(()) rtx arm_compare_op0;
+extern GTY(()) rtx arm_compare_op1;
 /* The label of the current constant pool.  */
-extern struct rtx_def * pool_vector_label;
+extern rtx pool_vector_label;
 /* Set to 1 when a return insn is output, this means that the epilogue
    is not needed. */
 extern int return_used_this_function;
+/* Used to produce AOF syntax assembler.  */
+extern GTY(()) rtx aof_pic_label;
 \f
 /* Just in case configure has failed to define anything. */
 #ifndef TARGET_CPU_DEFAULT
@@ -1412,10 +1413,10 @@ enum reg_class
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function
+typedef struct machine_function GTY(())
 {
   /* Additionsl stack adjustment in __builtin_eh_throw.  */
-  struct rtx_def *eh_epilogue_sp_ofs;
+  rtx eh_epilogue_sp_ofs;
   /* Records if LR has to be saved for far jumps.  */
   int far_jump_used;
   /* Records if ARG_POINTER was ever live.  */
index d8468d1709090963f25773f33780009d7ee0de8d..8176d4d37230dcd7b5db4bd8e031448bee73fa49 100644 (file)
@@ -272,19 +272,19 @@ extern int valid_parallel_operands_5 PARAMS ((rtx *, enum machine_mode));
 
 extern int valid_parallel_operands_6 PARAMS ((rtx *, enum machine_mode));
 
-extern rtx smulhi3_libfunc;
-extern rtx umulhi3_libfunc;
-extern rtx fix_truncqfhi2_libfunc;
-extern rtx fixuns_truncqfhi2_libfunc;
-extern rtx fix_trunchfhi2_libfunc;
-extern rtx fixuns_trunchfhi2_libfunc;
-extern rtx floathiqf2_libfunc;
-extern rtx floatunshiqf2_libfunc;
-extern rtx floathihf2_libfunc;
-extern rtx floatunshihf2_libfunc;
-
-extern struct rtx_def *c4x_compare_op0;        /* Operand 0 for comparisons.  */
-extern struct rtx_def *c4x_compare_op1;        /* Operand 1 for comparisons.  */
+extern GTY(()) rtx smulhi3_libfunc;
+extern GTY(()) rtx umulhi3_libfunc;
+extern GTY(()) rtx fix_truncqfhi2_libfunc;
+extern GTY(()) rtx fixuns_truncqfhi2_libfunc;
+extern GTY(()) rtx fix_trunchfhi2_libfunc;
+extern GTY(()) rtx fixuns_trunchfhi2_libfunc;
+extern GTY(()) rtx floathiqf2_libfunc;
+extern GTY(()) rtx floatunshiqf2_libfunc;
+extern GTY(()) rtx floathihf2_libfunc;
+extern GTY(()) rtx floatunshihf2_libfunc;
+
+extern GTY(()) rtx c4x_compare_op0;    /* Operand 0 for comparisons.  */
+extern GTY(()) rtx c4x_compare_op1;    /* Operand 1 for comparisons.  */
 
 #endif /* RTX_CODE */
 
@@ -303,7 +303,12 @@ extern void c4x_pr_FUNC_NEVER_RETURNS      PARAMS ((cpp_reader *));
 extern void c4x_pr_INTERRUPT           PARAMS ((cpp_reader *));
 extern void c4x_pr_ignored             PARAMS ((cpp_reader *));
 extern void c4x_init_pragma            PARAMS ((int (*) (tree *)));
-extern tree code_tree, data_tree, pure_tree, noreturn_tree, interrupt_tree;
 #endif
 
+extern GTY(()) tree code_tree;
+extern GTY(()) tree data_tree;
+extern GTY(()) tree pure_tree;
+extern GTY(()) tree noreturn_tree;
+extern GTY(()) tree interrupt_tree;
+
 #endif /* ! GCC_C4X_PROTOS_H */
index 126b132f5b5405a2d81a51d3f1ebbd0c9175b9ad..ad2ff6dff3ed2321da9298eb3433cb7b8dbb65ef 100644 (file)
@@ -148,8 +148,8 @@ enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
 /* Test and compare insns in c4x.md store the information needed to
    generate branch and scc insns here.  */
 
-struct rtx_def *c4x_compare_op0 = NULL_RTX;
-struct rtx_def *c4x_compare_op1 = NULL_RTX;
+rtx c4x_compare_op0;
+rtx c4x_compare_op1;
 
 const char *c4x_rpts_cycles_string;
 int c4x_rpts_cycles = 0;       /* Max. cycles for RPTS.  */
@@ -165,7 +165,6 @@ tree noreturn_tree = NULL_TREE;
 tree interrupt_tree = NULL_TREE;
 
 /* Forward declarations */
-static void c4x_add_gc_roots PARAMS ((void));
 static int c4x_isr_reg_used_p PARAMS ((unsigned int));
 static int c4x_leaf_function_p PARAMS ((void));
 static int c4x_assembler_function_p PARAMS ((void));
@@ -223,32 +222,6 @@ static void c4x_encode_section_info PARAMS ((tree, int));
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-c4x_add_gc_roots ()
-{
-  ggc_add_rtx_root (&c4x_compare_op0, 1);
-  ggc_add_rtx_root (&c4x_compare_op1, 1);
-  ggc_add_tree_root (&code_tree, 1);
-  ggc_add_tree_root (&data_tree, 1);
-  ggc_add_tree_root (&pure_tree, 1);
-  ggc_add_tree_root (&noreturn_tree, 1);
-  ggc_add_tree_root (&interrupt_tree, 1);
-  ggc_add_rtx_root (&smulhi3_libfunc, 1);
-  ggc_add_rtx_root (&umulhi3_libfunc, 1);
-  ggc_add_rtx_root (&fix_truncqfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fixuns_truncqfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fix_trunchfhi2_libfunc, 1);
-  ggc_add_rtx_root (&fixuns_trunchfhi2_libfunc, 1);
-  ggc_add_rtx_root (&floathiqf2_libfunc, 1);
-  ggc_add_rtx_root (&floatunshiqf2_libfunc, 1);
-  ggc_add_rtx_root (&floathihf2_libfunc, 1);
-  ggc_add_rtx_root (&floatunshihf2_libfunc, 1);
-}
-
-
 /* Override command line options.
    Called once after all options have been parsed.
    Mostly we process the processor
@@ -317,9 +290,6 @@ c4x_override_options ()
      This provides compatibility with the old -mno-aliases option.  */
   if (! TARGET_ALIASES && ! flag_argument_noalias)
     flag_argument_noalias = 1;
-
-  /* Register global variables with the garbage collector.  */
-  c4x_add_gc_roots ();
 }
 
 
@@ -5087,3 +5057,4 @@ c4x_asm_named_section (name, flags)
 {
   fprintf (asm_out_file, "\t.sect\t\"%s\"\n", name);
 }
+
index 62912f2e4244624ddef4ebf1a152989b6177652b..0fa6660dc9734bccb56c62eef1a10b6f1b0fc168 100644 (file)
@@ -63,7 +63,7 @@ Boston, MA 02111-1307, USA.  */
     } while (0)
 
 /* Per-function machine data.  */
-struct machine_function
+struct machine_function GTY(())
  {
    int needs_return_address_on_stack;
  };
@@ -85,7 +85,7 @@ static void cris_print_base PARAMS ((rtx, FILE *));
 
 static void cris_print_index PARAMS ((rtx, FILE *));
 
-static void cris_init_machine_status PARAMS ((struct function *));
+static struct machine_function * cris_init_machine_status PARAMS ((void));
 
 static int cris_initial_frame_pointer_offset PARAMS ((void));
 
@@ -2697,11 +2697,10 @@ cris_init_expanders ()
 
 /* Zero initialization is OK for all current fields.  */
 
-static void
-cris_init_machine_status (p)
-     struct function *p;
+static struct machine_function *
+cris_init_machine_status ()
 {
-  p->machine = xcalloc (1, sizeof (struct machine_function));
+  return ggc_alloc_cleared (sizeof (struct machine_function));
 }
 
 /* Split a 2 word move (DI or presumably DF) into component parts.
@@ -3129,6 +3128,8 @@ Prev_insn (insn)
 }
 #endif
 
+#include "gt-cris.h"
+
 /*
  * Local variables:
  * eval: (c-set-style "gnu")
index e79550b3881da7b798fbe5a27233eedab87400d0..61745e50867594c08a36711b58f7334a1f4da96d 100644 (file)
@@ -39,3 +39,6 @@ $(LIB2FUNCS_EXTRA): $(CRIS_LIB1CSRC)
        echo "#define L$$name" > tmp-$@ \
        && echo '#include "$<"' >> tmp-$@ \
        && mv -f tmp-$@ $@
+
+$(out_object_file): gt-cris.h
+gt-cris.h : s-gtype ; @true
index 8beaa7aea994f66b5a885ad7beea31929e523687..162a7172eb4a853e2edb3f7408690fdde234f04a 100644 (file)
@@ -140,8 +140,8 @@ extern void debug_stack_info                PARAMS ((d30v_stack_t *));
 /* Define the information needed to generate branch and scc insns.  This is
    stored from the compare operation.  */
 
-extern struct rtx_def *d30v_compare_op0;
-extern struct rtx_def *d30v_compare_op1;
+extern GTY(()) rtx d30v_compare_op0;
+extern GTY(()) rtx d30v_compare_op1;
 
 /* Define the information needed to modify the epilogue for EH.  */
 
index 12ae39ad3b5f496867ed5e33d1064660300b6ea5..2ce3468140b60e09d4824db5316506a3451e0a8c 100644 (file)
 static void d30v_print_operand_memory_reference PARAMS ((FILE *, rtx));
 static void d30v_build_long_insn PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT,
                                          rtx, rtx));
-static void d30v_add_gc_roots PARAMS ((void));
-static void d30v_init_machine_status PARAMS ((struct function *));
-static void d30v_mark_machine_status PARAMS ((struct function *));
-static void d30v_free_machine_status PARAMS ((struct function *));
+static struct machine_function * d30v_init_machine_status PARAMS ((void));
 static void d30v_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
 static void d30v_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static int d30v_adjust_cost PARAMS ((rtx, rtx, rtx, int));
@@ -298,8 +295,6 @@ override_options ()
   reg_class_from_letter['x'] = F0_REGS;
   reg_class_from_letter['y'] = F1_REGS;
   reg_class_from_letter['z'] = OTHER_FLAG_REGS;
-
-  d30v_add_gc_roots ();
 }
 
 \f
@@ -3482,35 +3477,10 @@ d30v_issue_rate ()
 /* Routine to allocate, mark and free a per-function,
    machine specific structure.  */
 
-static void
-d30v_init_machine_status (p)
-     struct function *p;
+static struct machine_function *
+d30v_init_machine_status ()
 {
-  p->machine =
-    (machine_function *) xcalloc (1, sizeof (machine_function));
-}
-
-static void
-d30v_mark_machine_status (p)
-     struct function * p;
-{
-  if (p->machine == NULL)
-    return;
-  
-  ggc_mark_rtx (p->machine->eh_epilogue_sp_ofs);
-}
-
-static void
-d30v_free_machine_status (p)
-     struct function *p;
-{
-  struct machine_function *machine = p->machine;
-
-  if (machine == NULL)
-    return;
-
-  free (machine);
-  p->machine = NULL;
+  return ggc_alloc_cleared (sizeof (machine_function));
 }
 
 /* Do anything needed before RTL is emitted for each function.  */
@@ -3520,8 +3490,6 @@ d30v_init_expanders ()
 {
   /* Arrange to save and restore machine status around nested functions.  */
   init_machine_status = d30v_init_machine_status;
-  mark_machine_status = d30v_mark_machine_status;
-  free_machine_status = d30v_free_machine_status;
 }
 
 /* Find the current function's return address.
@@ -3536,13 +3504,3 @@ d30v_return_addr ()
 {
   return get_hard_reg_initial_val (Pmode, GPR_LINK);
 }
-
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-d30v_add_gc_roots ()
-{
-  ggc_add_rtx_root (&d30v_compare_op0, 1);
-  ggc_add_rtx_root (&d30v_compare_op1, 1);
-}
index 122f535abcdf56b67596c7517f222021c28cce4c..680f7c10cc29990db4de7b984f5f8993bf8cabb9 100644 (file)
@@ -1929,10 +1929,10 @@ typedef int CUMULATIVE_ARGS;
 
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function
+typedef struct machine_function GTY(())
 {
   /* Additionsl stack adjustment in __builtin_eh_throw.  */
-  struct rtx_def * eh_epilogue_sp_ofs;
+  rtx eh_epilogue_sp_ofs;
 } machine_function;
 
 \f
index 14077298629e1325fda36d09df865ed969312f85..19f83c62308725448e2a4cf67b5998e5457eb26d 100644 (file)
@@ -26,8 +26,6 @@ extern char *machopic_function_base_name PARAMS ((void));
 extern char *machopic_non_lazy_ptr_name PARAMS ((const char*));
 extern char *machopic_stub_name PARAMS ((const char*));
 
-extern void machopic_add_gc_roots PARAMS ((void));
-
 extern void machopic_picsymbol_stub_section PARAMS ((void));
 extern void machopic_symbol_stub_section PARAMS ((void));
 extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
index 3b9ee8c3cbc382e27db142a091378d9b06b7b7b7..82e320babe098655631ae7adfdb109eab2e0f354 100644 (file)
@@ -67,7 +67,7 @@ name_needs_quotes (name)
 /* This module assumes that (const (symbol_ref "foo")) is a legal pic
    reference, which will not be changed.  */
 
-static tree machopic_defined_list;
+static GTY(()) tree machopic_defined_list;
 
 enum machopic_addr_class
 machopic_classify_ident (ident)
@@ -257,7 +257,7 @@ machopic_function_base_name ()
   return function_base;
 }
 
-static tree machopic_non_lazy_pointers = NULL;
+static GTY(()) tree machopic_non_lazy_pointers;
 
 /* Return a non-lazy pointer name corresponding to the given name,
    either by finding it in our list of pointer names, or by generating
@@ -321,17 +321,7 @@ machopic_non_lazy_ptr_name (name)
   }
 }
 
-static tree machopic_stubs = 0;
-
-/* Make sure the GC knows about our homemade lists.  */
-
-void
-machopic_add_gc_roots ()
-{
-  ggc_add_tree_root (&machopic_defined_list, 1);
-  ggc_add_tree_root (&machopic_non_lazy_pointers, 1);
-  ggc_add_tree_root (&machopic_stubs, 1);
-}
+static GTY(()) tree machopic_stubs;
 
 /* Return the name of the stub corresponding to the given name,
    generating a new stub name if necessary.  */
@@ -1297,3 +1287,6 @@ machopic_asm_out_destructor (symbol, priority)
   if (!flag_pic)
     fprintf (asm_out_file, ".reference .destructors_used\n");
 }
+
+#include "gt-darwin.h"
+
index 7f5cc0b06c42009821637508287e42c7fda69b03..cc1c9d4d27999bfb63fa0cdcbcbad07170165634 100644 (file)
@@ -1725,29 +1725,6 @@ override_options ()
   rsect_const = tmp = (char *) xmalloc (strlen(".rsect ") + 
                                        strlen(const_seg_name) + 3);
   sprintf (tmp, ".rsect \"%s\"", const_seg_name);
-  
-  /* Mark our global variables for GC.  */
-  ggc_add_rtx_root (&dsp16xx_addhf3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_subhf3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_mulhf3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_divhf3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_cmphf3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_fixhfhi2_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_floathihf2_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_neghf2_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_mulhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_udivqi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_udivhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_divqi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_divhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_modqi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_modhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_umodqi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_umodhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_ashrhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_ashlhi3_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_ucmphi2_libcall, 1);
-  ggc_add_rtx_root (&dsp16xx_lshrhi3_libcall, 1);
 }
 
 int
index 780c8c39f0c6e292412f6d6c0ff42557af110f52..905b027c8f03b1c42ca03a5d72adf48803162aa4 100644 (file)
@@ -31,29 +31,30 @@ extern const char *const_seg_name;
 extern const char *rsect_const;
 extern const char *chip_name;
 extern const char *save_chip_name;
-extern struct rtx_def *dsp16xx_compare_op0, *dsp16xx_compare_op1;
-extern struct rtx_def *dsp16xx_addhf3_libcall;
-extern struct rtx_def *dsp16xx_subhf3_libcall;
-extern struct rtx_def *dsp16xx_mulhf3_libcall;
-extern struct rtx_def *dsp16xx_divhf3_libcall;
-extern struct rtx_def *dsp16xx_cmphf3_libcall;
-extern struct rtx_def *dsp16xx_fixhfhi2_libcall;
-extern struct rtx_def *dsp16xx_floathihf2_libcall;
-extern struct rtx_def *dsp16xx_neghf2_libcall;
-extern struct rtx_def *dsp16xx_umulhi3_libcall;
-extern struct rtx_def *dsp16xx_mulhi3_libcall;
-extern struct rtx_def *dsp16xx_udivqi3_libcall;
-extern struct rtx_def *dsp16xx_udivhi3_libcall;
-extern struct rtx_def *dsp16xx_divqi3_libcall;
-extern struct rtx_def *dsp16xx_divhi3_libcall;
-extern struct rtx_def *dsp16xx_modqi3_libcall;
-extern struct rtx_def *dsp16xx_modhi3_libcall;
-extern struct rtx_def *dsp16xx_umodqi3_libcall;
-extern struct rtx_def *dsp16xx_umodhi3_libcall;
-
-extern struct rtx_def *dsp16xx_ashrhi3_libcall;
-extern struct rtx_def *dsp16xx_ashlhi3_libcall;
-extern struct rtx_def *dsp16xx_lshrhi3_libcall;
+extern GTY(()) rtx dsp16xx_compare_op0;
+extern GTY(()) rtx dsp16xx_compare_op1;
+extern GTY(()) rtx dsp16xx_addhf3_libcall;
+extern GTY(()) rtx dsp16xx_subhf3_libcall;
+extern GTY(()) rtx dsp16xx_mulhf3_libcall;
+extern GTY(()) rtx dsp16xx_divhf3_libcall;
+extern GTY(()) rtx dsp16xx_cmphf3_libcall;
+extern GTY(()) rtx dsp16xx_fixhfhi2_libcall;
+extern GTY(()) rtx dsp16xx_floathihf2_libcall;
+extern GTY(()) rtx dsp16xx_neghf2_libcall;
+extern GTY(()) rtx dsp16xx_umulhi3_libcall;
+extern GTY(()) rtx dsp16xx_mulhi3_libcall;
+extern GTY(()) rtx dsp16xx_udivqi3_libcall;
+extern GTY(()) rtx dsp16xx_udivhi3_libcall;
+extern GTY(()) rtx dsp16xx_divqi3_libcall;
+extern GTY(()) rtx dsp16xx_divhi3_libcall;
+extern GTY(()) rtx dsp16xx_modqi3_libcall;
+extern GTY(()) rtx dsp16xx_modhi3_libcall;
+extern GTY(()) rtx dsp16xx_umodqi3_libcall;
+extern GTY(()) rtx dsp16xx_umodhi3_libcall;
+
+extern GTY(()) rtx dsp16xx_ashrhi3_libcall;
+extern GTY(()) rtx dsp16xx_ashlhi3_libcall;
+extern GTY(()) rtx dsp16xx_lshrhi3_libcall;
 
 /* RUN-TIME TARGET SPECIFICATION */
 #define DSP16XX   1
index d512646fdc52a5f497b315e175dab4bdf685e017..b5ca28f4fc7717a59ee83734af1c1ad351d1f958 100644 (file)
@@ -553,7 +553,7 @@ static char const tls_model_chars[] = " GLil";
 #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
 
 /* Define the structure for the machine field in struct function.  */
-struct machine_function
+struct machine_function GTY(())
 {
   rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
   const char *some_ld_name;
@@ -680,9 +680,7 @@ static int ix86_agi_dependant PARAMS ((rtx, rtx, enum attr_type));
 static enum attr_ppro_uops ix86_safe_ppro_uops PARAMS ((rtx));
 static void ix86_dump_ppro_packet PARAMS ((FILE *));
 static void ix86_reorder_insn PARAMS ((rtx *, rtx *));
-static void ix86_init_machine_status PARAMS ((struct function *));
-static void ix86_mark_machine_status PARAMS ((struct function *));
-static void ix86_free_machine_status PARAMS ((struct function *));
+static struct machine_function * ix86_init_machine_status PARAMS ((void));
 static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
 static int ix86_nsaved_regs PARAMS ((void));
 static void ix86_emit_save_regs PARAMS ((void));
@@ -1042,9 +1040,7 @@ override_options ()
 
   /* Arrange to set up i386_stack_locals for all functions.  */
   init_machine_status = ix86_init_machine_status;
-  mark_machine_status = ix86_mark_machine_status;
-  free_machine_status = ix86_free_machine_status;
-
+  
   /* Validate -mregparm= value.  */
   if (ix86_regparm_string)
     {
@@ -10636,38 +10632,10 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
    This is called from INIT_EXPANDERS once before RTL is emitted for each
    function.  */
 
-static void
-ix86_init_machine_status (p)
-     struct function *p;
-{
-  p->machine = (struct machine_function *)
-    xcalloc (1, sizeof (struct machine_function));
-}
-
-/* Mark machine specific bits of P for GC.  */
-static void
-ix86_mark_machine_status (p)
-     struct function *p;
-{
-  struct machine_function *machine = p->machine;
-  enum machine_mode mode;
-  int n;
-
-  if (! machine)
-    return;
-
-  for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
-       mode = (enum machine_mode) ((int) mode + 1))
-    for (n = 0; n < MAX_386_STACK_LOCALS; n++)
-      ggc_mark_rtx (machine->stack_locals[(int) mode][n]);
-}
-
-static void
-ix86_free_machine_status (p)
-     struct function *p;
+static struct machine_function *
+ix86_init_machine_status ()
 {
-  free (p->machine);
-  p->machine = NULL;
+  return ggc_alloc_cleared (sizeof (struct machine_function));
 }
 
 /* Return a MEM corresponding to a stack slot with mode MODE.
@@ -10693,20 +10661,19 @@ assign_386_stack_local (mode, n)
 
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
 
+static GTY(()) rtx ix86_tls_symbol;
 rtx
 ix86_tls_get_addr ()
 {
-  static rtx symbol;
 
-  if (!symbol)
+  if (!ix86_tls_symbol)
     {
-      symbol = gen_rtx_SYMBOL_REF (Pmode, (TARGET_GNU_TLS
+      ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, (TARGET_GNU_TLS
                                           ? "___tls_get_addr"
                                           : "__tls_get_addr"));
-      ggc_add_rtx_root (&symbol, 1);
     }
 
-  return symbol;
+  return ix86_tls_symbol;
 }
 \f
 /* Calculate the length of the memory address in the instruction
@@ -13948,3 +13915,5 @@ x86_output_mi_thunk (file, delta, function)
        }
     }
 }
+
+#include "gt-i386.h"
index 204740a68e6b7db14a61038d3a73e2fd25d4c04a..2b10ef512aee84b13803aa17f339f535a6a3b8ad 100644 (file)
@@ -21,7 +21,8 @@ Boston, MA 02111-1307, USA.  */
 /* Variables defined in ia64.c.  */
 
 #ifdef RTX_CODE
-extern rtx ia64_compare_op0, ia64_compare_op1;
+extern GTY(()) rtx ia64_compare_op0;
+extern GTY(()) rtx ia64_compare_op1;
 #endif
 
 /* Functions defined in ia64.c */
index 1445ae9bea3e9e648b784af926aa221d8d5a9ab9..a6066d8894ceaa7bdf25a2ae511c25aa887e1482 100644 (file)
@@ -127,10 +127,7 @@ static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));
 
 static enum machine_mode hfa_element_mode PARAMS ((tree, int));
 static void fix_range PARAMS ((const char *));
-static void ia64_add_gc_roots PARAMS ((void));
-static void ia64_init_machine_status PARAMS ((struct function *));
-static void ia64_mark_machine_status PARAMS ((struct function *));
-static void ia64_free_machine_status PARAMS ((struct function *));
+static struct machine_function * ia64_init_machine_status PARAMS ((void));
 static void emit_insn_group_barriers PARAMS ((FILE *, rtx));
 static void emit_all_insn_group_barriers PARAMS ((FILE *, rtx));
 static void emit_predicate_relation_info PARAMS ((void));
@@ -1044,27 +1041,25 @@ ia64_expand_load_address (dest, src, scratch)
     emit_move_insn (dest, temp);
 }
 
+static GTY(()) rtx gen_tls_tga;
 static rtx
 gen_tls_get_addr ()
 {
-  static rtx tga;
-  if (!tga)
+  if (!gen_tls_tga)
     {
-      tga = init_one_libfunc ("__tls_get_addr");
-      ggc_add_rtx_root (&tga, 1);
-    }
-  return tga;
+      gen_tls_tga = init_one_libfunc ("__tls_get_addr");
+     }
+  return gen_tls_tga;
 }
 
+static GTY(()) rtx thread_pointer_rtx;
 static rtx
 gen_thread_pointer ()
 {
-  static rtx tp;
-  if (!tp)
+  if (!thread_pointer_rtx)
     {
-      tp = gen_rtx_REG (Pmode, 13);
-      RTX_UNCHANGING_P (tp);
-      ggc_add_rtx_root (&tp, 1);
+      thread_pointer_rtx = gen_rtx_REG (Pmode, 13);
+      RTX_UNCHANGING_P (thread_pointer_rtx);
     }
   return tp;
 }
@@ -4146,44 +4141,10 @@ fix_range (const_str)
     }
 }
 
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-ia64_add_gc_roots ()
-{
-  ggc_add_rtx_root (&ia64_compare_op0, 1);
-  ggc_add_rtx_root (&ia64_compare_op1, 1);
-}
-
-static void
-ia64_init_machine_status (p)
-     struct function *p;
-{
-  p->machine =
-    (struct machine_function *) xcalloc (1, sizeof (struct machine_function));
-}
-
-static void
-ia64_mark_machine_status (p)
-     struct function *p;
-{
-  struct machine_function *machine = p->machine;
-
-  if (machine)
-    {
-      ggc_mark_rtx (machine->ia64_eh_epilogue_sp);
-      ggc_mark_rtx (machine->ia64_eh_epilogue_bsp);
-      ggc_mark_rtx (machine->ia64_gp_save);
-    }
-}
-
-static void
-ia64_free_machine_status (p)
-     struct function *p;
+static struct machine_function *
+ia64_init_machine_status ()
 {
-  free (p->machine);
-  p->machine = NULL;
+  return ggc_alloc_cleared (sizeof (struct machine_function));
 }
 
 /* Handle TARGET_OPTIONS switches.  */
@@ -4219,10 +4180,6 @@ ia64_override_options ()
   ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
 
   init_machine_status = ia64_init_machine_status;
-  mark_machine_status = ia64_mark_machine_status;
-  free_machine_status = ia64_free_machine_status;
-
-  ia64_add_gc_roots ();
 }
 \f
 static enum attr_itanium_requires_unit0 ia64_safe_itanium_requires_unit0 PARAMS((rtx));
@@ -8161,3 +8118,5 @@ ia64_aix_select_rtx_section (mode, x, align)
   ia64_select_rtx_section (mode, x, align);
   flag_pic = save_pic;
 }
+
+#include "gt-ia64.h"
index d1e0556b128c9acd4c622b158ba44b6ce028c5ba..cfc44d4396408773ccf75d0fda8ad40b97f31f8e 100644 (file)
@@ -2440,16 +2440,16 @@ extern int ia64_final_schedule;
 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 15 : INVALID_REGNUM)
 
 /* This function contains machine specific function data.  */
-struct machine_function
+struct machine_function GTY(())
 {
   /* The new stack pointer when unwinding from EH.  */
-  struct rtx_def* ia64_eh_epilogue_sp;
+  rtx ia64_eh_epilogue_sp;
 
   /* The new bsp value when unwinding from EH.  */
-  struct rtx_def* ia64_eh_epilogue_bsp;
+  rtx ia64_eh_epilogue_bsp;
 
   /* The GP value save register.  */
-  struct rtx_def* ia64_gp_save;
+  rtx ia64_gp_save;
 
   /* The number of varargs registers to save.  */
   int n_varargs;
index 0b63a859ff4381b95f7eebb9e439f5ec943f47ba..ee5bd6a7844998c22636e218be59de1496e075ff 100644 (file)
@@ -43,10 +43,15 @@ extern void m68hc11_function_arg_advance PARAMS((CUMULATIVE_ARGS*,
 #ifdef RTX_CODE
 extern rtx m68hc11_compare_op0;
 extern rtx m68hc11_compare_op1;
-extern rtx m68hc11_soft_tmp_reg;
-extern rtx iy_reg;
-extern rtx ix_reg;
-extern rtx d_reg;
+extern GTY(()) rtx m68hc11_soft_tmp_reg;
+extern GTY(()) rtx ix_reg;
+extern GTY(()) rtx iy_reg;
+extern GTY(()) rtx d_reg;
+extern GTY(()) rtx da_reg;
+extern GTY(()) rtx stack_push_word;
+extern GTY(()) rtx stack_pop_word;
+extern GTY(()) rtx z_reg;
+extern GTY(()) rtx z_reg_qi;
 
 extern void m68hc11_initialize_trampoline PARAMS((rtx, rtx, rtx));
 
index a521bbd8df2e06d5a92413301410760f26b911a6..b3dab481efa45d44a84817af92b923b351c4dc54 100644 (file)
@@ -72,7 +72,6 @@ static tree m68hc11_handle_fntype_attribute PARAMS ((tree *, tree, tree, int, bo
 const struct attribute_spec m68hc11_attribute_table[];
 
 void create_regs_rtx PARAMS ((void));
-static void m68hc11_add_gc_roots PARAMS ((void));
 
 static void asm_print_register PARAMS ((FILE *, int));
 static void m68hc11_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
@@ -94,7 +93,7 @@ rtx da_reg;
 rtx stack_push_word;
 rtx stack_pop_word;
 static int regs_inited = 0;
-static rtx z_reg;
+rtx z_reg;
 
 /* Set to 1 by expand_prologue() when the function is an interrupt handler.  */
 int current_function_interrupt;
@@ -229,8 +228,6 @@ struct gcc_target targetm = TARGET_INITIALIZER;
 int
 m68hc11_override_options ()
 {
-  m68hc11_add_gc_roots ();
-
   memset (m68hc11_reg_valid_for_index, 0,
          sizeof (m68hc11_reg_valid_for_index));
   memset (m68hc11_reg_valid_for_base, 0, sizeof (m68hc11_reg_valid_for_base));
@@ -4005,7 +4002,7 @@ struct replace_info
   int z_loaded_with_sp;
 };
 
-static rtx z_reg_qi;
+rtx z_reg_qi;
 
 static int m68hc11_check_z_replacement PARAMS ((rtx, struct replace_info *));
 static void m68hc11_find_z_replacement PARAMS ((rtx, struct replace_info *));
@@ -5414,20 +5411,6 @@ m68hc11_asm_file_start (out, main_file)
 }
 
 
-static void
-m68hc11_add_gc_roots ()
-{
-  ggc_add_rtx_root (&m68hc11_soft_tmp_reg, 1);
-  ggc_add_rtx_root (&ix_reg, 1);
-  ggc_add_rtx_root (&iy_reg, 1);
-  ggc_add_rtx_root (&d_reg, 1);
-  ggc_add_rtx_root (&da_reg, 1);
-  ggc_add_rtx_root (&z_reg, 1);
-  ggc_add_rtx_root (&z_reg_qi, 1);
-  ggc_add_rtx_root (&stack_push_word, 1);
-  ggc_add_rtx_root (&stack_pop_word, 1);
-}
-
 static void
 m68hc11_asm_out_constructor (symbol, priority)
      rtx symbol;
index f985de4c0a2f9b7379b4a6fde4e91620d7125002..9910c3a5ec0f9d1da1c06b4acdab91642d6bf77a 100644 (file)
@@ -49,8 +49,8 @@ extern rtx          mcore_function_value              PARAMS ((tree, tree));
 
 #ifdef RTX_CODE
 
-extern rtx arch_compare_op0;
-extern rtx arch_compare_op1;
+extern GTY(()) rtx arch_compare_op0;
+extern GTY(()) rtx arch_compare_op1;
 
 extern const char * mcore_output_bclri                         PARAMS ((rtx, int));
 extern const char * mcore_output_bseti                         PARAMS ((rtx, int));
index 7276d813e2744b0e394736fbf050cc32a661a184..baf0a93f01f67f9b5e6600ff25358a82252ab2b9 100644 (file)
@@ -125,7 +125,6 @@ static cond_type  is_cond_candidate            PARAMS ((rtx));
 static rtx        emit_new_cond_insn           PARAMS ((rtx, int));
 static rtx        conditionalize_block         PARAMS ((rtx));
 static void       conditionalize_optimization  PARAMS ((rtx));
-static void       mcore_add_gc_roots           PARAMS ((void));
 static rtx        handle_structs_in_regs       PARAMS ((enum machine_mode, tree, int));
 static void       mcore_mark_dllexport         PARAMS ((tree));
 static void       mcore_mark_dllimport         PARAMS ((tree));
@@ -3069,15 +3068,6 @@ mcore_is_same_reg (x, y)
   return 0;
 }
 
-/* Called to register all of our global variables with the garbage
-   collector.  */
-static void
-mcore_add_gc_roots ()
-{
-  ggc_add_rtx_root (&arch_compare_op0, 1);
-  ggc_add_rtx_root (&arch_compare_op1, 1);
-}
-
 void
 mcore_override_options ()
 {
@@ -3096,8 +3086,6 @@ mcore_override_options ()
   /* Only the m340 supports little endian code.  */
   if (TARGET_LITTLE_END && ! TARGET_M340)
     target_flags |= M340_BIT;
-
-  mcore_add_gc_roots ();
 }
 \f
 int
index 9bcca17dcd36e6892a6fdeb249535428193fe254..1f6f71e42ef757c98ab1de8f01f57e857046cf5a 100644 (file)
@@ -124,7 +124,6 @@ static rtx mips_find_symbol                 PARAMS ((rtx));
 static void abort_with_insn                    PARAMS ((rtx, const char *))
   ATTRIBUTE_NORETURN;
 static int symbolic_expression_p                PARAMS ((rtx));
-static void mips_add_gc_roots                   PARAMS ((void));
 static bool mips_assemble_integer        PARAMS ((rtx, unsigned int, int));
 static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
@@ -143,9 +142,7 @@ static int iris6_section_align_1            PARAMS ((void **, void *));
 static int mips_adjust_cost                    PARAMS ((rtx, rtx, rtx, int));
 static int mips_issue_rate                     PARAMS ((void));
 
-static void mips_init_machine_status           PARAMS ((struct function *));
-static void mips_free_machine_status           PARAMS ((struct function *));
-static void mips_mark_machine_status           PARAMS ((struct function *));
+static struct machine_function * mips_init_machine_status PARAMS ((void));
 static void mips_select_section PARAMS ((tree, int, unsigned HOST_WIDE_INT))
        ATTRIBUTE_UNUSED;
 static void mips_unique_section                        PARAMS ((tree, int))
@@ -154,7 +151,7 @@ static void mips_select_rtx_section PARAMS ((enum machine_mode, rtx,
                                             unsigned HOST_WIDE_INT));
 static void mips_encode_section_info           PARAMS ((tree, int));
 
-struct machine_function {
+struct machine_function GTY(()) {
   /* Pseudo-reg holding the address of the current function when
      generating embedded PIC code.  Created by LEGITIMIZE_ADDRESS,
      used by mips_finalize_pic if it was created.  */
@@ -5435,44 +5432,16 @@ override_options ()
        align_functions = 8;
     }
 
-  /* Register global variables with the garbage collector.  */
-  mips_add_gc_roots ();
-
-  /* Functions to allocate, mark and deallocate machine-dependent
-     function status.  */
+  /* Function to allocate machine-dependent function status.  */
   init_machine_status = &mips_init_machine_status;
-  free_machine_status = &mips_free_machine_status;
-  mark_machine_status = &mips_mark_machine_status;
 }
 
 /* Allocate a chunk of memory for per-function machine-dependent data.  */
-static void
-mips_init_machine_status (fn)
-     struct function *fn;
-{
-  fn->machine = ((struct machine_function *)
-                xcalloc (1, sizeof (struct machine_function)));
-}
-
-/* Release the chunk of memory for per-function machine-dependent data.  */
-static void
-mips_free_machine_status (fn)
-     struct function *fn;
-{
-  free (fn->machine);
-  fn->machine = NULL;
-}
-
-/* Mark per-function machine-dependent data.  */
-static void
-mips_mark_machine_status (fn)
-     struct function *fn;
+static struct machine_function *
+mips_init_machine_status ()
 {
-  if (fn->machine)
-    {
-      ggc_mark_rtx (fn->machine->embedded_pic_fnaddr_rtx);
-      ggc_mark_rtx (fn->machine->mips16_gp_pseudo_rtx);
-    }
+  return ((struct machine_function *)
+         ggc_alloc_cleared (sizeof (struct machine_function)));
 }
 
 /* On the mips16, we want to allocate $24 (T_REG) before other
@@ -10128,19 +10097,6 @@ mips_output_conditional_branch (insn,
   return 0;
 }
 
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-mips_add_gc_roots ()
-{
-  ggc_add_rtx_root (&mips_load_reg, 1);
-  ggc_add_rtx_root (&mips_load_reg2, 1);
-  ggc_add_rtx_root (&mips_load_reg3, 1);
-  ggc_add_rtx_root (&mips_load_reg4, 1);
-  ggc_add_rtx_root (branch_cmp, ARRAY_SIZE (branch_cmp));
-}
-
 static enum processor_type
 mips_parse_cpu (cpu_string)
      const char *cpu_string;
@@ -10547,3 +10503,5 @@ iris6_asm_file_end (stream)
   mips_asm_file_end (stream);
 }
 #endif /* TARGET_IRIX6 */
+
+#include "gt-mips.h"
index 2a740684af220bc07dd78aeabbbb63e978e896f2..b17c2a0494d807ddab8ea1e4153575a3a0a6141f 100644 (file)
@@ -137,7 +137,7 @@ extern int set_noat;                        /* # of nested .set noat's  */
 extern int set_volatile;               /* # of nested .set volatile's  */
 extern int mips_branch_likely;         /* emit 'l' after br (branch likely) */
 extern int mips_dbx_regno[];           /* Map register # to debug register # */
-extern struct rtx_def *branch_cmp[2];  /* operands for compare */
+extern GTY(()) rtx branch_cmp[2];      /* operands for compare */
 extern enum cmp_type branch_type;      /* what type of branch to use */
 extern enum processor_type mips_arch;   /* which cpu to codegen for */
 extern enum processor_type mips_tune;   /* which cpu to schedule for */
@@ -162,10 +162,10 @@ extern int dslots_jump_total;             /* total # jump related delay slots */
 extern int dslots_jump_filled;         /* # filled jump delay slots */
 extern int dslots_number_nops;         /* # of nops needed by previous insn */
 extern int num_refs[3];                        /* # 1/2/3 word references */
-extern struct rtx_def *mips_load_reg;  /* register to check for load delay */
-extern struct rtx_def *mips_load_reg2; /* 2nd reg to check for load delay */
-extern struct rtx_def *mips_load_reg3; /* 3rd reg to check for load delay */
-extern struct rtx_def *mips_load_reg4; /* 4th reg to check for load delay */
+extern GTY(()) rtx mips_load_reg;      /* register to check for load delay */
+extern GTY(()) rtx mips_load_reg2;     /* 2nd reg to check for load delay */
+extern GTY(()) rtx mips_load_reg3;     /* 3rd reg to check for load delay */
+extern GTY(()) rtx mips_load_reg4;     /* 4th reg to check for load delay */
 extern int mips_string_length;         /* length of strings for mips16 */
 
 /* Functions to change what output section we are using.  */
@@ -2790,7 +2790,7 @@ typedef struct mips_args {
      the shift patterns, and function_arg, which returns them when given
      a VOIDmode argument.  */
   unsigned int num_adjusts;
-  struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS];
+  rtx adjust[MAX_ARGS_IN_REGISTERS];
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
index 234d84e0d0572cd7581cd4d680ef7865cf2ce688..d85b843767452b07f97e5eea60bd33d90d7633a1 100644 (file)
@@ -98,6 +98,7 @@ static void mmix_output_condition PARAMS ((FILE *, rtx, int));
 static HOST_WIDEST_INT mmix_intval PARAMS ((rtx));
 static void mmix_output_octa PARAMS ((FILE *, HOST_WIDEST_INT, int));
 static bool mmix_assemble_integer PARAMS ((rtx, unsigned int, int));
+static struct machine_function * mmix_init_machine_status PARAMS ((void));
 static void mmix_init_machine_status PARAMS ((struct function *));
 static void mmix_encode_section_info PARAMS ((tree, int));
 static const char *mmix_strip_name_encoding PARAMS ((const char *));
@@ -155,11 +156,6 @@ mmix_override_options ()
       warning ("-f%s not supported: ignored", (flag_pic > 1) ? "PIC" : "pic");
       flag_pic = 0;
     }
-
-  /* All other targets add GC roots from their override_options function,
-     so play along.  */
-  ggc_add_rtx_root (&mmix_compare_op0, 1);
-  ggc_add_rtx_root (&mmix_compare_op1, 1);
 }
 
 /* INIT_EXPANDERS.  */
@@ -172,11 +168,10 @@ mmix_init_expanders ()
 
 /* Set the per-function data.  */
 
-static void
-mmix_init_machine_status (f)
-     struct function *f;
+static struct machine_function *
+mmix_init_machine_status ()
 {
-  f->machine = xcalloc (1, sizeof (struct machine_function));
+  return ggc_alloc_cleared (sizeof (struct machine_function));
 }
 
 /* DATA_ALIGNMENT.
index 0f9d5b71698aa144758eba388be472fff9428d87..d553aea418c5c1c38049de5bc266a5f3a9d256bc 100644 (file)
@@ -82,13 +82,13 @@ Boston, MA 02111-1307, USA.  */
 
 /* Declarations for helper variables that are not tied to a particular
    target macro.  */
-extern struct rtx_def *mmix_compare_op0;
-extern struct rtx_def *mmix_compare_op1;
+extern GTY(()) rtx mmix_compare_op0;
+extern GTY(()) rtx mmix_compare_op1;
 
 /* Per-function machine data.  This is normally an opaque type just
    defined and used in the tm.c file, but we need to see the definition in
    mmix.md too.  */
-struct machine_function
+struct machine_function GTY(())
  {
    int has_landing_pad;
    int highest_saved_stack_register;
index 4fa4c2e1fb4edf8df994b17aa56f17d820596b5c..4dd1a01b39335b742485423c8e4f4207cd09d1c1 100644 (file)
@@ -85,8 +85,6 @@ asm_file_start (file)
   else
     fprintf (file, "\n\n");
   output_file_directive (file, main_input_filename);
-  ggc_add_rtx_root (&zero_dreg, 1);
-  ggc_add_rtx_root (&zero_areg, 1);
 }
 
 /* Print operand X using operand code CODE to assembly language output file
index 16f5f829d1fbe14e5cfe6a804726239c1ff6242d..bc9606e7129204cc03603c2108465db8da8d8bf3 100644 (file)
@@ -983,5 +983,5 @@ struct cum_arg { int nbytes; };
                                  SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM }}, \
   {"nshift_operator",          { ASHIFTRT, LSHIFTRT, ASHIFT }},
 
-extern struct rtx_def *zero_dreg;
-extern struct rtx_def *zero_areg;
+extern GTY(()) rtx zero_dreg;
+extern GTY(()) rtx zero_areg;
index 46d6846f770703b6232dc22272f473ac8e8cdc5f..258972534b5541f2e8bcbaddc735354a87ed0dc7 100644 (file)
@@ -100,8 +100,6 @@ static void pa_combine_instructions PARAMS ((rtx));
 static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
 static int forward_branch_p PARAMS ((rtx));
 static int shadd_constant_p PARAMS ((int));
-static void pa_add_gc_roots PARAMS ((void));
-static void mark_deferred_plabels PARAMS ((void *));
 static void compute_zdepwi_operands PARAMS ((unsigned HOST_WIDE_INT, unsigned *));
 static int compute_movstrsi_length PARAMS ((rtx));
 static bool pa_assemble_integer PARAMS ((rtx, unsigned int, int));
@@ -151,12 +149,14 @@ unsigned int total_code_bytes;
 /* Variables to handle plabels that we discover are necessary at assembly
    output time.  They are output after the current function.  */
 
-struct deferred_plabel
+struct deferred_plabel GTY(())
 {
   rtx internal_label;
   char *name;
-} *deferred_plabels = 0;
-int n_deferred_plabels = 0;
+};
+static GTY((length ("n_deferred_plabels"))) struct deferred_plabel *
+  deferred_plabels;
+static int n_deferred_plabels = 0;
 \f
 /* Initialize the GCC target structure.  */
 
@@ -301,9 +301,6 @@ override_options ()
       targetm.asm_out.unaligned_op.si = NULL;
       targetm.asm_out.unaligned_op.di = NULL;
     }
-
-  /* Register global variables with the garbage collector.  */
-  pa_add_gc_roots ();
 }
 
 /* Return non-zero only if OP is a register of mode MODE,
@@ -6277,10 +6274,10 @@ output_call (insn, call_dest, sibcall)
 
              if (deferred_plabels == 0)
                deferred_plabels = (struct deferred_plabel *)
-                 xmalloc (1 * sizeof (struct deferred_plabel));
+                 ggc_alloc (sizeof (struct deferred_plabel));
              else
                deferred_plabels = (struct deferred_plabel *)
-                 xrealloc (deferred_plabels,
+                 ggc_realloc (deferred_plabels,
                            ((n_deferred_plabels + 1)
                             * sizeof (struct deferred_plabel)));
 
@@ -7666,31 +7663,6 @@ cmpib_comparison_operator (op, mode)
              || GET_CODE (op) == LEU));
 }
 
-/* Mark ARG (which is really a struct deferred_plabel **) for GC.  */
-
-static void
-mark_deferred_plabels (arg)
-     void *arg;
-{
-  struct deferred_plabel *dp = *(struct deferred_plabel **) arg;
-  int i;
-
-  for (i = 0; i < n_deferred_plabels; ++i)
-    ggc_mark_rtx (dp[i].internal_label);
-}
-
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-pa_add_gc_roots ()
-{
-  ggc_add_rtx_root (&hppa_compare_op0, 1);
-  ggc_add_rtx_root (&hppa_compare_op1, 1);
-  ggc_add_root (&deferred_plabels, 1, sizeof (&deferred_plabels),
-               &mark_deferred_plabels);
-}
-
 /* On hpux10, the linker will give an error if we have a reference
    in the read-only data section to a symbol defined in a shared
    library.  Therefore, expressions that might require a reloc can
@@ -7717,3 +7689,5 @@ pa_select_section (exp, reloc, align)
   else
     data_section ();
 }
+
+#include "gt-pa.h"
index c2a6f584e1b89734ae9533ed670aeb01789b5c7a..9dd93f4a0c198d034d7b21eaeab00dec8d00b1f4 100644 (file)
@@ -865,7 +865,8 @@ struct hppa_args {int words, nargs_prototype, indirect; };
       || ((MODE) && GET_MODE_SIZE (MODE) > 8)))
 
 \f
-extern struct rtx_def *hppa_compare_op0, *hppa_compare_op1;
+extern GTY(()) rtx hppa_compare_op0;
+extern GTY(()) rtx hppa_compare_op1;
 extern enum cmp_type hppa_branch_type;
 
 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
index 17fdd3398ddca060bba93d4d29d5ad1f391ab923..a645695ca10a87514c2e776c2f0ae33aa3a5f60b 100644 (file)
@@ -147,8 +147,7 @@ static int toc_hash_eq PARAMS ((const void *, const void *));
 static int toc_hash_mark_entry PARAMS ((void **, void *));
 static void toc_hash_mark_table PARAMS ((void *));
 static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
-static void rs6000_free_machine_status PARAMS ((struct function *));
-static void rs6000_init_machine_status PARAMS ((struct function *));
+static struct machine_function * rs6000_init_machine_status PARAMS ((void));
 static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
 static int rs6000_ra_ever_killed PARAMS ((void));
 static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
@@ -631,7 +630,6 @@ rs6000_override_options (default_cpu)
 
   /* Arrange to save and restore machine status around nested functions.  */
   init_machine_status = rs6000_init_machine_status;
-  free_machine_status = rs6000_free_machine_status;
 }
 
 /* Handle -mvrsave= options.  */
@@ -6268,28 +6266,15 @@ rs6000_got_register (value)
   return pic_offset_table_rtx;
 }
 \f
-/* Functions to init, mark and free struct machine_function.
-   These will be called, via pointer variables,
-   from push_function_context and pop_function_context.  */
+/* Function to init struct machine_function.
+   This will be called, via a pointer variable,
+   from push_function_context.  */
 
-static void
-rs6000_init_machine_status (p)
-     struct function *p;
-{
-  p->machine = (machine_function *) xcalloc (1, sizeof (machine_function));
-}
-
-static void
-rs6000_free_machine_status (p)
-     struct function *p;
+static struct machine_function *
+rs6000_init_machine_status ()
 {
-  if (p->machine == NULL)
-    return;
-
-  free (p->machine);
-  p->machine = NULL;
+  return ggc_alloc_cleared (sizeof (machine_function));
 }
-
 \f
 /* Print an operand.  Recognize special options, documented below.  */
 
@@ -11254,16 +11239,9 @@ rs6000_fatal_bad_address (op)
 static void
 rs6000_add_gc_roots ()
 {
-  ggc_add_rtx_root (&rs6000_compare_op0, 1);
-  ggc_add_rtx_root (&rs6000_compare_op1, 1);
-
   toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
   ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table), 
                toc_hash_mark_table);
-
-#if TARGET_MACHO
-  machopic_add_gc_roots ();
-#endif
 }
 
 #if TARGET_MACHO
index 11ccee2221848b0a5ddfad722ddc2b81ed1b1a22..d9e0adec23e55f496445247060680b3ed3b0fef7 100644 (file)
@@ -1559,7 +1559,7 @@ typedef struct rs6000_stack {
 \f
 /* A C structure for machine-specific, per-function data.
    This is added to the cfun structure.  */
-typedef struct machine_function
+typedef struct machine_function GTY(())
 {
   /* Whether a System V.4 varargs area was created.  */
   int sysv_varargs_p;
@@ -2400,7 +2400,8 @@ do {                                                                           \
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
 
-extern struct rtx_def *rs6000_compare_op0, *rs6000_compare_op1;
+extern GTY(()) rtx rs6000_compare_op0;
+extern GTY(()) rtx rs6000_compare_op1;
 extern int rs6000_compare_fp_p;
 \f
 /* Control the assembler format that we output.  */
index 5839efa0cd2638b08b993a757e854df4aabaf8dc..16295788a73361dd3e0257c221b7442a86ff5bd8 100644 (file)
@@ -16,13 +16,15 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
 darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) $(RTL_BASE_H) \
           $(REGS_H) hard-reg-set.h insn-config.h conditions.h output.h \
           insn-attr.h flags.h $(TREE_H) $(EXPR_H) reload.h \
-          function.h $(GGC_H) $(TM_P_H)
+          function.h $(GGC_H) $(TM_P_H) gt-darwin.h
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
 
 darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) \
            $(TREE_H) $(C_TREE_H) c-pragma.h toplev.h cpplib.h $(TM_P_H)
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
 
+gt-darwin.h : s-gtype ; @true
+
 # Build the libraries for both hard and soft floating point
 
 MULTILIB_OPTIONS = msoft-float
index 3bbeb38fb4430aecd8bd6f49204431ebcffb6091..7656151f280fada419ec42f25522dd7419d106e2 100644 (file)
@@ -6230,16 +6230,14 @@ reg_unused_after (reg, insn)
 \f
 #include "ggc.h"
 
+static GTY(()) rtx fpscr_rtx;
 rtx
 get_fpscr_rtx ()
 {
-  static rtx fpscr_rtx;
-
   if (! fpscr_rtx)
     {
       fpscr_rtx = gen_rtx (REG, PSImode, FPSCR_REG);
       REG_USERVAR_P (fpscr_rtx) = 1;
-      ggc_add_rtx_root (&fpscr_rtx, 1);
       mark_user_reg (fpscr_rtx);
     }
   if (! reload_completed || mdep_reorg_phase != SH_AFTER_MDEP_REORG)
@@ -6819,3 +6817,5 @@ sh_strip_name_encoding (str)
   str += *str == '*';
   return str;
 }
+
+#include "gt-sh.h"
index 8d5c0728254331909ef63f2b95c7f18b5156950f..79528dd7d18a9c88b951319bf855e8332457a5ef 100644 (file)
@@ -44,5 +44,8 @@ $(T)crti.o: $(srcdir)/config/sh/crti.asm $(GCC_PASSES)
 $(T)crtn.o: $(srcdir)/config/sh/crtn.asm $(GCC_PASSES)
        $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/sh/crtn.asm
 
+$(out_object_file): gt-sh.h
+gt-sh.h : s-gtype ; @true
+
 # These are not suitable for COFF.
 # EXTRA_MULTILIB_PARTS= crt1.o crti.o crtn.o crtbegin.o crtend.o
index a43f48bd0f99b816cf585385fc90c0f8a2aebe7f..b9745c7c529315532a67bd29bd13aa3b70066b11 100644 (file)
@@ -140,7 +140,6 @@ static int hypersparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
 static void sparc_output_addr_vec PARAMS ((rtx));
 static void sparc_output_addr_diff_vec PARAMS ((rtx));
 static void sparc_output_deferred_case_vectors PARAMS ((void));
-static void sparc_add_gc_roots    PARAMS ((void));
 static int check_return_regs PARAMS ((rtx));
 static int epilogue_renumber PARAMS ((rtx *, int));
 static bool sparc_assemble_integer PARAMS ((rtx, unsigned int, int));
@@ -438,9 +437,6 @@ sparc_override_options ()
 
   /* Do various machine dependent initializations.  */
   sparc_init_modes ();
-
-  /* Register global variables with the garbage collector.  */
-  sparc_add_gc_roots ();
 }
 \f
 /* Miscellaneous utilities.  */
@@ -3114,10 +3110,10 @@ reg_unused_after (reg, insn)
 }
 \f
 /* The table we use to reference PIC data.  */
-static rtx global_offset_table;
+static GTY(()) rtx global_offset_table;
 
 /* The function we use to get at it.  */
-static rtx get_pc_symbol;
+static GTY(()) rtx get_pc_symbol;
 static char get_pc_symbol_name[256];
 
 /* Ensure that we are not using patterns that are not OK with PIC.  */
@@ -7786,8 +7782,8 @@ set_extends (insn)
 }
 
 /* We _ought_ to have only one kind per function, but...  */
-static rtx sparc_addr_diff_list;
-static rtx sparc_addr_list;
+static GTY(()) rtx sparc_addr_diff_list;
+static GTY(()) rtx sparc_addr_list;
 
 void
 sparc_defer_case_vector (lab, vec, diff)
@@ -7997,20 +7993,6 @@ sparc_profile_hook (labelno)
   emit_library_call (fun, LCT_NORMAL, VOIDmode, 1, lab, Pmode);
 }
 \f
-/* Called to register all of our global variables with the garbage
-   collector.  */
-
-static void
-sparc_add_gc_roots ()
-{
-  ggc_add_rtx_root (&sparc_compare_op0, 1);
-  ggc_add_rtx_root (&sparc_compare_op1, 1);
-  ggc_add_rtx_root (&global_offset_table, 1);
-  ggc_add_rtx_root (&get_pc_symbol, 1);
-  ggc_add_rtx_root (&sparc_addr_diff_list, 1);
-  ggc_add_rtx_root (&sparc_addr_list, 1);
-}
-
 #ifdef OBJECT_FORMAT_ELF
 static void
 sparc_elf_asm_named_section (name, flags)
@@ -8530,3 +8512,5 @@ sparc_output_mi_thunk (file, thunk_fndecl, delta, function)
   reload_completed = 0;
   no_new_pseudos = 0;
 }
+
+#include "gt-sparc.h"
index 12490d38a4232cea59e1838823a2c7066b169a93..333a5d56f164b8599a76cf70ec8367840ac936b2 100644 (file)
@@ -1809,7 +1809,8 @@ function_arg_padding ((MODE), (TYPE))
    stored from the compare operation.  Note that we can't use "rtx" here
    since it hasn't been defined!  */
 
-extern struct rtx_def *sparc_compare_op0, *sparc_compare_op1;
+extern GTY(()) rtx sparc_compare_op0;
+extern GTY(()) rtx sparc_compare_op1;
 
 \f
 /* Generate the special assembly code needed to tell the assembler whatever
index 83a5ee71bb5038fe403ef341d372199aecedcfa5..c29fff075c4a51ac72dd6ed82de26240c41f6c25 100644 (file)
@@ -27,3 +27,6 @@ LIB1ASMFUNCS = _mulsi3 _nsau _divsi3 _modsi3 _udivsi3 _umodsi3
 TARGET_LIBGCC2_CFLAGS += -mlongcalls
 
 LIB2FUNCS_EXTRA += $(srcdir)/config/xtensa/lib2funcs.S
+
+$(out_object_file): gt-xtensa.h
+gt-xtensa.h : s-gtype ; @true
index 1fc5302b83cc5504cf6f344a24b1883c876671e3..6e6c6d9a3e3839f924712849686a3d30f97971a1 100644 (file)
@@ -85,7 +85,7 @@ const char *xtensa_st_opcodes[(int) MAX_MACHINE_MODE];
 #define LARGEST_MOVE_RATIO 15
 
 /* Define the structure for the machine field in struct function.  */
-struct machine_function
+struct machine_function GTY(())
 {
   int accesses_prev_frame;
 };
@@ -193,8 +193,7 @@ static rtx gen_float_relational PARAMS ((enum rtx_code, rtx, rtx));
 static rtx gen_conditional_move PARAMS ((rtx));
 static rtx fixup_subreg_mem PARAMS ((rtx x));
 static enum machine_mode xtensa_find_mode_for_size PARAMS ((unsigned));
-static void xtensa_init_machine_status PARAMS ((struct function *p));
-static void xtensa_free_machine_status PARAMS ((struct function *p));
+static struct machine_status * xtensa_init_machine_status PARAMS ((void));
 static void printx PARAMS ((FILE *, signed int));
 static void xtensa_select_rtx_section PARAMS ((enum machine_mode, rtx,
                                               unsigned HOST_WIDE_INT));
@@ -1549,21 +1548,10 @@ xtensa_expand_nonlocal_goto (operands)
 }
 
 
-static void
-xtensa_init_machine_status (p)
-     struct function *p;
+static struct machine_function *
+xtensa_init_machine_status ()
 {
-  p->machine = (struct machine_function *)
-    xcalloc (1, sizeof (struct machine_function));
-}
-
-
-static void
-xtensa_free_machine_status (p)
-     struct function *p;
-{
-  free (p->machine);
-  p->machine = NULL;
+  return ggc_alloc_cleared (sizeof (struct machine_function));
 }
 
 
@@ -1846,7 +1834,6 @@ override_options ()
     }
 
   init_machine_status = xtensa_init_machine_status;
-  free_machine_status = xtensa_free_machine_status;
 
   /* Check PIC settings.  There's no need for -fPIC on Xtensa and
      some targets need to always use PIC.  */
@@ -2759,3 +2746,5 @@ xtensa_encode_section_info (decl, first)
   if (TREE_CODE (decl) == FUNCTION_DECL && ! TREE_PUBLIC (decl))
     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
 }
+
+#include "gt-xtensa.h"
index e87dc26703f61960c21bd55ec456690a92db1cf6..b949926770ae8e4dcc6e84fcbce0687df303f009 100755 (executable)
@@ -2226,7 +2226,7 @@ EOF
 fi
 
 # Find some useful tools
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
 do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
@@ -6706,7 +6706,7 @@ for f in $tm_file; do
     ansidecl.h )
        tm_file_list="${tm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
     defaults.h )
-       tm_file_list="${tm_file_list} $f" ;;
+       tm_file_list="${tm_file_list} \$(srcdir)/$f" ;;
     *) tm_file_list="${tm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -6721,8 +6721,10 @@ for f in $host_xm_file; do
   case $f in
     ansidecl.h )
        host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
-    auto-host.h | defaults.h )
+    auto-host.h )
        host_xm_file_list="${host_xm_file_list} $f" ;;
+    defaults.h )
+       host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
     *) host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -6732,8 +6734,10 @@ for f in $build_xm_file; do
   case $f in
     ansidecl.h )
        build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
-    auto-build.h | auto-host.h | defaults.h )
+    auto-build.h | auto-host.h )
        build_xm_file_list="${build_xm_file_list} $f" ;;
+    defaults.h )
+       host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
     *) build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -6841,7 +6845,7 @@ fi
 
 # Figure out what assembler we will be using.
 echo $ac_n "checking what assembler to use""... $ac_c" 1>&6
-echo "configure:6845: checking what assembler to use" >&5
+echo "configure:6849: checking what assembler to use" >&5
 gcc_cv_as=
 gcc_cv_gas_major_version=
 gcc_cv_gas_minor_version=
@@ -6935,7 +6939,7 @@ fi
 
 # Figure out what linker we will be using.
 echo $ac_n "checking what linker to use""... $ac_c" 1>&6
-echo "configure:6939: checking what linker to use" >&5
+echo "configure:6943: checking what linker to use" >&5
 gcc_cv_ld=
 gcc_cv_gld_major_version=
 gcc_cv_gld_minor_version=
@@ -7028,7 +7032,7 @@ fi
 
 # Figure out what nm we will be using.
 echo $ac_n "checking what nm to use""... $ac_c" 1>&6
-echo "configure:7032: checking what nm to use" >&5
+echo "configure:7036: checking what nm to use" >&5
 if test -x nm$host_exeext; then
        gcc_cv_nm=./nm$host_exeext
 elif test "x$program_prefix" != xNONE; then
@@ -7040,7 +7044,7 @@ echo "$ac_t""$gcc_cv_nm" 1>&6
 
 # Figure out what objdump we will be using.
 echo $ac_n "checking what objdump to use""... $ac_c" 1>&6
-echo "configure:7044: checking what objdump to use" >&5
+echo "configure:7048: checking what objdump to use" >&5
 if test -x objdump$host_exeext; then
        gcc_cv_objdump=./objdump$host_exeext
 elif test "x$program_prefix" != xNONE; then
@@ -7052,7 +7056,7 @@ echo "$ac_t""$gcc_cv_objdump" 1>&6
 
 # Figure out what assembler alignment features are present.
 echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:7056: checking assembler alignment features" >&5
+echo "configure:7060: checking assembler alignment features" >&5
 gcc_cv_as_alignment_features=none
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
        # Gas version 2.6 and later support for .balign and .p2align.
@@ -7100,7 +7104,7 @@ fi
 echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
 
 echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:7104: checking assembler subsection support" >&5
+echo "configure:7108: checking assembler subsection support" >&5
 gcc_cv_as_subsections=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
@@ -7140,7 +7144,7 @@ fi
 echo "$ac_t""$gcc_cv_as_subsections" 1>&6
 
 echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:7144: checking assembler weak support" >&5
+echo "configure:7148: checking assembler weak support" >&5
 gcc_cv_as_weak=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 2 -o "$gcc_cv_gas_major_version" -gt 2; then
@@ -7163,7 +7167,7 @@ fi
 echo "$ac_t""$gcc_cv_as_weak" 1>&6
 
 echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
-echo "configure:7167: checking assembler hidden support" >&5
+echo "configure:7171: checking assembler hidden support" >&5
 gcc_cv_as_hidden=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2    \
@@ -7226,7 +7230,7 @@ libgcc_visibility=$gcc_cv_as_hidden
 
 
 echo $ac_n "checking assembler leb128 support""... $ac_c" 1>&6
-echo "configure:7230: checking assembler leb128 support" >&5
+echo "configure:7234: checking assembler leb128 support" >&5
 gcc_cv_as_leb128=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 11 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
@@ -7271,7 +7275,7 @@ fi
 echo "$ac_t""$gcc_cv_as_leb128" 1>&6
 
 echo $ac_n "checking assembler eh_frame optimization""... $ac_c" 1>&6
-echo "configure:7275: checking assembler eh_frame optimization" >&5
+echo "configure:7279: checking assembler eh_frame optimization" >&5
 gcc_cv_as_eh_frame=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
@@ -7352,7 +7356,7 @@ fi
 echo "$ac_t""$gcc_cv_as_eh_frame" 1>&6
 
 echo $ac_n "checking assembler section merging support""... $ac_c" 1>&6
-echo "configure:7356: checking assembler section merging support" >&5
+echo "configure:7360: checking assembler section merging support" >&5
 gcc_cv_as_shf_merge=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
   if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
@@ -7375,7 +7379,7 @@ fi
 echo "$ac_t""$gcc_cv_as_shf_merge" 1>&6
 
 echo $ac_n "checking assembler thread-local storage support""... $ac_c" 1>&6
-echo "configure:7379: checking assembler thread-local storage support" >&5
+echo "configure:7383: checking assembler thread-local storage support" >&5
 gcc_cv_as_tls=no
 conftest_s=
 tls_first_major=
@@ -7467,7 +7471,7 @@ case "$target" in
   # All TARGET_ABI_OSF targets.
   alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
     echo $ac_n "checking assembler supports explicit relocations""... $ac_c" 1>&6
-echo "configure:7471: checking assembler supports explicit relocations" >&5
+echo "configure:7475: checking assembler supports explicit relocations" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_explicit_relocs'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7517,7 +7521,7 @@ EOF
     ;;
   sparc*-*-*)
     echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:7521: checking assembler .register pseudo-op support" >&5
+echo "configure:7525: checking assembler .register pseudo-op support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7545,7 +7549,7 @@ EOF
     fi
 
     echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
-echo "configure:7549: checking assembler supports -relax" >&5
+echo "configure:7553: checking assembler supports -relax" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_relax_opt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7573,7 +7577,7 @@ EOF
     fi
 
     echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
-echo "configure:7577: checking assembler and linker support unaligned pc related relocs" >&5
+echo "configure:7581: checking assembler and linker support unaligned pc related relocs" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7600,7 +7604,7 @@ EOF
     fi
 
     echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
-echo "configure:7604: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
+echo "configure:7608: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel_hidden'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7641,7 +7645,7 @@ EOF
 
     if test "x$gcc_cv_as_flags64" != xno; then
        echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:7645: checking for assembler offsetable %lo() support" >&5
+echo "configure:7649: checking for assembler offsetable %lo() support" >&5
 if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7681,7 +7685,7 @@ EOF
 
   i[34567]86-*-* | x86_64-*-*)
     echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:7685: checking assembler instructions" >&5
+echo "configure:7689: checking assembler instructions" >&5
     gcc_cv_as_instructions=
     if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
       if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2; then
@@ -7708,7 +7712,7 @@ EOF
     echo "$ac_t""$gcc_cv_as_instructions" 1>&6
 
     echo $ac_n "checking assembler GOTOFF in data directives""... $ac_c" 1>&6
-echo "configure:7712: checking assembler GOTOFF in data directives" >&5
+echo "configure:7716: checking assembler GOTOFF in data directives" >&5
     gcc_cv_as_gotoff_in_data=no
     if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
     then
@@ -7738,7 +7742,7 @@ EOF
 esac
 
 echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
-echo "configure:7742: checking assembler dwarf2 debug_line support" >&5
+echo "configure:7746: checking assembler dwarf2 debug_line support" >&5
 gcc_cv_as_dwarf2_debug_line=no
 # ??? Not all targets support dwarf2 debug_line, even within a version
 # of gas.  Moreover, we need to emit a valid instruction to trigger any
@@ -7794,7 +7798,7 @@ fi
 echo "$ac_t""$gcc_cv_as_dwarf2_debug_line" 1>&6
 
 echo $ac_n "checking assembler --gdwarf2 support""... $ac_c" 1>&6
-echo "configure:7798: checking assembler --gdwarf2 support" >&5
+echo "configure:7802: checking assembler --gdwarf2 support" >&5
 gcc_cv_as_gdwarf2_flag=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
 then
@@ -7823,7 +7827,7 @@ fi
 echo "$ac_t""$gcc_cv_as_gdwarf2_flag" 1>&6
 
 echo $ac_n "checking assembler --gstabs support""... $ac_c" 1>&6
-echo "configure:7827: checking assembler --gstabs support" >&5
+echo "configure:7831: checking assembler --gstabs support" >&5
 gcc_cv_as_gstabs_flag=no
 if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
 then
@@ -7851,7 +7855,7 @@ fi
 echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6
 
 echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6
-echo "configure:7855: checking linker PT_GNU_EH_FRAME support" >&5
+echo "configure:7859: checking linker PT_GNU_EH_FRAME support" >&5
 gcc_cv_ld_eh_frame_hdr=no
 if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
   if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
@@ -8014,7 +8018,7 @@ fi
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:8018: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:8022: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -8072,6 +8076,8 @@ all_stagestuff=
 all_outputs='Makefile intl/Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
 # List of language makefile fragments.
 all_lang_makefiles=
+# Files for gengtype
+all_gtfiles=
 
 # Add the language fragments.
 # Languages are added via two mechanisms.  Some information must be
@@ -8092,6 +8098,7 @@ do
                compilers=
                stagestuff=
                outputs=
+               gtfiles=
                . ${srcdir}/$s/config-lang.in
                if test "x$language" = x
                then
@@ -8110,6 +8117,7 @@ do
                all_compilers="$all_compilers $compilers"
                all_stagestuff="$all_stagestuff $stagestuff"
                all_outputs="$all_outputs $outputs"
+               all_gtfiles="$all_gtfiles $gtfiles"
        fi
 done
 
@@ -8304,6 +8312,7 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
 
 
 
+
 
 
 # Echo that links are built
@@ -8569,6 +8578,7 @@ s%@objdir@%$objdir%g
 s%@subdirs@%$subdirs%g
 s%@all_boot_languages@%$all_boot_languages%g
 s%@all_compilers@%$all_compilers%g
+s%@all_gtfiles@%$all_gtfiles%g
 s%@all_lang_makefiles@%$all_lang_makefiles%g
 s%@all_languages@%$all_languages%g
 s%@all_stagestuff@%$all_stagestuff%g
index a3b925aa52d67e7135e1b18f1a3f7924bcef38c9..d6a395ee425eae9b5fd0eea6b1dc3739ac829d16 100644 (file)
@@ -1062,7 +1062,7 @@ for f in $tm_file; do
     ansidecl.h )
        tm_file_list="${tm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
     defaults.h )
-       tm_file_list="${tm_file_list} $f" ;;
+       tm_file_list="${tm_file_list} \$(srcdir)/$f" ;;
     *) tm_file_list="${tm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -1077,8 +1077,10 @@ for f in $host_xm_file; do
   case $f in
     ansidecl.h )
        host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
-    auto-host.h | defaults.h )
+    auto-host.h )
        host_xm_file_list="${host_xm_file_list} $f" ;;
+    defaults.h )
+       host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
     *) host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -1088,8 +1090,10 @@ for f in $build_xm_file; do
   case $f in
     ansidecl.h )
        build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
-    auto-build.h | auto-host.h | defaults.h )
+    auto-build.h | auto-host.h )
        build_xm_file_list="${build_xm_file_list} $f" ;;
+    defaults.h )
+       host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
     *) build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" ;;
   esac
 done
@@ -2326,6 +2330,8 @@ all_stagestuff=
 all_outputs='Makefile intl/Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
 # List of language makefile fragments.
 all_lang_makefiles=
+# Files for gengtype
+all_gtfiles=
 
 # Add the language fragments.
 # Languages are added via two mechanisms.  Some information must be
@@ -2346,6 +2352,7 @@ do
                compilers=
                stagestuff=
                outputs=
+               gtfiles=
                . ${srcdir}/$s/config-lang.in
                if test "x$language" = x
                then
@@ -2364,6 +2371,7 @@ do
                all_compilers="$all_compilers $compilers"
                all_stagestuff="$all_stagestuff $stagestuff"
                all_outputs="$all_outputs $outputs"
+               all_gtfiles="$all_gtfiles $gtfiles"
        fi
 done
 
@@ -2496,6 +2504,7 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
 AC_SUBST(subdirs)
 AC_SUBST(all_boot_languages)
 AC_SUBST(all_compilers)
+AC_SUBST(all_gtfiles)
 AC_SUBST(all_lang_makefiles)
 AC_SUBST(all_languages)
 AC_SUBST(all_stagestuff)
index 75e7599869a78dbed35e0e06cb3cbec0bafa2920..e3af880f414e2eca3195b4b8b4ac47368563e408 100644 (file)
@@ -1,3 +1,213 @@
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       * pt.c (inline_parm_levels): Mark for GC.
+
+       * mangle.c (start_mangling): Allocate G.substitutions here...
+       (init_mangle): ... rather than here.
+       (finish_mangling): Clear the varray pointer when done with it.
+       * spew.c (yylexstring): Don't use VARRAY_FREE. 
+       * search.c (bfs_walk): Don't use VARRAY_FREE. 
+       * decl2.c (pending_statics): Use gengtype to mark.
+       (deferred_fns): Likewise.
+       (ssdf_decls): Likewise.
+       (init_decl2): Delete.
+       * decl.c (pop_from_top_level): Don't use VARRAY_FREE.
+       (cxx_init_decl_processing): Don't call init_decl2.
+       (cxx_pop_function_context): Don't use VARRAY_FREE.
+       * cp-tree.h (struct saved_scope): No need for special marking
+       of varrays.
+       (struct language_function): Likewise.
+       (local_classes): Use gengtype to mark.
+       (init_decl2): Delete prototype.
+       * class.c (init_class_processing): Don't use
+       ggc_add_tree_varray_root.
+       (build_vtbl_initializer): Don't use VARRAY_FREE.
+
+       * decl.c (typename_compare): Don't use same_type_p.
+
+       * decl.c: Include hashtab.h instead of hash.h.
+       (typename_hash): Update to use htab_h.
+       (typename_compare): Likewise.
+       (typename_htab): Use gengtype to mark.
+       (build_typename_type): Update to use htab_h.
+       * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h.
+
+       * Make-lang.in (gt-cp-tree.h): New rule.
+       (cp/tree.o): Depend on gt-cp-tree.h.
+       * config-lang.in (gtfiles): Add cp/tree.c.
+       * tree.c: Include gt-cp-tree.h.
+       (list_hash_table): Use gengtype to mark.
+       (init_tree): Use gengtype to mark trees.
+
+       * Make-lang.in (cp/decl.o): Add debug.h dependency.
+       * call.c (struct z_candidate): Use gengtype.
+       (USER_CONV_CAND): Use WRAPPER_ZC.
+       (convert_class_to_reference): Use build_zc_wrapper.
+       (build_type_conversion_1): Likewise.
+       (build_over_call): Use WRAPPER_ZC.
+       (add_warning): Use build_zc_wrapper.
+       * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+       * cp-tree.h (struct lang_identifier): Use gengtype.
+       (struct template_parm_index_s): Likewise.
+       (struct ptrmem_cst): Likewise.
+       (struct tree_binding): Likewise.
+       (struct tree_overload): Likewise.
+       (struct tree_srcloc): Likewise.
+       (struct tree_wrapper): Likewise.  Also modify to have a pointer
+       to struct z_candidate rather than void.
+       (enum cp_tree_node_structure_enum): New.
+       (union lang_tree_node): New.
+       (cxx_mark_tree): Delete prototype.
+       (cp_tree_node_structure): New prototype.
+       (build_ptr_wrapper): Delete prototype.
+       (build_int_wrapper): Delete prototype.
+       (build_zc_wrapper): New prototype.
+       * decl.c: Include debug.h
+       (cxx_mark_tree): Delete.
+       (cp_tree_node_structure): New.
+       * tree.c (build_ptr_wrapper): Delete.
+       (build_int_wrapper): Delete.
+       (build_zc_wrapper): New.
+
+       * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK):
+       Correct typo.  Patch from k_fukui@highway.ne.jp.
+
+       * semantics.c (current_stmt_tree): Update for change to
+       struct language_function.
+       (finish_mem_initializers): Likewise.
+       * decl.c (cxx_init_decl_processing): Don't set mark_lang_status.
+       * cp-tree.h (struct language_function): Rename from
+       cp_language_function.  Change all uses.
+       (cp_function_chain): Don't need to cast.
+
+       * class.c (duplicate_tag_error): Reset discriminator.
+       (check_bases_and_members): Update for data structure changes.
+       * cp-tree.h (struct lang_id2): Use gengtype.
+       (flagged_type_tree): Likewise.
+       (SET_LANG_ID): Use GGC on struct lang_id2.
+       (struct cp_language_function): Use gengtype.  Remove field
+       'x_vcalls_possible_p'.
+       (current_vcalls_possible_p): Delete.
+       (struct lang_type_header): New.
+       (struct lang_type_class): Rename from struct lang_type.  Include
+       struct lang_type_header.
+       (struct lang_type_ptrmem): New.
+       (struct lang_type): New.
+       (LANG_TYPE_CLASS_CHECK): New.  Use it in all the appropriate macros.
+       (LANG_TYPE_PTRMEM_CHECK): New.  Use it in all the appropriate macros.
+       (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes.
+       (struct lang_decl_flags): Use gengtype.  Add discriminators.
+       (struct lang_decl): Use gengtype.  Add and use discriminators.
+       Update the macros that reference moved fields.
+       (LANG_DECL_U2_CHECK): New function.  Use it when appropriate.
+       (SET_DECL_THUNK_P): Set discriminator too.
+       (clear_inline_text_obstack): Delete prototype.
+       (finish_inline_definitions): Delete prototype.
+       (mark_pending_inlines): Delete prototype.
+       (lang_check_failed): New prototype.
+       * decl.c (struct named_label_use_list): Use gengtype.
+       (struct named_label_list): Likewise.
+       (mark_binding_level): Delete.
+       (mark_named_label_lists): Delete.
+       (push_local_name): Set discriminator on DECL_LANG_SPECIFIC.
+       (cxx_init_decl_processing): Use generated marker routine.
+       (begin_destructor_body): Delete dead set to
+       current_vcalls_possible_p.
+       (mark_lang_function): Delete.
+       (mark_cp_function_context): Delete.
+       (lang_mark_tree): Use generated marker routines.
+       * decl2.c (start_objects): Set discriminator when setting
+       GLOBAL_INIT_PRIORITY.
+       * lex.c (retrofit_lang_decl): Set discriminators.
+       (copy_lang_type): Update for changes to lang_type structure.
+       (cp_make_lang_type): Set discriminator.
+       * parse.y: Use gengtype on YYLVAL.  Don't use dots in identifiers.
+       * search.c: Include ggc.h.
+       * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it.
+       (finish_inline_definitions): Delete.
+       * spew.c (struct token): Use gengtype.
+       (struct token_chunk): New.
+       (struct unparsed_text): Use gengtype.  Store tokens in chunks.
+       (struct feed): Use gengtype.
+       (feed_obstack): Delete.
+       (feed): Mark as GC root.
+       (pending_inlines): Mark as GC root.
+       (pending_inlines_tail): Likewise.
+       (processing_these_inlines): Likewise.
+       (token_obstack): Make static.
+       (first_token): Likewise.
+       (init_spew): Don't initialise deleted things; use gengtype for roots.
+       (clear_inline_text_obstack): Delete.
+       (feed_input): Use GC for struct feed.  Update for changes to
+       struct unparsed_text.
+       (mark_pending_inlines): Delete.
+       (next_token): Rename from add_token.  Change all callers.  Update
+       for changes to struct unparsed_text.
+       (space_for_token): New.
+       (remove_last_token): New.
+       (alloc_unparsed_text): New.
+       (snarf_block): Take an unparsed_text.  Update for changes to struct
+       unparsed_text.
+       (snarf_method): Update for changes to struct unparsed_text.
+       (snarf_defarg): Update for changes to struct unparsed_text.
+       * tree.c (lang_check_failed): New.
+
+       * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h
+       gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules.
+       (cp/spew.o): Add dependency on gt-<filename>.h.
+       (cp/decl2.o): Add dependency on gt-<filename>.h.
+       (cp/call.o): Add dependency on gt-<filename>.h.
+       (cp/pt.o): Add dependency on gt-<filename>.h.
+       (cp/repo.o): Add dependency on gt-<filename>.h.
+       (cp/parse.o): Add dependency on gt-<filename>.h.
+       * call.c: Use gengtype for roots.
+       * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c
+       decl2.c parse.y pt.c repo.c spew.c.
+       * cp-tree.h: Use gengtype for roots.
+       (struct saved_scope): Use GGC, gengtype.
+       (cp_parse_init): Delete prototype.
+       (init_pt): Delete prototype.
+       * decl.c: Use gengtype for roots.
+       (mark_saved_scope): Delete.
+       (cxx_init_decl_processing): Don't call deleted initilisation
+       routines.
+       (signed_size_zero_node): Delete, unused.
+       * decl.h: Use gengtype for roots.
+       * decl2.c: Use gengtype for roots.
+       * lex.h: Use gengtype for roots.
+       * parse.y: Use gengtype for roots.
+       (cp_parse_init): Delete.
+       * pt.c: Use gengtype for roots.
+       (init_pt): Delete.
+       * repo.c: Use gengtype for roots.
+       * spew.c: Use gengtype for roots.
+
+       * Make-lang.in: Allow for filename changes.  Add gtype-cp.h.
+       (cp/decl.o): Add dependency on gtype-cp.h.
+       * decl.c: Remove use of add_deletable_root, use GTY marker instead.
+       Include gtype-cp.h.  Allow for filename changes.
+
+       * Make-lang.in (cp/gt-decl.h): Generate using gengtype.
+       (cp/decl.o): Add cp/gt-decl.h dependency.
+       * config-lang.in (gtfiles): New.
+       * tree.h: Rename struct binding_level to struct cp_binding_level.
+       * decl.c: Rename struct binding_level to struct cp_binding_level.
+       Include cp/gt-decl.h.
+       (struct cp_binding_level): Use gengtype.
+       (make_binding_level): Use GGC on struct cp_binding_level.
+       (mark_binding_level): Use gt_ggc_m_cp_binding_level.
+       (cxx_init_decl_processing): Mark free_binding_level as
+       deletable.
+
+       * decl.c (mark_cp_function_context): Update calling sequence.
+
+       * decl.c (start_function): Don't free 'struct
+       cp_language_function'.
+       (pop_cp_function_context): Likewise.
+       (save_function_data): Allocate it using GC.
+       * semantics.c (genrtl_start_function): Don't free 'struct
+       cp_language_function'.
+
 2002-05-31  Matthew Woodcraft  <mattheww@chiark.greenend.org.uk>
 
        * lang-specs.h: Use cpp_debug_options.
index 029b6469f714b9f88fa022033f6371959f5b52ac..104adf8d7393bb105d7729adebfffd5b7b95a061 100644 (file)
@@ -131,6 +131,10 @@ $(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y
          false ; \
        fi
 
+gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true
+gt-cp-parse.h gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h : s-gtype; @true
+gt-cp-tree.h : s-gtype; @true
+
 #\f
 # Build hooks:
 
@@ -247,24 +251,26 @@ CXX_TREE_H = $(TREE_H) cp/cp-tree.h c-common.h cp/cp-tree.def c-common.def \
        function.h varray.h $(SYSTEM_H) $(CONFIG_H) $(TARGET_H) \
        $(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
 
-cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h
+cp/spew.o: cp/spew.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h toplev.h \
+  gt-cp-spew.h
 cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \
   toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \
   $(TM_P_H)
 cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \
   c-common.h
 cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
-  output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \
-  cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h
+  output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(GGC_H) $(RTL_H) \
+  cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
+  debug.h gt-cp-decl.h gtype-cp.h
 cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
-  output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h
+  output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h gt-cp-decl2.h
 cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \
    diagnostic.h
 cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
    diagnostic.h
 cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(TARGET_H)
 cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
-     $(GGC_H) diagnostic.h
+     $(GGC_H) diagnostic.h gt-cp-call.h
 cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
 cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
   $(GGC_H) except.h
@@ -273,7 +279,7 @@ cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \
 cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
 cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
 cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
-  insn-config.h integrate.h tree-inline.h real.h
+  insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h
 cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H)
 cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h
 cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
@@ -281,10 +287,11 @@ cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
 cp/expr.o: cp/expr.c $(CXX_TREE_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
   except.h $(TM_P_H)
 cp/pt.o: cp/pt.c $(CXX_TREE_H) cp/decl.h cp/parse.h cp/lex.h toplev.h \
-  $(GGC_H) $(RTL_H) except.h tree-inline.h
+  $(GGC_H) $(RTL_H) except.h tree-inline.h gt-cp-pt.h
 cp/error.o: cp/error.c $(CXX_TREE_H) toplev.h diagnostic.h flags.h real.h \
   $(LANGHOOKS_DEF_H)
-cp/repo.o: cp/repo.c $(CXX_TREE_H) toplev.h $(GGC_H) diagnostic.h
+cp/repo.o: cp/repo.c $(CXX_TREE_H) toplev.h $(GGC_H) diagnostic.h \
+  gt-cp-repo.h
 cp/semantics.o: cp/semantics.c $(CXX_TREE_H) cp/lex.h except.h toplev.h \
   flags.h $(GGC_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
   tree-inline.h
@@ -294,7 +301,7 @@ cp/optimize.o: cp/optimize.c $(CXX_TREE_H) rtl.h integrate.h insn-config.h \
 cp/mangle.o: cp/mangle.c $(CXX_TREE_H) toplev.h real.h
 
 cp/parse.o: cp/parse.c $(CXX_TREE_H) flags.h cp/lex.h except.h output.h \
-       $(SYSTEM_H) toplev.h $(GGC_H)
+       $(SYSTEM_H) toplev.h $(GGC_H) gt-cp-parse.h
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
                $(srcdir)/cp/parse.c $(OUTPUT_OPTION)
 #\f
index 75fac88df7d7a09d08f2176334a43f4fcb15aa20..ed6ab2e3f1b66d230cccafac3dc72cabd4ce68a4 100644 (file)
@@ -535,7 +535,7 @@ build_method_call (instance, name, parms, basetype_path, flags)
 
 /* New overloading code.  */
 
-struct z_candidate {
+struct z_candidate GTY(()) {
   tree fn;
   tree convs;
   tree second_conv;
@@ -572,8 +572,7 @@ struct z_candidate {
    should be created to hold the result of the conversion.  */
 #define NEED_TEMPORARY_P(NODE) TREE_LANG_FLAG_4 (NODE)
 
-#define USER_CONV_CAND(NODE) \
-  ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1)))
+#define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1))
 #define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
 
 int
@@ -1022,7 +1021,7 @@ convert_class_to_reference (t, s, expr)
   conv = build1 (IDENTITY_CONV, s, expr);
   conv = build_conv (USER_CONV, TREE_TYPE (TREE_TYPE (cand->fn)),
                     conv);
-  TREE_OPERAND (conv, 1) = build_ptr_wrapper (cand);
+  TREE_OPERAND (conv, 1) = build_zc_wrapper (cand);
   ICS_USER_FLAG (conv) = 1;
   if (cand->viable == -1)
     ICS_BAD_FLAG (conv) = 1;
@@ -2559,7 +2558,7 @@ build_user_type_conversion_1 (totype, expr, flags)
     (USER_CONV,
      (DECL_CONSTRUCTOR_P (cand->fn)
       ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
-     expr, build_ptr_wrapper (cand));
+     expr, build_zc_wrapper (cand));
   
   ICS_USER_FLAG (cand->second_conv) = ICS_USER_FLAG (*p) = 1;
   if (cand->viable == -1)
@@ -3826,7 +3825,7 @@ convert_like_real (convs, expr, fn, argnum, inner)
     case USER_CONV:
       {
        struct z_candidate *cand
-         = WRAPPER_PTR (TREE_OPERAND (convs, 1));
+         = WRAPPER_ZC (TREE_OPERAND (convs, 1));
        tree convfn = cand->fn;
        tree args;
 
@@ -4160,7 +4159,7 @@ build_over_call (cand, args, flags)
   /* Give any warnings we noticed during overload resolution.  */
   if (cand->warnings)
     for (val = cand->warnings; val; val = TREE_CHAIN (val))
-      joust (cand, WRAPPER_PTR (TREE_VALUE (val)), 1);
+      joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
 
   if (DECL_FUNCTION_MEMBER_P (fn))
     enforce_access (cand->basetype_path, fn);
@@ -4405,7 +4404,7 @@ build_over_call (cand, args, flags)
   return convert_from_reference (fn);
 }
 
-static tree java_iface_lookup_fn;
+static GTY(()) tree java_iface_lookup_fn;
 
 /* Make an expression which yields the address of the Java interface
    method FN.  This is achieved by generating a call to libjava's
@@ -4430,7 +4429,6 @@ build_java_interface_fn_ref (fn, instance)
        = builtin_function ("_Jv_LookupInterfaceMethodIdx",
                            build_function_type (ptr_type_node, t),
                            0, NOT_BUILT_IN, NULL);
-      ggc_add_tree_root (&java_iface_lookup_fn, 1);
     }
 
   /* Look up the pointer to the runtime java.lang.Class object for `instance'. 
@@ -5207,7 +5205,7 @@ add_warning (winner, loser)
      struct z_candidate *winner, *loser;
 {
   winner->warnings = tree_cons (NULL_TREE,
-                               build_ptr_wrapper (loser),
+                               build_zc_wrapper (loser),
                                winner->warnings);
 }
 
@@ -5635,3 +5633,5 @@ initialize_reference (type, expr)
 
   return convert_like (conv, expr);
 }
+
+#include "gt-cp-call.h"
index 64b528a5a67e3eaeed357c0fd7aa4dbbd33e134d..72f9faa0560eac13cf471da4120eb3fa7fd803b5 100644 (file)
@@ -2157,6 +2157,7 @@ duplicate_tag_error (t)
       memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
       BINFO_BASETYPES(binfo) = NULL_TREE;
 
+      TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
       TYPE_BINFO (t) = binfo;
       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
@@ -4379,7 +4380,7 @@ check_bases_and_members (t, empty_p)
 
   /* Figure out whether or not we will need a cookie when dynamically
      allocating an array of this type.  */
-  TYPE_LANG_SPECIFIC (t)->vec_new_uses_cookie
+  TYPE_LANG_SPECIFIC (t)->u.c.vec_new_uses_cookie
     = type_requires_array_cookie (t);
 }
 
@@ -5470,7 +5471,6 @@ init_class_processing ()
     = (class_stack_node_t) xmalloc (current_class_stack_size 
                                    * sizeof (struct class_stack_node));
   VARRAY_TREE_INIT (local_classes, 8, "local_classes");
-  ggc_add_tree_varray_root (&local_classes, 1);
 
   access_default_node = build_int_2 (0, 0);
   access_public_node = build_int_2 (ak_public, 0);
@@ -7511,8 +7511,6 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
   VARRAY_TREE_INIT (vid.fns, 32, "fns");
   /* Add the vcall and vbase offset entries.  */
   build_vcall_and_vbase_vtbl_entries (binfo, &vid);
-  /* Clean up.  */
-  VARRAY_FREE (vid.fns);
   /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
      build_vbase_offset_vtbl_entries.  */
   for (vbase = CLASSTYPE_VBASECLASSES (t); 
index c07408d5ad25e9a1d4d9f0335c00962dd759f769..ba3708bebb342019dd088be02c12b4ddb0c0ab48 100644 (file)
@@ -33,3 +33,5 @@ compilers="cc1plus\$(exeext)"
 stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
 
 target_libs="${libstdcxx_version} target-gperf"
+
+gtfiles="\$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c \$(srcdir)/cp/tree.c"
index ce5165e9cd376ab08a04d84be926f018c229e5e8..f482582c8c74d4b7365c3d6c6f92d7aa67f21dc7 100644 (file)
@@ -66,8 +66,6 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree));
 #define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
 #undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
 #define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES cxx_insert_default_attributes
-#undef LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE cxx_mark_tree
 #undef LANG_HOOKS_UNSAFE_FOR_REEVAL
 #define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
 #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
@@ -93,10 +91,8 @@ static bool cxx_warn_unused_global_decl PARAMS ((tree));
 
 #undef LANG_HOOKS_FUNCTION_INIT
 #define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context
-#undef LANG_HOOKS_FUNCTION_FREE
-#define LANG_HOOKS_FUNCTION_FREE cxx_pop_function_context
-#undef LANG_HOOKS_FUNCTION_MARK
-#define LANG_HOOKS_FUNCTION_MARK cxx_mark_function_context
+#undef LANG_HOOKS_FUNCTION_FINAL
+#define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context
 
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
index 907bbd0515c01c2b9da10e297cc6a9453a36bdcc..448cb88b6d848c1be2b6800ab835953f3719ea9e 100644 (file)
@@ -233,9 +233,9 @@ extern int flag_huge_objects;
 \f
 /* Language-dependent contents of an identifier.  */
 
-struct lang_identifier
+struct lang_identifier GTY(())
 {
-  struct c_common_identifier ignore;
+  struct c_common_identifier c_common;
   tree namespace_bindings;
   tree bindings;
   tree class_value;
@@ -255,20 +255,21 @@ extern const short rid_to_yy[RID_MAX];
 #define LANG_IDENTIFIER_CAST(NODE) \
        ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE))
 
-struct lang_id2
+struct lang_id2 GTY(())
 {
-  tree label_value, implicit_decl;
+  tree label_value;
+  tree implicit_decl;
   tree error_locus;
 };
 
-typedef struct
+typedef struct flagged_type_tree_s GTY(())
 {
   tree t;
   int new_type_flag;
   tree lookups;
 } flagged_type_tree;
 
-typedef struct
+typedef struct template_parm_index_s GTY(())
 {
   struct tree_common common;
   HOST_WIDE_INT index;
@@ -277,14 +278,15 @@ typedef struct
   tree decl;
 } template_parm_index;
 
-typedef struct ptrmem_cst
+struct ptrmem_cst GTY(())
 {
   struct tree_common common;
   /* This isn't used, but the middle-end expects all constants to have
      this field.  */
   rtx rtl;
   tree member;
-}* ptrmem_cst_t;
+};
+typedef struct ptrmem_cst * ptrmem_cst_t;
 
 /* Nonzero if this binding is for a local scope, as opposed to a class
    or namespace scope.  */
@@ -346,13 +348,13 @@ typedef struct ptrmem_cst
     && MAIN_NAME_P (DECL_NAME (NODE)))
 
 
-struct tree_binding
+struct tree_binding GTY(())
 {
   struct tree_common common;
-  union {
-    tree scope;
-    struct binding_level *level;
-  } scope;
+  union tree_binding_u {
+    tree GTY ((tag ("0"))) scope;
+    struct cp_binding_level * GTY ((tag ("1"))) level;
+  } GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) scope;
   tree value;
 };
 
@@ -370,7 +372,7 @@ struct tree_binding
    is not important for this node. */
 #define OVL_USED(NODE)        TREE_USED (NODE)
 
-struct tree_overload
+struct tree_overload GTY(())
 {
   struct tree_common common;
   tree function;
@@ -384,21 +386,17 @@ struct tree_overload
 #define SET_BASELINK_P(NODE) \
   (TREE_LANG_FLAG_1 (NODE) = 1)
 
-#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->u.ptr)
-#define WRAPPER_INT(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->u.i)
+#define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)
 
-struct tree_wrapper
+struct tree_wrapper GTY(())
 {
   struct tree_common common;
-  union {
-    void *ptr;
-    int i;
-  } u;
+  struct z_candidate *z_c;
 };
 
 #define SRCLOC_FILE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->filename)
 #define SRCLOC_LINE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->linenum)
-struct tree_srcloc
+struct tree_srcloc GTY(())
 {
   struct tree_common common;
   const char *filename;
@@ -450,10 +448,10 @@ struct tree_srcloc
   (LANG_IDENTIFIER_CAST (NODE)->x                      \
    ? LANG_IDENTIFIER_CAST (NODE)->x->NAME : 0)
 
-#define SET_LANG_ID(NODE, VALUE, NAME)                                   \
-  (LANG_IDENTIFIER_CAST (NODE)->x == 0                                   \
-   ? LANG_IDENTIFIER_CAST (NODE)->x                                      \
-      = (struct lang_id2 *)perm_calloc (1, sizeof (struct lang_id2)) : 0, \
+#define SET_LANG_ID(NODE, VALUE, NAME)                                      \
+  (LANG_IDENTIFIER_CAST (NODE)->x == 0                                      \
+   ? LANG_IDENTIFIER_CAST (NODE)->x                                         \
+      = (struct lang_id2 *)ggc_alloc_cleared (sizeof (struct lang_id2)) : 0, \
    LANG_IDENTIFIER_CAST (NODE)->x->NAME = (VALUE))
 
 #define IDENTIFIER_LABEL_VALUE(NODE) \
@@ -495,11 +493,36 @@ struct tree_srcloc
 /* Store a value in that field.  */
 #define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
   (TREE_COMPLEXITY (EXP) = (int)(CODE))
-\f
-/* If non-zero, a VAR_DECL whose cleanup will cause a throw to the
-   next exception handler.  */
-extern tree exception_throw_decl;
 
+enum cp_tree_node_structure_enum {
+  TS_CP_COMMON,
+  TS_CP_GENERIC,
+  TS_CP_IDENTIFIER,
+  TS_CP_TPI,
+  TS_CP_PTRMEM,
+  TS_CP_BINDING,
+  TS_CP_OVERLOAD,
+  TS_CP_WRAPPER,
+  TS_CP_SRCLOC,
+  LAST_TS_CP_ENUM
+};
+
+/* The resulting tree type.  */
+union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)")))
+{
+  struct tree_common GTY ((tag ("TS_CP_COMMON"))) common;
+  union tree_node GTY ((tag ("TS_CP_GENERIC"),
+                       desc ("tree_node_structure (&%h)"))) generic;
+  struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
+  struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
+  struct tree_binding GTY ((tag ("TS_CP_BINDING"))) binding;
+  struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
+  struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper;
+  struct tree_srcloc GTY ((tag ("TS_CP_SRCLOC"))) srcloc;
+  struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier;
+};
+
+\f
 enum cp_tree_index
 {
     CPTI_JAVA_BYTE_TYPE,
@@ -586,7 +609,7 @@ enum cp_tree_index
     CPTI_MAX
 };
 
-extern tree cp_global_trees[CPTI_MAX];
+extern GTY(()) tree cp_global_trees[CPTI_MAX];
 
 #define java_byte_type_node            cp_global_trees[CPTI_JAVA_BYTE_TYPE]
 #define java_short_type_node           cp_global_trees[CPTI_JAVA_SHORT_TYPE]
@@ -715,7 +738,7 @@ extern tree cp_global_trees[CPTI_MAX];
 
 /* Global state.  */
 
-struct saved_scope
+struct saved_scope GTY(())
 {
   tree old_bindings;
   tree old_namespace;
@@ -740,8 +763,8 @@ struct saved_scope
 
   struct stmt_tree_s x_stmt_tree;
 
-  struct binding_level *class_bindings;
-  struct binding_level *bindings;
+  struct cp_binding_level *class_bindings;
+  struct cp_binding_level *bindings;
 
   struct saved_scope *prev;
 };
@@ -798,15 +821,15 @@ struct saved_scope
 
 #define type_lookups scope_chain->lookups
 
-extern struct saved_scope *scope_chain;
+extern GTY(()) struct saved_scope *scope_chain;
 
 struct unparsed_text;
 
 /* Global state pertinent to the current function.  */
 
-struct cp_language_function
+struct language_function GTY(())
 {
-  struct language_function base;
+  struct c_language_function base;
 
   tree x_dtor_label;
   tree x_current_class_ptr;
@@ -816,8 +839,6 @@ struct cp_language_function
   tree x_vtt_parm;
   tree x_return_value;
 
-  tree *x_vcalls_possible_p;
-
   int returns_value;
   int returns_null;
   int returns_abnormally;
@@ -826,7 +847,7 @@ struct cp_language_function
 
   struct named_label_use_list *x_named_label_uses;
   struct named_label_list *x_named_labels;
-  struct binding_level *bindings;
+  struct cp_binding_level *bindings;
   varray_type x_local_names;
 
   const char *cannot_inline;
@@ -835,8 +856,7 @@ struct cp_language_function
 
 /* The current C++-specific per-function global variables.  */
 
-#define cp_function_chain \
-  ((struct cp_language_function *) (cfun->language))
+#define cp_function_chain (cfun->language)
 
 /* In a destructor, the point at which all derived class destroying
    has been done, just before any base class destroying will be done.  */
@@ -867,12 +887,6 @@ struct cp_language_function
 
 #define current_vtt_parm cp_function_chain->x_vtt_parm
 
-/* In destructors, this is a pointer to a condition in an
-   if-statement.  If the pointed-to value is boolean_true_node, then
-   there may be virtual function calls in this destructor.  */
-
-#define current_vcalls_possible_p cp_function_chain->x_vcalls_possible_p
-
 /* Set to 0 at beginning of a function definition, set to 1 if
    a return statement that specifies a return value is seen.  */
 
@@ -908,7 +922,7 @@ struct cp_language_function
 #define current_function_return_value \
   (cp_function_chain->x_return_value)
 
-extern tree global_namespace;
+extern GTY(()) tree global_namespace;
 
 #define ansi_opname(CODE) \
   (operator_name_info[(int) (CODE)].identifier)
@@ -1176,6 +1190,22 @@ enum languages { lang_c, lang_cplusplus, lang_java };
 #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
   lookup_base ((TYPE), (PARENT),  ba_not_special | ba_quiet, NULL)
 \f
+/* This is a few header flags for 'struct lang_type'.  Actually,
+   all but the first are used only for lang_type_class; they
+   are put in this structure to save space.  */
+struct lang_type_header GTY(())
+{
+  unsigned is_lang_type_class : 1;
+
+  unsigned has_type_conversion : 1;
+  unsigned has_init_ref : 1;
+  unsigned has_default_ctor : 1;
+  unsigned uses_multiple_inheritance : 1;
+  unsigned const_needs_init : 1;
+  unsigned ref_needs_init : 1;
+  unsigned has_const_assign_ref : 1;
+};
+
 /* This structure provides additional information above and beyond
    what is provide in the ordinary tree_type.  In the past, we used it
    for the types of class types, template parameters types, typename
@@ -1189,19 +1219,12 @@ enum languages { lang_c, lang_cplusplus, lang_java };
    many (i.e., thousands) of classes can easily be generated.
    Therefore, we should endeavor to keep the size of this structure to
    a minimum.  */
-struct lang_type
+struct lang_type_class GTY(())
 {
+  struct lang_type_header h;
+  
   unsigned char align;
 
-  unsigned has_type_conversion : 1;
-  unsigned has_init_ref : 1;
-  unsigned has_default_ctor : 1;
-  unsigned uses_multiple_inheritance : 1;
-  unsigned const_needs_init : 1;
-  unsigned ref_needs_init : 1;
-  unsigned has_const_assign_ref : 1;
-  unsigned anon_aggr : 1;
-
   unsigned has_mutable : 1;
   unsigned com_interface : 1;
   unsigned non_pod_class : 1;
@@ -1240,6 +1263,7 @@ struct lang_type
   unsigned is_partial_instantiation : 1;
   unsigned java_interface : 1;
 
+  unsigned anon_aggr : 1;
   unsigned non_zero_init : 1;
 
   /* When adding a flag here, consider whether or not it ought to
@@ -1249,7 +1273,7 @@ struct lang_type
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 7;
+  unsigned dummy : 6;
 
   int vsize;
 
@@ -1267,12 +1291,50 @@ struct lang_type
   tree befriending_classes;
 };
 
+struct lang_type_ptrmem GTY(())
+{
+  struct lang_type_header h;
+  tree record;
+};
+
+struct lang_type GTY(())
+{
+  union lang_type_u 
+  {
+    struct lang_type_header GTY((tag ("2"))) h;
+    struct lang_type_class  GTY((tag ("1"))) c;
+    struct lang_type_ptrmem GTY((tag ("0"))) ptrmem;
+  } GTY((desc ("%h.h.is_lang_type_class"))) u;
+};
+
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+
+#define LANG_TYPE_CLASS_CHECK(NODE)                            \
+({  struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE);          \
+    if (! lt->u.h.is_lang_type_class)                          \
+      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);    \
+    &lt->u.c; })
+
+#define LANG_TYPE_PTRMEM_CHECK(NODE)                           \
+({  struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE);          \
+    if (lt->u.h.is_lang_type_class)                            \
+      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);    \
+    &lt->u.ptrmem; })
+
+#else
+
+#define LANG_TYPE_CLASS_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.c)
+#define LANG_TYPE_PTRMEM_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.ptrmem)
+
+#endif /* ENABLE_TREE_CHECKING */
+
 /* Indicates whether or not (and how) a template was expanded for this class.
      0=no information yet/non-template class
      1=implicit template instantiation
      2=explicit template specialization
      3=explicit template instantiation  */
-#define CLASSTYPE_USE_TEMPLATE(NODE) (TYPE_LANG_SPECIFIC (NODE)->use_template)
+#define CLASSTYPE_USE_TEMPLATE(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->use_template)
 
 /* Fields used for storing information before the class is defined.
    After the class is defined, these fields hold other information.  */
@@ -1281,66 +1343,66 @@ struct lang_type
 #define CLASSTYPE_INLINE_FRIENDS(NODE) CLASSTYPE_PURE_VIRTUALS (NODE)
 
 /* Nonzero for _CLASSTYPE means that operator delete is defined.  */
-#define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC (NODE)->gets_delete)
+#define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
 #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
 
 /* Nonzero if `new NODE[x]' should cause the allocation of extra
    storage to indicate how many array elements are in use.  */
 #define TYPE_VEC_NEW_USES_COOKIE(NODE)                 \
   (CLASS_TYPE_P (NODE)                                 \
-   && TYPE_LANG_SPECIFIC (NODE)->vec_new_uses_cookie)
+   && LANG_TYPE_CLASS_CHECK (NODE)->vec_new_uses_cookie)
 
 /* Nonzero means that this _CLASSTYPE node defines ways of converting
    itself to other types.  */
 #define TYPE_HAS_CONVERSION(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_type_conversion)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion)
 
 /* Nonzero means that this _CLASSTYPE node overloads operator=(X&).  */
-#define TYPE_HAS_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_assign_ref)
+#define TYPE_HAS_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_assign_ref)
 #define TYPE_HAS_CONST_ASSIGN_REF(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_const_assign_ref)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_assign_ref)
 
 /* Nonzero means that this _CLASSTYPE node has an X(X&) constructor.  */
-#define TYPE_HAS_INIT_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_init_ref)
+#define TYPE_HAS_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_init_ref)
 #define TYPE_HAS_CONST_INIT_REF(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_const_init_ref)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_const_init_ref)
 
 /* Nonzero if this class defines an overloaded operator new.  (An
    operator new [] doesn't count.)  */
 #define TYPE_HAS_NEW_OPERATOR(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_new)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_new)
 
 /* Nonzero if this class defines an overloaded operator new[].  */
 #define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_array_new)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_array_new)
 
 /* Nonzero means that this type is being defined.  I.e., the left brace
    starting the definition of this type has been seen.  */
-#define TYPE_BEING_DEFINED(NODE) (TYPE_LANG_SPECIFIC (NODE)->being_defined)
+#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined)
 /* Nonzero means that this type has been redefined.  In this case, if
    convenient, don't reprocess any methods that appear in its redefinition.  */
-#define TYPE_REDEFINED(NODE) (TYPE_LANG_SPECIFIC (NODE)->redefined)
+#define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
 
 /* The is the basetype that contains NODE's rtti.  */
-#define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC (NODE)->rtti)
+#define CLASSTYPE_RTTI(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->rtti)
 
 /* Nonzero means that this _CLASSTYPE node overloads operator().  */
 #define TYPE_OVERLOADS_CALL_EXPR(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_call_overloaded)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded)
 
 /* Nonzero means that this _CLASSTYPE node overloads operator[].  */
 #define TYPE_OVERLOADS_ARRAY_REF(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_array_ref_overloaded)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_array_ref_overloaded)
 
 /* Nonzero means that this _CLASSTYPE node overloads operator->.  */
 #define TYPE_OVERLOADS_ARROW(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_arrow_overloaded)
+  (LANG_TYPE_CLASS_CHECK (NODE)->has_arrow_overloaded)
 
 /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses
    multiple inheritance.  If this is 0 for the root of a type
    hierarchy, then we can use more efficient search techniques.  */
 #define TYPE_USES_MULTIPLE_INHERITANCE(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->uses_multiple_inheritance)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.uses_multiple_inheritance)
 
 /* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses
    virtual base classes.  If this is 0 for the root of a type
@@ -1359,7 +1421,7 @@ struct lang_type
    functions.  There may be empty entries at the end of the vector.
    The conversion operators are unsorted. The ordinary member
    functions are sorted, once the class is complete.  */
-#define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC (NODE)->methods)
+#define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods)
 
 /* The slot in the CLASSTYPE_METHOD_VEC where constructors go.  */
 #define CLASSTYPE_CONSTRUCTOR_SLOT 0
@@ -1385,19 +1447,19 @@ struct lang_type
 
 /* Get the value of the Nth mark bit.  */
 #define CLASSTYPE_MARKED_N(NODE, N)                            \
-  (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->marks    \
+  (((CLASS_TYPE_P (NODE) ? LANG_TYPE_CLASS_CHECK (NODE)->marks \
      : ((unsigned) TYPE_ALIAS_SET (NODE))) & (1 << (N))) != 0)
 
 /* Set the Nth mark bit.  */
 #define SET_CLASSTYPE_MARKED_N(NODE, N)                                \
   (CLASS_TYPE_P (NODE)                                         \
-   ? (void) (TYPE_LANG_SPECIFIC (NODE)->marks |= (1 << (N)))   \
+   ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks |= (1 << (N)))        \
    : (void) (TYPE_ALIAS_SET (NODE) |= (1 << (N))))
 
 /* Clear the Nth mark bit.  */
 #define CLEAR_CLASSTYPE_MARKED_N(NODE, N)                      \
   (CLASS_TYPE_P (NODE)                                         \
-   ? (void) (TYPE_LANG_SPECIFIC (NODE)->marks &= ~(1 << (N)))  \
+   ? (void) (LANG_TYPE_CLASS_CHECK (NODE)->marks &= ~(1 << (N)))       \
    : (void) (TYPE_ALIAS_SET (NODE) &= ~(1 << (N))))
 
 /* Get the value of the mark bits.  */
@@ -1426,7 +1488,7 @@ struct lang_type
    found within this class.  The TREE_PURPOSE of each node is the name
    of the type; the TREE_VALUE is the type itself.  This list includes
    nested member class templates.  */
-#define CLASSTYPE_TAGS(NODE)           (TYPE_LANG_SPECIFIC (NODE)->tags)
+#define CLASSTYPE_TAGS(NODE)           (LANG_TYPE_CLASS_CHECK (NODE)->tags)
 
 /* Nonzero if NODE has a primary base class, i.e., a base class with
    which it shares the virtual function table pointer.  */
@@ -1437,11 +1499,11 @@ struct lang_type
    the base class which contains the virtual function table pointer
    for this class.  */
 #define CLASSTYPE_PRIMARY_BINFO(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->primary_base)
+  (LANG_TYPE_CLASS_CHECK (NODE)->primary_base)
 
 /* The number of virtual functions present in this class' virtual
    function table.  */
-#define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC (NODE)->vsize)
+#define CLASSTYPE_VSIZE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vsize)
 
 /* A chain of BINFOs for the direct and indirect virtual base classes
    that this type uses in a post-order depth-first left-to-right
@@ -1451,7 +1513,7 @@ struct lang_type
    list are all "real"; they are the same BINFOs that will be
    encountered when using dfs_unmarked_real_bases_queue_p and related
    functions.  */
-#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC (NODE)->vbases)
+#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
 
 /* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
    binfo_for_vbase.  C is the most derived class for the hierarchy
@@ -1467,10 +1529,10 @@ struct lang_type
 
 /* These are the size and alignment of the type without its virtual
    base classes, for when we use this type as a base itself.  */
-#define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC (NODE)->size)
-#define CLASSTYPE_SIZE_UNIT(NODE) (TYPE_LANG_SPECIFIC (NODE)->size_unit)
-#define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC (NODE)->align)
-#define CLASSTYPE_USER_ALIGN(NODE) (TYPE_LANG_SPECIFIC (NODE)->user_align)
+#define CLASSTYPE_SIZE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->size)
+#define CLASSTYPE_SIZE_UNIT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->size_unit)
+#define CLASSTYPE_ALIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->align)
+#define CLASSTYPE_USER_ALIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->user_align)
 
 /* The alignment of NODE, without its virtual bases, in bytes.  */
 #define CLASSTYPE_ALIGN_UNIT(NODE) \
@@ -1478,70 +1540,71 @@ struct lang_type
 
 /* True if this a Java interface type, declared with 
    '__attribute__ ((java_interface))'. */
-#define TYPE_JAVA_INTERFACE(NODE) (TYPE_LANG_SPECIFIC (NODE)->java_interface)
+#define TYPE_JAVA_INTERFACE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->java_interface)
 
 /* A cons list of virtual functions which cannot be inherited by
    derived classes.  When deriving from this type, the derived
    class must provide its own definition for each of these functions.  */
-#define CLASSTYPE_PURE_VIRTUALS(NODE) (TYPE_LANG_SPECIFIC (NODE)->pure_virtuals)
+#define CLASSTYPE_PURE_VIRTUALS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
 
 /* Nonzero means that this aggr type has been `closed' by a semicolon.  */
-#define CLASSTYPE_GOT_SEMICOLON(NODE) (TYPE_LANG_SPECIFIC (NODE)->got_semicolon)
+#define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon)
 
 /* Nonzero means that the main virtual function table pointer needs to be
    set because base constructors have placed the wrong value there.
    If this is zero, it means that they placed the right value there,
    and there is no need to change it.  */
 #define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->needs_virtual_reinit)
+  (LANG_TYPE_CLASS_CHECK (NODE)->needs_virtual_reinit)
 
 /* Nonzero means that this type has an X() constructor.  */
 #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->has_default_ctor)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
 
 /* Nonzero means that this type contains a mutable member */
-#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable)
+#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable)
 #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
 
 /* Nonzero means that this class type is a non-POD class.  */
-#define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
+#define CLASSTYPE_NON_POD_P(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class)
 
 /* Nonzero means that this class contains pod types whose default
    initialization is not a zero initialization (namely, pointers to
    data members).  */
-#define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init)
+#define CLASSTYPE_NON_ZERO_INIT_P(NODE) \
+  (LANG_TYPE_CLASS_CHECK (NODE)->non_zero_init)
 
 /* Nonzero if this class is "nearly empty", i.e., contains only a
    virtual function table pointer.  */
 #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->nearly_empty_p)
+  (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p)
 
 /* A list of class types of which this type is a friend.  The
    TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
    case of a template friend.  */
 #define CLASSTYPE_FRIEND_CLASSES(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->friend_classes)
+  (LANG_TYPE_CLASS_CHECK (NODE)->friend_classes)
 
 /* A list of the classes which grant friendship to this class.  */
 #define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->befriending_classes)
+  (LANG_TYPE_CLASS_CHECK (NODE)->befriending_classes)
 
 /* Say whether this node was declared as a "class" or a "struct".  */
 #define CLASSTYPE_DECLARED_CLASS(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->declared_class)
+  (LANG_TYPE_CLASS_CHECK (NODE)->declared_class)
 
 /* Nonzero if this class has const members which have no specified initialization.  */
 #define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->const_needs_init)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init)
 
 /* Nonzero if this class has ref members which have no specified initialization.  */
 #define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->ref_needs_init)
+  (LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init)
 
 /* Nonzero if this class is included from a header file which employs
    `#pragma interface', and it is not included in its implementation file.  */
 #define CLASSTYPE_INTERFACE_ONLY(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_only)
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_only)
 
 /* True if we have already determined whether or not vtables, VTTs,
    typeinfo, and other similar per-class data should be emitted in
@@ -1549,21 +1612,21 @@ struct lang_type
    these items should be emitted; it only indicates that we know one
    way or the other.  */
 #define CLASSTYPE_INTERFACE_KNOWN(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_unknown == 0)
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0)
 /* The opposite of CLASSTYPE_INTERFANCE_KNOWN.  */
 #define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_unknown)
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown)
 
 #define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = !!(X))
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X))
 #define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = 1)
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 1)
 #define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->interface_unknown = 0)
+  (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 0)
 
 /* Nonzero if a _DECL node requires us to output debug info for this class.  */
 #define CLASSTYPE_DEBUG_REQUESTED(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->debug_requested)
+  (LANG_TYPE_CLASS_CHECK (NODE)->debug_requested)
 \f
 /* Additional macros for inheritance information.  */
 
@@ -1676,7 +1739,7 @@ struct lang_type
    TREE_PURPOSE is NULL.  Otherwise, the TREE_PURPOSE is the BINFO for
    the class containing the vfield.  The TREE_VALUE is the class where
    the vfield was first defined.  */
-#define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC (NODE)->vfields)
+#define CLASSTYPE_VFIELDS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vfields)
 
 /* Get the assoc info that caused this vfield to exist.  */
 #define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE)
@@ -1736,7 +1799,7 @@ struct lang_type
      || TREE_CODE (NODE) == FIELD_DECL         \
      || TREE_CODE (NODE) == USING_DECL))
 
-struct lang_decl_flags
+struct lang_decl_flags GTY(())
 {
   struct c_lang_decl base;
 
@@ -1757,28 +1820,29 @@ struct lang_decl_flags
   unsigned not_really_extern : 1;
   unsigned needs_final_overrider : 1;
   unsigned initialized_in_class : 1;
-  unsigned pending_inline_p : 1;
+  unsigned assignment_operator_p : 1;
 
   unsigned global_ctor_p : 1;
   unsigned global_dtor_p : 1;
-  unsigned assignment_operator_p : 1;
   unsigned anticipated_p : 1;
   unsigned template_conv_p : 1;
-  
-  unsigned unused : 3; /* Three unused bits.  */
+  unsigned u1sel : 1;
+  unsigned u2sel : 1;
+  unsigned can_be_full : 1;
+  unsigned unused : 1; /* One unused bit.  */
 
-  union {
+  union lang_decl_u {
     /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
        is DECL_TEMPLATE_INFO.  */
-    tree template_info;
+    tree GTY ((tag ("0"))) template_info;
 
     /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL.  */
-    struct binding_level *level;
-  } u;
+    struct cp_binding_level * GTY ((tag ("1"))) level;
+  } GTY ((desc ("%1.u1sel"))) u;
 
-  union {
+  union lang_decl_u2 {
     /* This is DECL_ACCESS.  */
-    tree access;
+    tree GTY ((tag ("0"))) access;
 
     /* For VAR_DECL in function, this is DECL_DISCRIMINATOR.  */
     int discriminator;
@@ -1789,36 +1853,59 @@ struct lang_decl_flags
 
     /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
        THUNK_VCALL_OFFSET.  */
-    tree vcall_offset;
-  } u2;
+    tree GTY((tag ("2"))) vcall_offset;
+  } GTY ((desc ("%1.u2sel"))) u2;
 };
 
-struct lang_decl
+struct lang_decl GTY(())
 {
   struct lang_decl_flags decl_flags;
 
-  tree befriending_classes;
+  union lang_decl_u4
+    {
+      struct full_lang_decl 
+      {
+       tree befriending_classes;
+       
+       /* For a virtual FUNCTION_DECL, this is DECL_VIRTUAL_CONTEXT.  For a
+          non-virtual FUNCTION_DECL, this is DECL_FRIEND_CONTEXT.  */
+       tree context;
+       
+       /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION.  */
+       tree cloned_function;
+       
+       /* In an overloaded operator, this is the value of
+          DECL_OVERLOADED_OPERATOR_P.  */
+       enum tree_code operator_code;
+
+       unsigned u3sel : 1;
+       unsigned pending_inline_p : 1;
+       
+       union lang_decl_u3
+       {
+         tree GTY ((tag ("0"))) sorted_fields;
+         struct unparsed_text * GTY ((tag ("2"))) pending_inline_info;
+         struct language_function * GTY ((tag ("1"))) 
+              saved_language_function;
+       } GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;
+      } GTY ((tag ("1"))) f;
+  } GTY ((desc ("%1.decl_flags.can_be_full"))) u;
+};
 
-  /* For a virtual FUNCTION_DECL, this is DECL_VIRTUAL_CONTEXT.  For a
-     non-virtual FUNCTION_DECL, this is DECL_FRIEND_CONTEXT.  */
-  tree context;
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 
-  /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION.  */
-  tree cloned_function;
+#define LANG_DECL_U2_CHECK(NODE, TF)                           \
+({  struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE);          \
+    if (lt->decl_flags.u2sel != TF)                            \
+      lang_check_failed (__FILE__, __LINE__, __FUNCTION__);    \
+    &lt->decl_flags.u2; })
 
-  union
-  {
-    tree sorted_fields;
-    struct unparsed_text *pending_inline_info;
-    struct cp_language_function *saved_language_function;
-  } u;
-
-  union {
-    /* In an overloaded operator, this is the value of
-       DECL_OVERLOADED_OPERATOR_P.  */
-    enum tree_code operator_code;
-  } u2;
-};
+#else
+
+#define LANG_DECL_U2_CHECK(NODE, TF) \
+  (&DECL_LANG_SPECIFIC (NODE)->decl_flags.u2)
+
+#endif /* ENABLE_TREE_CHECKING */
 
 #define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK (NODE)->identifier.id.str)
 
@@ -1927,7 +2014,7 @@ struct lang_decl
 /* If DECL_CLONED_FUNCTION_P holds, this is the function that was
    cloned.  */
 #define DECL_CLONED_FUNCTION(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->cloned_function)
+  (DECL_LANG_SPECIFIC (NODE)->u.f.cloned_function)
 
 /* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS.  */
 #define DECL_DISCRIMINATOR_P(NODE)     \
@@ -1935,8 +2022,7 @@ struct lang_decl
    && DECL_FUNCTION_SCOPE_P (NODE))
 
 /* Discriminator for name mangling.  */
-#define DECL_DISCRIMINATOR(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.discriminator)
+#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)
 
 /* Non-zero if the VTT parm has been added to NODE.  */
 #define DECL_HAS_VTT_PARM_P(NODE) \
@@ -1961,7 +2047,7 @@ struct lang_decl
 
 /* Set the overloaded operator code for NODE to CODE.  */
 #define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u2.operator_code = (CODE))
+  (DECL_LANG_SPECIFIC (NODE)->u.f.operator_code = (CODE))
 
 /* If NODE is an overloaded operator, then this returns the TREE_CODE
    associcated with the overloaded operator.
@@ -1972,7 +2058,7 @@ struct lang_decl
    to test whether or not NODE is an overloaded operator.  */
 #define DECL_OVERLOADED_OPERATOR_P(NODE)               \
   (IDENTIFIER_OPNAME_P (DECL_NAME (NODE))              \
-   ? DECL_LANG_SPECIFIC (NODE)->u2.operator_code : ERROR_MARK)
+   ? DECL_LANG_SPECIFIC (NODE)->u.f.operator_code : ERROR_MARK)
 
 /* Non-zero if NODE is an assignment operator.  */
 #define DECL_ASSIGNMENT_OPERATOR_P(NODE) \
@@ -2007,7 +2093,7 @@ struct lang_decl
 
 /* A TREE_LIST of the types which have befriended this FUNCTION_DECL.  */
 #define DECL_BEFRIENDING_CLASSES(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->befriending_classes)
+  (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
 
 /* Nonzero for FUNCTION_DECL means that this decl is a static
    member function.  */
@@ -2081,8 +2167,9 @@ struct lang_decl
   (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))
 
 /* Set DECL_THUNK_P for node.  */
-#define SET_DECL_THUNK_P(NODE) \
-  (DECL_LANG_FLAG_7 (NODE) = 1)
+#define SET_DECL_THUNK_P(NODE)                                 \
+  (DECL_LANG_FLAG_7 (NODE) = 1,                                \
+   DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1)
 
 /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
    template function.  */
@@ -2102,12 +2189,12 @@ struct lang_decl
    the DECL_FRIEND_CONTEXT for `f' will be `S'.  */
 #define DECL_FRIEND_CONTEXT(NODE)                              \
   ((DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE))    \
-   ? DECL_LANG_SPECIFIC (NODE)->context                         \
+   ? DECL_LANG_SPECIFIC (NODE)->u.f.context                    \
    : NULL_TREE)
 
 /* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT.  */
 #define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \
-  (DECL_LANG_SPECIFIC (NODE)->context = (CONTEXT))
+  (DECL_LANG_SPECIFIC (NODE)->u.f.context = (CONTEXT))
 
 /* NULL_TREE in DECL_CONTEXT represents the global namespace. */
 #define CP_DECL_CONTEXT(NODE) \
@@ -2117,7 +2204,7 @@ struct lang_decl
 /* For a virtual function, the base where we find its vtable entry.
    For a non-virtual function, the base where it is defined.  */
 #define DECL_VIRTUAL_CONTEXT(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->context)
+  (DECL_LANG_SPECIFIC (NODE)->u.f.context)
 
 /* 1 iff NODE has namespace scope, including the global namespace.  */
 #define DECL_NAMESPACE_SCOPE_P(NODE)                           \
@@ -2176,17 +2263,17 @@ struct lang_decl
    the class definition.  We have saved away the text of the function,
    but have not yet processed it.  */
 #define DECL_PENDING_INLINE_P(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.pending_inline_p)
+  (DECL_LANG_SPECIFIC (NODE)->u.f.pending_inline_p)
 
 /* If DECL_PENDING_INLINE_P holds, this is the saved text of the
    function.  */
 #define DECL_PENDING_INLINE_INFO(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->u.pending_inline_info)
+  (DECL_LANG_SPECIFIC (NODE)->u.f.u.pending_inline_info)
 
 /* For a TYPE_DECL: if this function has many fields, we'll sort them
    and put them into a TREE_VEC. */
 #define DECL_SORTED_FIELDS(NODE) \
-  (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.sorted_fields)
+  (DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.f.u.sorted_fields)
 
 /* True if on the deferred_fns (see decl2.c) list.  */
 #define DECL_DEFERRED_FN(DECL) \
@@ -2200,7 +2287,7 @@ struct lang_decl
 
 /* Template information for a RECORD_TYPE or UNION_TYPE.  */
 #define CLASSTYPE_TEMPLATE_INFO(NODE) \
-  (TYPE_LANG_SPECIFIC (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info)
+  (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info)
 
 /* Template information for an ENUMERAL_TYPE.  Although an enumeration may
    not be a primary template, it may be declared within the scope of a
@@ -2210,7 +2297,7 @@ struct lang_decl
 
 /* Template information for a template template parameter.  */
 #define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \
-  (TYPE_LANG_SPECIFIC (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
+  (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \
    ->template_info)
 
 /* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE.  */
@@ -2348,8 +2435,9 @@ struct lang_decl
 #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE)
 
 /* In a FUNCTION_DECL, the saved language-specific per-function data.  */
-#define DECL_SAVED_FUNCTION_DATA(NODE) \
-  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))->u.saved_language_function)
+#define DECL_SAVED_FUNCTION_DATA(NODE)                 \
+  (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (NODE))     \
+   ->u.f.u.saved_language_function)
 
 #define NEW_EXPR_USE_GLOBAL(NODE)      TREE_LANG_FLAG_0 (NODE)
 #define DELETE_EXPR_USE_GLOBAL(NODE)   TREE_LANG_FLAG_0 (NODE)
@@ -2488,15 +2576,15 @@ extern int flag_new_for_scope;
 /* Nonzero means that an object of this type can not be initialized using
    an initializer list.  */
 #define CLASSTYPE_NON_AGGREGATE(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->non_aggregate)
+  (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate)
 #define TYPE_NON_AGGREGATE_CLASS(NODE) \
   (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE))
 
 /* Nonzero if there is a user-defined X::op=(x&) for this class.  */
-#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_real_assign_ref)
-#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_complex_assign_ref)
-#define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_abstract_assign_ref)
-#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_complex_init_ref)
+#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_real_assign_ref)
+#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_assign_ref)
+#define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_abstract_assign_ref)
+#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_init_ref)
 
 /* Nonzero if TYPE has a trivial destructor.  From [class.dtor]:
 
@@ -2555,7 +2643,7 @@ extern int flag_new_for_scope;
    && TYPE_PTRMEMFUNC_FLAG (NODE))
 
 #define TYPE_PTRMEMFUNC_FLAG(NODE) \
-  (TYPE_LANG_SPECIFIC (NODE)->ptrmemfunc_flag)
+  (LANG_TYPE_CLASS_CHECK (NODE)->ptrmemfunc_flag)
 
 /* Indicates when overload resolution may resolve to a pointer to
    member function. [expr.unary.op]/3 */
@@ -2600,9 +2688,17 @@ enum ptrmemfunc_vbit_where_t
 /* These are use to manipulate the canonical RECORD_TYPE from the
    hashed POINTER_TYPE, and can only be used on the POINTER_TYPE.  */
 #define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \
-  ((tree)TYPE_LANG_SPECIFIC (NODE))
-#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) \
-  (TYPE_LANG_SPECIFIC (NODE) = ((struct lang_type *)(void*)(VALUE)))
+  (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL)
+#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE)                          \
+  do {                                                                 \
+    if (TYPE_LANG_SPECIFIC (NODE) == NULL)                             \
+      {                                                                        \
+       TYPE_LANG_SPECIFIC (NODE) =                                     \
+         ggc_alloc_cleared (sizeof (struct lang_type_ptrmem));         \
+       TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0;   \
+      }                                                                        \
+    TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE);              \
+  } while (0)
 /* Returns the pfn field from a TYPE_PTRMEMFUNC_P.  */
 #define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE))
 
@@ -2647,9 +2743,9 @@ enum ptrmemfunc_vbit_where_t
    flag for this because "A union for which objects or pointers are
    declared is not an anonymous union" [class.union].  */
 #define ANON_AGGR_TYPE_P(NODE)                         \
-  (CLASS_TYPE_P (NODE) && TYPE_LANG_SPECIFIC (NODE)->anon_aggr)
+  (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr)
 #define SET_ANON_AGGR_TYPE_P(NODE)                     \
-  (TYPE_LANG_SPECIFIC (NODE)->anon_aggr = 1)
+  (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1)
 
 /* Nonzero if TYPE is an anonymous union type.  */
 #define ANON_UNION_TYPE_P(NODE) \
@@ -2659,7 +2755,7 @@ enum ptrmemfunc_vbit_where_t
 
 /* Define fields and accessors for nodes representing declared names.  */
 
-#define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->was_anonymous)
+#define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous)
 
 /* C++: all of these are overloaded!  These apply only to TYPE_DECLs.  */
 
@@ -2684,7 +2780,7 @@ enum ptrmemfunc_vbit_where_t
    For example, if a member that would normally be public in a
    derived class is made protected, then the derived class and the
    protected_access_node will appear in the DECL_ACCESS for the node.  */
-#define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.access)
+#define DECL_ACCESS(NODE) (LANG_DECL_U2_CHECK (NODE, 0)->access)
 
 /* Nonzero if the FUNCTION_DECL is a global constructor.  */
 #define DECL_GLOBAL_CTOR_P(NODE) \
@@ -2699,7 +2795,7 @@ enum ptrmemfunc_vbit_where_t
    with lower numbers should be run first.  Destructors should be run
    in the reverse order of constructors.  */
 #define GLOBAL_INIT_PRIORITY(NODE) \
-  (DECL_LANG_SPECIFIC (NODE)->decl_flags.u2.init_priority)
+  (LANG_DECL_U2_CHECK (NODE, 1)->init_priority)
 
 /* Accessor macros for C++ template decl nodes.  */
 
@@ -2882,7 +2978,7 @@ enum ptrmemfunc_vbit_where_t
    i.e., an instantiation whose instantiation arguments involve
    template types.  */
 #define PARTIAL_INSTANTIATION_P(TYPE) \
-  (TYPE_LANG_SPECIFIC (TYPE)->is_partial_instantiation)
+  (LANG_TYPE_CLASS_CHECK (TYPE)->is_partial_instantiation)
 
 /* Non-zero iff we are currently processing a declaration for an
    entity with its own template parameter list, and which is not a
@@ -2947,7 +3043,7 @@ enum ptrmemfunc_vbit_where_t
    is always located at offset zero from the f `this' pointer.)  If
    NULL, then there is no vcall offset.  */
 #define THUNK_VCALL_OFFSET(DECL) \
-  (DECL_LANG_SPECIFIC (DECL)->decl_flags.u2.vcall_offset)
+  (LANG_DECL_U2_CHECK (DECL, 0)->vcall_offset)
 
 /* These macros provide convenient access to the various _STMT nodes
    created when parsing template declarations.  */
@@ -3124,7 +3220,7 @@ extern int warn_nontemplate_friend;
 
 /* in decl{2}.c */
 /* A node that is a list (length 1) of error_mark_nodes.  */
-extern tree error_mark_list;
+extern GTY(()) tree error_mark_list;
 
 /* Node for "pointer to (virtual) function".
    This may be distinct from ptr_type_node so gdb can distinguish them.  */
@@ -3132,9 +3228,10 @@ extern tree error_mark_list;
 
 
 /* For building calls to `delete'.  */
-extern tree integer_two_node, integer_three_node;
+extern GTY(()) tree integer_two_node;
+extern GTY(()) tree integer_three_node;
 
-extern tree anonymous_namespace_name;
+extern GTY(()) tree anonymous_namespace_name;
 
 /* The number of function bodies which we are currently processing.
    (Zero if we are at namespace scope, one inside the body of a
@@ -3165,13 +3262,9 @@ typedef enum unification_kind_t {
 
 extern int current_class_depth;
 
-/* Points to the name of that function. May not be the DECL_NAME
-   of CURRENT_FUNCTION_DECL due to overloading */
-extern tree original_function_name;
-
 /* An array of all local classes present in this translation unit, in
    declaration order.  */
-extern varray_type local_classes;
+extern GTY(()) varray_type local_classes;
 \f
 /* Here's where we control how name mangling takes place.  */
 
@@ -3331,8 +3424,8 @@ extern int at_eof;
 
 /* Functions called along with real static constructors and destructors.  */
 
-extern tree static_ctors;
-extern tree static_dtors;
+extern GTY(()) tree static_ctors;
+extern GTY(()) tree static_dtors;
 
 enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
 
@@ -3652,7 +3745,8 @@ extern void insert_block                  PARAMS ((tree));
 extern void set_block                          PARAMS ((tree));
 extern tree pushdecl                           PARAMS ((tree));
 extern void cxx_init_decl_processing           PARAMS ((void));
-extern void cxx_mark_tree                      PARAMS ((tree));
+enum cp_tree_node_structure_enum cp_tree_node_structure 
+  PARAMS ((union lang_tree_node *));
 extern void cxx_insert_default_attributes      PARAMS ((tree));
 extern bool cxx_mark_addressable               PARAMS ((tree));
 extern void cxx_push_function_context          PARAMS ((struct function *));
@@ -3669,13 +3763,13 @@ extern void finish_scope                        PARAMS ((void));
 extern void note_level_for_for                 PARAMS ((void));
 extern void note_level_for_try                 PARAMS ((void));
 extern void note_level_for_catch               PARAMS ((void));
-extern void resume_level                       PARAMS ((struct binding_level *));
+extern void resume_level                       PARAMS ((struct cp_binding_level *));
 extern void delete_block                       PARAMS ((tree));
 extern void add_block_current_level            PARAMS ((tree));
 extern void pushlevel_class                    PARAMS ((void));
 extern void poplevel_class                      PARAMS ((void));
 extern void print_binding_stack                        PARAMS ((void));
-extern void print_binding_level                        PARAMS ((struct binding_level *));
+extern void print_binding_level                        PARAMS ((struct cp_binding_level *));
 extern void push_namespace                     PARAMS ((tree));
 extern void pop_namespace                      PARAMS ((void));
 extern void push_nested_namespace              PARAMS ((tree));
@@ -3764,7 +3858,7 @@ extern tree finish_method                 PARAMS ((tree));
 extern void maybe_register_incomplete_var       PARAMS ((tree));
 extern void complete_vars                      PARAMS ((tree));
 extern void finish_stmt                                PARAMS ((void));
-extern void print_other_binding_stack          PARAMS ((struct binding_level *));
+extern void print_other_binding_stack          PARAMS ((struct cp_binding_level *));
 extern void revert_static_member_fn             PARAMS ((tree));
 extern void fixup_anonymous_aggr                PARAMS ((tree));
 extern int check_static_variable_definition     PARAMS ((tree, tree));
@@ -3799,7 +3893,6 @@ extern tmpl_spec_kind current_tmpl_spec_kind    PARAMS ((int));
 extern tree cp_fname_init                      PARAMS ((const char *));
 
 /* in decl2.c */
-extern void init_decl2                         PARAMS ((void));
 extern int check_java_method                   PARAMS ((tree));
 extern int cxx_decode_option                   PARAMS ((int, char **));
 extern int grok_method_quals                   PARAMS ((tree, tree, tree));
@@ -3857,9 +3950,6 @@ extern tree get_guard                           PARAMS ((tree));
 extern tree get_guard_cond                      PARAMS ((tree));
 extern tree set_guard                           PARAMS ((tree));
 
-/* in parse.y */
-extern void cp_parse_init                      PARAMS ((void));
-
 extern void cp_error_at                PARAMS ((const char *msgid, ...));
 extern void cp_warning_at      PARAMS ((const char *msgid, ...));
 extern void cp_pedwarn_at      PARAMS ((const char *msgid, ...));
@@ -3968,7 +4058,6 @@ extern tree make_aggr_type                        PARAMS ((enum tree_code));
 extern void compiler_error                     PARAMS ((const char *, ...))
   ATTRIBUTE_PRINTF_1;
 extern void yyerror                            PARAMS ((const char *));
-extern void clear_inline_text_obstack          PARAMS ((void));
 extern void yyhook                             PARAMS ((int));
 extern int cp_type_qual_from_rid                PARAMS ((tree));
 extern const char *cxx_init                    PARAMS ((const char *));
@@ -3992,7 +4081,6 @@ extern int calls_setjmp_p                       PARAMS ((tree));
 extern int maybe_clone_body                     PARAMS ((tree));
 
 /* in pt.c */
-extern void init_pt                             PARAMS ((void));
 extern void check_template_shadow              PARAMS ((tree));
 extern tree get_innermost_template_args         PARAMS ((tree, int));
 extern tree tsubst                             PARAMS ((tree, tree, tsubst_flags_t, tree));
@@ -4192,7 +4280,6 @@ extern tree begin_class_definition              PARAMS ((tree));
 extern tree finish_class_definition             PARAMS ((tree, tree, int, int));
 extern void finish_default_args                 PARAMS ((void));
 extern void begin_inline_definitions            PARAMS ((void));
-extern void finish_inline_definitions           PARAMS ((void));
 extern tree finish_member_class_template        PARAMS ((tree));
 extern void finish_template_decl                PARAMS ((tree));
 extern tree finish_template_type                PARAMS ((tree, tree, int));
@@ -4219,7 +4306,6 @@ extern tree finish_global_stmt_expr             PARAMS ((tree));
 
 /* in spew.c */
 extern void init_spew                          PARAMS ((void));
-extern void mark_pending_inlines               PARAMS ((PTR));
 extern int peekyylex                           PARAMS ((void));
 extern tree arbitrate_lookup                   PARAMS ((tree, tree, tree));
 extern tree frob_opname                         PARAMS ((tree));
@@ -4232,8 +4318,10 @@ extern void replace_defarg                       PARAMS ((tree, tree));
 extern void end_input                          PARAMS ((void));
 
 /* in tree.c */
-extern tree stabilize_expr             PARAMS ((tree, tree *));
-extern tree cxx_unsave_expr_now                PARAMS ((tree));
+extern void lang_check_failed                  PARAMS ((const char *, int,
+                                                        const char *));
+extern tree stabilize_expr                     PARAMS ((tree, tree *));
+extern tree cxx_unsave_expr_now                        PARAMS ((tree));
 extern tree cxx_maybe_build_cleanup            PARAMS ((tree));
 extern void init_tree                          PARAMS ((void));
 extern int pod_type_p                          PARAMS ((tree));
@@ -4242,7 +4330,8 @@ extern tree canonical_type_variant              PARAMS ((tree));
 extern void unshare_base_binfos                        PARAMS ((tree));
 extern int member_p                            PARAMS ((tree));
 extern cp_lvalue_kind real_lvalue_p            PARAMS ((tree));
-extern tree build_min                          PARAMS ((enum tree_code, tree, ...));
+extern tree build_min                          PARAMS ((enum tree_code, tree,
+                                                        ...));
 extern tree build_min_nt                       PARAMS ((enum tree_code, ...));
 extern tree build_cplus_new                    PARAMS ((tree, tree));
 extern tree get_target_expr                    PARAMS ((tree));
@@ -4275,8 +4364,7 @@ extern tree vec_binfo_member                      PARAMS ((tree, tree));
 extern tree decl_namespace_context             PARAMS ((tree));
 extern tree lvalue_type                                PARAMS ((tree));
 extern tree error_type                         PARAMS ((tree));
-extern tree build_ptr_wrapper                  PARAMS ((void *));
-extern tree build_int_wrapper                  PARAMS ((int));
+extern tree build_zc_wrapper                   PARAMS ((struct z_candidate *));
 extern tree build_srcloc_here                  PARAMS ((void));
 extern int varargs_function_p                  PARAMS ((tree));
 extern int really_overloaded_fn                        PARAMS ((tree));
index dbaf68548c13e57f55c4a1762cc3535d279a5698..de6a293bb08c15b543b1df1424ea01d134bbbcb9 100644 (file)
@@ -41,23 +41,24 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "except.h"
 #include "toplev.h"
-#include "../hash.h"
+#include "hashtab.h"
 #include "ggc.h"
 #include "tm_p.h"
 #include "target.h"
 #include "c-common.h"
 #include "c-pragma.h"
 #include "diagnostic.h"
+#include "debug.h"
 
 static tree grokparms                          PARAMS ((tree));
 static const char *redeclaration_error_message PARAMS ((tree, tree));
 
-static void push_binding_level PARAMS ((struct binding_level *, int,
+static void push_binding_level PARAMS ((struct cp_binding_level *, int,
                                      int));
 static void pop_binding_level PARAMS ((void));
 static void suspend_binding_level PARAMS ((void));
-static void resume_binding_level PARAMS ((struct binding_level *));
-static struct binding_level *make_binding_level PARAMS ((void));
+static void resume_binding_level PARAMS ((struct cp_binding_level *));
+static struct cp_binding_level *make_binding_level PARAMS ((void));
 static void declare_namespace_level PARAMS ((void));
 static int decl_jump_unsafe PARAMS ((tree));
 static void storedecls PARAMS ((tree));
@@ -77,9 +78,9 @@ static tree grokfndecl PARAMS ((tree, tree, tree, tree, int,
 static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree));
 static tree follow_tag_typedef PARAMS ((tree));
 static tree lookup_tag PARAMS ((enum tree_code, tree,
-                             struct binding_level *, int));
+                             struct cp_binding_level *, int));
 static void set_identifier_type_value_with_scope
-       PARAMS ((tree, tree, struct binding_level *));
+       PARAMS ((tree, tree, struct cp_binding_level *));
 static void record_unknown_type PARAMS ((tree, const char *));
 static tree builtin_function_1 PARAMS ((const char *, tree, tree, int,
                                       enum built_in_class, const char *));
@@ -87,11 +88,11 @@ static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
 static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
 static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
                                  int));
-static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct binding_level*));
+static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct cp_binding_level*));
 static void check_for_uninitialized_const_var PARAMS ((tree));
-static unsigned long typename_hash PARAMS ((hash_table_key));
-static bool typename_compare PARAMS ((hash_table_key, hash_table_key));
-static void push_binding PARAMS ((tree, tree, struct binding_level*));
+static hashval_t typename_hash PARAMS ((const void *));
+static int typename_compare PARAMS ((const void *, const void *));
+static void push_binding PARAMS ((tree, tree, struct cp_binding_level*));
 static int add_binding PARAMS ((tree, tree));
 static void pop_binding PARAMS ((tree, tree));
 static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *));
@@ -102,17 +103,17 @@ static tree qualify_lookup PARAMS ((tree, int));
 static tree record_builtin_java_type PARAMS ((const char *, int));
 static const char *tag_name PARAMS ((enum tag_types code));
 static void find_class_binding_level PARAMS ((void));
-static struct binding_level *innermost_nonclass_level PARAMS ((void));
+static struct cp_binding_level *innermost_nonclass_level PARAMS ((void));
 static void warn_about_implicit_typename_lookup PARAMS ((tree, tree));
 static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *));
 static int walk_globals_r PARAMS ((tree, void *));
-static void add_decl_to_level PARAMS ((tree, struct binding_level *));
+static void add_decl_to_level PARAMS ((tree, struct cp_binding_level *));
 static tree make_label_decl PARAMS ((tree, int));
 static void use_label PARAMS ((tree));
-static void check_previous_goto_1 PARAMS ((tree, struct binding_level *, tree,
+static void check_previous_goto_1 PARAMS ((tree, struct cp_binding_level *, tree,
                                           const char *, int));
 static void check_previous_goto PARAMS ((struct named_label_use_list *));
-static void check_switch_goto PARAMS ((struct binding_level *));
+static void check_switch_goto PARAMS ((struct cp_binding_level *));
 static void check_previous_gotos PARAMS ((tree));
 static void pop_label PARAMS ((tree, tree));
 static void pop_labels PARAMS ((tree));
@@ -121,10 +122,6 @@ static void layout_var_decl PARAMS ((tree));
 static void maybe_commonize_var PARAMS ((tree));
 static tree check_initializer PARAMS ((tree, tree));
 static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *));
-static void mark_binding_level PARAMS ((void *));
-static void mark_named_label_lists PARAMS ((void *, void *));
-static void mark_saved_scope PARAMS ((void *));
-static void mark_lang_function PARAMS ((struct cp_language_function *));
 static void save_function_data PARAMS ((tree));
 static void check_function_type PARAMS ((tree, tree));
 static void destroy_local_var PARAMS ((tree));
@@ -146,7 +143,7 @@ static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
 static void store_parm_decls PARAMS ((tree));
 static int cp_missing_noreturn_ok_p PARAMS ((tree));
 
-#if defined (DEBUG_CP_BINDING_LEVELS)
+#if defined (DEBUG_BINDING_LEVELS)
 static void indent PARAMS ((void));
 #endif
 
@@ -203,7 +200,7 @@ tree cp_global_trees[CPTI_MAX];
 /* Indicates that there is a type value in some namespace, although
    that is not necessarily in scope at the moment.  */
 
-static tree global_type_node;
+static GTY(()) tree global_type_node;
 
 /* Expect only namespace names now. */
 static int only_namespace_names;
@@ -211,9 +208,9 @@ static int only_namespace_names;
 /* Used only for jumps to as-yet undefined labels, since jumps to
    defined labels can have their validity checked immediately.  */
 
-struct named_label_use_list
+struct named_label_use_list GTY(())
 {
-  struct binding_level *binding_level;
+  struct cp_binding_level *binding_level;
   tree names_in_scope;
   tree label_decl;
   const char *filename_o_goto;
@@ -244,9 +241,9 @@ tree last_function_parms;
    we can clear out their names' definitions at the end of the
    function, and so we can check the validity of jumps to these labels.  */
 
-struct named_label_list
+struct named_label_list GTY(())
 {
-  struct binding_level *binding_level;
+  struct cp_binding_level *binding_level;
   tree names_in_scope;
   tree old_value;
   tree label_decl;
@@ -283,10 +280,6 @@ extern int flag_conserve_space;
 \f
 /* C and C++ flags are in decl2.c.  */
 
-/* A expression of value 0 with the same precision as a sizetype
-   node, but signed.  */
-tree signed_size_zero_node;
-
 /* The name of the anonymous namespace, throughout this translation
    unit.  */
 tree anonymous_namespace_name;
@@ -337,7 +330,7 @@ int adding_implicit_members = 0;
 /* Note that the information in the `names' component of the global contour
    is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
 
-struct binding_level
+struct cp_binding_level GTY(())
   {
     /* A chain of _DECL nodes for all variables, constants, functions,
        and typedef types.  These are in the reverse of the order
@@ -387,7 +380,7 @@ struct binding_level
     tree this_class;
 
     /* The binding level which this one is contained in (inherits from).  */
-    struct binding_level *level_chain;
+    struct cp_binding_level *level_chain;
 
     /* List of VAR_DECLS saved from a previous for statement.
        These would be dead in ISO-conforming code, but might
@@ -438,13 +431,11 @@ struct binding_level
 
     /* Three bits left for this word.  */
 
-#if defined(DEBUG_CP_BINDING_LEVELS)
     /* Binding depth at which this level began.  */
     unsigned binding_depth;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
   };
 
-#define NULL_BINDING_LEVEL ((struct binding_level *) NULL)
+#define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL)
 
 /* The binding level currently in effect.  */
 
@@ -459,13 +450,13 @@ struct binding_level
 
 /* A chain of binding_level structures awaiting reuse.  */
 
-static struct binding_level *free_binding_level;
+static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
 
 /* The outermost binding level, for names of file scope.
    This is created when the compiler is started and exists
    through the entire run.  */
 
-static struct binding_level *global_binding_level;
+static GTY(()) struct cp_binding_level *global_binding_level;
 
 /* Nonzero means unconditionally make a BLOCK for the next level pushed.  */
 
@@ -475,9 +466,9 @@ static int keep_next_level_flag;
    UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type.  At the
    time the VAR_DECL was declared, the type was incomplete.  */
 
-static tree incomplete_vars;
+static GTY(()) tree incomplete_vars;
 
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
 static int binding_depth = 0;
 static int is_class_level = 0;
 
@@ -489,32 +480,32 @@ indent ()
   for (i = 0; i < binding_depth*2; i++)
     putc (' ', stderr);
 }
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
 
-static tree pushdecl_with_scope        PARAMS ((tree, struct binding_level *));
+static tree pushdecl_with_scope        PARAMS ((tree, struct cp_binding_level *));
 
 static void
 push_binding_level (newlevel, tag_transparent, keep)
-     struct binding_level *newlevel;
+     struct cp_binding_level *newlevel;
      int tag_transparent, keep;
 {
   /* Add this level to the front of the chain (stack) of levels that
      are active.  */
-  memset ((char*) newlevel, 0, sizeof (struct binding_level));
+  memset ((char*) newlevel, 0, sizeof (struct cp_binding_level));
   newlevel->level_chain = current_binding_level;
   current_binding_level = newlevel;
   newlevel->tag_transparent = tag_transparent;
   newlevel->more_cleanups_ok = 1;
 
   newlevel->keep = keep;
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   newlevel->binding_depth = binding_depth;
   indent ();
   fprintf (stderr, "push %s level 0x%08x line %d\n",
           (is_class_level) ? "class" : "block", newlevel, lineno);
   is_class_level = 0;
   binding_depth++;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
 }
 
 /* Find the innermost enclosing class scope, and reset
@@ -523,7 +514,7 @@ push_binding_level (newlevel, tag_transparent, keep)
 static void
 find_class_binding_level ()
 {
-  struct binding_level *level = current_binding_level;
+  struct cp_binding_level *level = current_binding_level;
 
   while (level && level->parm_flag != 2)
     level = level->level_chain;
@@ -543,7 +534,7 @@ pop_binding_level ()
        abort ();
     }
   /* Pop the current level, and free the structure for reuse.  */
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   binding_depth--;
   indent ();
   fprintf (stderr, "pop  %s level 0x%08x line %d\n",
@@ -555,15 +546,15 @@ pop_binding_level ()
       fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
     }
   is_class_level = 0;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
   {
-    register struct binding_level *level = current_binding_level;
+    register struct cp_binding_level *level = current_binding_level;
     current_binding_level = current_binding_level->level_chain;
     level->level_chain = free_binding_level;
-#if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */
+#if 0 /* defined(DEBUG_BINDING_LEVELS) */
     if (level->binding_depth != binding_depth)
       abort ();
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
     free_binding_level = level;
     find_class_binding_level ();
   }
@@ -582,7 +573,7 @@ suspend_binding_level ()
        abort ();
     }
   /* Suspend the current level.  */
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   binding_depth--;
   indent ();
   fprintf (stderr, "suspend  %s level 0x%08x line %d\n",
@@ -594,14 +585,14 @@ suspend_binding_level ()
       fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n");
     }
   is_class_level = 0;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
   current_binding_level = current_binding_level->level_chain;
   find_class_binding_level ();
 }
 
 static void
 resume_binding_level (b)
-     struct binding_level *b;
+     struct cp_binding_level *b;
 {
   /* Resuming binding levels is meant only for namespaces,
      and those cannot nest into classes. */
@@ -609,24 +600,24 @@ resume_binding_level (b)
   /* Also, resuming a non-directly nested namespace is a no-no.  */
   my_friendly_assert(b->level_chain == current_binding_level, 386);
   current_binding_level = b;
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   b->binding_depth = binding_depth;
   indent ();
   fprintf (stderr, "resume %s level 0x%08x line %d\n",
           (is_class_level) ? "class" : "block", b, lineno);
   is_class_level = 0;
   binding_depth++;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
 }
 \f
-/* Create a new `struct binding_level'.  */
+/* Create a new `struct cp_binding_level'.  */
 
 static
-struct binding_level *
+struct cp_binding_level *
 make_binding_level ()
 {
   /* NOSTRICT */
-  return (struct binding_level *) xmalloc (sizeof (struct binding_level));
+  return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level));
 }
 
 /* Nonzero if we are currently in the global binding level.  */
@@ -639,10 +630,10 @@ global_bindings_p ()
 
 /* Return the innermost binding level that is not for a class scope.  */
 
-static struct binding_level *
+static struct cp_binding_level *
 innermost_nonclass_level ()
 {
-  struct binding_level *b;
+  struct cp_binding_level *b;
 
   b = current_binding_level;
   while (b->parm_flag == 2)
@@ -660,7 +651,7 @@ innermost_nonclass_level ()
 int
 toplevel_bindings_p ()
 {
-  struct binding_level *b = innermost_nonclass_level ();
+  struct cp_binding_level *b = innermost_nonclass_level ();
 
   return b->namespace_p || b->template_parms_p;
 }
@@ -672,7 +663,7 @@ toplevel_bindings_p ()
 int
 namespace_bindings_p ()
 {
-  struct binding_level *b = innermost_nonclass_level ();
+  struct cp_binding_level *b = innermost_nonclass_level ();
 
   return b->namespace_p;
 }
@@ -726,7 +717,7 @@ current_tmpl_spec_kind (n_class_scopes)
   int n_template_parm_scopes = 0;
   int seen_specialization_p = 0;
   int innermost_specialization_p = 0;
-  struct binding_level *b;
+  struct cp_binding_level *b;
 
   /* Scan through the template parameter scopes.  */
   for (b = current_binding_level; b->template_parms_p; b = b->level_chain)
@@ -819,17 +810,17 @@ void
 pushlevel (tag_transparent)
      int tag_transparent;
 {
-  struct binding_level *newlevel;
+  struct cp_binding_level *newlevel;
 
   if (cfun && !doing_semantic_analysis_p ())
     return;
 
   /* Reuse or create a struct for this binding level.  */
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   if (0)
-#else /* !defined(DEBUG_CP_BINDING_LEVELS) */
+#else /* !defined(DEBUG_BINDING_LEVELS) */
   if (free_binding_level)
-#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* !defined(DEBUG_BINDING_LEVELS) */
     {
       newlevel = free_binding_level;
       free_binding_level = free_binding_level->level_chain;
@@ -914,14 +905,14 @@ note_level_for_catch ()
 }
 
 /* For a binding between a name and an entity at a block scope,
-   this is the `struct binding_level' for the block.  */
+   this is the `struct cp_binding_level' for the block.  */
 #define BINDING_LEVEL(NODE) \
   (((struct tree_binding*)(NODE))->scope.level)
 
 /* A free list of CPLUS_BINDING nodes, connected by their
    TREE_CHAINs.  */
 
-static tree free_bindings;
+static GTY((deletable (""))) tree free_bindings;
 
 /* Make DECL the innermost binding for ID.  The LEVEL is the binding
    level at which this declaration is being bound.  */
@@ -930,7 +921,7 @@ static void
 push_binding (id, decl, level)
      tree id;
      tree decl;
-     struct binding_level* level;
+     struct cp_binding_level* level;
 {
   tree binding;
 
@@ -1033,7 +1024,7 @@ add_binding (id, decl)
 static void
 add_decl_to_level (decl, b)
      tree decl;
-     struct binding_level *b;
+     struct cp_binding_level *b;
 {
   /* We build up the list in reverse order, and reverse it later if
      necessary.  */
@@ -1052,7 +1043,7 @@ push_local_binding (id, decl, flags)
      tree decl;
      int flags;
 {
-  struct binding_level *b;
+  struct cp_binding_level *b;
 
   /* Skip over any local classes.  This makes sense if we call
      push_local_binding with a friend decl of a local class.  */
@@ -1303,7 +1294,7 @@ poplevel (keep, reverse, functionbody)
      under constraints of next binding contour.  */
   if (cfun && !functionbody)
     {
-      struct binding_level *level_chain;
+      struct cp_binding_level *level_chain;
       level_chain = current_binding_level->level_chain;
       if (level_chain)
        {
@@ -1626,14 +1617,14 @@ set_block (block)
 void
 pushlevel_class ()
 {
-  register struct binding_level *newlevel;
+  register struct cp_binding_level *newlevel;
 
   /* Reuse or create a struct for this binding level.  */
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   if (0)
-#else /* !defined(DEBUG_CP_BINDING_LEVELS) */
+#else /* !defined(DEBUG_BINDING_LEVELS) */
   if (free_binding_level)
-#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* !defined(DEBUG_BINDING_LEVELS) */
     {
       newlevel = free_binding_level;
       free_binding_level = free_binding_level->level_chain;
@@ -1641,9 +1632,9 @@ pushlevel_class ()
   else
     newlevel = make_binding_level ();
 
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   is_class_level = 1;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
 
   push_binding_level (newlevel, 0, 0);
 
@@ -1657,7 +1648,7 @@ pushlevel_class ()
 void
 poplevel_class ()
 {
-  register struct binding_level *level = class_binding_level;
+  register struct cp_binding_level *level = class_binding_level;
   tree shadowed;
 
   my_friendly_assert (level != 0, 354);
@@ -1669,7 +1660,7 @@ poplevel_class ()
      next time we're entering a class scope, it is the same class.  */
   if (current_class_depth != 1)
     {
-      struct binding_level* b;
+      struct cp_binding_level* b;
 
       /* Clear out our IDENTIFIER_CLASS_VALUEs.  */
       for (shadowed = level->class_shadowed;
@@ -1719,9 +1710,9 @@ poplevel_class ()
 
   /* Now, pop out of the binding level which we created up in the
      `pushlevel_class' routine.  */
-#if defined(DEBUG_CP_BINDING_LEVELS)
+#if defined(DEBUG_BINDING_LEVELS)
   is_class_level = 1;
-#endif /* defined(DEBUG_CP_BINDING_LEVELS) */
+#endif /* defined(DEBUG_BINDING_LEVELS) */
 
   pop_binding_level ();
 }
@@ -1930,50 +1921,6 @@ wrapup_globals_for_namespace (namespace, data)
   return result;
 }
 
-\f
-/* Mark ARG (which is really a struct binding_level **) for GC.  */
-
-static void
-mark_binding_level (arg)
-     void *arg;
-{
-  struct binding_level *lvl = *(struct binding_level **)arg;
-
-  for (; lvl; lvl = lvl->level_chain)
-    {
-      ggc_mark_tree (lvl->names);
-      ggc_mark_tree (lvl->tags);
-      ggc_mark_tree (lvl->usings);
-      ggc_mark_tree (lvl->using_directives);
-      ggc_mark_tree (lvl->class_shadowed);
-      ggc_mark_tree (lvl->type_shadowed);
-      ggc_mark_tree (lvl->shadowed_labels);
-      ggc_mark_tree (lvl->blocks);
-      ggc_mark_tree (lvl->this_class);
-      ggc_mark_tree (lvl->dead_vars_from_for);
-    }
-}
-
-static void
-mark_named_label_lists (labs, uses)
-     void *labs;
-     void *uses;
-{
-  struct named_label_list *l = *(struct named_label_list **)labs;
-  struct named_label_use_list *u = *(struct named_label_use_list **)uses;
-
-  for (; l; l = l->next)
-    {
-      ggc_mark (l);
-      mark_binding_level (l->binding_level);
-      ggc_mark_tree (l->old_value);
-      ggc_mark_tree (l->label_decl);
-      ggc_mark_tree (l->bad_decls);
-    }
-
-  for (; u; u = u->next)
-    ggc_mark (u);
-}
 \f
 /* For debugging.  */
 static int no_print_functions = 0;
@@ -1981,7 +1928,7 @@ static int no_print_builtins = 0;
 
 void
 print_binding_level (lvl)
-     struct binding_level *lvl;
+     struct cp_binding_level *lvl;
 {
   tree t;
   int i = 0, len;
@@ -2082,9 +2029,9 @@ print_binding_level (lvl)
 
 void
 print_other_binding_stack (stack)
-     struct binding_level *stack;
+     struct cp_binding_level *stack;
 {
-  struct binding_level *level;
+  struct cp_binding_level *level;
   for (level = stack; level != global_binding_level; level = level->level_chain)
     {
       fprintf (stderr, "binding level ");
@@ -2097,7 +2044,7 @@ print_other_binding_stack (stack)
 void
 print_binding_stack ()
 {
-  struct binding_level *b;
+  struct cp_binding_level *b;
   fprintf (stderr, "current_binding_level=");
   fprintf (stderr, HOST_PTR_PRINTF, current_binding_level);
   fprintf (stderr, "\nclass_binding_level=");
@@ -2363,38 +2310,6 @@ pop_nested_namespace (ns)
    scope isn't enough, because more binding levels may be pushed.  */
 struct saved_scope *scope_chain;
 
-/* Mark ARG (which is really a struct saved_scope **) for GC.  */
-
-static void
-mark_saved_scope (arg)
-     void *arg;
-{
-  struct saved_scope *t = *(struct saved_scope **)arg;
-  while (t)
-    {
-      mark_binding_level (&t->class_bindings);
-      ggc_mark_tree (t->old_bindings);
-      ggc_mark_tree (t->old_namespace);
-      ggc_mark_tree (t->decl_ns_list);
-      ggc_mark_tree (t->class_name);
-      ggc_mark_tree (t->class_type);
-      ggc_mark_tree (t->access_specifier);
-      ggc_mark_tree (t->function_decl);
-      if (t->lang_base)
-       ggc_mark_tree_varray (t->lang_base);
-      ggc_mark_tree (t->lang_name);
-      ggc_mark_tree (t->template_parms);
-      ggc_mark_tree (t->x_previous_class_type);
-      ggc_mark_tree (t->x_previous_class_values);
-      ggc_mark_tree (t->x_saved_tree);
-      ggc_mark_tree (t->lookups);
-
-      mark_stmt_tree (&t->x_stmt_tree);
-      mark_binding_level (&t->bindings);
-      t = t->prev;
-    }
-}
-
 static tree
 store_bindings (names, old_bindings)
      tree names, old_bindings;
@@ -2443,11 +2358,11 @@ maybe_push_to_top_level (pseudo)
      int pseudo;
 {
   struct saved_scope *s;
-  struct binding_level *b;
+  struct cp_binding_level *b;
   tree old_bindings;
   int need_pop;
 
-  s = (struct saved_scope *) xcalloc (1, sizeof (struct saved_scope));
+  s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope));
 
   b = scope_chain ? current_binding_level : 0;
 
@@ -2517,7 +2432,7 @@ pop_from_top_level ()
   if (previous_class_type)
     invalidate_class_lookup_cache ();
 
-  VARRAY_FREE (current_lang_base);
+  current_lang_base = 0;
 
   scope_chain = s->prev;
   for (t = s->old_bindings; t; t = TREE_CHAIN (t))
@@ -2535,8 +2450,6 @@ pop_from_top_level ()
     pop_function_context_from (NULL_TREE);
   current_function_decl = s->function_decl;
   last_function_parms = s->last_parms;
-
-  free (s);
 }
 \f
 /* Push a definition of struct, union or enum tag "name".
@@ -2556,7 +2469,7 @@ static void
 set_identifier_type_value_with_scope (id, type, b)
      tree id;
      tree type;
-     struct binding_level *b;
+     struct cp_binding_level *b;
 {
   if (!b->namespace_p)
     {
@@ -2613,7 +2526,7 @@ identifier_type_value (id)
 void
 pop_everything ()
 {
-#ifdef DEBUG_CP_BINDING_LEVELS
+#ifdef DEBUG_BINDING_LEVELS
   fprintf (stderr, "XXX entering pop_everything ()\n");
 #endif
   while (!toplevel_bindings_p ())
@@ -2623,7 +2536,7 @@ pop_everything ()
       else
        poplevel (0, 0, 0);
     }
-#ifdef DEBUG_CP_BINDING_LEVELS
+#ifdef DEBUG_BINDING_LEVELS
   fprintf (stderr, "XXX leaving pop_everything ()\n");
 #endif
 }
@@ -2641,7 +2554,7 @@ static tree
 maybe_process_template_type_declaration (type, globalize, b)
      tree type;
      int globalize;
-     struct binding_level* b;
+     struct cp_binding_level* b;
 {
   tree decl = TYPE_NAME (type);
 
@@ -2739,6 +2652,7 @@ push_local_name (decl)
        {
          if (!DECL_LANG_SPECIFIC (decl))
            retrofit_lang_decl (decl);
+         DECL_LANG_SPECIFIC (decl)->decl_flags.u2sel = 1;
          if (DECL_LANG_SPECIFIC (t))
            DECL_DISCRIMINATOR (decl) = DECL_DISCRIMINATOR (t) + 1;
          else
@@ -2762,7 +2676,7 @@ pushtag (name, type, globalize)
      tree name, type;
      int globalize;
 {
-  register struct binding_level *b;
+  register struct cp_binding_level *b;
 
   b = current_binding_level;
   while (b->tag_transparent
@@ -2893,7 +2807,7 @@ make_anon_name ()
 void
 clear_anon_tags ()
 {
-  register struct binding_level *b;
+  register struct cp_binding_level *b;
   register tree tags;
   static int last_cnt = 0;
 
@@ -3654,7 +3568,8 @@ duplicate_decls (newdecl, olddecl)
       /* Don't really know how much of the language-specific
         values we should copy from old to new.  */
       DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
-      DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
+      DECL_LANG_SPECIFIC (newdecl)->decl_flags.u2 = 
+       DECL_LANG_SPECIFIC (olddecl)->decl_flags.u2;
       DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
       DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
       DECL_INITIALIZED_IN_CLASS_P (newdecl)
@@ -4212,7 +4127,7 @@ pushdecl (x)
                {
                  /* Go to where the parms should be and see if we find
                     them there.  */
-                 struct binding_level *b = current_binding_level->level_chain;
+                 struct cp_binding_level *b = current_binding_level->level_chain;
 
                  /* ARM $8.3 */
                  if (b->parm_flag == 1)
@@ -4271,9 +4186,9 @@ pushdecl (x)
 static tree
 pushdecl_with_scope (x, level)
      tree x;
-     struct binding_level *level;
+     struct cp_binding_level *level;
 {
-  register struct binding_level *b;
+  register struct cp_binding_level *b;
   tree function_decl = current_function_decl;
 
   current_function_decl = NULL_TREE;
@@ -4302,7 +4217,7 @@ tree
 pushdecl_namespace_level (x)
      tree x;
 {
-  register struct binding_level *b = current_binding_level;
+  register struct cp_binding_level *b = current_binding_level;
   register tree t;
 
   t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
@@ -4945,14 +4860,14 @@ decl_jump_unsafe (decl)
 static void
 check_previous_goto_1 (decl, level, names, file, line)
      tree decl;
-     struct binding_level *level;
+     struct cp_binding_level *level;
      tree names;
      const char *file;
      int line;
 {
   int identified = 0;
   int saw_eh = 0;
-  struct binding_level *b = current_binding_level;
+  struct cp_binding_level *b = current_binding_level;
   for (; b; b = b->level_chain)
     {
       tree new_decls = b->names;
@@ -5019,7 +4934,7 @@ check_previous_goto (use)
 
 static void
 check_switch_goto (level)
-     struct binding_level *level;
+     struct cp_binding_level *level;
 {
   check_previous_goto_1 (NULL_TREE, level, level->names, NULL, 0);
 }
@@ -5121,7 +5036,7 @@ define_label (filename, line, name)
 {
   tree decl = lookup_label (name);
   struct named_label_list *ent;
-  register struct binding_level *p;
+  register struct cp_binding_level *p;
 
   for (ent = named_labels; ent; ent = ent->next)
     if (ent->label_decl == decl)
@@ -5159,7 +5074,7 @@ define_label (filename, line, name)
 
 struct cp_switch
 {
-  struct binding_level *level;
+  struct cp_binding_level *level;
   struct cp_switch *next;
   /* The SWITCH_STMT being built.  */
   tree switch_stmt;
@@ -5215,7 +5130,7 @@ finish_case_label (low_value, high_value)
      tree high_value;
 {
   tree cond, r;
-  register struct binding_level *p;
+  register struct cp_binding_level *p;
 
   if (! switch_stack)
     {
@@ -5353,10 +5268,10 @@ static tree
 lookup_tag (form, name, binding_level, thislevel_only)
      enum tree_code form;
      tree name;
-     struct binding_level *binding_level;
+     struct cp_binding_level *binding_level;
      int thislevel_only;
 {
-  register struct binding_level *level;
+  register struct cp_binding_level *level;
   /* Non-zero if, we should look past a template parameter level, even
      if THISLEVEL_ONLY.  */
   int allow_template_parms_p = 1;
@@ -5472,7 +5387,7 @@ lookup_tag_reverse (type, name)
      tree type;
      tree name;
 {
-  register struct binding_level *level;
+  register struct cp_binding_level *level;
 
   for (level = current_binding_level; level; level = level->level_chain)
     {
@@ -5572,26 +5487,25 @@ lookup_namespace_name (namespace, name)
 
 /* Hash a TYPENAME_TYPE.  K is really of type `tree'.  */
 
-static unsigned long
+static hashval_t
 typename_hash (k)
-     hash_table_key k;
+     const void * k;
 {
-  unsigned long hash;
-  tree t;
+  hashval_t hash;
+  tree t = (tree) k;
 
-  t = (tree) k;
-  hash = (((unsigned long) TYPE_CONTEXT (t))
-         ^ ((unsigned long) DECL_NAME (TYPE_NAME (t))));
+  hash = (((hashval_t) TYPE_CONTEXT (t))
+         ^ ((hashval_t) DECL_NAME (TYPE_NAME (t))));
 
   return hash;
 }
 
 /* Compare two TYPENAME_TYPEs.  K1 and K2 are really of type `tree'.  */
 
-static bool
+static int
 typename_compare (k1, k2)
-     hash_table_key k1;
-     hash_table_key k2;
+     const void * k1;
+     const void * k2;
 {
   tree t1;
   tree t2;
@@ -5604,7 +5518,7 @@ typename_compare (k1, k2)
   d2 = TYPE_NAME (t2);
 
   return (DECL_NAME (d1) == DECL_NAME (d2)
-         && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2))
+         && TYPE_CONTEXT (t1) == TYPE_CONTEXT (t2)
          && ((TREE_TYPE (t1) != NULL_TREE)
              == (TREE_TYPE (t2) != NULL_TREE))
          && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
@@ -5619,6 +5533,8 @@ typename_compare (k1, k2)
 
    Returns the new TYPENAME_TYPE.  */
 
+static GTY ((param_is (union tree_node))) htab_t typename_htab;
+
 tree
 build_typename_type (context, name, fullname, base_type)
      tree context;
@@ -5628,16 +5544,12 @@ build_typename_type (context, name, fullname, base_type)
 {
   tree t;
   tree d;
-  struct hash_entry *e;
+  PTR *e;
 
-  static struct hash_table ht;
-
-  if (!ht.table)
+  if (typename_htab == NULL)
     {
-      static struct hash_table *h = &ht;
-
-      hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare);
-      ggc_add_tree_hash_table_root (&h, 1);
+      typename_htab = htab_create_ggc (61, &typename_hash, 
+                                      &typename_compare, NULL);
     }
 
   /* Build the TYPENAME_TYPE.  */
@@ -5654,12 +5566,11 @@ build_typename_type (context, name, fullname, base_type)
   DECL_ARTIFICIAL (d) = 1;
 
   /* See if we already have this type.  */
-  e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0);
-  if (e)
-    t = (tree) e->key;
+  e = htab_find_slot (typename_htab, t, INSERT);
+  if (*e)
+    t = (tree) *e;
   else
-    /* Insert the type into the table.  */
-    hash_lookup (&ht, t, /*create=*/true, /*copy=*/0);
+    *e = t;
 
   return t;
 }
@@ -5890,7 +5801,7 @@ unqualified_namespace_lookup (name, flags, spacesp)
   tree initial = current_decl_namespace ();
   tree scope = initial;
   tree siter;
-  struct binding_level *level;
+  struct cp_binding_level *level;
   tree val = NULL_TREE;
 
   if (spacesp)
@@ -6238,7 +6149,7 @@ tree
 lookup_name_current_level (name)
      tree name;
 {
-  struct binding_level *b;
+  struct cp_binding_level *b;
   tree t = NULL_TREE;
 
   b = current_binding_level;
@@ -6284,7 +6195,7 @@ lookup_type_current_level (name)
   if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
       && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
     {
-      struct binding_level *b = current_binding_level;
+      struct cp_binding_level *b = current_binding_level;
       while (1)
        {
          if (purpose_member (name, b->type_shadowed))
@@ -6476,10 +6387,6 @@ cxx_init_decl_processing ()
   /* Fill in back-end hooks.  */
   lang_missing_noreturn_ok_p = &cp_missing_noreturn_ok_p;
 
-  cp_parse_init ();
-  init_decl2 ();
-  init_pt ();
-
   /* Create the global variables.  */
   push_to_top_level ();
 
@@ -6554,9 +6461,6 @@ cxx_init_decl_processing ()
   boolean_true_node = build_int_2 (1, 0);
   TREE_TYPE (boolean_true_node) = boolean_type_node;
 
-  signed_size_zero_node = build_int_2 (0, 0);
-  TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype));
-
   empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
 
 #if 0
@@ -6666,36 +6570,6 @@ cxx_init_decl_processing ()
      say -fwritable-strings?  */
   if (flag_writable_strings)
     flag_const_strings = 0;
-
-  /* Add GC roots for all of our global variables.  */
-  ggc_add_tree_root (c_global_trees, ARRAY_SIZE (c_global_trees));
-  ggc_add_tree_root (cp_global_trees, ARRAY_SIZE (cp_global_trees));
-  ggc_add_tree_root (&integer_three_node, 1);
-  ggc_add_tree_root (&integer_two_node, 1);
-  ggc_add_tree_root (&signed_size_zero_node, 1);
-  ggc_add_tree_root (&size_one_node, 1);
-  ggc_add_tree_root (&size_zero_node, 1);
-  ggc_add_root (&global_binding_level, 1, sizeof global_binding_level,
-               mark_binding_level);
-  ggc_add_root (&scope_chain, 1, sizeof scope_chain, &mark_saved_scope);
-  ggc_add_tree_root (&static_ctors, 1);
-  ggc_add_tree_root (&static_dtors, 1);
-  ggc_add_tree_root (&lastiddecl, 1);
-
-  ggc_add_tree_root (&last_function_parms, 1);
-  ggc_add_tree_root (&error_mark_list, 1);
-
-  ggc_add_tree_root (&global_namespace, 1);
-  ggc_add_tree_root (&global_type_node, 1);
-  ggc_add_tree_root (&anonymous_namespace_name, 1);
-
-  ggc_add_tree_root (&got_object, 1);
-  ggc_add_tree_root (&got_scope, 1);
-
-  ggc_add_tree_root (&current_lang_name, 1);
-  ggc_add_tree_root (&static_aggregates, 1);
-  ggc_add_tree_root (&free_bindings, 1);
-  ggc_add_tree_root (&incomplete_vars, 1);
 }
 
 /* Generate an initializer for a function naming variable from
@@ -8017,7 +7891,7 @@ maybe_inject_for_scope_var (decl)
 
   if (current_binding_level->is_for_scope)
     {
-      struct binding_level *outer
+      struct cp_binding_level *outer
        = current_binding_level->level_chain;
 
       /* Check to see if the same name is already bound at the outer
@@ -10097,7 +9971,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
 
   if (decl_context == NORMAL && !toplevel_bindings_p ())
     {
-      struct binding_level *b = current_binding_level;
+      struct cp_binding_level *b = current_binding_level;
       current_binding_level = b->level_chain;
       if (current_binding_level != 0 && toplevel_bindings_p ())
        decl_context = PARM;
@@ -12804,7 +12678,7 @@ xref_tag (code_type_node, name, globalize)
   enum tag_types tag_code;
   enum tree_code code;
   register tree ref, t;
-  struct binding_level *b = current_binding_level;
+  struct cp_binding_level *b = current_binding_level;
   tree attributes = NULL_TREE;
   tree context = NULL_TREE;
 
@@ -13000,14 +12874,14 @@ xref_tag (code_type_node, name, globalize)
        }
       else
        {
-         struct binding_level *old_b = class_binding_level;
+         struct cp_binding_level *old_b = class_binding_level;
 
          ref = make_aggr_type (code);
          TYPE_CONTEXT (ref) = context;
 
 #ifdef NONNESTED_CLASSES
          /* Class types don't nest the way enums do.  */
-         class_binding_level = (struct binding_level *)0;
+         class_binding_level = (struct cp_binding_level *)0;
 #endif
          pushtag (name, ref, globalize);
          class_binding_level = old_b;
@@ -13239,7 +13113,7 @@ start_enum (name)
      tree name;
 {
   register tree enumtype = NULL_TREE;
-  struct binding_level *b = current_binding_level;
+  struct cp_binding_level *b = current_binding_level;
 
   /* If this is the real definition for a previous forward reference,
      fill in the contents in the same object that used to be the
@@ -13586,7 +13460,7 @@ start_function (declspecs, declarator, attrs, flags)
   extern int have_extern_spec;
   extern int used_extern_spec;
   int doing_friend = 0;
-  struct binding_level *bl;
+  struct cp_binding_level *bl;
   tree current_function_parms;
 
   /* Sanity check.  */
@@ -13810,12 +13684,8 @@ start_function (declspecs, declarator, attrs, flags)
 
   /* If we are (erroneously) defining a function that we have already
      defined before, wipe out what we knew before.  */
-  if (!DECL_PENDING_INLINE_P (decl1)
-      && DECL_SAVED_FUNCTION_DATA (decl1))
-    {
-      free (DECL_SAVED_FUNCTION_DATA (decl1));
-      DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
-    }
+  if (!DECL_PENDING_INLINE_P (decl1))
+    DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
 
   if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
     {
@@ -14024,7 +13894,7 @@ static void
 save_function_data (decl)
      tree decl;
 {
-  struct cp_language_function *f;
+  struct language_function *f;
 
   /* Save the language-specific per-function data so that we can
      get it back when we really expand this function.  */
@@ -14032,9 +13902,9 @@ save_function_data (decl)
                      19990908);
 
   /* Make a copy.  */
-  f = ((struct cp_language_function *)
-       xmalloc (sizeof (struct cp_language_function)));
-  memcpy (f, cp_function_chain, sizeof (struct cp_language_function));
+  f = ((struct language_function *)
+       ggc_alloc (sizeof (struct language_function)));
+  memcpy (f, cp_function_chain, sizeof (struct language_function));
   DECL_SAVED_FUNCTION_DATA (decl) = f;
 
   /* Clear out the bits we don't need.  */
@@ -14105,7 +13975,6 @@ begin_destructor_body ()
      appropriately, so we just assume that we always need to
      initialize the vtables.)  */
   finish_if_stmt_cond (boolean_true_node, if_stmt);
-  current_vcalls_possible_p = &IF_COND (if_stmt);
 
   compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
 
@@ -14688,10 +14557,10 @@ void
 cxx_push_function_context (f)
      struct function *f;
 {
-  struct cp_language_function *p
-    = ((struct cp_language_function *)
-       xcalloc (1, sizeof (struct cp_language_function)));
-  f->language = (struct language_function *) p;
+  struct language_function *p
+    = ((struct language_function *)
+       ggc_alloc_cleared (sizeof (struct language_function)));
+  f->language = p;
 
   /* It takes an explicit call to expand_body to generate RTL for a
      function.  */
@@ -14709,137 +14578,27 @@ void
 cxx_pop_function_context (f)
      struct function *f;
 {
-  if (f->language)
-    {
-      struct cp_language_function *cp =
-       (struct cp_language_function *) f->language;
-      if (cp->x_local_names)
-       VARRAY_FREE (cp->x_local_names);
-      free (f->language);
-    }
   f->language = 0;
 }
 
-/* Mark P for GC.  */
-
-static void
-mark_lang_function (p)
-     struct cp_language_function *p;
-{
-  if (!p)
-    return;
-
-  mark_c_language_function (&p->base);
-
-  ggc_mark_tree (p->x_dtor_label);
-  ggc_mark_tree (p->x_current_class_ptr);
-  ggc_mark_tree (p->x_current_class_ref);
-  ggc_mark_tree (p->x_eh_spec_block);
-  ggc_mark_tree_varray (p->x_local_names);
-
-  mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses);
-  mark_binding_level (&p->bindings);
-  mark_pending_inlines (&p->unparsed_inlines);
-}
+/* Return which tree structure is used by T, or TS_CP_GENERIC if T is
+   one of the language-independent trees.  */
 
-/* Mark the language-specific data in F for GC.  */
-
-void
-cxx_mark_function_context (f)
-     struct function *f;
-{
-  mark_lang_function ((struct cp_language_function *) f->language);
-}
-
-void
-cxx_mark_tree (t)
-     tree t;
+enum cp_tree_node_structure_enum
+cp_tree_node_structure (t)
+     union lang_tree_node *t;
 {
-  enum tree_code code = TREE_CODE (t);
-  if (code == IDENTIFIER_NODE)
+  switch (TREE_CODE (&t->generic))
     {
-      struct lang_identifier *li = (struct lang_identifier *) t;
-      struct lang_id2 *li2 = li->x;
-      ggc_mark_tree (li->namespace_bindings);
-      ggc_mark_tree (li->bindings);
-      ggc_mark_tree (li->class_value);
-      ggc_mark_tree (li->class_template_info);
-
-      if (li2)
-       {
-         ggc_mark_tree (li2->label_value);
-         ggc_mark_tree (li2->implicit_decl);
-         ggc_mark_tree (li2->error_locus);
-       }
-    }
-  else if (code == CPLUS_BINDING)
-    {
-      if (BINDING_HAS_LEVEL_P (t))
-       mark_binding_level (&BINDING_LEVEL (t));
-      else
-       ggc_mark_tree (BINDING_SCOPE (t));
-      ggc_mark_tree (BINDING_VALUE (t));
-    }
-  else if (code == OVERLOAD)
-    ggc_mark_tree (OVL_FUNCTION (t));
-  else if (code == TEMPLATE_PARM_INDEX)
-    ggc_mark_tree (TEMPLATE_PARM_DECL (t));
-  else if (TREE_CODE_CLASS (code) == 'd')
-    {
-      struct lang_decl *ld = DECL_LANG_SPECIFIC (t);
-
-      if (ld)
-       {
-         ggc_mark (ld);
-         c_mark_lang_decl (&ld->decl_flags.base);
-         if (!DECL_GLOBAL_CTOR_P (t)
-             && !DECL_GLOBAL_DTOR_P (t)
-             && !DECL_THUNK_P (t)
-             && !DECL_DISCRIMINATOR_P (t))
-           ggc_mark_tree (ld->decl_flags.u2.access);
-         else if (DECL_THUNK_P (t))
-           ggc_mark_tree (ld->decl_flags.u2.vcall_offset);
-         if (TREE_CODE (t) != NAMESPACE_DECL)
-           ggc_mark_tree (ld->decl_flags.u.template_info);
-         else
-           mark_binding_level (&NAMESPACE_LEVEL (t));
-         if (CAN_HAVE_FULL_LANG_DECL_P (t))
-           {
-             ggc_mark_tree (ld->befriending_classes);
-             ggc_mark_tree (ld->context);
-             ggc_mark_tree (ld->cloned_function);
-             if (TREE_CODE (t) == TYPE_DECL)
-               ggc_mark_tree (ld->u.sorted_fields);
-             else if (TREE_CODE (t) == FUNCTION_DECL
-                      && !DECL_PENDING_INLINE_P (t))
-               mark_lang_function (DECL_SAVED_FUNCTION_DATA (t));
-           }
-       }
-    }
-  else if (TREE_CODE_CLASS (code) == 't')
-    {
-      struct lang_type *lt = TYPE_LANG_SPECIFIC (t);
-
-      if (lt && !(TREE_CODE (t) == POINTER_TYPE
-                 && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))
-       {
-         ggc_mark (lt);
-         ggc_mark_tree (lt->primary_base);
-         ggc_mark_tree (lt->vfields);
-         ggc_mark_tree (lt->vbases);
-         ggc_mark_tree (lt->tags);
-         ggc_mark_tree (lt->size);
-         ggc_mark_tree (lt->pure_virtuals);
-         ggc_mark_tree (lt->friend_classes);
-         ggc_mark_tree (lt->rtti);
-         ggc_mark_tree (lt->methods);
-         ggc_mark_tree (lt->template_info);
-         ggc_mark_tree (lt->befriending_classes);
-       }
-      else if (lt)
-       /* In the case of pointer-to-member function types, the
-          TYPE_LANG_SPECIFIC is really just a tree.  */
-       ggc_mark_tree ((tree) lt);
+    case DEFAULT_ARG:          return TS_CP_IDENTIFIER;
+    case IDENTIFIER_NODE:      return TS_CP_IDENTIFIER;
+    case CPLUS_BINDING:                return TS_CP_BINDING;
+    case OVERLOAD:             return TS_CP_OVERLOAD;
+    case TEMPLATE_PARM_INDEX:  return TS_CP_TPI;
+    case PTRMEM_CST:           return TS_CP_PTRMEM;
+    case WRAPPER:              return TS_CP_WRAPPER;
+    case SRCLOC:               return TS_CP_SRCLOC;
+    default:                   return TS_CP_GENERIC;
     }
 }
 
@@ -14869,3 +14628,6 @@ cp_missing_noreturn_ok_p (decl)
   /* A missing noreturn is ok for the `main' function.  */
   return DECL_MAIN_P (decl);
 }
+
+#include "gt-cp-decl.h"
+#include "gtype-cp.h"
index 2316f06728d9b5e3ca2eba711e72022a7e2f5751..eeac80f29ad4afb3f0bce332bca649dacf445eaf 100644 (file)
@@ -36,13 +36,13 @@ extern tree grokdeclarator PARAMS ((tree, tree, enum decl_context, int,
 
 /* Parsing a function declarator leaves a list of parameter names
    or a chain or parameter decls here.  */
-extern tree last_function_parms;
+extern GTY(()) tree last_function_parms;
 
 /* A list of objects which have constructors or destructors
    which reside in the global scope.  The decl is stored in
    the TREE_VALUE slot and the initializer is stored
    in the TREE_PURPOSE slot.  */
-extern tree static_aggregates;
+extern GTY(()) tree static_aggregates;
 
 #ifdef DEBUG_CP_BINDING_LEVELS
 /* Purely for debugging purposes.  */
index 238bde8d900d3e213cd9366833e4f517c6b5477a..c63c48b67bcd8141fa2d517c9d790a1e0543e8f6 100644 (file)
@@ -95,13 +95,13 @@ static tree get_guard_bits PARAMS ((tree));
 /* A list of static class variables.  This is needed, because a
    static class variable can be declared inside the class without
    an initializer, and then initialized, statically, outside the class.  */
-static varray_type pending_statics;
+static GTY(()) varray_type pending_statics;
 #define pending_statics_used \
   (pending_statics ? pending_statics->elements_used : 0)
 
 /* A list of functions which were declared inline, but which we
    may need to emit outline anyway.  */
-static varray_type deferred_fns;
+static GTY(()) varray_type deferred_fns;
 #define deferred_fns_used \
   (deferred_fns ? deferred_fns->elements_used : 0)
 
@@ -2712,6 +2712,7 @@ start_objects (method_type, initp)
     DECL_GLOBAL_CTOR_P (current_function_decl) = 1;
   else
     DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
+  DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1;
   GLOBAL_INIT_PRIORITY (current_function_decl) = initp;
 
   body = begin_compound_stmt (/*has_no_scope=*/0);
@@ -2768,17 +2769,17 @@ finish_objects (method_type, initp, body)
 #define SSDF_IDENTIFIER "__static_initialization_and_destruction"
 
 /* The declaration for the __INITIALIZE_P argument.  */
-static tree initialize_p_decl;
+static GTY(()) tree initialize_p_decl;
 
 /* The declaration for the __PRIORITY argument.  */
-static tree priority_decl;
+static GTY(()) tree priority_decl;
 
 /* The declaration for the static storage duration function.  */
-static tree ssdf_decl;
+static GTY(()) tree ssdf_decl;
 
 /* All the static storage duration functions created in this
    translation unit.  */
-static varray_type ssdf_decls;
+static GTY(()) varray_type ssdf_decls;
 
 /* A map from priority levels to information about that priority
    level.  There may be many such levels, so efficient lookup is
@@ -5280,15 +5281,4 @@ handle_class_head (aggr, scope, id, defn_p, new_type_p)
   return decl;
 }
 
-/* Initialize decl2.c.  */
-
-void
-init_decl2 ()
-{
-  ggc_add_tree_varray_root (&deferred_fns, 1);
-  ggc_add_tree_varray_root (&pending_statics, 1);
-  ggc_add_tree_varray_root (&ssdf_decls, 1);
-  ggc_add_tree_root (&ssdf_decl, 1);
-  ggc_add_tree_root (&priority_decl, 1);
-  ggc_add_tree_root (&initialize_p_decl, 1);
-}
+#include "gt-cp-decl2.h"
index 7be5acbd3728a5474f2c17074eab393291f1a254..dad7df6d3b0c94c68d569637ca4f18165f2decdb 100644 (file)
@@ -1434,6 +1434,12 @@ retrofit_lang_decl (t)
 
   ld = (struct lang_decl *) ggc_alloc_cleared (size);
 
+  ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
+  ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
+  ld->decl_flags.u2sel = 0;
+  if (ld->decl_flags.can_be_full)
+    ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
+
   DECL_LANG_SPECIFIC (t) = ld;
   if (current_lang_name == lang_name_cplusplus)
     SET_DECL_LANGUAGE (t, lang_cplusplus);
@@ -1498,7 +1504,10 @@ copy_lang_type (node)
   if (! TYPE_LANG_SPECIFIC (node))
     return;
 
-  size = sizeof (struct lang_type);
+  if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class)
+    size = sizeof (struct lang_type);
+  else
+    size = sizeof (struct lang_type_ptrmem);
   lt = (struct lang_type *) ggc_alloc (size);
   memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
   TYPE_LANG_SPECIFIC (node) = lt;
@@ -1538,6 +1547,7 @@ cxx_make_type (code)
            ggc_alloc_cleared (sizeof (struct lang_type)));
 
       TYPE_LANG_SPECIFIC (t) = pi;
+      pi->u.c.h.is_lang_type_class = 1;
 
 #ifdef GATHER_STATISTICS
       tree_node_counts[(int)lang_type] += 1;
index 9f86833777b8980a4e58a4fcc336d47573f0f870..15de16866b72cb0dfd009f22ada14f37215a2ed1 100644 (file)
@@ -68,15 +68,15 @@ typedef unsigned long RID_BIT_TYPE; /* assumed at least 32 bits */
    yylex must look this up to detect typedefs, which get token type TYPENAME,
    so it is left around in case the identifier is not a typedef but is
    used in a context which makes it a reference to a variable.  */
-extern tree lastiddecl;
+extern GTY(()) tree lastiddecl;
 
 /* Back-door communication channel to the lexer.  */
 extern int looking_for_typename;
 extern int looking_for_template;
 
 /* Tell the lexer where to look for names.  */
-extern tree got_scope;
-extern tree got_object;
+extern GTY(()) tree got_scope;
+extern GTY(()) tree got_object;
 
 /* Pending language change.
    Positive is push count, negative is pop count.  */
index 8365b0354fac111b3e729622ea5f14910dcb27cb..12888ace7d8ec5bc1a87a598b0e5a49ae1cd745e 100644 (file)
@@ -2166,6 +2166,7 @@ write_substitution (seq_id)
 static inline void
 start_mangling ()
 {
+  VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions");
   obstack_free (&G.name_obstack, obstack_base (&G.name_obstack));
 }
 
@@ -2175,7 +2176,7 @@ static inline const char *
 finish_mangling ()
 {
   /* Clear all the substitutions.  */
-  VARRAY_POP_ALL (G.substitutions);
+  G.substitutions = 0;
 
   /* Null-terminate the string.  */
   write_char ('\0');
@@ -2189,7 +2190,6 @@ void
 init_mangle ()
 {
   gcc_obstack_init (&G.name_obstack);
-  VARRAY_TREE_INIT (G.substitutions, 1, "mangling substitutions");
 
   /* Cache these identifiers for quick comparison when checking for
      standard substitutions.  */
index b6abd0bfe7ae74b27291335aca637f356821bcf1..e815addccee720ba62213eb41256b2394683cca2 100644 (file)
@@ -103,21 +103,21 @@ int have_extern_spec;
 int used_extern_spec;
 
 /* List of types and structure classes of the current declaration.  */
-static tree current_declspecs;
+static GTY(()) tree current_declspecs;
 
 /* List of prefix attributes in effect.
    Prefix attributes are parsed by the reserved_declspecs and declmods
    rules.  They create a list that contains *both* declspecs and attrs.  */
 /* ??? It is not clear yet that all cases where an attribute can now appear in
    a declspec list have been updated.  */
-static tree prefix_attributes;
+static GTY(()) tree prefix_attributes;
 
 /* When defining an enumeration, this is the type of the enumeration.  */
-static tree current_enum_type;
+static GTY(()) tree current_enum_type;
 
 /* When parsing a conversion operator name, this is the scope of the
    operator itself.  */
-static tree saved_scopes;
+static GTY(()) tree saved_scopes;
 
 static tree empty_parms PARAMS ((void));
 static tree parse_decl0 PARAMS ((tree, tree, tree, tree, int));
@@ -263,19 +263,11 @@ check_class_key (key, aggr)
             : key == record_type_node ? "struct" : "class", aggr);
 }
 
-void
-cp_parse_init ()
-{
-  ggc_add_tree_root (&current_declspecs, 1);
-  ggc_add_tree_root (&prefix_attributes, 1);
-  ggc_add_tree_root (&current_enum_type, 1);
-  ggc_add_tree_root (&saved_scopes, 1);
-}
 %}
 
 %start program
 
-%union {
+%union { GTY(())
   long itype; 
   tree ttype; 
   char *strtype; 
@@ -388,7 +380,7 @@ cp_parse_init ()
 %type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME
 %type <ttype> expr_no_commas expr_no_comma_rangle
 %type <ttype> cast_expr unary_expr primary STRING
-%type <ttype> reserved_declspecs boolean.literal
+%type <ttype> reserved_declspecs boolean_literal
 %type <ttype> reserved_typespecquals
 %type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
 %type <ttype> init initlist maybeasm maybe_init defarg defarg1
@@ -436,13 +428,13 @@ cp_parse_init ()
 %token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER
 %token <pi> PRE_PARSED_FUNCTION_DECL 
 %type <ttype> component_constructor_declarator
-%type <ttype> fn.def2 return_id constructor_declarator
-%type <ttype> .begin_function_body
+%type <ttype> fn_def2 return_id constructor_declarator
+%type <ttype> begin_function_body_
 %type <ttype> class_head class_head_apparent_template
 %type <ftype> class_head_decl class_head_defn
 %type <ttype> base_class_list
 %type <ttype> base_class_access_list
-%type <ttype> base_class maybe_base_class_list base_class.1
+%type <ttype> base_class maybe_base_class_list base_class_1
 %type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers
 %type <ttype> operator_name
 %type <ttype> object aggr
@@ -470,7 +462,7 @@ cp_parse_init ()
 %token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN
 %type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN
 %type <ttype> handler_args
-%type <ttype> self_template_type .finish_template_type
+%type <ttype> self_template_type finish_template_type_
 
 %token NSNAME
 %type <ttype> NSNAME
@@ -815,7 +807,7 @@ eat_saved_input:
    mem-initializer-list, so we open one there and suppress the one that
    actually corresponds to the curly braces.  */
 function_body:
-         .begin_function_body ctor_initializer_opt save_lineno '{'
+         begin_function_body_ ctor_initializer_opt save_lineno '{'
                { $<ttype>$ = begin_compound_stmt (/*has_no_scope=*/1); }
          compstmtend 
                 {
@@ -909,7 +901,7 @@ component_constructor_declarator:
 
 /* more C++ complexity.  See component_decl for a comment on the
    reduce/reduce conflict introduced by these rules.  */
-fn.def2:
+fn_def2:
          declmods component_constructor_declarator
                { $$ = parse_method ($2, $1.t, $1.lookups);
                 rest_of_mdef:
@@ -963,7 +955,7 @@ base_init:
                }
        ;
 
-.begin_function_body:
+begin_function_body_:
          /* empty */
                {
                  $$ = begin_function_body ();
@@ -1095,10 +1087,10 @@ end_explicit_instantiation:
 
 template_type:
          PTYPENAME '<' template_arg_list_opt template_close_bracket
-           .finish_template_type
+           finish_template_type_
                 { $$ = $5; }
        | TYPENAME  '<' template_arg_list_opt template_close_bracket
-           .finish_template_type
+           finish_template_type_
                 { $$ = $5; }
        | self_template_type
        ;
@@ -1106,17 +1098,17 @@ template_type:
 apparent_template_type:
          template_type
        | identifier '<' template_arg_list_opt '>'
-           .finish_template_type
+           finish_template_type_
                { $$ = $5; }
         ;
 
 self_template_type:
          SELFNAME  '<' template_arg_list_opt template_close_bracket
-           .finish_template_type
+           finish_template_type_
                 { $$ = $5; }
        ;
 
-.finish_template_type:
+finish_template_type_:
                 { 
                  if (yychar == YYEMPTY)
                    yychar = YYLEX;
@@ -1615,7 +1607,7 @@ primary:
                    $$ = finish_id_expr ($1);
                }               
        | CONSTANT
-       | boolean.literal
+       | boolean_literal
        | STRING
                {
                  $$ = fix_string_type ($$);
@@ -1813,7 +1805,7 @@ delete:
                { got_scope = NULL_TREE; $$ = 1; }
        ;
 
-boolean.literal:
+boolean_literal:
          CXX_TRUE
                { $$ = boolean_true_node; }
        | CXX_FALSE
@@ -2372,7 +2364,6 @@ structsp:
                }
          pending_inlines
                 {
-                 finish_inline_definitions ();
                  $$.t = $<ttype>8;
                  $$.new_type_flag = 1; 
                }
@@ -2550,13 +2541,13 @@ base_class_list:
        ;
 
 base_class:
-         base_class.1
+         base_class_1
                { $$ = finish_base_specifier (access_default_node, $1); }
-       | base_class_access_list see_typename base_class.1
+       | base_class_access_list see_typename base_class_1
                 { $$ = finish_base_specifier ($1, $3); }
        ;
 
-base_class.1:
+base_class_1:
          typename_sub
                { if (!TYPE_P ($$))
                    $$ = error_mark_node; }
@@ -2632,13 +2623,13 @@ component_decl:
                  yyungetc ('}', 0); }
        /* C++: handle constructors, destructors and inline functions */
        /* note that INLINE is like a TYPESPEC */
-       | fn.def2 ':' /* base_init compstmt */
+       | fn_def2 ':' /* base_init compstmt */
                { $$ = finish_method ($$); }
-       | fn.def2 TRY /* base_init compstmt */
+       | fn_def2 TRY /* base_init compstmt */
                { $$ = finish_method ($$); }
-       | fn.def2 RETURN_KEYWORD /* base_init compstmt */
+       | fn_def2 RETURN_KEYWORD /* base_init compstmt */
                { $$ = finish_method ($$); }
-       | fn.def2 '{' /* nodecls compstmt */
+       | fn_def2 '{' /* nodecls compstmt */
                { $$ = finish_method ($$); }
        | ';'
                { $$ = NULL_TREE; }
@@ -4026,3 +4017,5 @@ free_parser_stacks ()
       free (malloced_yyvs);
     }
 }
+
+#include "gt-cp-parse.h"
index e54ab8e3ebc93d1cae48c776e29f7b5e55e7353b..873e5a3f1416deb6d0670c63fdd0cafe797e05d0 100644 (file)
@@ -56,17 +56,17 @@ extern struct obstack permanent_obstack;
    the instantiate request occurred; the TREE_VALUE is a either a DECL
    (for a function or static data member), or a TYPE (for a class)
    indicating what we are hoping to instantiate.  */
-static tree pending_templates;
+static GTY(()) tree pending_templates;
 static tree last_pending_template;
 
 int processing_template_parmlist;
 static int template_header_count;
 
-static tree saved_trees;
-static varray_type inline_parm_levels;
+static GTY(()) tree saved_trees;
+static GTY(()) varray_type inline_parm_levels;
 static size_t inline_parm_levels_used;
 
-static tree current_tinst_level;
+static GTY(()) tree current_tinst_level;
 
 /* A map from local variable declarations in the body of the template
    presently being instantiated to the corresponding instantiated
@@ -170,16 +170,6 @@ static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
 static void copy_default_args_to_explicit_spec PARAMS ((tree));
 static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
 
-/* Called once to initialize pt.c.  */
-
-void
-init_pt ()
-{
-  ggc_add_tree_root (&pending_templates, 1);
-  ggc_add_tree_root (&saved_trees, 1);
-  ggc_add_tree_root (&current_tinst_level, 1);
-}
-
 /* Do any processing required when DECL (a member template declaration
    using TEMPLATE_PARAMETERS as its innermost parameter list) is
    finished.  Returns the TEMPLATE_DECL corresponding to DECL, unless
@@ -10426,3 +10416,5 @@ invalid_nontype_parm_type_p (type, complain)
               type);
   return 1;
 }
+
+#include "gt-cp-pt.h"
index fe2eb62601bba3159298b829285369c428fa9f44..6aacebfdd604171b5e65d3628a76b5caaeeb1ed8 100644 (file)
@@ -42,8 +42,8 @@ static void open_repo_file PARAMS ((const char *));
 static char *afgets PARAMS ((FILE *));
 static void reopen_repo_file_for_write PARAMS ((void));
 
-static tree pending_repo;
-static tree original_repo;
+static GTY(()) tree pending_repo;
+static GTY(()) tree original_repo;
 static char *repo_name;
 static FILE *repo_file;
 
@@ -320,8 +320,6 @@ init_repo (filename)
   if (! flag_use_repository)
     return;
 
-  ggc_add_tree_root (&pending_repo, 1);
-  ggc_add_tree_root (&original_repo, 1);
   gcc_obstack_init (&temporary_obstack);
 
   open_repo_file (filename);
@@ -458,3 +456,5 @@ finish_repo ()
   if (repo_file)
     fclose (repo_file);
 }
+
+#include "gt-cp-repo.h"
index 38841589dfd257bc503fa05e7b7c9fe164b0eb01..9617796dfbde36aa241c7dcf5b09fa360c9c07e1 100644 (file)
@@ -31,6 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "flags.h"
 #include "rtl.h"
 #include "output.h"
+#include "ggc.h"
 #include "toplev.h"
 
 #define obstack_chunk_alloc xmalloc
@@ -1673,9 +1674,6 @@ bfs_walk (binfo, fn, qfn, data)
        }
     }
 
-  /* Clean up.  */
-  VARRAY_FREE (bfs_bases);
-
   return rval;
 }
 
index ce1cbaca68a4532ebc128901c7a8e0819cb414fc..bbc22037ecef153ace1943ba945d3d39b3cdf8b1 100644 (file)
@@ -97,7 +97,7 @@ stmt_tree
 current_stmt_tree ()
 {
   return (cfun 
-         ? &cfun->language->x_stmt_tree 
+         ? &cfun->language->base.x_stmt_tree 
          : &scope_chain->x_stmt_tree);
 }
 
@@ -109,7 +109,7 @@ int
 anon_aggr_type_p (node)
      tree node;
 {
-  return (CLASS_TYPE_P (node) && TYPE_LANG_SPECIFIC(node)->anon_aggr);
+  return ANON_AGGR_TYPE_P (node);
 }
 
 /* Finish a scope.  */
@@ -1131,7 +1131,7 @@ finish_mem_initializers (init_list)
 tree *
 current_scope_stmt_stack ()
 {
-  return &cfun->language->x_scope_stmt_stack;
+  return &cfun->language->base.x_scope_stmt_stack;
 }
 
 /* Finish a parenthesized expression EXPR.  */
@@ -1882,16 +1882,6 @@ begin_inline_definitions ()
     do_pending_inlines ();
 }
 
-/* Finish processing the inline function definitions cached during the
-   processing of a class definition.  */
-
-void
-finish_inline_definitions ()
-{
-  if (current_class_type == NULL_TREE)
-    clear_inline_text_obstack (); 
-}
-
 /* Finish processing the declaration of a member class template
    TYPES whose template parameters are given by PARMS.  */
 
@@ -2475,10 +2465,7 @@ genrtl_start_function (fn)
          function; we need the named return value info for
          cp_copy_res_decl_for_inlining.  */
       if (! DECL_INLINE (fn))
-       {
-         free (DECL_SAVED_FUNCTION_DATA (fn));
-         DECL_SAVED_FUNCTION_DATA (fn) = NULL;
-       }
+       DECL_SAVED_FUNCTION_DATA (fn) = NULL;
     }
 
   /* Keep track of how many functions we're presently expanding.  */
index c1aa95438996057a14bba41b26f38e2eb8ce5240..d56f6117392ccb18dc8ae14d564089e0c429a8c9 100644 (file)
@@ -50,12 +50,12 @@ Boston, MA 02111-1307, USA.  */
    backtracking.  */
 
 /* fifo of tokens recognized and available to parser.  */
-struct token
+struct token GTY(())
 {
   /* The values for YYCHAR will fit in a short.  */
   short                yychar;
   unsigned int lineno;
-  YYSTYPE      yylval;
+  YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
 };
 
 /* Since inline methods can refer to text which has not yet been seen,
@@ -68,7 +68,14 @@ struct token
    This function's FUNCTION_DECL will have a bit set in its common so
    that we know to watch out for it.  */
 
-struct unparsed_text
+#define TOKEN_CHUNK_SIZE 20
+struct token_chunk GTY(())
+{
+  struct token_chunk *next;
+  struct token toks[TOKEN_CHUNK_SIZE];
+};
+
+struct unparsed_text GTY(())
 {
   struct unparsed_text *next;  /* process this one next */
   tree decl;           /* associated declaration */
@@ -76,26 +83,31 @@ struct unparsed_text
   int lineno;          /* line number we got the text from */
   int interface;       /* remembering interface_unknown and interface_only */
 
-  struct token *pos;   /* current position, when rescanning */
-  struct token *limit; /* end of saved text */
+  struct token_chunk * tokens; /* Start of the token list.  */
+
+  struct token_chunk *last_chunk; /* End of the token list.  */
+  short last_pos;      /* Number of tokens used in the last chunk of 
+                          TOKENS. */
+
+  short cur_pos;       /* Current token in 'cur_chunk', when rescanning.  */
+  struct token_chunk *cur_chunk;  /* Current chunk, when rescanning.  */
 };
 
 /* Stack of state saved off when we return to an inline method or
    default argument that has been stored for later parsing.  */
-struct feed
+struct feed GTY(())
 {
   struct unparsed_text *input;
   const char *filename;
   int lineno;
   int yychar;
-  YYSTYPE yylval;
+  YYSTYPE GTY ((desc ("%1.yychar"))) yylval;
   int first_token;
-  struct obstack token_obstack;
+  struct obstack GTY ((skip (""))) token_obstack;
   struct feed *next;
-};  
+};
 
-static struct obstack feed_obstack;
-static struct feed *feed;
+static GTY(()) struct feed *feed;
 
 static SPEW_INLINE void do_aggr PARAMS ((void));
 static SPEW_INLINE int identifier_type PARAMS ((tree));
@@ -107,25 +119,32 @@ static int read_token PARAMS ((struct token *));
 
 static SPEW_INLINE int num_tokens PARAMS ((void));
 static SPEW_INLINE struct token *nth_token PARAMS ((int));
-static SPEW_INLINE int add_token PARAMS ((struct token *));
+static SPEW_INLINE int next_token PARAMS ((struct token *));
 static SPEW_INLINE int shift_token PARAMS ((void));
 static SPEW_INLINE void push_token PARAMS ((struct token *));
 static SPEW_INLINE void consume_token PARAMS ((void));
 static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *));
 
 static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *));
-static SPEW_INLINE void snarf_block PARAMS ((const char *, int));
+static SPEW_INLINE struct token * space_for_token 
+  PARAMS ((struct unparsed_text *t));
+static SPEW_INLINE struct token * remove_last_token
+  PARAMS ((struct unparsed_text *t));
+static struct unparsed_text * alloc_unparsed_text
+  PARAMS ((const char *fn, int li, tree decl, int interface));
+
+static void snarf_block PARAMS ((struct unparsed_text *t));
 static tree snarf_defarg PARAMS ((void));
 static int frob_id PARAMS ((int, int, tree *));
 
 /* The list of inline functions being held off until we reach the end of
    the current class declaration.  */
-static struct unparsed_text *pending_inlines;
-static struct unparsed_text *pending_inlines_tail;
+static GTY(()) struct unparsed_text *pending_inlines;
+static GTY(()) struct unparsed_text *pending_inlines_tail;
 
 /* The list of previously-deferred inline functions currently being parsed.
    This exists solely to be a GC root.  */
-static struct unparsed_text *processing_these_inlines;
+static GTY(()) struct unparsed_text *processing_these_inlines;
 
 static void begin_parsing_inclass_inline PARAMS ((struct unparsed_text *));
 
@@ -151,13 +170,8 @@ extern int yychar;         /*  the lookahead symbol                */
 extern YYSTYPE yylval;         /*  the semantic value of the           */
                                /*  lookahead symbol                    */
 /* The token fifo lives in this obstack.  */
-struct obstack token_obstack;
-int first_token;
-
-/* Sometimes we need to save tokens for later parsing.  If so, they are
-   stored on this obstack.  */
-struct obstack inline_text_obstack;
-char *inline_text_firstobj;
+static struct obstack token_obstack;
+static int first_token;
 
 /* When we see a default argument in a method declaration, we snarf it as
    text using snarf_defarg.  When we get up to namespace scope, we then go
@@ -168,35 +182,21 @@ char *inline_text_firstobj;
    the TREE_TYPE is the current_class_type, TREE_VALUE is the FUNCTION_DECL,
    and TREE_PURPOSE is the list unprocessed dependent functions.  */
 
-static tree defarg_fns;     /* list of functions with unprocessed defargs */
-static tree defarg_parm;    /* current default parameter */
-static tree defarg_depfns;  /* list of unprocessed fns met during current fn. */
-static tree defarg_fnsdone; /* list of fns with circular defargs */
+/* list of functions with unprocessed defargs */
+static GTY(()) tree defarg_fns;
+/* current default parameter */
+static GTY(()) tree defarg_parm;
+/* list of unprocessed fns met during current fn. */
+static GTY(()) tree defarg_depfns;
+/* list of fns with circular defargs */
+static GTY(()) tree defarg_fnsdone;
 
 /* Initialize obstacks. Called once, from cxx_init.  */
 
 void
 init_spew ()
 {
-  gcc_obstack_init (&inline_text_obstack);
-  inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
   gcc_obstack_init (&token_obstack);
-  gcc_obstack_init (&feed_obstack);
-  ggc_add_tree_root (&defarg_fns, 1);
-  ggc_add_tree_root (&defarg_parm, 1);
-  ggc_add_tree_root (&defarg_depfns, 1);
-  ggc_add_tree_root (&defarg_fnsdone, 1);
-
-  ggc_add_root (&pending_inlines, 1, sizeof (struct unparsed_text *),
-               mark_pending_inlines);
-  ggc_add_root (&processing_these_inlines, 1, sizeof (struct unparsed_text *),
-               mark_pending_inlines);
-}
-
-void
-clear_inline_text_obstack ()
-{
-  obstack_free (&inline_text_obstack, inline_text_firstobj);
 }
 
 /* Subroutine of read_token.  */
@@ -270,8 +270,6 @@ yylexstring (t)
 
       t->yylval.ttype = combine_strings (strings);
       last_token_id = t->yylval.ttype;
-
-      VARRAY_FREE (strings);
     }
 
   /* We will have always read one token too many.  */
@@ -396,10 +394,10 @@ feed_input (input)
     abort ();
 #endif
 
-  f = obstack_alloc (&feed_obstack, sizeof (struct feed));
+  f = ggc_alloc (sizeof (struct feed));
 
-  /* The token list starts just after the struct unparsed_text in memory.  */
-  input->pos = (struct token *) (input + 1);
+  input->cur_chunk = input->tokens;
+  input->cur_pos = 0;
 
 #ifdef SPEW_DEBUG
   if (spew_debug)
@@ -439,48 +437,12 @@ end_input ()
   token_obstack = f->token_obstack;
   feed = f->next;
 
-  obstack_free (&feed_obstack, f);
-
 #ifdef SPEW_DEBUG
   if (spew_debug)
     fprintf (stderr, "\treturning to %s:%d\n", input_filename, lineno);
 #endif
 }
 
-/* GC callback to mark memory pointed to by the pending inline queue.  */
-void
-mark_pending_inlines (pi)
-     PTR pi;
-{
-  struct unparsed_text *up = * (struct unparsed_text **)pi;
-
-  while (up)
-    {
-      struct token *t = (struct token *) (up + 1);
-      struct token *l = up->limit;
-
-      while (t < l)
-       {
-         /* Some of the possible values for yychar use yylval.code
-            instead of yylval.ttype.  We only have to worry about
-            yychars that could have been returned by read_token.  */
-         switch (t->yychar)
-           {
-           case '+':       case '-':       case '*':       case '/':
-           case '%':       case '&':       case '|':       case '^':
-           case '>':       case '<':       case LSHIFT:    case RSHIFT:
-           case ASSIGN:    case MIN_MAX:   case EQCOMPARE: case ARITHCOMPARE:
-             t++;
-             continue;
-           }
-         if (t->yylval.ttype)
-           ggc_mark_tree (t->yylval.ttype);
-         t++;
-       }
-      up = up->next;
-    }
-}
-  
 /* Token queue management.  */
 
 /* Return the number of tokens available on the fifo.  */
@@ -510,16 +472,24 @@ static const struct token Tpad = { EMPTY, 0 UNION_INIT_ZERO };
 
 /* Copy the next token into T and return its value.  */
 static SPEW_INLINE int
-add_token (t)
+next_token (t)
      struct token *t;
 {
   if (!feed)
     return read_token (t);
 
-  if (feed->input->pos < feed->input->limit)
+  if (feed->input->cur_chunk != feed->input->last_chunk
+      || feed->input->cur_pos != feed->input->last_pos)
     {
-      memcpy (t, feed->input->pos, sizeof (struct token));
-      return (feed->input->pos++)->yychar;
+      if (feed->input->cur_pos == TOKEN_CHUNK_SIZE)
+       {
+         feed->input->cur_chunk = feed->input->cur_chunk->next;
+         feed->input->cur_pos = 0;
+       }
+      memcpy (t, feed->input->cur_chunk->toks + feed->input->cur_pos, 
+             sizeof (struct token));
+      feed->input->cur_pos++;
+      return t->yychar;
     }
   
   memcpy (t, &Teosi, sizeof (struct token));
@@ -532,7 +502,7 @@ shift_token ()
 {
   size_t point = obstack_object_size (&token_obstack);
   obstack_blank (&token_obstack, sizeof (struct token));
-  return add_token ((struct token *) (obstack_base (&token_obstack) + point));
+  return next_token ((struct token *) (obstack_base (&token_obstack) + point));
 }
 
 /* Consume the next token out of the fifo.  */
@@ -1060,22 +1030,73 @@ process_next_inline (i)
       extract_interface_info ();
     }
 }
+\f
+/* Create a new token at the end of the token list in T.  */
+static SPEW_INLINE struct token *
+space_for_token (t)
+     struct unparsed_text *t;
+{
+  if (t->last_pos != TOKEN_CHUNK_SIZE)
+    return t->last_chunk->toks + (t->last_pos++);
 
+  t->last_chunk->next = ggc_alloc (sizeof (*t->last_chunk->next));
+  t->last_chunk = t->last_chunk->next;
+  t->last_chunk->next = NULL;
+  
+  t->last_pos = 1;
+  return t->last_chunk->toks;
+}
+
+/* Shrink the token list in T by one token.  */
+static SPEW_INLINE struct token *
+remove_last_token (t)
+     struct unparsed_text *t;
+{
+  struct token *result = t->last_chunk->toks + t->last_pos - 1;
+  if (t->last_pos == 0)
+    abort ();
+  t->last_pos--;
+  if (t->last_pos == 0 && t->last_chunk != t->tokens)
+    {
+      struct token_chunk **tc;
+      for (tc = &t->tokens; (*tc)->next != NULL; tc = &(*tc)->next)
+       ;
+      *tc = NULL;
+      t->last_pos = sizeof ((*tc)->toks) / sizeof ((*tc)->toks[0]);
+    }
+  return result;
+}
+
+/* Allocate an 'unparsed_text' structure, ready to use space_for_token.  */
+static struct unparsed_text *
+alloc_unparsed_text (fn, li, decl, interface)
+     const char *fn;
+     int li;
+     tree decl;
+     int interface;
+{
+  struct unparsed_text *r;
+  r = ggc_alloc_cleared (sizeof (*r));
+  r->decl = decl;
+  r->filename = fn;
+  r->lineno = li;
+  r->interface = interface;
+  r->tokens = r->last_chunk = ggc_alloc_cleared (sizeof (*r->tokens));
+  return r;
+}
 
 /* Subroutine of snarf_method, deals with actual absorption of the block.  */
 
-static SPEW_INLINE void
-snarf_block (starting_file, starting_line)
-     const char *starting_file;
-     int starting_line;
+static void
+snarf_block (t)
+     struct unparsed_text *t;
 {
   int blev = 1;
   int look_for_semicolon = 0;
   int look_for_lbrac = 0;
   int look_for_catch = 0;
   int yyc;
-  struct token tmp;
-  size_t point;
+  struct token *current;
 
   if (yychar == '{')
     ;
@@ -1092,17 +1113,14 @@ snarf_block (starting_file, starting_line)
     yyerror ("parse error in method specification");
 
   /* The current token is the first one to be recorded.  */
-  tmp.yychar = yychar;
-  tmp.yylval = yylval;
-  tmp.lineno = lineno;
-  obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
+  current = space_for_token (t);
+  current->yychar = yychar;
+  current->yylval = yylval;
+  current->lineno = lineno;
 
   for (;;)
     {
-      point = obstack_object_size (&inline_text_obstack);
-      obstack_blank (&inline_text_obstack, sizeof (struct token));
-      yyc = add_token ((struct token *)
-                      (obstack_base (&inline_text_obstack) + point));
+      yyc = next_token (space_for_token (t));
 
       if (yyc == '{')
        {
@@ -1117,27 +1135,29 @@ snarf_block (starting_file, starting_line)
              if (!look_for_catch)
                break;
              
-             if (add_token (&tmp) != CATCH)
+             if (next_token (space_for_token (t)) != CATCH)
                {
-                 push_token (&tmp);
+                 push_token (remove_last_token (t));
                  break;
                }
 
              look_for_lbrac = 1;
-             obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
            }
        }
       else if (yyc == ';')
        {
          if (look_for_lbrac)
            {
+             struct token *fake;
+             
              error ("function body for constructor missing");
              /* fake a { } to avoid further errors */
-             tmp.yylval.ttype = 0;
-             tmp.yychar = '{';
-             obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
-             tmp.yychar = '}';
-             obstack_grow (&inline_text_obstack, &tmp, sizeof (struct token));
+             fake = space_for_token (t);
+             fake->yylval.ttype = 0;
+             fake->yychar = '{';
+             fake = space_for_token (t);
+             fake->yylval.ttype = 0;
+             fake->yychar = '}';
              break;
            }
          else if (look_for_semicolon && blev == 0)
@@ -1145,7 +1165,7 @@ snarf_block (starting_file, starting_line)
        }
       else if (yyc == 0)
        {
-         error_with_file_and_line (starting_file, starting_line,
+         error_with_file_and_line (t->filename, t->lineno,
                                    "end of file read inside definition");
          break;
        }
@@ -1160,37 +1180,24 @@ snarf_method (decl)
 {
   int starting_lineno = lineno;
   const char *starting_filename = input_filename;
-  size_t len;
-
   struct unparsed_text *meth;
 
-  /* Leave room for the header, then absorb the block.  */
-  obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text));
-  snarf_block (starting_filename, starting_lineno);
+  meth = alloc_unparsed_text (starting_filename, starting_lineno, decl,
+                             (interface_unknown ? 1 
+                              : (interface_only ? 0 : 2)));
 
-  len = obstack_object_size (&inline_text_obstack);
-  meth = (struct unparsed_text *) obstack_finish (&inline_text_obstack);
+  snarf_block (meth);
 
   /* Happens when we get two declarations of the same function in the
      same scope.  */
   if (decl == void_type_node
       || (current_class_type && TYPE_REDEFINED (current_class_type)))
-    {
-      obstack_free (&inline_text_obstack, (char *)meth);
-      return;
-    }
-
-  meth->decl = decl;
-  meth->filename = starting_filename;
-  meth->lineno = starting_lineno;
-  meth->limit = (struct token *) ((char *)meth + len);
-  meth->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
-  meth->next = 0;
+    return;
 
 #ifdef SPEW_DEBUG
   if (spew_debug)
     fprintf (stderr, "\tsaved method of %d tokens from %s:%d\n",
-            meth->limit - (struct token *) (meth + 1),
+            meth->limit,
             starting_filename, starting_lineno);
 #endif
 
@@ -1204,8 +1211,8 @@ snarf_method (decl)
   pending_inlines_tail = meth;
 }
 
-/* Consume a no-commas expression - a default argument - and save it
-   on the inline_text_obstack.  */
+/* Consume a no-commas expression - a default argument - and return
+   a DEFAULT_ARG tree node.  */
 
 static tree
 snarf_defarg ()
@@ -1214,19 +1221,14 @@ snarf_defarg ()
   const char *starting_filename = input_filename;
   int yyc;
   int plev = 0;
-  size_t point;
-  size_t len;
   struct unparsed_text *buf;
   tree arg;
 
-  obstack_blank (&inline_text_obstack, sizeof (struct unparsed_text));
+  buf = alloc_unparsed_text (starting_filename, starting_lineno, 0, 0);
 
   for (;;)
     {
-      point = obstack_object_size (&inline_text_obstack);
-      obstack_blank (&inline_text_obstack, sizeof (struct token));
-      yyc = add_token ((struct token *)
-                      (obstack_base (&inline_text_obstack) + point));
+      yyc = next_token (space_for_token (buf));
 
       if (plev <= 0 && (yyc == ')' || yyc == ','))
        break;
@@ -1243,24 +1245,13 @@ snarf_defarg ()
     }
 
   /* Unget the last token.  */
-  push_token ((struct token *) (obstack_base (&inline_text_obstack) + point));
-  /* This is the documented way to shrink a growing obstack block.  */
-  obstack_blank (&inline_text_obstack, - (int) sizeof (struct token));
+  push_token (remove_last_token (buf));
 
  done:
-  len = obstack_object_size (&inline_text_obstack);
-  buf = (struct unparsed_text *) obstack_finish (&inline_text_obstack);
-
-  buf->decl = 0;
-  buf->filename = starting_filename;
-  buf->lineno = starting_lineno;
-  buf->limit = (struct token *) ((char *)buf + len);
-  buf->next = 0;
-  
 #ifdef SPEW_DEBUG
   if (spew_debug)
     fprintf (stderr, "\tsaved defarg of %d tokens from %s:%d\n",
-            buf->limit - (struct token *) (buf + 1),
+            buf->limit,
             starting_filename, starting_lineno);
 #endif
 
@@ -1531,3 +1522,5 @@ yyerror (msgid)
   else
     error ("%s before `%s' token", string, NAME (last_token));
 }
+
+#include "gt-cp-spew.h"
index a144c6d928f7c86c0c34935dc88a6353e25c6f91..0752d7bc8dc99f00bbdb37b9c73555e37ff35149 100644 (file)
@@ -710,7 +710,7 @@ unshare_base_binfos (binfo)
    While all these live in the same table, they are completely independent,
    and the hash code is computed differently for each of these.  */
 
-static htab_t list_hash_table;
+static GTY ((param_is (union tree_node))) htab_t list_hash_table;
 
 struct list_proxy 
 {
@@ -1720,25 +1720,15 @@ cp_tree_equal (t1, t2)
   return -1;
 }
 
-/* Build a wrapper around some pointer PTR so we can use it as a tree.  */
+/* Build a wrapper around a 'struct z_candidate' so we can use it as a
+   tree.  */
 
 tree
-build_ptr_wrapper (ptr)
-     void *ptr;
+build_zc_wrapper (ptr)
+     struct z_candidate *ptr;
 {
   tree t = make_node (WRAPPER);
-  WRAPPER_PTR (t) = ptr;
-  return t;
-}
-
-/* Build a wrapper around some integer I so we can use it as a tree.  */
-
-tree
-build_int_wrapper (i)
-     int i;
-{
-  tree t = make_node (WRAPPER);
-  WRAPPER_INT (t) = i;
+  WRAPPER_ZC (t) = ptr;
   return t;
 }
 
@@ -2326,10 +2316,7 @@ void
 init_tree ()
 {
   lang_statement_code_p = cp_statement_code_p;
-  list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL);
-  ggc_add_root (&list_hash_table, 1, 
-               sizeof (list_hash_table),
-               mark_tree_hashtable);
+  list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
 }
 
 /* Called via walk_tree.  If *TP points to a DECL_STMT for a local
@@ -2557,3 +2544,20 @@ stabilize_expr (exp, initp)
   *initp = init_expr;
   return exp;
 }
+\f
+#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+/* Complain that some language-specific thing hanging off a tree
+   node has been accessed improperly.  */
+
+void
+lang_check_failed (file, line, function)
+     const char *file;
+     int line;
+     const char *function;
+{
+  internal_error ("lang_* check: failed in %s, at %s:%d",
+                 function, trim_filename (file), line);
+}
+#endif /* ENABLE_TREE_CHECKING */
+
+#include "gt-cp-tree.h"
index b0348fbc46209b4dc6f3b6d4f3b88313545d3bb5..d9b6ee14e56f9dab47b0c3548fb5556c0c1ed9e2 100644 (file)
@@ -35,7 +35,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "toplev.h"
 #include "output.h"
 #include "ggc.h"
-#include "obstack.h"
 #include "hashtab.h"
 #include "cselib.h"
 
@@ -79,7 +78,7 @@ static void cselib_record_sets                PARAMS ((rtx));
      the locations of the entries with the rtx we are looking up.  */
 
 /* A table that enables us to look up elts by their value.  */
-static htab_t hash_table;
+static GTY((param_is (cselib_val))) htab_t hash_table;
 
 /* This is a global so we don't have to pass this through every function.
    It is used in new_elt_loc_list to set SETTING_INSN.  */
@@ -101,7 +100,8 @@ static int n_useless_values;
 /* This table maps from register number to values.  It does not contain
    pointers to cselib_val structures, but rather elt_lists.  The purpose is
    to be able to refer to the same register in different modes.  */
-static varray_type reg_values;
+static GTY(()) varray_type reg_values;
+static GTY((deletable (""))) varray_type reg_values_old;
 #define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
 
 /* The largest number of hard regs used by any entry added to the
@@ -110,22 +110,17 @@ static unsigned int max_value_regs;
 
 /* Here the set of indices I with REG_VALUES(I) != 0 is saved.  This is used
    in clear_table() for fast emptying.  */
-static varray_type used_regs;
+static GTY(()) varray_type used_regs;
+static GTY((deletable (""))) varray_type used_regs_old;
 
 /* We pass this to cselib_invalidate_mem to invalidate all of
    memory for a non-const call instruction.  */
-static rtx callmem;
-
-/* Memory for our structures is allocated from this obstack.  */
-static struct obstack cselib_obstack;
-
-/* Used to quickly free all memory.  */
-static char *cselib_startobj;
+static GTY(()) rtx callmem;
 
 /* Caches for unused structures.  */
-static cselib_val *empty_vals;
-static struct elt_list *empty_elt_lists;
-static struct elt_loc_list *empty_elt_loc_lists;
+static GTY((deletable (""))) cselib_val *empty_vals;
+static GTY((deletable (""))) struct elt_list *empty_elt_lists;
+static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists;
 
 /* Set by discard_useless_locs if it deleted the last location of any
    value.  */
@@ -145,8 +140,7 @@ new_elt_list (next, elt)
   if (el)
     empty_elt_lists = el->next;
   else
-    el = (struct elt_list *) obstack_alloc (&cselib_obstack,
-                                           sizeof (struct elt_list));
+    el = (struct elt_list *) ggc_alloc (sizeof (struct elt_list));
   el->next = next;
   el->elt = elt;
   return el;
@@ -165,8 +159,7 @@ new_elt_loc_list (next, loc)
   if (el)
     empty_elt_loc_lists = el->next;
   else
-    el = (struct elt_loc_list *) obstack_alloc (&cselib_obstack,
-                                               sizeof (struct elt_loc_list));
+    el = (struct elt_loc_list *) ggc_alloc (sizeof (struct elt_loc_list));
   el->next = next;
   el->loc = loc;
   el->setting_insn = cselib_current_insn;
@@ -236,11 +229,7 @@ clear_table (clear_all)
   VARRAY_POP_ALL (used_regs);
 
   htab_empty (hash_table);
-  obstack_free (&cselib_obstack, cselib_startobj);
 
-  empty_vals = 0;
-  empty_elt_lists = 0;
-  empty_elt_loc_lists = 0;
   n_useless_values = 0;
 
   next_unknown_value = 0;
@@ -704,7 +693,7 @@ new_cselib_val (value, mode)
   if (e)
     empty_vals = e->u.next_free;
   else
-    e = (cselib_val *) obstack_alloc (&cselib_obstack, sizeof (cselib_val));
+    e = (cselib_val *) ggc_alloc (sizeof (cselib_val));
 
   if (value == 0)
     abort ();
@@ -1399,20 +1388,25 @@ cselib_update_varray_sizes ()
 void
 cselib_init ()
 {
-  /* These are only created once.  */
+  /* This is only created once.  */
   if (! callmem)
-    {
-      gcc_obstack_init (&cselib_obstack);
-      cselib_startobj = obstack_alloc (&cselib_obstack, 0);
-
-      callmem = gen_rtx_MEM (BLKmode, const0_rtx);
-      ggc_add_rtx_root (&callmem, 1);
-    }
+    callmem = gen_rtx_MEM (BLKmode, const0_rtx);
 
   cselib_nregs = max_reg_num ();
-  VARRAY_ELT_LIST_INIT (reg_values, cselib_nregs, "reg_values");
-  VARRAY_UINT_INIT (used_regs, cselib_nregs, "used_regs");
-  hash_table = htab_create (31, get_value_hash, entry_and_rtx_equal_p, NULL);
+  if (reg_values_old != NULL && VARRAY_SIZE (reg_values_old) >= cselib_nregs)
+    {
+      reg_values = reg_values_old;
+      used_regs = used_regs_old;
+      VARRAY_CLEAR (reg_values);
+      VARRAY_CLEAR (used_regs);
+    }
+  else
+    {
+      VARRAY_ELT_LIST_INIT (reg_values, cselib_nregs, "reg_values");
+      VARRAY_UINT_INIT (used_regs, cselib_nregs, "used_regs");
+    }
+  hash_table = htab_create_ggc (31, get_value_hash, entry_and_rtx_equal_p, 
+                               NULL);
   clear_table (1);
 }
 
@@ -1421,8 +1415,13 @@ cselib_init ()
 void
 cselib_finish ()
 {
-  clear_table (0);
-  VARRAY_FREE (reg_values);
-  VARRAY_FREE (used_regs);
-  htab_delete (hash_table);
+  reg_values_old = reg_values;
+  reg_values = 0;
+  used_regs_old = used_regs;
+  used_regs = 0;
+  hash_table = 0;
+  n_useless_values = 0;
+  next_unknown_value = 0;
 }
+
+#include "gt-cselib.h"
index 72885982fbf73a5e47f0ce0b80c5ef3cf9f4dd4f..8cb2e6b41e31cefd0b6dce2db1a6e572bd8b2b53 100644 (file)
@@ -20,17 +20,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
 /* Describe a value.  */
-typedef struct cselib_val_struct
+typedef struct cselib_val_struct GTY(())
 {
   /* The hash value.  */
   unsigned int value;
-  union
+  union cselib_val_u
   {
     /* A VALUE rtx that points back to this structure.  */
-    rtx val_rtx;
+    rtx GTY ((tag ("1"))) val_rtx;
     /* Used to keep a list of free cselib_val structures.  */
-    struct cselib_val_struct *next_free;
-  } u;
+    struct cselib_val_struct * GTY ((skip (""))) next_free;
+  } GTY ((desc ("1"))) u;
 
   /* All rtl expressions that hold this value at the current time during a
      scan.  */
@@ -41,7 +41,7 @@ typedef struct cselib_val_struct
 } cselib_val;
 
 /* A list of rtl expressions that hold the same value.  */
-struct elt_loc_list
+struct elt_loc_list GTY(())
 {
   /* Next element in the list.  */
   struct elt_loc_list *next;
@@ -52,7 +52,7 @@ struct elt_loc_list
 };
 
 /* A list of cselib_val structures.  */
-struct elt_list
+struct elt_list GTY(())
 {
   struct elt_list *next;
   cselib_val *elt;
index d4bb2eac4fa95bf713540a906cf1a5836474a1fd..ec46d988bf191c2ce312335172b0e41b614bf406 100644 (file)
@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree.h"
 #include "c-common.h"
 #include "flags.h"
+#include "ggc.h"
 #include "varray.h"
 
 #define MAX_SUBSCRIPTS 13
@@ -81,7 +82,7 @@ enum complexity_type {ziv, strong_siv, weak_siv, weak_zero_siv,
    for that variable.  Alternately one can sequentially follow each
    element of def_use_chain.  */
 
-typedef struct def_use
+typedef struct def_use GTY(())
 {
   /* outermost loop */
   tree outer_loop;
@@ -106,7 +107,7 @@ typedef struct def_use
    element of loop_chain and check outer_loop to get all loops
    contained within a certain loop.  */
 
-typedef struct loop
+typedef struct loop GTY(())
 {
   /* outermost loop containing this loop */
   tree outer_loop;
@@ -124,7 +125,7 @@ typedef struct loop
 
 /* Pointed to by loop. One per induction variable.  */
 
-typedef struct induction
+typedef struct induction GTY(())
 {
   /* our name */
   const char *variable;
@@ -140,7 +141,7 @@ typedef struct induction
 
 /* Pointed to by def/use.  One per dependence.  */
 
-typedef struct dependence
+typedef struct dependence GTY(())
 {
   tree source;
   tree destination;
@@ -172,16 +173,16 @@ typedef struct subscript
 static tree dest_to_remember;
 
 /* Chain for def_use */
-static varray_type def_use_chain;
+static GTY ((param_is (def_use))) varray_type def_use_chain;
 
 /* Chain for dependence */
-static varray_type dep_chain;
+static GTY ((param_is (dependence))) varray_type dep_chain;
 
 /* Chain for loop */
-static varray_type loop_chain;
+static GTY ((param_is (loop))) varray_type loop_chain;
 
 /* Chain for induction */
-static varray_type induction_chain;
+static GTY ((param_is (induction))) varray_type induction_chain;
 
 void init_dependence_analysis PARAMS ((tree));
 static void build_def_use PARAMS ((tree, enum def_use_type));
@@ -227,8 +228,6 @@ void
 init_dependence_analysis (exp)
      tree exp;
 {
-  def_use *du_ptr;
-
   VARRAY_GENERIC_PTR_INIT (def_use_chain, 50, "def_use_chain");
   VARRAY_GENERIC_PTR_INIT (dep_chain, 50, "dep_chain");
   VARRAY_GENERIC_PTR_INIT (loop_chain, 50, "loop_chain");
@@ -242,16 +241,9 @@ init_dependence_analysis (exp)
 
   /* dump_node_dependence (&def_use_chain);*/
 
-  for (du_ptr = VARRAY_TOP (def_use_chain, generic);
-       VARRAY_POP (def_use_chain);
-       du_ptr = VARRAY_TOP (def_use_chain, generic))
-    {
-      free (du_ptr);
-    }
-
-  VARRAY_FREE (def_use_chain);
-  VARRAY_FREE (loop_chain);
-  VARRAY_FREE (induction_chain);
+  def_use_chain = 0;
+  loop_chain = 0;
+  induction_chain = 0;
 }
 
 /* Build ARRAY_REF def/use info 'def_use_chain' starting at EXP which is a def
@@ -337,7 +329,8 @@ build_def_use (exp, du_type)
            int i;
            char null_string = '\0';
 
-           VARRAY_PUSH_GENERIC_PTR (def_use_chain, xmalloc (sizeof (def_use)));
+           VARRAY_PUSH_GENERIC_PTR (def_use_chain, 
+                                    ggc_alloc (sizeof (def_use)));
            du_ptr = VARRAY_GENERIC_PTR (def_use_chain, du_idx++);
            du_ptr->type = du_type;
            du_ptr->status = unseen;
@@ -418,7 +411,7 @@ add_loop (loop_node, outer_loop, nloop)
 {
   loop *loop_ptr;
 
-  VARRAY_PUSH_GENERIC_PTR (loop_chain, xmalloc (sizeof (loop)));
+  VARRAY_PUSH_GENERIC_PTR (loop_chain, ggc_alloc (sizeof (loop)));
   loop_ptr = VARRAY_TOP (loop_chain, generic);
   loop_ptr->outer_loop = outer_loop;
   loop_ptr->containing_loop = loop_node;
@@ -502,7 +495,8 @@ find_induction_variable (init_node, cond_node, incr_node, loop_def)
       if (!INDEX_LIMIT_CHECK (cond_node))
        return 0;
 
-      VARRAY_PUSH_GENERIC_PTR (induction_chain, xmalloc (sizeof (induction)));
+      VARRAY_PUSH_GENERIC_PTR (induction_chain, 
+                              ggc_alloc (sizeof (induction)));
       ind_ptr = VARRAY_TOP (induction_chain, generic);
       loop_def->ind = ind_ptr;
       ind_ptr->variable = IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND
@@ -747,7 +741,7 @@ check_node_dependence (du)
          if (! have_dependence)
            continue;
 
-         VARRAY_PUSH_GENERIC_PTR (dep_chain, xmalloc (sizeof (dependence)));
+         VARRAY_PUSH_GENERIC_PTR (dep_chain, ggc_alloc (sizeof (dependence)));
          dep_ptr = VARRAY_TOP (dep_chain, generic);
          dep_ptr->source = use_ptr->expression;
          dep_ptr->destination = def_ptr->expression;
@@ -790,7 +784,8 @@ check_node_dependence (du)
              /* Dummy for rtl interface */
              dependence *dep_root_ptr;
 
-             VARRAY_PUSH_GENERIC_PTR (dep_chain, xmalloc (sizeof (dependence)));
+             VARRAY_PUSH_GENERIC_PTR (dep_chain, 
+                                      ggc_alloc (sizeof (dependence)));
              dep_root_ptr = VARRAY_TOP (dep_chain, generic);
              dep_root_ptr->source = 0;
              dep_root_ptr->destination = def_ptr->expression;
@@ -1364,7 +1359,6 @@ dump_node_dependence (void)
       if (i >= VARRAY_SIZE (seen))
        dump_one_node (du_ptr, &seen);
     }
-  VARRAY_FREE (seen);
 }
 #endif
 
@@ -1463,5 +1457,7 @@ have_dependence_p (dest_rtx, src_rtx, direction, distance)
 void
 end_dependence_analysis ()
 {
-  VARRAY_FREE (dep_chain);
+  dep_chain = 0;
 }
+
+#include "gt-dependence.h"
index 82a7d317a40b8293c8fe13e7e28cdfd25d6a547a..35bd02cc21ac9b18a89035a836a4f4afcc0a6b9d 100644 (file)
@@ -169,6 +169,7 @@ Additional tutorial information is linked to from
 * Fragments::       Writing the @file{t-@var{target}} and @file{x-@var{host}} files.
 * Collect2::        How @code{collect2} works; how it finds @code{ld}.
 * Header Dirs::     Understanding the standard header file directories.
+* Type Information:: GCC's memory management; generating type information.
 
 * Funding::         How to help assure funding for free software.
 * GNU Project::     The GNU Project and GNU/Linux.
@@ -196,6 +197,7 @@ Additional tutorial information is linked to from
 @include fragments.texi
 @include collect2.texi
 @include headerdirs.texi
+@include gty.texi
 
 @include funding.texi
 @include gnu.texi
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
new file mode 100644 (file)
index 0000000..132cd41
--- /dev/null
@@ -0,0 +1,257 @@
+@c Copyright (C) 2002
+@c Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+
+@node Type Information
+@chapter Memory Management and Type Information
+@cindex GGC
+@findex GTY
+
+GCC uses some fairly sophisticated memory management techniques, which
+involve determining information about GCC's data structures from GCC's
+source code and using this information to perform garbage collection.
+
+A full C parser would be too overcomplicated for this task, so a limited
+subset of C is interpreted and special markers are used to determine
+what parts of the source to look at.  The parser can also detect
+simple typedefs of the form @code{typedef struct ID1 *ID2;} and
+@code{typedef int ID3;}, and these don't need to be specially marked.
+
+The two forms that do need to be marked are:
+@verbatim
+struct ID1 GTY(([options]))
+{
+  [fields]
+};
+
+typedef struct ID2 GTY(([options]))
+{
+  [fields]
+} ID3;
+@end verbatim
+
+@menu
+* GTY Options::                What goes inside a @code{GTY(())}.
+* GGC Roots::          Making global variables GGC roots.
+* Files::              How the generated files work.
+@end menu
+
+@node GTY Options
+@section The Inside of a @code{GTY(())}
+
+Sometimes the C code is not enough to fully describe the type structure.
+Extra information can be provided by using more @code{GTY} markers.
+These markers can be placed:
+@itemize @bullet
+@item
+In a structure definition, before the open brace;
+@item
+In a global variable declaration, after the keyword @code{static} or 
+@code{extern}; and
+@item
+In a structure field definition, before the name of the field.
+@end itemize
+
+The format of a marker is
+@verbatim
+GTY (([name] ([param]), [name] ([param]) ...))
+@end verbatim
+The parameter is either a string or a type name.
+
+When the parameter is a string, often it is a fragment of C code.  Three
+special escapes may be available:
+
+@cindex % in GTY option
+@table @code
+@item %h
+This expands to an expression that evaluates to the current structure.
+@item %1
+This expands to an expression that evaluates to the structure that
+immediately contains the current structure.
+@item %0
+This expands to an expression that evaluates to the outermost structure
+that contains the current structure.
+@end table
+
+The available options are:
+
+@table @code
+@findex length
+@item length
+
+There are two places the type machinery will need to be explicitly told
+the length of an array.  The first case is when a structure ends in a
+variable-length array, like this:
+@verbatim
+struct rtvec_def GTY(()) {
+  int num_elem;                /* number of elements */
+  rtx GTY ((length ("%h.num_elem"))) elem[1];
+};
+@end verbatim
+In this case, the @code{length} option is used to override the specified
+array length (which should usually be @code{1}).  The parameter of the
+option is a fragment of C code that calculates the length.
+
+The second case is when a structure or a global variable contains a
+pointer to an array, like this:
+@verbatim
+  tree * GTY ((length ("%h.regno_pointer_align_length"))) regno_decl;
+@end verbatim
+In this case, @code{regno_decl} has been allocated by writing something like
+@verbatim
+  x->regno_decl = ggc_alloc (x->regno_pointer_align_length * sizeof (tree));
+@end verbatim
+and the @code{length} provides the length of the field.
+
+This second use of @code{length} also works on global variables, like:
+@verbatim
+static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
+@end verbatim
+
+@findex skip
+@item skip
+
+If @code{skip} is applied to a field, the type machinery will ignore it.
+This is somewhat dangerous; the only safe use is in a union when one
+field really isn't ever used.
+
+@findex desc
+@findex tag
+@findex always
+@item desc
+@itemx tag
+@itemx always
+
+The type machinery needs to be told which field of a @code{union} is
+currently active.  This is done by giving each field a constant @code{tag}
+value, and then specifying a discriminator using @code{desc}.  For example,
+@verbatim
+struct tree_binding GTY(())
+{
+  struct tree_common common;
+  union tree_binding_u {
+    tree GTY ((tag ("0"))) scope;
+    struct cp_binding_level * GTY ((tag ("1"))) level;
+  } GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) scope;
+  tree value;
+};
+@end verbatim
+
+In the @code{desc} option, the ``current structure'' is the union that
+it discriminates.  Use @code{%1} to mean the structure containing it.
+(There are no escapes available to the @code{tag} option, since it's
+supposed to be a constant.)
+
+You can use @code{always} to mean that this field is always used.
+
+@findex param_is
+@findex use_param
+@item param_is
+@itemx use_param
+
+Sometimes it's convenient to define some data structure to work on
+generic pointers (that is, @code{PTR}), and then use it with specific types.
+@code{param_is} specifies the real type pointed to, and @code{use_param}
+says where in the generic data structure that type should be put.
+
+For instance, to have a @code{htab_t} that points to trees, one should write
+@verbatim
+  htab_t GTY ((param_is (union tree_node))) ict;
+@end verbatim
+
+@findex deletable
+@item deletable
+
+@code{deletable}, when applied to a global variable, indicates that when
+garbage collection runs, there's no need to mark anything pointed to
+by this variable, it can just be set to @code{NULL} instead.  This is used
+to keep a list of free structures around for re-use.
+
+@findex if_marked
+@item if_marked
+
+Suppose you want some kinds of object to be unique, and so you put them
+in a hash table.  If garbage collection marks the hash table, these
+objects will never be freed, even if the last other reference to them
+goes away.  GGC has special handling to deal with this: if you use the
+@code{if_marked} option on a global hash table, GGC will call the
+routine whose name is the parameter to the option on each hash table
+entry.  If the routine returns nonzero, the hash table entry will
+be marked as usual.  If the routine returns zero, the hash table entry
+will be deleted.
+
+The routine @code{ggc_marked_p} can be used to determine if an element
+has been marked already; in fact, the usual case is to use
+@code{if_marked ("ggc_marked_p")}.
+
+@findex maybe_undef
+@item maybe_undef
+
+When applied to a field, @code{maybe_undef} indicates that it's OK if
+the structure that this fields points to is never defined, so long as
+this field is always @code{NULL}.  This is used to avoid requiring
+backends to define certain optional structures.  It doesn't work with
+language frontends.
+
+@findex special
+@item special
+
+The @code{special} option is used for those bizarre cases that are just
+too hard to deal with otherwise.  Don't use it for new code.
+
+@end table
+
+@node GGC Roots
+@section Marking Roots for the Garbage Collector
+@cindex roots, marking
+@cindex marking roots
+
+In addition to keeping track of types, the type machinery also locates
+the global variables that the garbage collector starts at.  There are
+two syntaxes it accepts to indicate a root:
+
+@enumerate
+@item
+@verb{|extern GTY (([options])) [type] ID;|}
+@item
+@verb{|static GTY (([options])) [type] ID;|}
+@end enumerate
+
+@node Files
+@section Source Files Containing Type Information
+@cindex generated files
+@cindex files, generated
+
+Whenever you add @code{GTY} markers to a new source file, there are three
+things you need to do:
+
+@enumerate
+@item
+You need to add the file to the list of source files the type machinery
+scans.  For a back-end file, this is done automatically.  For a
+front-end file, this is done by adding the filename to the
+@code{gtfiles} variable defined in @file{config-lang.in}.  For other
+files, this is done by adding the filename to the @code{GTFILES} variable
+in @file{Makefile.in}.
+
+@item
+You need to include the file that the type machinery will generate in
+the source file you just changed.  The file will be called
+@file{gt-@var{path}.h} where @var{path} is the pathname from the
+@file{gcc} directory with slashes replaced by @verb{|-|}.  Don't forget
+to mention this file as a dependency in the @file{Makefile}!
+
+@item
+Finally, you need to add a @file{Makefile} rule that will ensure this file
+can be built.  This is done by making it a dependency of @code{s-gtype},
+like this:
+@verbatim
+gt-path.h : s-gtype ; @true
+@end verbatim
+@end enumerate
+
+For language frontends, there is another file that needs to be included
+somewhere.  It will be called @file{gtype-@var{lang}.h}, where
+@var{lang} is the name of the subdirectory the language is contained in.
+It will need @file{Makefile} rules just like the other generated files.
index cc87da63325a03e5d347caea337635721388ea32..45a65ce25d751cf0d0b78c4e622220f0b02db5d2 100644 (file)
@@ -824,11 +824,9 @@ structure contains a field called @code{machine} whose type is
 to their own specific data.
 
 If a target needs per-function specific data it should define the type
-@code{struct machine_function} and also the macro
-@code{INIT_EXPANDERS}.  This macro should be used to initialize some or
-all of the function pointers @code{init_machine_status},
-@code{free_machine_status} and @code{mark_machine_status}.  These
-pointers are explained below.
+@code{struct machine_function} and also the macro @code{INIT_EXPANDERS}.
+This macro should be used to initialize the function pointer
+@code{init_machine_status}.  This pointer is explained below.
 
 One typical use of per-function, target specific data is to create an
 RTX to hold the register containing the function's return address.  This
@@ -864,19 +862,9 @@ specific initialization of the @code{struct function} structure.  It is
 intended that this would be used to initialize the @code{machine} of
 that structure.
 
-@findex free_machine_status
-@item   free_machine_status
-This is a @code{void (*)(struct function *)} function pointer.  If this
-pointer is non-@code{NULL} it will be called once per function, after the
-function has been compiled, in order to allow any memory allocated
-during the @code{init_machine_status} function call to be freed.
-
-@findex mark_machine_status
-@item   mark_machine_status
-This is a @code{void (*)(struct function *)} function pointer.  If this
-pointer is non-@code{NULL} it will be called once per function in order to mark
-any data items in the @code{struct machine_function} structure which
-need garbage collection.
+@code{struct machine_function} structures are expected to be freed by GC.
+Generally, any memory that they reference must be allocated by using
+@code{ggc_alloc}, including the structure itself.
 
 @end table
 
index 80be6513721d0f43c313de98dea1c10e449d725e..6e6a5d02303da785ee835ce691bf5d8852055c47 100644 (file)
@@ -704,7 +704,7 @@ mark_indirect_pool_entry (node, data)
      splay_tree_node node;
      void* data ATTRIBUTE_UNUSED;
 {
-  ggc_mark_nonnull_tree ((tree) node->value);
+  ggc_mark_tree ((tree) node->value);
   return 0;
 }
 
index f4b0ee7ff5d93b3e4bcbe08eebaa645969a2a81e..3941490109dd96f3e504084f410378847a2da36e 100644 (file)
@@ -134,6 +134,22 @@ default_eh_frame_section ()
 #endif
 }
 
+/* Array of RTXes referenced by the debugging information, which therefore
+   must be kept around forever.  */
+static GTY(()) varray_type used_rtx_varray;
+
+/* A pointer to the base of a list of incomplete types which might be
+   completed at some later time.  incomplete_types_list needs to be a VARRAY
+   because we want to tell the garbage collector about it.  */
+static GTY(()) varray_type incomplete_types;
+
+/* A pointer to the base of a table of references to declaration
+   scopes.  This table is a display which tracks the nesting
+   of declaration scopes at the current scope and containing
+   scopes.  This table is used to find the proper place to
+   define type declaration DIE's.  */
+static GTY(()) varray_type decl_scope_table;
+
 #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
 
 /* How to start an assembler comment.  */
@@ -3352,13 +3368,6 @@ static unsigned decl_die_table_in_use;
    decl_die_table.  */
 #define DECL_DIE_TABLE_INCREMENT 256
 
-/* A pointer to the base of a table of references to declaration
-   scopes.  This table is a display which tracks the nesting
-   of declaration scopes at the current scope and containing
-   scopes.  This table is used to find the proper place to
-   define type declaration DIE's.  */
-varray_type decl_scope_table;
-
 /* A pointer to the base of a list of references to DIE's that
    are uniquely identified by their tag, presence/absence of
    children DIE's, and list of attribute/value pairs.  */
@@ -3441,21 +3450,12 @@ static unsigned ranges_table_in_use;
 /* Whether we have location lists that need outputting */
 static unsigned have_location_lists;
 
-/* A pointer to the base of a list of incomplete types which might be
-   completed at some later time.  incomplete_types_list needs to be a VARRAY
-   because we want to tell the garbage collector about it.  */
-varray_type incomplete_types;
-
 /* Record whether the function being analyzed contains inlined functions.  */
 static int current_function_has_inlines;
 #if 0 && defined (MIPS_DEBUGGING_INFO)
 static int comp_unit_has_inlines;
 #endif
 
-/* Array of RTXes referenced by the debugging information, which therefore
-   must be kept around forever.  This is a GC root.  */
-static varray_type used_rtx_varray;
-
 /* Forward declarations for functions defined in this file.  */
 
 static int is_pseudo_reg               PARAMS ((rtx));
@@ -5123,7 +5123,7 @@ static inline dw_die_ref
 lookup_type_die (type)
      tree type;
 {
-  return (dw_die_ref) TYPE_SYMTAB_POINTER (type);
+  return TYPE_SYMTAB_DIE (type);
 }
 
 /* Equate a DIE to a given type specifier.  */
@@ -5133,7 +5133,7 @@ equate_type_number_to_die (type, type_die)
      tree type;
      dw_die_ref type_die;
 {
-  TYPE_SYMTAB_POINTER (type) = (char *) type_die;
+  TYPE_SYMTAB_DIE (type) = type_die;
 }
 
 /* Return the DIE associated with a given declaration.  */
@@ -12034,7 +12034,6 @@ dwarf2out_init (main_input_filename)
 
   /* Allocate the initial hunk of the decl_scope_table.  */
   VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
-  ggc_add_tree_varray_root (&decl_scope_table, 1);
 
   /* Allocate the initial hunk of the abbrev_die_table.  */
   abbrev_die_table
@@ -12061,10 +12060,8 @@ dwarf2out_init (main_input_filename)
   comp_unit_die = gen_compile_unit_die (main_input_filename);
 
   VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
-  ggc_add_tree_varray_root (&incomplete_types, 1);
 
   VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
-  ggc_add_rtx_varray_root (&used_rtx_varray, 1);
 
   ggc_add_root (&limbo_die_list, 1, 1, mark_limbo_die_list);
 
@@ -12322,4 +12319,11 @@ dwarf2out_finish (input_filename)
   if (debug_str_hash)
     ht_forall (debug_str_hash, output_indirect_string, NULL);
 }
-#endif /* DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO */
+#else
+
+/* This should never be used, but its address is needed for comparisons.  */
+const struct gcc_debug_hooks dwarf2_debug_hooks;
+
+#endif /* DWARF2_DEBUGGING_INFO */
+
+#include "gt-dwarf2out.h"
index 4651473e2b350d13e680a7c8d2c890852e589fad..4ee90ef1ae97c6f846b96b227e33a92ebc672396 100644 (file)
@@ -143,13 +143,16 @@ rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
 /* A hash table storing CONST_INTs whose absolute value is greater
    than MAX_SAVED_CONST_INT.  */
 
-static htab_t const_int_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+     htab_t const_int_htab;
 
 /* A hash table storing memory attribute structures.  */
-static htab_t mem_attrs_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
+     htab_t mem_attrs_htab;
 
 /* A hash table storing all CONST_DOUBLEs.  */
-static htab_t const_double_htab;
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
+     htab_t const_double_htab;
 
 #define first_insn (cfun->emit->x_first_insn)
 #define last_insn (cfun->emit->x_last_insn)
@@ -161,7 +164,6 @@ static htab_t const_double_htab;
 static rtx make_jump_insn_raw          PARAMS ((rtx));
 static rtx make_call_insn_raw          PARAMS ((rtx));
 static rtx find_line_note              PARAMS ((rtx));
-static void mark_sequence_stack         PARAMS ((struct sequence_stack *));
 static rtx change_address_1            PARAMS ((rtx, enum machine_mode, rtx,
                                                 int));
 static void unshare_all_rtl_1          PARAMS ((rtx));
@@ -178,7 +180,6 @@ static rtx lookup_const_double              PARAMS ((rtx));
 static hashval_t mem_attrs_htab_hash    PARAMS ((const void *));
 static int mem_attrs_htab_eq            PARAMS ((const void *,
                                                 const void *));
-static void mem_attrs_mark             PARAMS ((const void *));
 static mem_attrs *get_mem_attrs                PARAMS ((HOST_WIDE_INT, tree, rtx,
                                                 rtx, unsigned int,
                                                 enum machine_mode));
@@ -273,25 +274,6 @@ mem_attrs_htab_eq (x, y)
          && p->size == q->size && p->align == q->align);
 }
 
-/* This routine is called when we determine that we need a mem_attrs entry.
-   It marks the associated decl and RTL as being used, if present.  */
-
-static void
-mem_attrs_mark (x)
-     const void *x;
-{
-  mem_attrs *p = (mem_attrs *) x;
-
-  if (p->expr)
-    ggc_mark_tree (p->expr);
-
-  if (p->offset)
-    ggc_mark_rtx (p->offset);
-
-  if (p->size)
-    ggc_mark_rtx (p->size);
-}
-
 /* Allocate a new mem_attrs structure and insert it into the hash table if
    one identical to it is not already in the table.  We are doing this for
    MEM of mode MODE.  */
@@ -811,17 +793,17 @@ gen_reg_rtx (mode)
       rtx *new1;
       tree *new2;
 
-      new = xrealloc (f->emit->regno_pointer_align, old_size * 2);
+      new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
       memset (new + old_size, 0, old_size);
       f->emit->regno_pointer_align = (unsigned char *) new;
 
-      new1 = (rtx *) xrealloc (f->emit->x_regno_reg_rtx,
-                              old_size * 2 * sizeof (rtx));
+      new1 = (rtx *) ggc_realloc (f->emit->x_regno_reg_rtx,
+                                 old_size * 2 * sizeof (rtx));
       memset (new1 + old_size, 0, old_size * sizeof (rtx));
       regno_reg_rtx = new1;
 
-      new2 = (tree *) xrealloc (f->emit->regno_decl,
-                               old_size * 2 * sizeof (tree));
+      new2 = (tree *) ggc_realloc (f->emit->regno_decl,
+                                  old_size * 2 * sizeof (tree));
       memset (new2 + old_size, 0, old_size * sizeof (tree));
       f->emit->regno_decl = new2;
 
@@ -2237,21 +2219,6 @@ restore_emit_status (p)
 {
   last_label_num = 0;
 }
-
-/* 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.  */
-
-void
-free_emit_status (f)
-     struct function *f;
-{
-  free (f->emit->x_regno_reg_rtx);
-  free (f->emit->regno_pointer_align);
-  free (f->emit->regno_decl);
-  free (f->emit);
-  f->emit = NULL;
-}
 \f
 /* Go through all the RTL insn bodies and copy any invalid shared
    structure.  This routine should only be called once.  */
@@ -4436,6 +4403,9 @@ emit (x)
     abort ();
 }
 \f
+/* Space for free sequence stack entries.  */
+static GTY ((deletable (""))) struct sequence_stack *free_sequence_stack;
+
 /* Begin emitting insns to a sequence which can be packaged in an
    RTL_EXPR.  If this sequence will contain something that might cause
    the compiler to pop arguments to function calls (because those
@@ -4449,7 +4419,13 @@ start_sequence ()
 {
   struct sequence_stack *tem;
 
-  tem = (struct sequence_stack *) xmalloc (sizeof (struct sequence_stack));
+  if (free_sequence_stack != NULL)
+    {
+      tem = free_sequence_stack;
+      free_sequence_stack = tem->next;
+    }
+  else
+    tem = (struct sequence_stack *) ggc_alloc (sizeof (struct sequence_stack));
 
   tem->next = seq_stack;
   tem->first = first_insn;
@@ -4566,7 +4542,9 @@ end_sequence ()
   seq_rtl_expr = tem->sequence_rtl_expr;
   seq_stack = tem->next;
 
-  free (tem);
+  memset (tem, 0, sizeof (*tem));
+  tem->next = free_sequence_stack;
+  free_sequence_stack = tem;
 }
 
 /* This works like end_sequence, but records the old sequence in FIRST
@@ -4824,7 +4802,7 @@ init_emit ()
 {
   struct function *f = cfun;
 
-  f->emit = (struct emit_status *) xmalloc (sizeof (struct emit_status));
+  f->emit = (struct emit_status *) ggc_alloc (sizeof (struct emit_status));
   first_insn = NULL;
   last_insn = NULL;
   seq_rtl_expr = NULL;
@@ -4841,14 +4819,16 @@ init_emit ()
   f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
 
   f->emit->regno_pointer_align
-    = (unsigned char *) xcalloc (f->emit->regno_pointer_align_length,
-                                sizeof (unsigned char));
+    = (unsigned char *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+                                          * sizeof (unsigned char));
 
   regno_reg_rtx
-    = (rtx *) xcalloc (f->emit->regno_pointer_align_length, sizeof (rtx));
+    = (rtx *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+                                * sizeof (rtx));
 
   f->emit->regno_decl
-    = (tree *) xcalloc (f->emit->regno_pointer_align_length, sizeof (tree));
+    = (tree *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
+                                 * sizeof (tree));
 
   /* Put copies of all the virtual register rtx into regno_reg_rtx.  */
   init_virtual_regs (f->emit);
@@ -4884,46 +4864,6 @@ init_emit ()
 #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_status (es)
-     struct emit_status *es;
-{
-  rtx *r;
-  tree *t;
-  int i;
-
-  if (es == 0)
-    return;
-
-  for (i = es->regno_pointer_align_length, r = es->x_regno_reg_rtx,
-       t = es->regno_decl;
-       i > 0; --i, ++r, ++t)
-    {
-      ggc_mark_rtx (*r);
-      ggc_mark_tree (*t);
-    }
-
-  mark_sequence_stack (es->sequence_stack);
-  ggc_mark_tree (es->sequence_rtl_expr);
-  ggc_mark_rtx (es->x_first_insn);
-}
-
 /* Generate the constant 0.  */
 
 static rtx
@@ -4966,15 +4906,12 @@ init_emit_once (line_numbers)
      tables.  */
   const_int_htab = htab_create (37, const_int_htab_hash,
                                const_int_htab_eq, NULL);
-  ggc_add_deletable_htab (const_int_htab, 0, 0);
 
   const_double_htab = htab_create (37, const_double_htab_hash,
                                   const_double_htab_eq, NULL);
-  ggc_add_deletable_htab (const_double_htab, 0, 0);
 
   mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
                                mem_attrs_htab_eq, NULL);
-  ggc_add_deletable_htab (mem_attrs_htab, 0, mem_attrs_mark);
 
   no_line_numbers = ! line_numbers;
 
@@ -5029,9 +4966,6 @@ init_emit_once (line_numbers)
     gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
   virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
 
-  /* These rtx must be roots if GC is enabled.  */
-  ggc_add_rtx_root (global_rtl, GR_MAX);
-
 #ifdef INIT_EXPANDERS
   /* This is to initialize {init|mark|free}_machine_status before the first
      call to push_function_context_to.  This is needed by the Chill front
@@ -5047,7 +4981,6 @@ init_emit_once (line_numbers)
   for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
     const_int_rtx[i + MAX_SAVED_CONST_INT] =
       gen_rtx_raw_CONST_INT (VOIDmode, i);
-  ggc_add_rtx_root (const_int_rtx, 2 * MAX_SAVED_CONST_INT + 1);
 
   if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
       && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
@@ -5100,12 +5033,6 @@ init_emit_once (line_numbers)
   if (STORE_FLAG_VALUE == 1)
     const_tiny_rtx[1][(int) BImode] = const1_rtx;
 
-  /* For bounded pointers, `&const_tiny_rtx[0][0]' is not the same as
-     `(rtx *) const_tiny_rtx'.  The former has bounds that only cover
-     `const_tiny_rtx[0]', whereas the latter has bounds that cover all.  */
-  ggc_add_rtx_root ((rtx *) const_tiny_rtx, sizeof const_tiny_rtx / sizeof (rtx));
-  ggc_add_rtx_root (&const_true_rtx, 1);
-
 #ifdef RETURN_ADDRESS_POINTER_REGNUM
   return_address_pointer_rtx
     = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
@@ -5152,13 +5079,6 @@ init_emit_once (line_numbers)
 
   if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
     pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
-
-  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);
-  ggc_add_rtx_root (&static_chain_rtx, 1);
-  ggc_add_rtx_root (&static_chain_incoming_rtx, 1);
-  ggc_add_rtx_root (&return_address_pointer_rtx, 1);
 }
 \f
 /* Query and clear/ restore no_line_numbers.  This is used by the
@@ -5249,3 +5169,5 @@ emit_copy_of_insn_after (insn, after)
     }
   return new;
 }
+
+#include "gt-emit-rtl.h"
index a2f2c69a1e1358630577e841b6a06348b7b8418a..53db90e8c0a5c95f7a9710e6c377eba634cf60c0 100644 (file)
@@ -100,20 +100,19 @@ tree (*lang_eh_runtime_type) PARAMS ((tree));
 
 /* A hash table of label to region number.  */
 
-struct ehl_map_entry
+struct ehl_map_entry GTY(())
 {
   rtx label;
   struct eh_region *region;
 };
 
-static htab_t exception_handler_label_map;
-
 static int call_site_base;
 static unsigned int sjlj_funcdef_number;
-static htab_t type_to_runtime_map;
+static GTY ((param_is (union tree_node)))
+  htab_t type_to_runtime_map;
 
 /* Describe the SjLj_Function_Context structure.  */
-static tree sjlj_fc_type_node;
+static GTY(()) tree sjlj_fc_type_node;
 static int sjlj_fc_call_site_ofs;
 static int sjlj_fc_data_ofs;
 static int sjlj_fc_personality_ofs;
@@ -121,7 +120,7 @@ static int sjlj_fc_lsda_ofs;
 static int sjlj_fc_jbuf_ofs;
 \f
 /* Describes one exception region.  */
-struct eh_region
+struct eh_region GTY(())
 {
   /* The immediately surrounding region.  */
   struct eh_region *outer;
@@ -151,50 +150,50 @@ struct eh_region
   } type;
 
   /* Holds the action to perform based on the preceding type.  */
-  union {
+  union eh_region_u {
     /* A list of catch blocks, a surrounding try block,
        and the label for continuing after a catch.  */
-    struct {
+    struct eh_region_u_try {
       struct eh_region *catch;
       struct eh_region *last_catch;
       struct eh_region *prev_try;
       rtx continue_label;
-    } try;
+    } GTY ((tag ("ERT_TRY"))) try;
 
     /* The list through the catch handlers, the list of type objects
        matched, and the list of associated filters.  */
-    struct {
+    struct eh_region_u_catch {
       struct eh_region *next_catch;
       struct eh_region *prev_catch;
       tree type_list;
       tree filter_list;
-    } catch;
+    } GTY ((tag ("ERT_CATCH"))) catch;
 
     /* A tree_list of allowed types.  */
-    struct {
+    struct eh_region_u_allowed {
       tree type_list;
       int filter;
-    } allowed;
+    } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
 
     /* The type given by a call to "throw foo();", or discovered
        for a throw.  */
-    struct {
+    struct eh_region_u_throw {
       tree type;
-    } throw;
+    } GTY ((tag ("ERT_THROW"))) throw;
 
     /* Retain the cleanup expression even after expansion so that
        we can match up fixup regions.  */
-    struct {
+    struct eh_region_u_cleanup {
       tree exp;
-    } cleanup;
+    } GTY ((tag ("ERT_CLEANUP"))) cleanup;
 
     /* The real region (by expression and by pointer) that fixup code
        should live in.  */
-    struct {
+    struct eh_region_u_fixup {
       tree cleanup_exp;
       struct eh_region *real_region;
-    } fixup;
-  } u;
+    } GTY ((tag ("ERT_FIXUP"))) fixup;
+  } GTY ((desc ("%0.type"))) u;
 
   /* Entry point for this region's handler before landing pads are built.  */
   rtx label;
@@ -210,14 +209,20 @@ struct eh_region
   rtx resume;
 };
 
+struct call_site_record GTY(())
+{
+  rtx landing_pad;
+  int action;
+};
+
 /* Used to save exception status for each function.  */
-struct eh_status
+struct eh_status GTY(())
 {
   /* The tree of all regions for this function.  */
   struct eh_region *region_tree;
 
   /* The same information as an indexable array.  */
-  struct eh_region **region_array;
+  struct eh_region ** GTY ((length ("%h.last_region_number"))) region_array;
 
   /* The most recently open region.  */
   struct eh_region *cur_region;
@@ -235,11 +240,10 @@ struct eh_status
   varray_type ehspec_data;
   varray_type action_record_data;
 
-  struct call_site_record
-  {
-    rtx landing_pad;
-    int action;
-  } *call_site_data;
+  htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
+
+  struct call_site_record * GTY ((length ("%h.call_site_data_used"))) 
+    call_site_data;
   int call_site_data_used;
   int call_site_data_size;
 
@@ -252,17 +256,9 @@ struct eh_status
 };
 
 \f
-static void mark_eh_region                     PARAMS ((struct eh_region *));
-static int mark_ehl_map_entry                  PARAMS ((PTR *, PTR));
-static void mark_ehl_map                       PARAMS ((void *));
-
-static void free_region                                PARAMS ((struct eh_region *));
-
 static int t2r_eq                              PARAMS ((const PTR,
                                                         const PTR));
 static hashval_t t2r_hash                      PARAMS ((const PTR));
-static int t2r_mark_1                          PARAMS ((PTR *, PTR));
-static void t2r_mark                           PARAMS ((PTR));
 static void add_type_for_runtime               PARAMS ((tree));
 static tree lookup_type_for_runtime            PARAMS ((tree));
 
@@ -386,13 +382,10 @@ doing_eh (do_warn)
 void
 init_eh ()
 {
-  ggc_add_root (&exception_handler_label_map, 1, 1, mark_ehl_map);
-
   if (! flag_exceptions)
     return;
 
-  type_to_runtime_map = htab_create (31, t2r_hash, t2r_eq, NULL);
-  ggc_add_root (&type_to_runtime_map, 1, sizeof (htab_t), t2r_mark);
+  type_to_runtime_map = htab_create_ggc (31, t2r_hash, t2r_eq, NULL);
 
   /* Create the SjLj_Function_Context structure.  This should match
      the definition in unwind-sjlj.c.  */
@@ -401,7 +394,6 @@ init_eh ()
       tree f_jbuf, f_per, f_lsda, f_prev, f_cs, f_data, tmp;
 
       sjlj_fc_type_node = (*lang_hooks.types.make_type) (RECORD_TYPE);
-      ggc_add_tree_root (&sjlj_fc_type_node, 1);
 
       f_prev = build_decl (FIELD_DECL, get_identifier ("__prev"),
                           build_pointer_type (sjlj_fc_type_node));
@@ -484,209 +476,9 @@ init_eh ()
 void
 init_eh_for_function ()
 {
-  cfun->eh = (struct eh_status *) xcalloc (1, sizeof (struct eh_status));
-}
-
-/* Mark EH for GC.  */
-
-static void
-mark_eh_region (region)
-     struct eh_region *region;
-{
-  if (! region)
-    return;
-
-  switch (region->type)
-    {
-    case ERT_UNKNOWN:
-      /* This can happen if a nested function is inside the body of a region
-        and we do a GC as part of processing it.  */
-      break;
-    case ERT_CLEANUP:
-      ggc_mark_tree (region->u.cleanup.exp);
-      break;
-    case ERT_TRY:
-      ggc_mark_rtx (region->u.try.continue_label);
-      break;
-    case ERT_CATCH:
-      ggc_mark_tree (region->u.catch.type_list);
-      ggc_mark_tree (region->u.catch.filter_list);
-      break;
-    case ERT_ALLOWED_EXCEPTIONS:
-      ggc_mark_tree (region->u.allowed.type_list);
-      break;
-    case ERT_MUST_NOT_THROW:
-      break;
-    case ERT_THROW:
-      ggc_mark_tree (region->u.throw.type);
-      break;
-    case ERT_FIXUP:
-      ggc_mark_tree (region->u.fixup.cleanup_exp);
-      break;
-    default:
-      abort ();
-    }
-
-  ggc_mark_rtx (region->label);
-  ggc_mark_rtx (region->resume);
-  ggc_mark_rtx (region->landing_pad);
-  ggc_mark_rtx (region->post_landing_pad);
-}
-
-static int
-mark_ehl_map_entry (pentry, data)
-     PTR *pentry;
-     PTR data ATTRIBUTE_UNUSED;
-{
-  struct ehl_map_entry *entry = *(struct ehl_map_entry **) pentry;
-  ggc_mark_rtx (entry->label);
-  return 1;
-}
-
-static void
-mark_ehl_map (pp)
-    void *pp;
-{
-  htab_t map = *(htab_t *) pp;
-  if (map)
-    htab_traverse (map, mark_ehl_map_entry, NULL);
+  cfun->eh = (struct eh_status *) 
+    ggc_alloc_cleared (sizeof (struct eh_status));
 }
-
-void
-mark_eh_status (eh)
-     struct eh_status *eh;
-{
-  int i;
-
-  if (eh == 0)
-    return;
-
-  /* If we've called collect_eh_region_array, use it.  Otherwise walk
-     the tree non-recursively.  */
-  if (eh->region_array)
-    {
-      for (i = eh->last_region_number; i > 0; --i)
-       {
-         struct eh_region *r = eh->region_array[i];
-         if (r && r->region_number == i)
-           mark_eh_region (r);
-       }
-    }
-  else if (eh->region_tree)
-    {
-      struct eh_region *r = eh->region_tree;
-      while (1)
-       {
-         mark_eh_region (r);
-         if (r->inner)
-           r = r->inner;
-         else if (r->next_peer)
-           r = r->next_peer;
-         else
-           {
-             do {
-               r = r->outer;
-               if (r == NULL)
-                 goto tree_done;
-             } while (r->next_peer == NULL);
-             r = r->next_peer;
-           }
-       }
-    tree_done:;
-    }
-
-  ggc_mark_rtx (eh->filter);
-  ggc_mark_rtx (eh->exc_ptr);
-  ggc_mark_tree_varray (eh->ttype_data);
-
-  if (eh->call_site_data)
-    {
-      for (i = eh->call_site_data_used - 1; i >= 0; --i)
-       ggc_mark_rtx (eh->call_site_data[i].landing_pad);
-    }
-
-  ggc_mark_rtx (eh->ehr_stackadj);
-  ggc_mark_rtx (eh->ehr_handler);
-  ggc_mark_rtx (eh->ehr_label);
-
-  ggc_mark_rtx (eh->sjlj_fc);
-  ggc_mark_rtx (eh->sjlj_exit_after);
-}
-
-static inline void
-free_region (r)
-     struct eh_region *r;
-{
-  /* Note that the aka bitmap is freed by regset_release_memory.  But if
-     we ever replace with a non-obstack implementation, this would be
-     the place to do it.  */
-  free (r);
-}
-
-void
-free_eh_status (f)
-     struct function *f;
-{
-  struct eh_status *eh = f->eh;
-
-  if (eh->region_array)
-    {
-      int i;
-      for (i = eh->last_region_number; i > 0; --i)
-       {
-         struct eh_region *r = eh->region_array[i];
-         /* Mind we don't free a region struct more than once.  */
-         if (r && r->region_number == i)
-           free_region (r);
-       }
-      free (eh->region_array);
-    }
-  else if (eh->region_tree)
-    {
-      struct eh_region *next, *r = eh->region_tree;
-      while (1)
-       {
-         if (r->inner)
-           r = r->inner;
-         else if (r->next_peer)
-           {
-             next = r->next_peer;
-             free_region (r);
-             r = next;
-           }
-         else
-           {
-             do {
-               next = r->outer;
-               free_region (r);
-               r = next;
-               if (r == NULL)
-                 goto tree_done;
-             } while (r->next_peer == NULL);
-             next = r->next_peer;
-             free_region (r);
-             r = next;
-           }
-       }
-    tree_done:;
-    }
-
-  VARRAY_FREE (eh->ttype_data);
-  VARRAY_FREE (eh->ehspec_data);
-  VARRAY_FREE (eh->action_record_data);
-  if (eh->call_site_data)
-    free (eh->call_site_data);
-
-  free (eh);
-  f->eh = NULL;
-
-  if (exception_handler_label_map)
-    {
-      htab_delete (exception_handler_label_map);
-      exception_handler_label_map = NULL;
-    }
-}
-
 \f
 /* Start an exception handling region.  All instructions emitted
    after this point are considered to be part of the region until
@@ -703,7 +495,7 @@ expand_eh_region_start ()
     return;
 
   /* Insert a new blank region as a leaf in the tree.  */
-  new_region = (struct eh_region *) xcalloc (1, sizeof (*new_region));
+  new_region = (struct eh_region *) ggc_alloc_cleared (sizeof (*new_region));
   cur_region = cfun->eh->cur_region;
   new_region->outer = cur_region;
   if (cur_region)
@@ -1076,7 +868,8 @@ collect_eh_region_array ()
   if (! i)
     return;
 
-  array = xcalloc (cfun->eh->last_region_number + 1, sizeof (*array));
+  array = ggc_alloc_cleared ((cfun->eh->last_region_number + 1)
+                            * sizeof (*array));
   cfun->eh->region_array = array;
 
   while (1)
@@ -1377,12 +1170,12 @@ add_ehl_entry (label, region)
 
   LABEL_PRESERVE_P (label) = 1;
 
-  entry = (struct ehl_map_entry *) xmalloc (sizeof (*entry));
+  entry = (struct ehl_map_entry *) ggc_alloc (sizeof (*entry));
   entry->label = label;
   entry->region = region;
 
   slot = (struct ehl_map_entry **)
-    htab_find_slot (exception_handler_label_map, entry, INSERT);
+    htab_find_slot (cfun->eh->exception_handler_label_map, entry, INSERT);
 
   /* Before landing pad creation, each exception handler has its own
      label.  After landing pad creation, the exception handlers may
@@ -1400,7 +1193,6 @@ ehl_free (pentry)
 {
   struct ehl_map_entry *entry = (struct ehl_map_entry *)pentry;
   LABEL_PRESERVE_P (entry->label) = 0;
-  free (entry);
 }
 
 void
@@ -1408,15 +1200,15 @@ find_exception_handler_labels ()
 {
   int i;
 
-  if (exception_handler_label_map)
-    htab_empty (exception_handler_label_map);
+  if (cfun->eh->exception_handler_label_map)
+    htab_empty (cfun->eh->exception_handler_label_map);
   else
     {
       /* ??? The expansion factor here (3/2) must be greater than the htab
         occupancy factor (4/3) to avoid unnecessary resizing.  */
-      exception_handler_label_map
-       = htab_create (cfun->eh->last_region_number * 3 / 2,
-                      ehl_hash, ehl_eq, ehl_free);
+      cfun->eh->exception_handler_label_map
+        = htab_create_ggc (cfun->eh->last_region_number * 3 / 2,
+                          ehl_hash, ehl_eq, NULL);
     }
 
   if (cfun->eh->region_tree == NULL)
@@ -1468,7 +1260,7 @@ duplicate_eh_region_1 (o, map)
      struct inline_remap *map;
 {
   struct eh_region *n
-    = (struct eh_region *) xcalloc (1, sizeof (struct eh_region));
+    = (struct eh_region *) ggc_alloc_cleared (sizeof (struct eh_region));
 
   n->region_number = o->region_number + cfun->eh->last_region_number;
   n->type = o->type;
@@ -1633,23 +1425,6 @@ t2r_hash (pentry)
   return TYPE_HASH (TREE_PURPOSE (entry));
 }
 
-static int
-t2r_mark_1 (slot, data)
-     PTR *slot;
-     PTR data ATTRIBUTE_UNUSED;
-{
-  tree contents = (tree) *slot;
-  ggc_mark_tree (contents);
-  return 1;
-}
-
-static void
-t2r_mark (addr)
-     PTR addr;
-{
-  htab_traverse (*(htab_t *)addr, t2r_mark_1, NULL);
-}
-
 static void
 add_type_for_runtime (type)
      tree type;
@@ -1681,7 +1456,7 @@ lookup_type_for_runtime (type)
 \f
 /* Represent an entry in @TTypes for either catch actions
    or exception filter actions.  */
-struct ttypes_filter
+struct ttypes_filter GTY(())
 {
   tree t;
   int filter;
@@ -2559,16 +2334,16 @@ remove_exception_handler_label (label)
 
   /* If exception_handler_label_map was not built yet,
      there is nothing to do.  */
-  if (exception_handler_label_map == NULL)
+  if (cfun->eh->exception_handler_label_map == NULL)
     return;
 
   tmp.label = label;
   slot = (struct ehl_map_entry **)
-    htab_find_slot (exception_handler_label_map, &tmp, NO_INSERT);
+    htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
   if (! slot)
     abort ();
 
-  htab_clear_slot (exception_handler_label_map, (void **) slot);
+  htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
 }
 
 /* Splice REGION from the region tree etc.  */
@@ -2598,7 +2373,7 @@ remove_eh_handler (region)
   if (outer)
     {
       if (!outer->aka)
-       outer->aka = BITMAP_XMALLOC ();
+        outer->aka = BITMAP_GGC_ALLOC ();
       if (region->aka)
        bitmap_a_or_b (outer->aka, outer->aka, region->aka);
       bitmap_set_bit (outer->aka, region->region_number);
@@ -2657,8 +2432,6 @@ remove_eh_handler (region)
            remove_eh_handler (try);
        }
     }
-
-  free_region (region);
 }
 
 /* LABEL heads a basic block that is about to be deleted.  If this
@@ -2681,7 +2454,7 @@ maybe_remove_eh_handler (label)
 
   tmp.label = label;
   slot = (struct ehl_map_entry **)
-    htab_find_slot (exception_handler_label_map, &tmp, NO_INSERT);
+    htab_find_slot (cfun->eh->exception_handler_label_map, &tmp, NO_INSERT);
   if (! slot)
     return;
   region = (*slot)->region;
@@ -2694,7 +2467,7 @@ maybe_remove_eh_handler (label)
      are no more contained calls, which we don't see here.  */
   if (region->type == ERT_MUST_NOT_THROW)
     {
-      htab_clear_slot (exception_handler_label_map, (void **) slot);
+      htab_clear_slot (cfun->eh->exception_handler_label_map, (void **) slot);
       region->label = NULL_RTX;
     }
   else
@@ -2708,7 +2481,7 @@ void
 for_each_eh_label (callback)
      void (*callback) PARAMS ((rtx));
 {
-  htab_traverse (exception_handler_label_map, for_each_eh_label_1,
+  htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
                 (void *)callback);
 }
 
@@ -2727,7 +2500,7 @@ for_each_eh_label_1 (pentry, data)
 /* This section describes CFG exception edges for flow.  */
 
 /* For communicating between calls to reachable_next_level.  */
-struct reachable_info
+struct reachable_info GTY(())
 {
   tree types_caught;
   tree types_allowed;
@@ -3507,7 +3280,7 @@ add_call_site (landing_pad, action)
     {
       size = (size ? size * 2 : 64);
       data = (struct call_site_record *)
-       xrealloc (data, sizeof (*data) * size);
+       ggc_realloc (data, sizeof (*data) * size);
       cfun->eh->call_site_data = data;
       cfun->eh->call_site_data_size = size;
     }
@@ -3982,3 +3755,5 @@ output_function_exception_table ()
   if (USING_SJLJ_EXCEPTIONS)
     sjlj_funcdef_number += 1;
 }
+
+#include "gt-except.h"
index fb1c2a0388c3fb785c1973f1e8ff1424bcec8a32..2846636ec202860f35e70e8ebb12602f5a9a7f0b 100644 (file)
@@ -1422,14 +1422,13 @@ allocate_dynamic_stack_space (size, target, known_align)
    run-time routine to call to check the stack, so provide a mechanism for
    calling that routine.  */
 
-static rtx stack_check_libfunc;
+static GTY(()) rtx stack_check_libfunc;
 
 void
 set_stack_check_libfunc (libfunc)
      rtx libfunc;
 {
   stack_check_libfunc = libfunc;
-  ggc_add_rtx_root (&stack_check_libfunc, 1);
 }
 \f
 /* Emit one stack probe at ADDRESS, an address within the stack.  */
@@ -1684,3 +1683,6 @@ rtx_to_tree_code (code)
     }
   return ((int) tcode);
 }
+
+#include "gt-explow.h"
+
index e633232c06ece690e489d40d2192581cf9c2e736..e9cb241153049a3ec398b184335ddecae98408ca 100644 (file)
@@ -298,7 +298,7 @@ init_expr_once ()
 void
 init_expr ()
 {
-  cfun->expr = (struct expr_status *) xmalloc (sizeof (struct expr_status));
+  cfun->expr = (struct expr_status *) ggc_alloc (sizeof (struct expr_status));
 
   pending_chain = 0;
   pending_stack_adjust = 0;
@@ -309,26 +309,6 @@ init_expr ()
   forced_labels = 0;
 }
 
-void
-mark_expr_status (p)
-     struct expr_status *p;
-{
-  if (p == NULL)
-    return;
-
-  ggc_mark_rtx (p->x_saveregs_value);
-  ggc_mark_rtx (p->x_apply_args_value);
-  ggc_mark_rtx (p->x_forced_labels);
-}
-
-void
-free_expr_status (f)
-     struct function *f;
-{
-  free (f->expr);
-  f->expr = NULL;
-}
-
 /* Small sanity check that the queue is empty at the end of a function.  */
 
 void
@@ -1650,6 +1630,7 @@ move_by_pieces_1 (genfun, mode, data)
    Return the address of the new block, if memcpy is called and returns it,
    0 otherwise.  */
 
+static GTY(()) tree block_move_fn;
 rtx
 emit_block_move (x, y, size)
      rtx x, y;
@@ -1657,7 +1638,6 @@ emit_block_move (x, y, size)
 {
   rtx retval = 0;
 #ifdef TARGET_MEM_FUNCTIONS
-  static tree fn;
   tree call_expr, arg_list;
 #endif
   unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
@@ -1781,23 +1761,22 @@ emit_block_move (x, y, size)
 
         So instead of using a libcall sequence we build up a suitable
         CALL_EXPR and expand the call in the normal fashion.  */
-      if (fn == NULL_TREE)
+      if (block_move_fn == NULL_TREE)
        {
          tree fntype;
 
          /* This was copied from except.c, I don't know if all this is
             necessary in this context or not.  */
-         fn = get_identifier ("memcpy");
+         block_move_fn = get_identifier ("memcpy");
          fntype = build_pointer_type (void_type_node);
          fntype = build_function_type (fntype, NULL_TREE);
-         fn = build_decl (FUNCTION_DECL, fn, fntype);
-         ggc_add_tree_root (&fn, 1);
-         DECL_EXTERNAL (fn) = 1;
-         TREE_PUBLIC (fn) = 1;
-         DECL_ARTIFICIAL (fn) = 1;
-         TREE_NOTHROW (fn) = 1;
-         make_decl_rtl (fn, NULL);
-         assemble_external (fn);
+         block_move_fn = build_decl (FUNCTION_DECL, block_move_fn, fntype);
+         DECL_EXTERNAL (block_move_fn) = 1;
+         TREE_PUBLIC (block_move_fn) = 1;
+         DECL_ARTIFICIAL (block_move_fn) = 1;
+         TREE_NOTHROW (block_move_fn) = 1;
+         make_decl_rtl (block_move_fn, NULL);
+         assemble_external (block_move_fn);
        }
 
       /* We need to make an argument list for the function call.
@@ -1815,8 +1794,10 @@ emit_block_move (x, y, size)
       TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arg_list))) = NULL_TREE;
 
       /* Now we have to build up the CALL_EXPR itself.  */
-      call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
-      call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
+      call_expr = build1 (ADDR_EXPR, 
+                         build_pointer_type (TREE_TYPE (block_move_fn)), 
+                         block_move_fn);
+      call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (block_move_fn)),
                         call_expr, arg_list, NULL_TREE);
       TREE_SIDE_EFFECTS (call_expr) = 1;
 
@@ -2606,13 +2587,13 @@ store_by_pieces_2 (genfun, mode, data)
 /* Write zeros through the storage of OBJECT.  If OBJECT has BLKmode, SIZE is
    its length in bytes.  */
 
+static GTY(()) tree block_clear_fn;
 rtx
 clear_storage (object, size)
      rtx object;
      rtx size;
 {
 #ifdef TARGET_MEM_FUNCTIONS
-  static tree fn;
   tree call_expr, arg_list;
 #endif
   rtx retval = 0;
@@ -2725,23 +2706,23 @@ clear_storage (object, size)
 
             So instead of using a libcall sequence we build up a suitable
             CALL_EXPR and expand the call in the normal fashion.  */
-         if (fn == NULL_TREE)
+         if (block_clear_fn == NULL_TREE)
            {
              tree fntype;
 
              /* This was copied from except.c, I don't know if all this is
                 necessary in this context or not.  */
-             fn = get_identifier ("memset");
+             block_clear_fn = get_identifier ("memset");
              fntype = build_pointer_type (void_type_node);
              fntype = build_function_type (fntype, NULL_TREE);
-             fn = build_decl (FUNCTION_DECL, fn, fntype);
-             ggc_add_tree_root (&fn, 1);
-             DECL_EXTERNAL (fn) = 1;
-             TREE_PUBLIC (fn) = 1;
-             DECL_ARTIFICIAL (fn) = 1;
-             TREE_NOTHROW (fn) = 1;
-             make_decl_rtl (fn, NULL);
-             assemble_external (fn);
+             block_clear_fn = build_decl (FUNCTION_DECL, block_clear_fn,
+                                          fntype);
+             DECL_EXTERNAL (block_clear_fn) = 1;
+             TREE_PUBLIC (block_clear_fn) = 1;
+             DECL_ARTIFICIAL (block_clear_fn) = 1;
+             TREE_NOTHROW (block_clear_fn) = 1;
+             make_decl_rtl (block_clear_fn, NULL);
+             assemble_external (block_clear_fn);
            }
 
          /* We need to make an argument list for the function call.
@@ -2762,8 +2743,9 @@ clear_storage (object, size)
 
          /* Now we have to build up the CALL_EXPR itself.  */
          call_expr = build1 (ADDR_EXPR,
-                             build_pointer_type (TREE_TYPE (fn)), fn);
-         call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
+                             build_pointer_type (TREE_TYPE (block_clear_fn)),
+                             block_clear_fn);
+         call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (block_clear_fn)),
                             call_expr, arg_list, NULL_TREE);
          TREE_SIDE_EFFECTS (call_expr) = 1;
 
@@ -10785,3 +10767,5 @@ try_tablejump (index_type, index_expr, minval, range,
                table_label, default_label);
   return 1;
 }
+
+#include "gt-expr.h"
index 6b05218073385977b91af8e79820b8a8bd273c84..5ebefbad8bad5b322a804e826ca4cb4dbcbda2ba 100644 (file)
@@ -369,10 +369,6 @@ extern void init_expr_once PARAMS ((void));
 /* This is run at the start of compiling a function.  */
 extern void init_expr PARAMS ((void));
 
-/* This function is run once to initialize stor-layout.c.  */
-
-extern void init_stor_layout_once PARAMS ((void));
-
 /* This is run at the end of compiling a function.  */
 extern void finish_expr_for_function PARAMS ((void));
 
index 005b151bbdc6f02299977b04988cb5346a223163..f4634d166723abf81c400aa7cabb9f867f379000 100644 (file)
@@ -1,3 +1,42 @@
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       * Make-lang.in (f/com.o): Depend on debug.h.
+       * com.c: Include debug.h.
+       (LANG_HOOKS_MARK_TREE): Delete.
+       (struct lang_identifier): Use gengtype.
+       (union lang_tree_node): New.
+       (struct lang_decl): New dummy definition.
+       (struct lang_type): New dummy definition.
+       (ffe_mark_tree): Delete.
+
+       * com.c (struct language_function): New dummy structure.
+
+       * Make-lang.in: Add rules to generate gt-f-ste.h gtype-f.h; allow
+       for filename changes.
+       (com.o): Allow for filename changes; add gtype-f.h as dependency.
+       (ste.o): Add gt-f-ste.h as dependency.
+       * config-lang.in (gtfiles): Add com.h, ste.c.
+       * com.c: Replace uses of ggc_add_* with GTY markers.  Include
+       gtype-f.h.
+       (mark_binding_level): Delete.
+       * com.h: Replace uses of ggc_add_* with GTY markers.
+       * ste.c: Replace uses of ggc_add_* with GTY markers.  Include
+       gt-f-ste.h.
+
+       * Make-lang.in (f/gt-com.h): Build using gengtype.
+       (com.o): Depend on f/gt-com.h.
+       * com.c: Rename struct binding_level to f_binding_level.
+       (struct f_binding_level): Use gengtype.
+       (struct tree_ggc_tracker): Use gengtype.
+       (mark_tracker_head): Use gt_ggc_m_tree_ggc_tracker.
+       (make_binding_level): Use GGC.
+       (mark_binding_level): Use gt_ggc_m_f_binding_level.
+       (ffecom_init_decl_processing): Change free_binding_level
+       to a deletable root.
+       * config-lang.in (gtfiles): Define.
+       * where.c: Strings need no longer be allocated in GCable memory;
+       remove my change of 30 Dec 1999.
+
 2002-05-31  Matthew Woodcraft  <mattheww@chiark.greenend.org.uk>
 
        * lang-specs.h: Use cpp_debug_options.
index 288ed9a156f5b64fbe0924bfb0d85c8dfb61cd13..86cf411fa37bc742d5e647ca41452846497cb866 100644 (file)
@@ -137,6 +137,8 @@ f/fini.o:
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
              -c $(srcdir)/f/fini.c $(OUTPUT_OPTION)
 
+gt-f-com.h gt-f-ste.h gtype-f.h : s-gtype; @true
+
 #\f
 # Build hooks:
 
@@ -364,7 +366,7 @@ f/com.o: f/com.c f/proj.h $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
  f/bad.def f/where.h glimits.h f/top.h f/lex.h f/type.h f/intrin.h \
  f/intrin.def f/lab.h f/symbol.h f/symbol.def f/equiv.h f/storag.h f/global.h \
  f/name.h f/expr.h f/implic.h f/src.h f/st.h $(GGC_H) toplev.h diagnostic.h \
langhooks.h langhooks-def.h intl.h real.h
$(LANGHOOKS_DEF) langhooks.h intl.h real.h debug.h gt-f-com.h gtype-f.h
 f/data.o: f/data.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/data.h f/bld.h f/bld-op.def \
  f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def \
  f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h \
@@ -460,7 +462,8 @@ f/ste.o: f/ste.c f/proj.h $(CONFIG_H) $(SYSTEM_H) $(RTL_H) toplev.h f/ste.h \
  f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def \
  f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h \
  f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def f/stp.h \
- f/stt.h f/stamp-str f/sts.h f/stv.h f/stw.h f/expr.h f/sta.h $(GGC_H)
+ f/stt.h f/stamp-str f/sts.h f/stv.h f/stw.h f/expr.h f/sta.h $(GGC_H) \
+ gt-f-ste.h
 f/storag.o: f/storag.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/storag.h f/bld.h  \
  f/bld-op.def f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) \
  f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
index d66951542b4672683b539e9d47c8aed28f196d46..310a3107677e9da50994071b6d534f286cb92fcf 100644 (file)
@@ -93,6 +93,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "intl.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
+#include "debug.h"
 
 /* VMS-specific definitions */
 #ifdef VMS
@@ -155,7 +156,7 @@ tree string_type_node;
    inventions should be renamed to be canonical.  Note that only
    the ones currently required to be global are so.  */
 
-static tree ffecom_tree_fun_type_void;
+static GTY(()) tree ffecom_tree_fun_type_void;
 
 tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */
 tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */
@@ -166,13 +167,14 @@ tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
    just use build_function_type and build_pointer_type on the
    appropriate _tree_type array element.  */
 
-static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
-static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
-static tree ffecom_tree_subr_type;
-static tree ffecom_tree_ptr_to_subr_type;
-static tree ffecom_tree_blockdata_type;
+static GTY(()) tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
+static GTY(()) tree 
+  ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
+static GTY(()) tree ffecom_tree_subr_type;
+static GTY(()) tree ffecom_tree_ptr_to_subr_type;
+static GTY(()) tree ffecom_tree_blockdata_type;
 
-static tree ffecom_tree_xargc_;
+static GTY(()) tree ffecom_tree_xargc_;
 
 ffecomSymbol ffecom_symbol_null_
 =
@@ -188,10 +190,10 @@ ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE;
 
 int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
 tree ffecom_f2c_integer_type_node;
-tree ffecom_f2c_ptr_to_integer_type_node;
+static GTY(()) tree ffecom_f2c_ptr_to_integer_type_node;
 tree ffecom_f2c_address_type_node;
 tree ffecom_f2c_real_type_node;
-tree ffecom_f2c_ptr_to_real_type_node;
+static GTY(()) tree ffecom_f2c_ptr_to_real_type_node;
 tree ffecom_f2c_doublereal_type_node;
 tree ffecom_f2c_complex_type_node;
 tree ffecom_f2c_doublecomplex_type_node;
@@ -375,7 +377,7 @@ static void finish_function (int nested);
 static const char *ffe_printable_name (tree decl, int v);
 static void ffe_print_error_function (diagnostic_context *, const char *);
 static tree lookup_name_current_level (tree name);
-static struct binding_level *make_binding_level (void);
+static struct f_binding_level *make_binding_level (void);
 static void pop_f_function_context (void);
 static void push_f_function_context (void);
 static void push_parm_decl (tree parm);
@@ -397,15 +399,15 @@ static ffesymbol ffecom_primary_entry_ = NULL;
 static ffesymbol ffecom_nested_entry_ = NULL;
 static ffeinfoKind ffecom_primary_entry_kind_;
 static bool ffecom_primary_entry_is_proc_;
-static tree ffecom_outer_function_decl_;
-static tree ffecom_previous_function_decl_;
-static tree ffecom_which_entrypoint_decl_;
-static tree ffecom_float_zero_ = NULL_TREE;
-static tree ffecom_float_half_ = NULL_TREE;
-static tree ffecom_double_zero_ = NULL_TREE;
-static tree ffecom_double_half_ = NULL_TREE;
-static tree ffecom_func_result_;/* For functions. */
-static tree ffecom_func_length_;/* For CHARACTER fns. */
+static GTY(()) tree ffecom_outer_function_decl_;
+static GTY(()) tree ffecom_previous_function_decl_;
+static GTY(()) tree ffecom_which_entrypoint_decl_;
+static GTY(()) tree ffecom_float_zero_;
+static GTY(()) tree ffecom_float_half_;
+static GTY(()) tree ffecom_double_zero_;
+static GTY(()) tree ffecom_double_half_;
+static GTY(()) tree ffecom_func_result_;/* For functions. */
+static GTY(()) tree ffecom_func_length_;/* For CHARACTER fns. */
 static ffebld ffecom_list_blockdata_;
 static ffebld ffecom_list_common_;
 static ffebld ffecom_master_arglist_;
@@ -415,9 +417,9 @@ static ffetargetCharacterSize ffecom_master_size_;
 static int ffecom_num_fns_ = 0;
 static int ffecom_num_entrypoints_ = 0;
 static bool ffecom_is_altreturning_ = FALSE;
-static tree ffecom_multi_type_node_;
-static tree ffecom_multi_retval_;
-static tree
+static GTY(()) tree ffecom_multi_type_node_;
+static GTY(()) tree ffecom_multi_retval_;
+static GTY(()) tree
   ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype];
 static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */
 static bool ffecom_doing_entry_ = FALSE;
@@ -427,13 +429,7 @@ static int ffecom_typesize_integer1_;
 
 /* Holds pointer-to-function expressions.  */
 
-static tree ffecom_gfrt_[FFECOM_gfrt]
-=
-{
-#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX,CONST) NULL_TREE,
-#include "com-rt.def"
-#undef DEFGFRT
-};
+static GTY(()) tree ffecom_gfrt_[FFECOM_gfrt];
 
 /* Holds the external names of the functions.  */
 
@@ -530,7 +526,7 @@ static const char *const ffecom_gfrt_argstring_[FFECOM_gfrt]
 /* Note that the information in the `names' component of the global contour
    is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers.  */
 
-struct binding_level
+struct f_binding_level GTY(())
   {
     /* A chain of _DECL nodes for all variables, constants, functions,
        and typedef types.  These are in the reverse of the order supplied.
@@ -547,7 +543,7 @@ struct binding_level
     tree this_block;
 
     /* The binding level which this one is contained in (inherits from).  */
-    struct binding_level *level_chain;
+    struct f_binding_level *level_chain;
 
     /* 0: no ffecom_prepare_* functions called at this level yet;
        1: ffecom_prepare* functions called, except not ffecom_prepare_end;
@@ -555,36 +551,38 @@ struct binding_level
     int prep_state;
   };
 
-#define NULL_BINDING_LEVEL (struct binding_level *) NULL
+#define NULL_BINDING_LEVEL (struct f_binding_level *) NULL
 
 /* The binding level currently in effect.  */
 
-static struct binding_level *current_binding_level;
+static GTY(()) struct f_binding_level *current_binding_level;
 
 /* A chain of binding_level structures awaiting reuse.  */
 
-static struct binding_level *free_binding_level;
+static GTY((deletable (""))) struct f_binding_level *free_binding_level;
 
 /* The outermost binding level, for names of file scope.
    This is created when the compiler is started and exists
    through the entire run.  */
 
-static struct binding_level *global_binding_level;
+static struct f_binding_level *global_binding_level;
 
 /* Binding level structures are initialized by copying this one.  */
 
-static const struct binding_level clear_binding_level
+static const struct f_binding_level clear_binding_level
 =
 {NULL, NULL, NULL, NULL_BINDING_LEVEL, 0};
 
 /* Language-dependent contents of an identifier.  */
 
-struct lang_identifier
-  {
-    struct tree_identifier ignore;
-    tree global_value, local_value, label_value;
-    bool invented;
-  };
+struct lang_identifier GTY(())
+{
+  struct tree_identifier common;
+  tree global_value;
+  tree local_value;
+  tree label_value;
+  bool invented;
+};
 
 /* Macros for access to language-specific slots in an identifier.  */
 /* Each of these slots contains a DECL node or null.  */
@@ -605,6 +603,24 @@ struct lang_identifier
 #define IDENTIFIER_INVENTED(NODE)      \
   (((struct lang_identifier *)(NODE))->invented)
 
+/* The resulting tree type.  */
+union lang_tree_node 
+  GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
+{
+  union tree_node GTY ((tag ("0"), 
+                       desc ("tree_node_structure (&%h)"))) 
+    generic;
+  struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
+/* Fortran doesn't use either of these.  */
+struct lang_decl GTY(()) 
+{
+};
+struct lang_type GTY(())
+{
+};
+
 /* In identifiers, C uses the following fields in a special way:
    TREE_PUBLIC       to record that there was a previous local extern decl.
    TREE_USED         to record that such a decl was used.
@@ -614,11 +630,11 @@ struct lang_identifier
    that have names.  Here so we can clear out their names' definitions
    at the end of the function.  */
 
-static tree named_labels;
+static GTY(()) tree named_labels;
 
 /* A list of LABEL_DECLs from outer contexts that are currently shadowed.  */
 
-static tree shadowed_labels;
+static GTY(()) tree shadowed_labels;
 \f
 /* Return the subscript expression, modified to do range-checking.
 
@@ -6276,27 +6292,12 @@ ffecom_gfrt_tree_ (ffecomGfrt ix)
 /* A somewhat evil way to prevent the garbage collector
    from collecting 'tree' structures.  */
 #define NUM_TRACKED_CHUNK 63
-static struct tree_ggc_tracker
+struct tree_ggc_tracker GTY(())
 {
   struct tree_ggc_tracker *next;
   tree trees[NUM_TRACKED_CHUNK];
-} *tracker_head = NULL;
-
-static void
-mark_tracker_head (void *arg)
-{
-  struct tree_ggc_tracker *head;
-  int i;
-
-  for (head = * (struct tree_ggc_tracker **) arg;
-       head != NULL;
-       head = head->next)
-  {
-    ggc_mark (head);
-    for (i = 0; i < NUM_TRACKED_CHUNK; i++)
-      ggc_mark_tree (head->trees[i]);
-  }
-}
+};
+static GTY(()) struct tree_ggc_tracker *tracker_head;
 
 void
 ffecom_save_tree_forever (tree t)
@@ -9214,15 +9215,13 @@ ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
 
 /* Build Namelist type.  */
 
+static GTY(()) tree ffecom_type_namelist_var;
 static tree
 ffecom_type_namelist_ ()
 {
-  static tree type = NULL_TREE;
-
-  if (type == NULL_TREE)
+  if (ffecom_type_namelist_var == NULL_TREE)
     {
-      static tree namefield, varsfield, nvarsfield;
-      tree vardesctype;
+      tree namefield, varsfield, nvarsfield, vardesctype, type;
 
       vardesctype = ffecom_type_vardesc_ ();
 
@@ -9239,22 +9238,21 @@ ffecom_type_namelist_ ()
       TYPE_FIELDS (type) = namefield;
       layout_type (type);
 
-      ggc_add_tree_root (&type, 1);
+      ffecom_type_namelist_var = type;
     }
 
-  return type;
+  return ffecom_type_namelist_var;
 }
 
 /* Build Vardesc type.  */
 
+static GTY(()) tree ffecom_type_vardesc_var;
 static tree
 ffecom_type_vardesc_ ()
 {
-  static tree type = NULL_TREE;
-  static tree namefield, addrfield, dimsfield, typefield;
-
-  if (type == NULL_TREE)
+  if (ffecom_type_vardesc_var == NULL_TREE)
     {
+      tree namefield, addrfield, dimsfield, typefield, type;
       type = make_node (RECORD_TYPE);
 
       namefield = ffecom_decl_field (type, NULL_TREE, "name",
@@ -9269,10 +9267,10 @@ ffecom_type_vardesc_ ()
       TYPE_FIELDS (type) = namefield;
       layout_type (type);
 
-      ggc_add_tree_root (&type, 1);
+      ffecom_type_vardesc_var = type;
     }
 
-  return type;
+  return ffecom_type_vardesc_var;
 }
 
 static tree
@@ -13732,13 +13730,13 @@ lookup_name_current_level (tree name)
   return t;
 }
 
-/* Create a new `struct binding_level'.  */
+/* Create a new `struct f_binding_level'.  */
 
-static struct binding_level *
+static struct f_binding_level *
 make_binding_level ()
 {
   /* NOSTRICT */
-  return (struct binding_level *) xmalloc (sizeof (struct binding_level));
+  return ggc_alloc (sizeof (struct f_binding_level));
 }
 
 /* Save and restore the variables in this file and elsewhere
@@ -13750,7 +13748,7 @@ struct f_function
   struct f_function *next;
   tree named_labels;
   tree shadowed_labels;
-  struct binding_level *binding_level;
+  struct f_binding_level *binding_level;
 };
 
 struct f_function *f_function_chain;
@@ -13838,7 +13836,7 @@ pushdecl_top_level (x)
      tree x;
 {
   register tree t;
-  register struct binding_level *b = current_binding_level;
+  register struct f_binding_level *b = current_binding_level;
   register tree f = current_function_decl;
 
   current_binding_level = global_binding_level;
@@ -14078,86 +14076,11 @@ global_bindings_p ()
   return current_binding_level == global_binding_level;
 }
 
-/* Mark ARG for GC.  */
-static void
-mark_binding_level (void *arg)
-{
-  struct binding_level *level = *(struct binding_level **) arg;
-
-  while (level)
-    {
-      ggc_mark_tree (level->names);
-      ggc_mark_tree (level->blocks);
-      ggc_mark_tree (level->this_block);
-      level = level->level_chain;
-    }
-}
-
 static void
 ffecom_init_decl_processing ()
 {
-  static tree *const tree_roots[] = {
-    &current_function_decl,
-    &string_type_node,
-    &ffecom_tree_fun_type_void,
-    &ffecom_integer_zero_node,
-    &ffecom_integer_one_node,
-    &ffecom_tree_subr_type,
-    &ffecom_tree_ptr_to_subr_type,
-    &ffecom_tree_blockdata_type,
-    &ffecom_tree_xargc_,
-    &ffecom_f2c_integer_type_node,
-    &ffecom_f2c_ptr_to_integer_type_node,
-    &ffecom_f2c_address_type_node,
-    &ffecom_f2c_real_type_node,
-    &ffecom_f2c_ptr_to_real_type_node,
-    &ffecom_f2c_doublereal_type_node,
-    &ffecom_f2c_complex_type_node,
-    &ffecom_f2c_doublecomplex_type_node,
-    &ffecom_f2c_longint_type_node,
-    &ffecom_f2c_logical_type_node,
-    &ffecom_f2c_flag_type_node,
-    &ffecom_f2c_ftnlen_type_node,
-    &ffecom_f2c_ftnlen_zero_node,
-    &ffecom_f2c_ftnlen_one_node,
-    &ffecom_f2c_ftnlen_two_node,
-    &ffecom_f2c_ptr_to_ftnlen_type_node,
-    &ffecom_f2c_ftnint_type_node,
-    &ffecom_f2c_ptr_to_ftnint_type_node,
-    &ffecom_outer_function_decl_,
-    &ffecom_previous_function_decl_,
-    &ffecom_which_entrypoint_decl_,
-    &ffecom_float_zero_,
-    &ffecom_float_half_,
-    &ffecom_double_zero_,
-    &ffecom_double_half_,
-    &ffecom_func_result_,
-    &ffecom_func_length_,
-    &ffecom_multi_type_node_,
-    &ffecom_multi_retval_,
-    &named_labels,
-    &shadowed_labels
-  };
-  size_t i;
-
   malloc_init ();
 
-  /* Record our roots.  */
-  for (i = 0; i < ARRAY_SIZE (tree_roots); i++)
-    ggc_add_tree_root (tree_roots[i], 1);
-  ggc_add_tree_root (&ffecom_tree_type[0][0],
-                    FFEINFO_basictype*FFEINFO_kindtype);
-  ggc_add_tree_root (&ffecom_tree_fun_type[0][0],
-                    FFEINFO_basictype*FFEINFO_kindtype);
-  ggc_add_tree_root (&ffecom_tree_ptr_to_fun_type[0][0],
-                    FFEINFO_basictype*FFEINFO_kindtype);
-  ggc_add_tree_root (ffecom_gfrt_, FFECOM_gfrt);
-  ggc_add_root (&current_binding_level, 1, sizeof current_binding_level,
-                mark_binding_level);
-  ggc_add_root (&free_binding_level, 1, sizeof current_binding_level,
-                mark_binding_level);
-  ggc_add_root (&tracker_head, 1, sizeof tracker_head, mark_tracker_head);
-
   ffe_init_0 ();
 }
 
@@ -14199,7 +14122,11 @@ static const char *ffe_init PARAMS ((const char *));
 static void ffe_finish PARAMS ((void));
 static void ffe_init_options PARAMS ((void));
 static void ffe_print_identifier PARAMS ((FILE *, tree, int));
-static void ffe_mark_tree (tree);
+
+struct language_function GTY(())
+{
+  int unused;
+};
 
 #undef  LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME                        "GNU F77"
@@ -14213,8 +14140,6 @@ static void ffe_mark_tree (tree);
 #define LANG_HOOKS_DECODE_OPTION       ffe_decode_option
 #undef  LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE          ffe_parse_file
-#undef  LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE           ffe_mark_tree
 #undef  LANG_HOOKS_MARK_ADDRESSABLE
 #define LANG_HOOKS_MARK_ADDRESSABLE    ffe_mark_addressable
 #undef  LANG_HOOKS_PRINT_IDENTIFIER
@@ -14517,7 +14442,7 @@ poplevel (keep, reverse, functionbody)
   /* Pop the current level, and free the structure for reuse.  */
 
   {
-    register struct binding_level *level = current_binding_level;
+    register struct f_binding_level *level = current_binding_level;
     current_binding_level = current_binding_level->level_chain;
 
     level->level_chain = free_binding_level;
@@ -14572,7 +14497,7 @@ pushdecl (x)
 {
   register tree t;
   register tree name = DECL_NAME (x);
-  register struct binding_level *b = current_binding_level;
+  register struct f_binding_level *b = current_binding_level;
 
   if ((TREE_CODE (x) == FUNCTION_DECL)
       && (DECL_INITIAL (x) == 0)
@@ -14704,7 +14629,7 @@ void
 pushlevel (tag_transparent)
      int tag_transparent;
 {
-  register struct binding_level *newlevel = NULL_BINDING_LEVEL;
+  register struct f_binding_level *newlevel = NULL_BINDING_LEVEL;
 
   assert (! tag_transparent);
 
@@ -15138,21 +15063,6 @@ ffe_unsigned_type (type)
 
   return type;
 }
-
-static void
-ffe_mark_tree (t)
-     tree t;
-{
-  if (TREE_CODE (t) == IDENTIFIER_NODE)
-    {
-      struct lang_identifier *i = (struct lang_identifier *) t;
-      ggc_mark_tree (IDENTIFIER_GLOBAL_VALUE (i));
-      ggc_mark_tree (IDENTIFIER_LOCAL_VALUE (i));
-      ggc_mark_tree (IDENTIFIER_LABEL_VALUE (i));
-    }
-  else if (TYPE_P (t) && TYPE_LANG_SPECIFIC (t))
-    ggc_mark (TYPE_LANG_SPECIFIC (t));
-}
 \f
 /* From gcc/cccp.c, the code to handle -I.  */
 
@@ -16656,3 +16566,6 @@ typedef doublereal E_f; // real function with -R not specified //
 -------- (end output file from f2c)
 
 */
+
+#include "gt-f-com.h"
+#include "gtype-f.h"
index be49242ff921b5ab6895bb0571d39ebd3e7d0416..8b8bb861e82da0ff63f2d9844ea0edd9bb491bba 100644 (file)
@@ -167,32 +167,32 @@ extern tree pushdecl                              PARAMS ((tree));
 
 /* Global objects accessed by users of this module. */
 
-extern tree string_type_node;
-extern tree ffecom_integer_type_node;
-extern tree ffecom_integer_zero_node;
-extern tree ffecom_integer_one_node;
-extern tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
+extern GTY(()) tree string_type_node;
+extern GTY(()) tree ffecom_integer_type_node;
+extern GTY(()) tree ffecom_integer_zero_node;
+extern GTY(()) tree ffecom_integer_one_node;
+extern GTY(()) tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
 extern ffecomSymbol ffecom_symbol_null_;
 extern ffeinfoKindtype ffecom_pointer_kind_;
 extern ffeinfoKindtype ffecom_label_kind_;
 
 extern int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype];
-extern tree ffecom_f2c_integer_type_node;
-extern tree ffecom_f2c_address_type_node;
-extern tree ffecom_f2c_real_type_node;
-extern tree ffecom_f2c_doublereal_type_node;
-extern tree ffecom_f2c_complex_type_node;
-extern tree ffecom_f2c_doublecomplex_type_node;
-extern tree ffecom_f2c_longint_type_node;
-extern tree ffecom_f2c_logical_type_node;
-extern tree ffecom_f2c_flag_type_node;
-extern tree ffecom_f2c_ftnlen_type_node;
-extern tree ffecom_f2c_ftnlen_zero_node;
-extern tree ffecom_f2c_ftnlen_one_node;
-extern tree ffecom_f2c_ftnlen_two_node;
-extern tree ffecom_f2c_ptr_to_ftnlen_type_node;
-extern tree ffecom_f2c_ftnint_type_node;
-extern tree ffecom_f2c_ptr_to_ftnint_type_node;
+extern GTY(()) tree ffecom_f2c_integer_type_node;
+extern GTY(()) tree ffecom_f2c_address_type_node;
+extern GTY(()) tree ffecom_f2c_real_type_node;
+extern GTY(()) tree ffecom_f2c_doublereal_type_node;
+extern GTY(()) tree ffecom_f2c_complex_type_node;
+extern GTY(()) tree ffecom_f2c_doublecomplex_type_node;
+extern GTY(()) tree ffecom_f2c_longint_type_node;
+extern GTY(()) tree ffecom_f2c_logical_type_node;
+extern GTY(()) tree ffecom_f2c_flag_type_node;
+extern GTY(()) tree ffecom_f2c_ftnlen_type_node;
+extern GTY(()) tree ffecom_f2c_ftnlen_zero_node;
+extern GTY(()) tree ffecom_f2c_ftnlen_one_node;
+extern GTY(()) tree ffecom_f2c_ftnlen_two_node;
+extern GTY(()) tree ffecom_f2c_ptr_to_ftnlen_type_node;
+extern GTY(()) tree ffecom_f2c_ftnint_type_node;
+extern GTY(()) tree ffecom_f2c_ptr_to_ftnint_type_node;
 
 /* Declare functions with prototypes. */
 
index 168daadfc9e647ca788a0ed4c5fc43abd7fb97e1..2c5bd2d5572708f64c7a83a9afe3e3a902fa2b6b 100644 (file)
@@ -32,3 +32,5 @@ compilers="f771\$(exeext)"
 stagestuff="g77\$(exeext) g77-cross\$(exeext) f771\$(exeext)"
 
 target_libs=target-libf2c
+
+gtfiles="\$(srcdir)/f/com.c \$(srcdir)/f/com.h \$(srcdir)/f/ste.c"
index 2959984c4b88f4456469b1c7073a4f748aeb0e83..d7d84954eefde8a10558d1c5c3ff151a8f13f295 100644 (file)
@@ -1162,13 +1162,13 @@ ffeste_io_douio_ (ffebld expr)
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_alist_struct;
 static tree
 ffeste_io_ialist_ (bool have_err,
                   ffestvUnit unit,
                   ffebld unit_expr,
                   int unit_dflt)
 {
-  static tree f2c_alist_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -1193,8 +1193,6 @@ ffeste_io_ialist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_alist_struct, 1);
-
       f2c_alist_struct = ref;
     }
 
@@ -1283,6 +1281,7 @@ ffeste_io_ialist_ (bool have_err,
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_cilist_struct;
 static tree
 ffeste_io_cilist_ (bool have_err,
                   ffestvUnit unit,
@@ -1294,7 +1293,6 @@ ffeste_io_cilist_ (bool have_err,
                   bool rec,
                   ffebld rec_expr)
 {
-  static tree f2c_cilist_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -1325,8 +1323,6 @@ ffeste_io_cilist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_cilist_struct, 1);
-
       f2c_cilist_struct = ref;
     }
 
@@ -1508,12 +1504,12 @@ ffeste_io_cilist_ (bool have_err,
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_close_struct;
 static tree
 ffeste_io_cllist_ (bool have_err,
                   ffebld unit_expr,
                   ffestpFile *stat_spec)
 {
-  static tree f2c_close_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -1541,8 +1537,6 @@ ffeste_io_cllist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_close_struct, 1);
-
       f2c_close_struct = ref;
     }
 
@@ -1622,6 +1616,7 @@ ffeste_io_cllist_ (bool have_err,
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_icilist_struct;
 static tree
 ffeste_io_icilist_ (bool have_err,
                    ffebld unit_expr,
@@ -1629,7 +1624,6 @@ ffeste_io_icilist_ (bool have_err,
                    ffestvFormat format,
                    ffestpFile *format_spec)
 {
-  static tree f2c_icilist_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -1663,8 +1657,6 @@ ffeste_io_icilist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_icilist_struct, 1);
-
       f2c_icilist_struct = ref;
     }
 
@@ -1851,6 +1843,7 @@ ffeste_io_icilist_ (bool have_err,
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_inquire_struct;
 static tree
 ffeste_io_inlist_ (bool have_err,
                   ffestpFile *unit_spec,
@@ -1870,7 +1863,6 @@ ffeste_io_inlist_ (bool have_err,
                   ffestpFile *nextrec_spec,
                   ffestpFile *blank_spec)
 {
-  static tree f2c_inquire_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -1959,8 +1951,6 @@ ffeste_io_inlist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_inquire_struct, 1);
-
       f2c_inquire_struct = ref;
     }
 
@@ -2109,6 +2099,7 @@ ffeste_io_inlist_ (bool have_err,
    declaration of variables (temporaries) to the expanding of expressions,
    statements, etc.  */
 
+static GTY(()) tree f2c_open_struct;
 static tree
 ffeste_io_olist_ (bool have_err,
                  ffebld unit_expr,
@@ -2119,7 +2110,6 @@ ffeste_io_olist_ (bool have_err,
                  ffestpFile *recl_spec,
                  ffestpFile *blank_spec)
 {
-  static tree f2c_open_struct = NULL_TREE;
   tree t;
   tree ttype;
   tree field;
@@ -2163,8 +2153,6 @@ ffeste_io_olist_ (bool have_err,
       TYPE_FIELDS (ref) = errfield;
       layout_type (ref);
 
-      ggc_add_tree_root (&f2c_open_struct, 1);
-
       f2c_open_struct = ref;
     }
 
@@ -4618,3 +4606,5 @@ ffeste_terminate_2 (void)
   assert (! ffeste_top_block_);
 }
 #endif
+
+#include "gt-f-ste.h"
index 9f853545c67f632e60e4f2239c439b4d859c7d35..e7d2e990090f1832809a8ba5556a0b9b239aabc4 100644 (file)
@@ -33,7 +33,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "where.h"
 #include "lex.h"
 #include "malloc.h"
-#include "ggc.h"
 
 /* Externals defined here. */
 
@@ -109,32 +108,6 @@ ffewhere_ll_lookup_ (ffewhereLineNumber ln)
   return NULL;
 }
 
-/* A somewhat evil way to prevent the garbage collector
-   from collecting 'file' structures.  */
-#define NUM_FFEWHERE_HEAD_FILES 31
-static struct ffewhere_ggc_tracker 
-{
-  struct ffewhere_ggc_tracker *next;
-  ffewhereFile files[NUM_FFEWHERE_HEAD_FILES];
-} *ffewhere_head = NULL;
-
-static void 
-mark_ffewhere_head (void *arg)
-{
-  struct ffewhere_ggc_tracker *head;
-  int i;
-  
-  for (head = * (struct ffewhere_ggc_tracker **) arg;
-       head != NULL;
-       head = head->next)
-  {
-    ggc_mark (head);
-    for (i = 0; i < NUM_FFEWHERE_HEAD_FILES; i++)
-      ggc_mark (head->files[i]);
-  }
-}
-
-
 /* Kill file object.
 
    Note that this object must not have been passed in a call
@@ -144,18 +117,9 @@ mark_ffewhere_head (void *arg)
 void
 ffewhere_file_kill (ffewhereFile wf)
 {
-  struct ffewhere_ggc_tracker *head;
-  int i;
-  
-  for (head = ffewhere_head; head != NULL; head = head->next)
-    for (i = 0; i < NUM_FFEWHERE_HEAD_FILES; i++)
-      if (head->files[i] == wf)
-       {
-         head->files[i] = NULL;
-         return;
-       }
-  /* Called on a file that has already been deallocated... */
-  abort();
+  malloc_kill_ks (ffe_pool_file (), wf,
+                 offsetof (struct _ffewhere_file_, text)
+                 + wf->length + 1);
 }
 
 /* Create file object.  */
@@ -164,42 +128,14 @@ ffewhereFile
 ffewhere_file_new (const char *name, size_t length)
 {
   ffewhereFile wf;
-  int filepos;
-  wf = ggc_alloc (offsetof (struct _ffewhere_file_, text)
-                 + length + 1);
+
+  wf = malloc_new_ks (ffe_pool_file (), "ffewhereFile",
+                     offsetof (struct _ffewhere_file_, text)
+                     + length + 1);
   wf->length = length;
   memcpy (&wf->text[0], name, length);
   wf->text[length] = '\0';
 
-  if (ffewhere_head == NULL)
-    {
-      ggc_add_root (&ffewhere_head, 1, sizeof ffewhere_head,
-                   mark_ffewhere_head);
-      filepos = NUM_FFEWHERE_HEAD_FILES;
-    }
-  else
-    {
-      for (filepos = 0; filepos < NUM_FFEWHERE_HEAD_FILES; filepos++)
-       if (ffewhere_head->files[filepos] == NULL)
-         {
-           ffewhere_head->files[filepos] = wf;
-           break;
-         }
-    }
-  if (filepos == NUM_FFEWHERE_HEAD_FILES)
-    {
-      /* Need to allocate a new block.  */
-      struct ffewhere_ggc_tracker *old_head = ffewhere_head;
-      int i;
-      
-      ffewhere_head = ggc_alloc (sizeof (*ffewhere_head));
-      ffewhere_head->next = old_head;
-      ffewhere_head->files[0] = wf;
-      for (i = 1; i < NUM_FFEWHERE_HEAD_FILES; i++)
-       ffewhere_head->files[i] = NULL;
-    }
-
   return wf;
 }
 
index a66bd5c53f6bcbaa6b79dbebdf950c246d3d71c9..9fe1c11f586d11d7a67028ce3f68264357b882b5 100644 (file)
@@ -586,9 +586,7 @@ dbr_sequence_length ()
 
 static int *insn_lengths;
 
-#ifdef HAVE_ATTR_length
 varray_type insn_addresses_;
-#endif
 
 /* Max uid for which the above arrays are valid.  */
 static int insn_lengths_max_uid;
index 947d575dd9398442d5faab5fe6eea3f204f7dbf4..6febe585d55562bd92a2fd430140757dcf66b1c3 100644 (file)
@@ -1376,21 +1376,21 @@ size_int_wide (number, kind)
 
 /* Likewise, but the desired type is specified explicitly.  */
 
+static GTY (()) tree new_const;
+static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
+     htab_t size_htab;
+
 tree
 size_int_type_wide (number, type)
      HOST_WIDE_INT number;
      tree type;
 {
-  static htab_t size_htab = 0;
-  static tree new_const = 0;
   PTR *slot;
 
   if (size_htab == 0)
     {
       size_htab = htab_create (1024, size_htab_hash, size_htab_eq, NULL);
-      ggc_add_deletable_htab (size_htab, NULL, NULL);
       new_const = make_node (INTEGER_CST);
-      ggc_add_tree_root (&new_const, 1);
     }
 
   /* Adjust NEW_CONST to be the constant we want.  If it's already in the
@@ -7236,3 +7236,5 @@ rtl_expr_nonnegative_p (r)
       return 0;
     }
 }
+
+#include "gt-fold-const.h"
index 669dd2ecf851f8ae8b4026d82f3f639b5701b721..d1f4e89d5c2355eb167d8b1fe2f4a45a0a72de3c 100644 (file)
@@ -55,7 +55,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "basic-block.h"
 #include "obstack.h"
 #include "toplev.h"
-#include "hash.h"
+#include "hashtab.h"
 #include "ggc.h"
 #include "tm_p.h"
 #include "integrate.h"
@@ -129,12 +129,7 @@ static int profile_label_no;
 
 /* These variables hold pointers to functions to create and destroy
    target specific, per-function data structures.  */
-void (*init_machine_status) PARAMS ((struct function *));
-void (*free_machine_status) PARAMS ((struct function *));
-/* This variable holds a pointer to a function to register any
-   data items in the target specific, per-function data structure
-   that will need garbage collection.  */
-void (*mark_machine_status) PARAMS ((struct function *));
+struct machine_function * (*init_machine_status) PARAMS ((void));
 
 /* The FUNCTION_DECL for an inline function currently being expanded.  */
 tree inline_function_decl;
@@ -143,12 +138,12 @@ tree inline_function_decl;
 struct function *cfun = 0;
 
 /* These arrays record the INSN_UIDs of the prologue and epilogue insns.  */
-static varray_type prologue;
-static varray_type epilogue;
+static GTY(()) varray_type prologue;
+static GTY(()) varray_type epilogue;
 
 /* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue
    in this function.  */
-static varray_type sibcall_epilogue;
+static GTY(()) varray_type sibcall_epilogue;
 \f
 /* In order to evaluate some expressions, such as function calls returning
    structures in memory, we need to temporarily allocate stack locations.
@@ -168,7 +163,7 @@ static varray_type sibcall_epilogue;
    level where they are defined.  They are marked a "kept" so that
    free_temp_slots will not free them.  */
 
-struct temp_slot
+struct temp_slot GTY(())
 {
   /* Points to next temporary slot.  */
   struct temp_slot *next;
@@ -209,7 +204,7 @@ struct temp_slot
    maintain this list in case two operands of an insn were required to match;
    in that case we must ensure we use the same replacement.  */
 
-struct fixup_replacement
+struct fixup_replacement GTY(())
 {
   rtx old;
   rtx new;
@@ -218,9 +213,9 @@ struct fixup_replacement
 
 struct insns_for_mem_entry
 {
-  /* The KEY in HE will be a MEM.  */
-  struct hash_entry he;
-  /* These are the INSNS which reference the MEM.  */
+  /* A MEM.  */
+  rtx key;
+  /* These are the INSNs which reference the MEM.  */
   rtx insns;
 };
 
@@ -232,18 +227,18 @@ static struct temp_slot *find_temp_slot_from_address  PARAMS ((rtx));
 static void put_reg_into_stack PARAMS ((struct function *, rtx, tree,
                                         enum machine_mode, enum machine_mode,
                                         int, unsigned int, int,
-                                        struct hash_table *));
+                                        htab_t));
 static void schedule_fixup_var_refs PARAMS ((struct function *, rtx, tree,
                                             enum machine_mode,
-                                            struct hash_table *));
+                                            htab_t));
 static void fixup_var_refs     PARAMS ((rtx, enum machine_mode, int, rtx,
-                                        struct hash_table *));
+                                        htab_t));
 static struct fixup_replacement
   *find_fixup_replacement      PARAMS ((struct fixup_replacement **, rtx));
 static void fixup_var_refs_insns PARAMS ((rtx, rtx, enum machine_mode,
                                          int, int, rtx));
 static void fixup_var_refs_insns_with_hash
-                               PARAMS ((struct hash_table *, rtx,
+                               PARAMS ((htab_t, rtx,
                                         enum machine_mode, int, rtx));
 static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
                                         int, int, rtx));
@@ -283,29 +278,24 @@ static int contains               PARAMS ((rtx, varray_type));
 #ifdef HAVE_return
 static void emit_return_into_block PARAMS ((basic_block, rtx));
 #endif
-static void put_addressof_into_stack PARAMS ((rtx, struct hash_table *));
+static void put_addressof_into_stack PARAMS ((rtx, htab_t));
 static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int,
-                                         struct hash_table *));
+                                         htab_t));
 static void purge_single_hard_subreg_set PARAMS ((rtx));
 #if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
 static rtx keep_stack_depressed PARAMS ((rtx));
 #endif
 static int is_addressof                PARAMS ((rtx *, void *));
-static struct hash_entry *insns_for_mem_newfunc PARAMS ((struct hash_entry *,
-                                                        struct hash_table *,
-                                                        hash_table_key));
-static unsigned long insns_for_mem_hash PARAMS ((hash_table_key));
-static bool insns_for_mem_comp PARAMS ((hash_table_key, hash_table_key));
+static hashval_t insns_for_mem_hash PARAMS ((const void *));
+static int insns_for_mem_comp PARAMS ((const void *, const void *));
 static int insns_for_mem_walk   PARAMS ((rtx *, void *));
-static void compute_insns_for_mem PARAMS ((rtx, rtx, struct hash_table *));
-static void mark_function_status PARAMS ((struct function *));
-static void maybe_mark_struct_function PARAMS ((void *));
+static void compute_insns_for_mem PARAMS ((rtx, rtx, htab_t));
 static void prepare_function_start PARAMS ((void));
 static void do_clobber_return_reg PARAMS ((rtx, void *));
 static void do_use_return_reg PARAMS ((rtx, void *));
 \f
 /* Pointer to chain of `struct function' for containing functions.  */
-static struct function *outer_function_chain;
+static GTY(()) struct function *outer_function_chain;
 
 /* Given a function decl for a containing function,
    return the `struct function' for it.  */
@@ -436,8 +426,8 @@ free_after_parsing (f)
   /* f->varasm is used by code generation.  */
   /* f->eh->eh_return_stub_label is used by code generation.  */
 
-  (*lang_hooks.function.free) (f);
-  free_stmt_status (f);
+  (*lang_hooks.function.final) (f);
+  f->stmt = NULL;
 }
 
 /* Clear out all parts of the state in F that can safely be discarded
@@ -448,16 +438,11 @@ void
 free_after_compilation (f)
      struct function *f;
 {
-  free_eh_status (f);
-  free_expr_status (f);
-  free_emit_status (f);
-  free_varasm_status (f);
-
-  if (free_machine_status)
-    (*free_machine_status) (f);
-
-  if (f->x_parm_reg_stack_loc)
-    free (f->x_parm_reg_stack_loc);
+  f->eh = NULL;
+  f->expr = NULL;
+  f->emit = NULL;
+  f->varasm = NULL;
+  f->machine = NULL;
 
   f->x_temp_slots = NULL;
   f->arg_offset_rtx = NULL;
@@ -1497,7 +1482,7 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
      int volatile_p;
      unsigned int original_regno;
      int used_p;
-     struct hash_table *ht;
+     htab_t ht;
 {
   struct function *func = function ? function : cfun;
   rtx new = 0;
@@ -1545,7 +1530,7 @@ schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
      rtx reg;
      tree type;
      enum machine_mode promoted_mode;
-     struct hash_table *ht;
+     htab_t ht;
 {
   int unsigned_p = type ? TREE_UNSIGNED (type) : 0;
 
@@ -1571,7 +1556,7 @@ fixup_var_refs (var, promoted_mode, unsignedp, may_share, ht)
      rtx var;
      enum machine_mode promoted_mode;
      int unsignedp;
-     struct hash_table *ht;
+     htab_t ht;
      rtx may_share;
 {
   tree pending;
@@ -1707,17 +1692,18 @@ fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel, may_share)
 
 static void
 fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp, may_share)
-     struct hash_table *ht;
+     htab_t ht;
      rtx var;
      enum machine_mode promoted_mode;
      int unsignedp;
      rtx may_share;
 {
-  struct insns_for_mem_entry *ime
-    = (struct insns_for_mem_entry *) hash_lookup (ht, var,
-                                                 /*create=*/0, /*copy=*/0);
+  struct insns_for_mem_entry tmp;
+  struct insns_for_mem_entry *ime;
   rtx insn_list;
 
+  tmp.key = var;
+  ime = (struct insns_for_mem_entry *) htab_find (ht, &tmp);
   for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
     if (INSN_P (XEXP (insn_list, 0)))
       fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
@@ -2979,7 +2965,7 @@ flush_addressof (decl)
 static void
 put_addressof_into_stack (r, ht)
      rtx r;
-     struct hash_table *ht;
+     htab_t ht;
 {
   tree decl, type;
   int volatile_p, used_p;
@@ -3031,7 +3017,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
      rtx *loc;
      rtx insn;
      int force, store;
-     struct hash_table *ht;
+     htab_t ht;
 {
   rtx x;
   RTX_CODE code;
@@ -3291,50 +3277,34 @@ purge_addressof_1 (loc, insn, force, store, ht)
   return result;
 }
 
-/* Return a new hash table entry in HT.  */
-
-static struct hash_entry *
-insns_for_mem_newfunc (he, ht, k)
-     struct hash_entry *he;
-     struct hash_table *ht;
-     hash_table_key k ATTRIBUTE_UNUSED;
-{
-  struct insns_for_mem_entry *ifmhe;
-  if (he)
-    return he;
-
-  ifmhe = ((struct insns_for_mem_entry *)
-          hash_allocate (ht, sizeof (struct insns_for_mem_entry)));
-  ifmhe->insns = NULL_RTX;
-
-  return &ifmhe->he;
-}
-
 /* Return a hash value for K, a REG.  */
 
-static unsigned long
+static hashval_t
 insns_for_mem_hash (k)
-     hash_table_key k;
+     const void * k;
 {
-  /* K is really a RTX.  Just use the address as the hash value.  */
-  return (unsigned long) k;
+  /* Use the address of the key for the hash value.  */
+  struct insns_for_mem_entry *m = (struct insns_for_mem_entry *) k;
+  return (hashval_t) m->key;
 }
 
 /* Return non-zero if K1 and K2 (two REGs) are the same.  */
 
-static bool
+static int
 insns_for_mem_comp (k1, k2)
-     hash_table_key k1;
-     hash_table_key k2;
+     const void * k1;
+     const void * k2;
 {
-  return k1 == k2;
+  struct insns_for_mem_entry *m1 = (struct insns_for_mem_entry *) k1;
+  struct insns_for_mem_entry *m2 = (struct insns_for_mem_entry *) k2;
+  return m1->key == m2->key;
 }
 
 struct insns_for_mem_walk_info
 {
   /* The hash table that we are using to record which INSNs use which
      MEMs.  */
-  struct hash_table *ht;
+  htab_t ht;
 
   /* The INSN we are currently processing.  */
   rtx insn;
@@ -3356,18 +3326,26 @@ insns_for_mem_walk (r, data)
 {
   struct insns_for_mem_walk_info *ifmwi
     = (struct insns_for_mem_walk_info *) data;
+  struct insns_for_mem_entry tmp;
+  tmp.insns = NULL_RTX;
 
   if (ifmwi->pass == 0 && *r && GET_CODE (*r) == ADDRESSOF
       && GET_CODE (XEXP (*r, 0)) == REG)
-    hash_lookup (ifmwi->ht, XEXP (*r, 0), /*create=*/1, /*copy=*/0);
+    {
+      PTR *e;
+      tmp.key = XEXP (*r, 0);
+      e = htab_find_slot (ifmwi->ht, &tmp, INSERT);
+      if (*e == NULL)
+       {
+         *e = ggc_alloc (sizeof (tmp));
+         memcpy (*e, &tmp, sizeof (tmp));
+       }
+    }
   else if (ifmwi->pass == 1 && *r && GET_CODE (*r) == REG)
     {
-      /* Lookup this MEM in the hashtable, creating it if necessary.  */
-      struct insns_for_mem_entry *ifme
-       = (struct insns_for_mem_entry *) hash_lookup (ifmwi->ht,
-                                                     *r,
-                                                     /*create=*/0,
-                                                     /*copy=*/0);
+      struct insns_for_mem_entry *ifme;
+      tmp.key = *r;
+      ifme = (struct insns_for_mem_entry *) htab_find (ifmwi->ht, &tmp);
 
       /* If we have not already recorded this INSN, do so now.  Since
         we process the INSNs in order, we know that if we have
@@ -3387,7 +3365,7 @@ static void
 compute_insns_for_mem (insns, last_insn, ht)
      rtx insns;
      rtx last_insn;
-     struct hash_table *ht;
+     htab_t ht;
 {
   rtx insn;
   struct insns_for_mem_walk_info ifmwi;
@@ -3422,7 +3400,7 @@ purge_addressof (insns)
      rtx insns;
 {
   rtx insn;
-  struct hash_table ht;
+  htab_t ht;
 
   /* When we actually purge ADDRESSOFs, we turn REGs into MEMs.  That
      requires a fixup pass over the instruction stream to correct
@@ -3431,23 +3409,20 @@ purge_addressof (insns)
      mentioned in very many instructions.  So, we speed up the process
      by pre-calculating which REGs occur in which INSNs; that allows
      us to perform the fixup passes much more quickly.  */
-  hash_table_init (&ht,
-                  insns_for_mem_newfunc,
-                  insns_for_mem_hash,
-                  insns_for_mem_comp);
-  compute_insns_for_mem (insns, NULL_RTX, &ht);
+  ht = htab_create_ggc (1000, insns_for_mem_hash, insns_for_mem_comp, NULL);
+  compute_insns_for_mem (insns, NULL_RTX, ht);
 
   for (insn = insns; insn; insn = NEXT_INSN (insn))
     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
        || GET_CODE (insn) == CALL_INSN)
       {
        if (! purge_addressof_1 (&PATTERN (insn), insn,
-                                asm_noperands (PATTERN (insn)) > 0, 0, &ht))
+                                asm_noperands (PATTERN (insn)) > 0, 0, ht))
          /* If we could not replace the ADDRESSOFs in the insn,
             something is wrong.  */
          abort ();
 
-       if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht))
+       if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, ht))
          {
            /* If we could not replace the ADDRESSOFs in the insn's notes,
               we can just remove the offending notes instead.  */
@@ -3468,7 +3443,6 @@ purge_addressof (insns)
       }
 
   /* Clean up.  */
-  hash_table_free (&ht);
   purge_bitfield_addressof_replacements = 0;
   purge_addressof_replacements = 0;
 
@@ -4370,7 +4344,7 @@ assign_parms (fndecl)
     }
 
   max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
-  parm_reg_stack_loc = (rtx *) xcalloc (max_parm_reg, sizeof (rtx));
+  parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
 
 #ifdef INIT_CUMULATIVE_INCOMING_ARGS
   INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
@@ -4934,7 +4908,7 @@ assign_parms (fndecl)
                 but it's also rare and we need max_parm_reg to be
                 precisely correct.  */
              max_parm_reg = regno + 1;
-             new = (rtx *) xrealloc (parm_reg_stack_loc,
+             new = (rtx *) ggc_realloc (parm_reg_stack_loc,
                                      max_parm_reg * sizeof (rtx));
              memset ((char *) (new + old_max_parm_reg), 0,
                     (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
@@ -5936,8 +5910,6 @@ reorder_blocks ()
 
   /* Remove deleted blocks from the block fragment chains.  */
   reorder_fix_fragments (block);
-
-  VARRAY_FREE (block_stack);
 }
 
 /* Helper function for reorder_blocks.  Reset TREE_ASM_WRITTEN.  */
@@ -6326,7 +6298,7 @@ prepare_function_start ()
 
   (*lang_hooks.function.init) (cfun);
   if (init_machine_status)
-    (*init_machine_status) (cfun);
+    cfun->machine = (*init_machine_status) ();
 }
 
 /* Initialize the rtl expansion mechanism so that we can do simple things
@@ -6797,6 +6769,8 @@ use_return_register ()
   diddle_return_value (do_use_return_reg, NULL);
 }
 
+static GTY(()) rtx initial_trampoline;
+
 /* Generate RTL for the end of the current function.
    FILENAME and LINE are the current position in the source file.
 
@@ -6812,10 +6786,6 @@ expand_function_end (filename, line, end_bindings)
   tree link;
   rtx clobber_after;
 
-#ifdef TRAMPOLINE_TEMPLATE
-  static rtx initial_trampoline;
-#endif
-
   finish_expr_for_function ();
 
   /* If arg_pointer_save_area was referenced only from a nested
@@ -6854,8 +6824,6 @@ expand_function_end (filename, line, end_bindings)
          initial_trampoline
            = gen_rtx_MEM (BLKmode, assemble_trampoline_template ());
          set_mem_align (initial_trampoline, TRAMPOLINE_ALIGNMENT);
-
-         ggc_add_rtx_root (&initial_trampoline, 1);
        }
 #endif
 
@@ -7955,121 +7923,14 @@ reposition_prologue_and_epilogue_notes (f)
 #endif /* HAVE_prologue or HAVE_epilogue */
 }
 
-/* Mark P for GC.  */
-
-static void
-mark_function_status (p)
-     struct function *p;
-{
-  struct var_refs_queue *q;
-  struct temp_slot *t;
-  int i;
-  rtx *r;
-
-  if (p == 0)
-    return;
-
-  ggc_mark_rtx (p->arg_offset_rtx);
-
-  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);
-  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);
-  ggc_mark_rtx (p->x_clobber_return_insn);
-
-  for (t = p->x_temp_slots; t != 0; t = t->next)
-    {
-      ggc_mark (t);
-      ggc_mark_rtx (t->slot);
-      ggc_mark_rtx (t->address);
-      ggc_mark_tree (t->rtl_expr);
-      ggc_mark_tree (t->type);
-    }
-
-  for (q = p->fixup_var_refs_queue; q != 0; q = q->next)
-    {
-      ggc_mark (q);
-      ggc_mark_rtx (q->modified);
-    }
-
-  ggc_mark_rtx (p->x_nonlocal_goto_handler_slots);
-  ggc_mark_rtx (p->x_nonlocal_goto_handler_labels);
-  ggc_mark_rtx (p->x_nonlocal_goto_stack_level);
-  ggc_mark_tree (p->x_nonlocal_labels);
-
-  mark_hard_reg_initial_vals (p);
-}
-
-/* Mark the struct function pointed to by *ARG for GC, if it is not
-   NULL.  This is used to mark the current function and the outer
-   function chain.  */
-
-static void
-maybe_mark_struct_function (arg)
-     void *arg;
-{
-  struct function *f = *(struct function **) arg;
-
-  if (f == 0)
-    return;
-
-  ggc_mark_struct_function (f);
-}
-
-/* Mark a struct function * for GC.  This is called from ggc-common.c.  */
-
-void
-ggc_mark_struct_function (f)
-     struct function *f;
-{
-  ggc_mark (f);
-  ggc_mark_tree (f->decl);
-
-  mark_function_status (f);
-  mark_eh_status (f->eh);
-  mark_stmt_status (f->stmt);
-  mark_expr_status (f->expr);
-  mark_emit_status (f->emit);
-  mark_varasm_status (f->varasm);
-
-  if (mark_machine_status)
-    (*mark_machine_status) (f);
-  (*lang_hooks.function.mark) (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);
-  if (f->outer)
-    ggc_mark_struct_function (f->outer);
-}
-
 /* Called once, at initialization, to initialize function.c.  */
 
 void
 init_function_once ()
 {
-  ggc_add_root (&cfun, 1, sizeof cfun, maybe_mark_struct_function);
-  ggc_add_root (&outer_function_chain, 1, sizeof outer_function_chain,
-               maybe_mark_struct_function);
-
   VARRAY_INT_INIT (prologue, 0, "prologue");
   VARRAY_INT_INIT (epilogue, 0, "epilogue");
   VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
 }
+
+#include "gt-function.h"
index 912f8513c53745ffa81d3d8af8749da5dd72e43c..0c598be18de7a74ca13033d6d80da9ca346d2548 100644 (file)
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
-struct var_refs_queue
+struct var_refs_queue GTY(())
 {
   rtx modified;
   enum machine_mode promoted_mode;
@@ -32,10 +32,11 @@ struct var_refs_queue
    The main insn-chain is saved in the last element of the chain,
    unless the chain is empty.  */
 
-struct sequence_stack
+struct sequence_stack GTY(())
 {
   /* First and last insns in the chain of the saved sequence.  */
-  rtx first, last;
+  rtx first;
+  rtx last;
   tree sequence_rtl_expr;
   struct sequence_stack *next;
 };
@@ -50,7 +51,7 @@ struct simple_obstack_stack
   struct simple_obstack_stack *next;
 };
 \f
-struct emit_status
+struct emit_status GTY(())
 {
   /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
      After rtl generation, it is 1 plus the largest register number used.  */
@@ -96,15 +97,16 @@ struct emit_status
   /* Indexed by pseudo register number, if nonzero gives the known alignment
      for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
      Allocated in parallel with x_regno_reg_rtx.  */
-  unsigned char *regno_pointer_align;
+  unsigned char * GTY ((length ("%h.regno_pointer_align_length"))) 
+    regno_pointer_align;
 
   /* Indexed by pseudo register number, if nonzero gives the decl
      corresponding to that register.  */
-  tree *regno_decl;
+  tree * GTY ((length ("%h.regno_pointer_align_length"))) regno_decl;
 
   /* Indexed by pseudo register number, gives the rtx for that pseudo.
      Allocated in parallel with regno_pointer_align.  */
-  rtx *x_regno_reg_rtx;
+  rtx * GTY ((length ("%h.regno_pointer_align_length"))) x_regno_reg_rtx;
 };
 
 /* For backward compatibility... eventually these should all go away.  */
@@ -116,7 +118,7 @@ struct emit_status
 #define REGNO_POINTER_ALIGN(REGNO) (cfun->emit->regno_pointer_align[REGNO])
 #define REGNO_DECL(REGNO) (cfun->emit->regno_decl[REGNO])
 
-struct expr_status
+struct expr_status GTY(())
 {
   /* Number of units that we should eventually pop off the stack.
      These are the arguments to function calls that have already returned.  */
@@ -171,7 +173,7 @@ struct expr_status
 /* This structure can save all the important global and static variables
    describing the status of the current function.  */
 
-struct function
+struct function GTY(())
 {
   struct eh_status *eh;
   struct stmt_status *stmt;
@@ -331,7 +333,7 @@ struct function
      to put the parm which is nominally in pseudo register REGNO,
      if we discover that that parm must go in the stack.  The highest
      element in this vector is one less than MAX_PARM_REG, above.  */
-  rtx *x_parm_reg_stack_loc;
+  rtx * GTY ((length ("%h.x_max_parm_reg"))) x_parm_reg_stack_loc;
 
   /* List of all temporaries allocated, both available and in use.  */
   struct temp_slot *x_temp_slots;
@@ -355,8 +357,7 @@ struct function
   /* For integrate.c.  */
   int inlinable;
   int no_debugging_symbols;
-  /* This is in fact an rtvec.  */
-  void *original_arg_vector;
+  rtvec original_arg_vector;
   tree original_decl_initial;
   /* Last insn of those whose job was to put parms into their nominal
      homes.  */
@@ -370,14 +371,14 @@ struct function
   /* For md files.  */
 
   /* tm.h can use this to store whatever it likes.  */
-  struct machine_function *machine;
+  struct machine_function * GTY ((maybe_undef (""))) machine;
   /* The largest alignment of slot allocated on the stack.  */
   int stack_alignment_needed;
   /* Preferred alignment of the end of stack frame.  */
   int preferred_stack_boundary;
 
   /* Language-specific code can use this to store whatever it likes.  */
-  struct language_function *language;
+  struct language_function * language;
 
   /* For reorg.  */
 
@@ -497,7 +498,7 @@ struct function
 };
 
 /* The function currently being compiled.  */
-extern struct function *cfun;
+extern GTY(()) struct function *cfun;
 
 /* Nonzero if we've already converted virtual regs to hard regs.  */
 extern int virtuals_instantiated;
@@ -585,14 +586,9 @@ extern HOST_WIDE_INT get_frame_size        PARAMS ((void));
 /* Likewise, but for a different than the current function.  */
 extern HOST_WIDE_INT get_func_frame_size       PARAMS ((struct function *));
 
-/* These variables hold pointers to functions to create and destroy
-   target specific, per-function data structures.  */
-extern void (*init_machine_status)     PARAMS ((struct function *));
-extern void (*free_machine_status)     PARAMS ((struct function *));
-/* This variable holds a pointer to a function to register any
-   data items in the target specific, per-function data structure
-   that will need garbage collection.  */
-extern void (*mark_machine_status)     PARAMS ((struct function *));
+/* A pointer to a function to create target specific, per-function
+   data structures.  */
+extern struct machine_function * (*init_machine_status)        PARAMS ((void));
 
 /* Save and restore status information for a nested function.  */
 extern void restore_emit_status                PARAMS ((struct function *));
@@ -600,11 +596,6 @@ extern void free_after_parsing             PARAMS ((struct function *));
 extern void free_after_compilation     PARAMS ((struct function *));
 
 extern void init_varasm_status         PARAMS ((struct function *));
-extern void free_varasm_status         PARAMS ((struct function *));
-extern void free_emit_status           PARAMS ((struct function *));
-extern void free_stmt_status            PARAMS ((struct function *));
-extern void free_eh_status             PARAMS ((struct function *));
-extern void free_expr_status           PARAMS ((struct function *));
 
 extern rtx get_first_block_beg         PARAMS ((void));
 
index e9c35a665e864d104f5fcd1b36059be198a4750d..fa20e96a395b690f1d82f39f527c5f254556e2e4 100644 (file)
@@ -1305,11 +1305,11 @@ static basic_block current_bb;
 /* See whether X, the source of a set, is something we want to consider for
    GCSE.  */
 
+static GTY(()) rtx test_insn;
 static int
 want_to_gcse_p (x)
      rtx x;
 {
-  static rtx test_insn = 0;
   int num_clobbers = 0;
   int icode;
 
@@ -1343,7 +1343,6 @@ want_to_gcse_p (x)
                                                   FIRST_PSEUDO_REGISTER * 2),
                                      const0_rtx));
       NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0;
-      ggc_add_rtx_root (&test_insn, 1);
     }
 
   /* Now make an insn like the one we would make when GCSE'ing and see if
@@ -7206,3 +7205,5 @@ store_motion ()
   remove_fake_edges ();
   end_alias_analysis ();
 }
+
+#include "gt-gcse.h"
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
new file mode 100644 (file)
index 0000000..a7b2346
--- /dev/null
@@ -0,0 +1,322 @@
+/* -*- indented-text -*- */
+/* Process source files and output type information.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+%{
+#define malloc xmalloc
+#define realloc xrealloc
+
+#include "hconfig.h"
+#include "system.h"
+#include <ctype.h>
+#include "gengtype.h"
+#include "gengtype-yacc.h"
+
+static void update_lineno PARAMS ((const char *l, size_t len));
+
+struct fileloc lexer_line;
+int lexer_toplevel_done;
+
+static void 
+update_lineno (l, len)
+     const char *l;
+     size_t len;
+{
+  while (len-- > 0)
+    if (*l++ == '\n')
+      lexer_line.line++;
+}
+
+#define IDchar(c) (isalnum(c) || (c) == '_')
+%}
+
+ID     [[:alpha:]][[:alnum:]_]*
+WS     [[:space:]]+
+IWORD  short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t
+ITYPE  {IWORD}({WS}{IWORD})*
+
+%x in_struct in_struct_comment in_comment in_yacc_escape
+%option warn noyywrap nounput nodefault perf-report
+%option 8bit never-interactive
+%%
+
+[^[:alnum:]_]typedef{WS}(struct|union){WS}{ID}{WS}?[*[:space:]]{WS}?{ID}{WS}?";" {
+  char *tagstart;
+  size_t taglen;
+  char *namestart;
+  size_t namelen;
+  int is_pointer = 0;
+  struct type *t;
+  int union_p;
+
+  tagstart = yytext + strlen (" typedef ");
+  while (isspace (*tagstart))
+    tagstart++;
+  union_p = tagstart[0] == 'u';
+  tagstart += strlen ("union ");
+  while (isspace (*tagstart))
+    tagstart++;
+  for (taglen = 1; IDchar (tagstart[taglen]); taglen++)
+    ;
+  for (namestart = tagstart + taglen; 
+       ! IDchar (*namestart);
+       namestart++)
+    if (*namestart == '*')
+      is_pointer = 1;
+  for (namelen = 1; IDchar (namestart[namelen]); namelen++)
+    ;
+  t = find_structure (xmemdup (tagstart, taglen, taglen+1), union_p);
+  if (is_pointer)
+    t = create_pointer (t);
+  do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+  update_lineno (yytext, yyleng);
+}
+
+[^[:alnum:]_]typedef{WS}{ITYPE}{WS}{ID}{WS}?";" {
+
+  char *namestart;
+  size_t namelen;
+  struct type *t;
+  char *typestart;
+  size_t typelen;
+
+  for (namestart = yytext + yyleng - 2; isspace (*namestart); namestart--)
+    ;
+  for (namelen = 1; !isspace (namestart[-namelen]); namelen++)
+    ;
+  namestart -= namelen - 1;
+  for (typestart = yytext + strlen (" typedef "); 
+       isspace(*typestart);
+       typestart++)
+    ;
+  for (typelen = namestart - typestart; 
+       isspace(typestart[typelen-1]); 
+       typelen--)
+    ;
+
+  t = create_scalar_type (typestart, typelen);
+  do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+  update_lineno (yytext, yyleng);
+}
+
+[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}PARAMS {
+  char *namestart;
+  size_t namelen;
+  struct type *t;
+
+  for (namestart = yytext + yyleng - 7; isspace (*namestart); namestart--)
+    ;
+  for (namelen = 1; !isspace (namestart[-namelen]); namelen++)
+    ;
+  namestart -= namelen - 1;
+
+  t = create_scalar_type ("function type", sizeof ("function type")-1);
+  do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+  update_lineno (yytext, yyleng);
+}
+[^[:alnum:]_]typedef{WS}{ID}{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
+  char *namestart;
+  size_t namelen;
+  struct type *t;
+
+  for (namestart = yytext + yyleng - 7; !IDchar (*namestart); namestart--)
+    ;
+  for (namelen = 1; IDchar (namestart[-namelen]); namelen++)
+    ;
+  namestart -= namelen - 1;
+
+  t = create_scalar_type ("function type", sizeof ("function type")-1);
+  do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+  update_lineno (yytext, yyleng);
+}
+
+[^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
+  char *tagstart;
+  size_t taglen;
+  int typedef_p;
+  int union_p;
+
+  typedef_p = yytext[1] == 't';
+  if (typedef_p)
+    for (tagstart = yytext + strlen (" typedef "); 
+        isspace(*tagstart);
+        tagstart++)
+      ;
+  else
+    tagstart = yytext + 1;
+
+  union_p = tagstart[0] == 'u';
+  tagstart += strlen ("union ");
+  while (isspace (*tagstart))
+    tagstart++;
+  for (taglen = 1; IDchar (tagstart[taglen]); taglen++)
+    ;
+
+  yylval.t = find_structure (xmemdup (tagstart, taglen, taglen + 1), union_p);
+  BEGIN(in_struct);
+  update_lineno (yytext, yyleng);
+  return typedef_p ? ENT_TYPEDEF_STRUCT : ENT_STRUCT;
+}
+
+[^[:alnum:]_](extern|static){WS}/"GTY" {
+  BEGIN(in_struct);
+  update_lineno (yytext, yyleng);
+  return ENT_EXTERNSTATIC;
+}
+
+^"%union"{WS}"{"{WS}/"GTY" {
+  BEGIN(in_struct);
+  update_lineno (yytext, yyleng);
+  return ENT_YACCUNION;
+}
+
+<in_struct>{
+
+"/*"                           { BEGIN(in_struct_comment); }
+
+^"%{"                          { BEGIN(in_yacc_escape); }
+
+{WS}                           { update_lineno (yytext, yyleng); }
+
+"const"/[^[:alnum:]_]          /* don't care */
+
+"GTY"/[^[:alnum:]_]            { return GTY_TOKEN; }
+"union"/[^[:alnum:]_]          { return UNION; }
+"struct"/[^[:alnum:]_]         { return STRUCT; }
+"enum"/[^[:alnum:]_]           { return ENUM; }
+"ptr_alias"/[^[:alnum:]_]      { return ALIAS; }
+"param_is"/[^[:alnum:]_]       { return PARAM_IS; }
+[0-9]+                         { return NUM; }
+
+{IWORD}({WS}{IWORD})*/[^[:alnum:]_]            |
+"ENUM_BITFIELD"{WS}?"("{WS}?{ID}{WS}?")"       {
+  size_t len;
+
+  for (len = yyleng; isspace (yytext[len-1]); len--)
+    ;
+
+  yylval.t = create_scalar_type (yytext, len);
+  update_lineno (yytext, yyleng);
+  return SCALAR;
+}
+
+{ID}/[^[:alnum:]_]             {
+  yylval.s = xmemdup (yytext, yyleng, yyleng+1);
+  return ID;
+}
+
+\"([^"\\]|\\.)*\"              {
+  yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
+  return STRING;
+}
+"["[^\[\]]*"]"                 {
+  yylval.s = xmemdup (yytext+1, yyleng-2, yyleng-1);
+  return ARRAY;
+}
+^"%"{ID}                       {
+  yylval.s = xmemdup (yytext+1, yyleng-1, yyleng);
+  return PERCENT_ID;
+}
+"'"("\\".|[^\\])"'"            {
+  yylval.s = xmemdup (yytext+1, yyleng-2, yyleng);
+  return CHAR;
+}
+
+[(){},*:<>]                    { return yytext[0]; }
+
+[;=]                           {
+  if (lexer_toplevel_done)
+    {
+      BEGIN(INITIAL);
+      lexer_toplevel_done = 0;
+    }
+  return yytext[0];
+}
+
+^"%%"                          {
+  BEGIN(INITIAL);
+  return PERCENTPERCENT;
+}
+
+.                              {
+  error_at_line (&lexer_line, "unexpected character `%s'", yytext);
+}
+}
+
+"/*"                   { BEGIN(in_comment); }
+\n                     { lexer_line.line++; }
+{ID}                   |
+[^"/\n]                        /* do nothing */
+\"([^"\\]|\\.|\\\n)*\" { update_lineno (yytext, yyleng); }
+"/"/[^*]               /* do nothing */
+
+<in_comment,in_struct_comment>{
+\n             { lexer_line.line++; }
+[^*\n]{16}     |
+[^*\n]         /* do nothing */
+"*"/[^/]       /* do nothing */
+}
+<in_comment>"*/"       { BEGIN(INITIAL); } 
+<in_struct_comment>"*/"        { BEGIN(in_struct); }
+
+<in_yacc_escape>{
+\n             { lexer_line.line++; }
+[^%]{16}       |
+[^%]           /* do nothing */
+"%"/[^}]       /* do nothing */
+"%}"           { BEGIN(in_struct); }
+"%"            {
+  error_at_line (&lexer_line, 
+                "unterminated %{; unexpected EOF");
+}
+}
+
+
+["/]                   |
+<in_struct_comment,in_comment>"*"      {
+  error_at_line (&lexer_line, 
+                "unterminated comment or string; unexpected EOF");
+}
+
+%%
+
+void
+yyerror (s)
+     const char *s;
+{
+  error_at_line (&lexer_line, s);
+}
+
+void
+parse_file (fname)
+      char *fname;
+{
+  yyin = fopen (fname, "r");
+  lexer_line.file = fname;
+  lexer_line.line = 1;
+  if (yyin == NULL)
+    {
+      perror (fname);
+      exit (1);
+    }
+  if (yyparse() != 0)
+    exit (1);
+  fclose (yyin);
+}
diff --git a/gcc/gengtype-yacc.y b/gcc/gengtype-yacc.y
new file mode 100644 (file)
index 0000000..43fbea6
--- /dev/null
@@ -0,0 +1,282 @@
+/* -*- indented-text -*- */
+/* Process source files and output type information.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+%{
+#include "hconfig.h"
+#include "system.h"
+#include "gengtype.h"
+#define YYERROR_VERBOSE
+%}
+
+%union {
+  type_p t;
+  pair_p p;
+  options_p o;
+  const char *s;
+}
+
+%token <t>ENT_TYPEDEF_STRUCT
+%token <t>ENT_STRUCT
+%token ENT_EXTERNSTATIC
+%token ENT_YACCUNION
+%token GTY_TOKEN "GTY"
+%token UNION "union"
+%token STRUCT "struct"
+%token ENUM "enum"
+%token ALIAS "ptr_alias"
+%token PARAM_IS "param_is"
+%token NUM
+%token PERCENTPERCENT "%%"
+%token <t>SCALAR
+%token <s>ID
+%token <s>STRING
+%token <s>ARRAY
+%token <s>PERCENT_ID
+%token <s>CHAR
+
+%type <p> struct_fields yacc_ids yacc_typematch
+%type <t> type lasttype
+%type <o> optionsopt options option optionseq optionseqopt
+%type <s> type_option
+
+%%
+
+start: /* empty */
+       | typedef_struct start
+       | externstatic start
+       | yacc_union start
+
+typedef_struct: ENT_TYPEDEF_STRUCT options '{' struct_fields '}' ID
+                  {
+                    new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
+                                   $4, $2);
+                    do_typedef ($6, $1, &lexer_line);
+                    lexer_toplevel_done = 1;
+                  }
+                ';'
+               | ENT_STRUCT options '{' struct_fields '}'
+                  {
+                    new_structure ($1->u.s.tag, UNION_P ($1), &lexer_line,
+                                   $4, $2);
+                    lexer_toplevel_done = 1;
+                  }
+                ';'
+
+externstatic: ENT_EXTERNSTATIC options lasttype ID semiequal
+                {
+                  note_variable ($4, adjust_field_type ($3, $2), $2, 
+                                 &lexer_line);
+                }
+             | ENT_EXTERNSTATIC options lasttype ID ARRAY semiequal
+                {
+                  note_variable ($4, create_array ($3, $5),
+                           $2, &lexer_line);
+                }
+             | ENT_EXTERNSTATIC options lasttype ID ARRAY ARRAY semiequal
+                {
+                  note_variable ($4, create_array (create_array ($3, $6),
+                                             $5),
+                           $2, &lexer_line);
+                }
+
+lasttype: type
+           { 
+             lexer_toplevel_done = 1;
+             $$ = $1;
+           }
+
+semiequal: ';'
+          | '='
+          ;
+
+yacc_union: ENT_YACCUNION options struct_fields '}' yacc_typematch PERCENTPERCENT
+             {
+               note_yacc_type ($2, $3, $5, &lexer_line);
+             }
+
+yacc_typematch: /* empty */
+                  { $$ = NULL; }
+               | yacc_typematch PERCENT_ID yacc_ids
+                  { 
+                    pair_p p;
+                    for (p = $3; p->next != NULL; p = p->next)
+                      {
+                        p->name = NULL;
+                        p->type = NULL;
+                      }
+                    p->name = NULL;
+                    p->type = NULL;
+                    p->next = $1;
+                    $$ = $3;
+                  }
+               | yacc_typematch PERCENT_ID '<' ID '>' yacc_ids
+                  {
+                    pair_p p;
+                    type_p newtype = NULL;
+                    if (strcmp ($2, "type") == 0)
+                      newtype = (type_p) 1;
+                    for (p = $6; p->next != NULL; p = p->next)
+                      {
+                        p->name = $4;
+                        p->type = newtype;
+                      }
+                    p->name = $4;
+                    p->next = $1;
+                    p->type = newtype;
+                    $$ = $6;
+                  }
+               ;
+
+yacc_ids: /* empty */
+       { $$ = NULL; }
+     | yacc_ids ID
+        { 
+         pair_p p = xcalloc (1, sizeof (*p));
+         p->next = $1;
+         p->line = lexer_line;
+         p->opt = xmalloc (sizeof (*(p->opt)));
+         p->opt->name = "tag";
+         p->opt->next = NULL;
+         p->opt->info = (char *)$2;
+         $$ = p;
+       }
+     | yacc_ids CHAR
+        {
+         pair_p p = xcalloc (1, sizeof (*p));
+         p->next = $1;
+         p->line = lexer_line;
+         p->opt = xmalloc (sizeof (*(p->opt)));
+         p->opt->name = "tag";
+         p->opt->next = NULL;
+         p->opt->info = xmalloc (3 + strlen ($2));
+         sprintf (p->opt->info, "'%s'", $2);
+         $$ = p;
+       }
+
+struct_fields: { $$ = NULL; }
+              | type optionsopt ID bitfieldopt ';' struct_fields
+                 {
+                   pair_p p = xmalloc (sizeof (*p));
+                   p->type = adjust_field_type ($1, $2);
+                   p->opt = $2;
+                   p->name = $3;
+                   p->next = $6;
+                   p->line = lexer_line;
+                   $$ = p;
+                 }
+              | type optionsopt ID ARRAY ';' struct_fields
+                 {
+                   pair_p p = xmalloc (sizeof (*p));
+                   p->type = adjust_field_type (create_array ($1, $4), $2);
+                   p->opt = $2;
+                   p->name = $3;
+                   p->next = $6;
+                   p->line = lexer_line;
+                   $$ = p;
+                 }
+              | type optionsopt ID ARRAY ARRAY ';' struct_fields
+                 {
+                   pair_p p = xmalloc (sizeof (*p));
+                   p->type = create_array (create_array ($1, $5), $4);
+                   p->opt = $2;
+                   p->name = $3;
+                   p->next = $7;
+                   p->line = lexer_line;
+                   $$ = p;
+                 }
+
+bitfieldopt: /* empty */
+            | ':' NUM
+
+type: SCALAR
+         { $$ = $1; }
+      | ID
+         { $$ = resolve_typedef ($1, &lexer_line); }
+      | type '*'
+         { $$ = create_pointer ($1); }
+      | STRUCT ID '{' struct_fields '}'
+         {
+          new_structure ($2, 0, &lexer_line, $4, NULL);
+           $$ = find_structure ($2, 0);
+        }
+      | STRUCT ID
+         { $$ = find_structure ($2, 0); }
+      | UNION ID '{' struct_fields '}'
+         {
+          new_structure ($2, 1, &lexer_line, $4, NULL);
+           $$ = find_structure ($2, 1);
+        }
+      | UNION ID
+         { $$ = find_structure ($2, 1); }
+      | ENUM ID
+         { $$ = create_scalar_type ($2, strlen ($2)); }
+      | ENUM ID '{' enum_items '}'
+         { $$ = create_scalar_type ($2, strlen ($2)); }
+
+enum_items: /* empty */
+           | ID '=' NUM ',' enum_items
+             { }
+           | ID ',' enum_items
+             { }
+           | ID enum_items
+             { }
+           ;
+
+optionsopt: { $$ = NULL; }
+           | options { $$ = $1; }
+
+options: GTY_TOKEN '(' '(' optionseqopt ')' ')' { $$ = $4; }
+
+type_option : ALIAS
+               { $$ = "ptr_alias"; }
+             | PARAM_IS
+               { $$ = "param_is"; }
+
+option:        type_option '(' type ')'
+          {
+            options_p o = xmalloc (sizeof (*o));
+            o->name = $1;
+            o->info = $3;
+            $$ = o;
+          }
+       | ID '(' STRING ')'
+          { 
+            options_p o = xmalloc (sizeof (*o));
+            o->name = $1;
+            o->info = (void *)$3;
+            $$ = o;
+          }
+
+optionseq: option
+             {
+               $1->next = NULL;
+               $$ = $1;
+             }
+           | optionseq ',' option
+             {
+               $3->next = $1;
+               $$ = $3;
+             }
+
+optionseqopt: { $$ = NULL }
+             | optionseq { $$ = $1; }
+
+%%
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
new file mode 100644 (file)
index 0000000..dda57e2
--- /dev/null
@@ -0,0 +1,1824 @@
+/* Process source files and output type information.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include "hconfig.h"
+#include "system.h"
+#include <ctype.h>
+#include "gengtype.h"
+
+static int hit_error = 0;
+void
+error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
+{
+  VA_OPEN (ap, msg);
+  VA_FIXEDARG (ap, struct fileloc *, pos);
+  VA_FIXEDARG (ap, const char *, msg);
+
+  fprintf (stderr, "%s:%d: ", pos->file, pos->line);
+  vfprintf (stderr, msg, ap);
+  fputc ('\n', stderr);
+  hit_error = 1;
+
+  VA_CLOSE (ap);
+}
+
+struct type string_type = {
+  TYPE_STRING, NULL, NULL, GC_USED
+  UNION_INIT_ZERO
+}; 
+
+static pair_p typedefs;
+static type_p structures;
+static type_p param_structs;
+static pair_p variables;
+
+void
+do_typedef (s, t, pos)
+     const char *s;
+     type_p t;
+     struct fileloc *pos;
+{
+  pair_p p;
+
+  for (p = typedefs; p != NULL; p = p->next)
+    if (strcmp (p->name, s) == 0)
+      {
+       if (p->type != t)
+         {
+           error_at_line (pos, "type `%s' previously defined", s);
+           error_at_line (&p->line, "previously defined here");
+         }
+       return;
+      }
+
+  p = xmalloc (sizeof (struct pair));
+  p->next = typedefs;
+  p->name = s;
+  p->type = t;
+  p->line = *pos;
+  typedefs = p;
+}
+
+type_p
+resolve_typedef (s, pos)
+     const char *s;
+     struct fileloc *pos;
+{
+  pair_p p;
+  for (p = typedefs; p != NULL; p = p->next)
+    if (strcmp (p->name, s) == 0)
+      return p->type;
+  error_at_line (pos, "unidentified type `%s'", s);
+  return create_scalar_type ("char", 4);
+}
+
+void
+new_structure (name, isunion, pos, fields, o)
+     const char *name;
+     int isunion;
+     struct fileloc *pos;
+     pair_p fields;
+     options_p o;
+{
+  type_p si;
+  type_p s = NULL;
+  lang_bitmap bitmap = get_base_file_bitmap (pos->file);
+
+  for (si = structures; si != NULL; si = si->next)
+    if (strcmp (name, si->u.s.tag) == 0 
+       && UNION_P (si) == isunion)
+      {
+       type_p ls = NULL;
+       if (si->kind == TYPE_LANG_STRUCT)
+         {
+           ls = si;
+           
+           for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
+             if (si->u.s.bitmap == bitmap)
+               s = si;
+         }
+       else if (si->u.s.line.file != NULL && si->u.s.bitmap != bitmap)
+         {
+           ls = si;
+           si = xcalloc (1, sizeof (struct type));
+           memcpy (si, ls, sizeof (struct type));
+           ls->kind = TYPE_LANG_STRUCT;
+           ls->u.s.lang_struct = si;
+           ls->u.s.fields = NULL;
+           si->next = NULL;
+           si->pointer_to = NULL;
+           si->u.s.lang_struct = ls;
+         }
+       else
+         s = si;
+
+       if (ls != NULL && s == NULL)
+         {
+           s = xcalloc (1, sizeof (struct type));
+           s->next = ls->u.s.lang_struct;
+           ls->u.s.lang_struct = s;
+           s->u.s.lang_struct = ls;
+         }
+       break;
+      }
+  
+  if (s == NULL)
+    {
+      s = xcalloc (1, sizeof (struct type));
+      s->next = structures;
+      structures = s;
+    }
+
+  if (s->u.s.line.file != NULL
+      || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
+    {
+      error_at_line (pos, "duplicate structure definition");
+      error_at_line (&s->u.s.line, "previous definition here");
+    }
+
+  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
+  s->u.s.tag = name;
+  s->u.s.line = *pos;
+  s->u.s.fields = fields;
+  s->u.s.opt = o;
+  s->u.s.bitmap = bitmap;
+  if (s->u.s.lang_struct)
+    s->u.s.lang_struct->u.s.bitmap |= bitmap;
+}
+
+type_p
+find_structure (name, isunion)
+     const char *name;
+     int isunion;
+{
+  type_p s;
+
+  for (s = structures; s != NULL; s = s->next)
+    if (strcmp (name, s->u.s.tag) == 0 
+       && UNION_P (s) == isunion)
+      return s;
+
+  s = xcalloc (1, sizeof (struct type));
+  s->next = structures;
+  structures = s;
+  s->kind = isunion ? TYPE_UNION : TYPE_STRUCT;
+  s->u.s.tag = name;
+  structures = s;
+  return s;
+}
+
+type_p
+create_scalar_type (name, name_len)
+     const char *name;
+     size_t name_len;
+{
+  type_p r = xcalloc (1, sizeof (struct type));
+  r->kind = TYPE_SCALAR;
+  r->u.sc = xmemdup (name, name_len, name_len + 1);
+  return r;
+}
+
+type_p
+create_pointer (t)
+     type_p t;
+{
+  if (! t->pointer_to)
+    {
+      type_p r = xcalloc (1, sizeof (struct type));
+      r->kind = TYPE_POINTER;
+      r->u.p = t;
+      t->pointer_to = r;
+    }
+  return t->pointer_to;
+}
+
+type_p
+create_array (t, len)
+     type_p t;
+     const char *len;
+{
+  type_p v;
+  
+  v = xcalloc (1, sizeof (*v));
+  v->kind = TYPE_ARRAY;
+  v->u.a.p = t;
+  v->u.a.len = len;
+  return v;
+}
+
+type_p
+adjust_field_type (t, opt)
+     type_p t;
+     options_p opt;
+{
+  int length_p = 0;
+  const int pointer_p = t->kind == TYPE_POINTER;
+  
+  for (; opt; opt = opt->next)
+    if (strcmp (opt->name, "length") == 0)
+      length_p = 1;
+    else if (strcmp (opt->name, "param_is") == 0)
+      {
+       type_p realt;
+
+       if (pointer_p)
+         t = t->u.p;
+       
+       for (realt = param_structs; realt; realt = realt->next)
+         if (realt->u.param_struct.stru == t
+             && realt->u.param_struct.param == (type_p) opt->info)
+           return pointer_p ? create_pointer (realt) : realt;
+       realt = xcalloc (1, sizeof (*realt));
+       realt->kind = TYPE_PARAM_STRUCT;
+       realt->next = param_structs;
+       param_structs = realt;
+       realt->u.param_struct.stru = t;
+       realt->u.param_struct.param = (type_p) opt->info;
+       return pointer_p ? create_pointer (realt) : realt;
+      }
+  
+  if (! length_p
+      && pointer_p
+      && t->u.p->kind == TYPE_SCALAR
+      && (strcmp (t->u.p->u.sc, "char") == 0
+         || strcmp (t->u.p->u.sc, "unsigned char") == 0))
+    return &string_type;
+  if (t->kind == TYPE_ARRAY && t->u.a.p->kind == TYPE_POINTER
+      && t->u.a.p->u.p->kind == TYPE_SCALAR
+      && (strcmp (t->u.a.p->u.p->u.sc, "char") == 0
+         || strcmp (t->u.a.p->u.p->u.sc, "unsigned char") == 0))
+    return create_array (&string_type, t->u.a.len);
+
+  return t;
+}
+
+void
+note_variable (s, t, o, pos)
+     const char *s;
+     type_p t;
+     options_p o;
+     struct fileloc *pos;
+{
+  pair_p n;
+  n = xmalloc (sizeof (*n));
+  n->name = s;
+  n->type = t;
+  n->line = *pos;
+  n->opt = o;
+  n->next = variables;
+  variables = n;
+}
+
+void
+note_yacc_type (o, fields, typeinfo, pos)
+     options_p o;
+     pair_p fields;
+     pair_p typeinfo;
+     struct fileloc *pos;
+{
+  pair_p p;
+  pair_p *p_p;
+  
+  for (p = typeinfo; p; p = p->next)
+    {
+      pair_p m;
+      
+      if (p->name == NULL)
+       continue;
+
+      if (p->type == (type_p) 1)
+       {
+         pair_p pp;
+         int ok = 0;
+         
+         for (pp = typeinfo; pp; pp = pp->next)
+           if (pp->type != (type_p) 1
+               && strcmp (pp->opt->info, p->opt->info) == 0)
+             {
+               ok = 1;
+               break;
+             }
+         if (! ok)
+           continue;
+       }
+
+      for (m = fields; m; m = m->next)
+       if (strcmp (m->name, p->name) == 0)
+         p->type = m->type;
+      if (p->type == NULL)
+       {
+         error_at_line (&p->line, 
+                        "couldn't match fieldname `%s'", p->name);
+         p->name = NULL;
+       }
+    }
+  
+  p_p = &typeinfo;
+  while (*p_p)
+    {
+      pair_p p = *p_p;
+
+      if (p->name == NULL
+         || p->type == (type_p) 1)
+       *p_p = p->next;
+      else
+       p_p = &p->next;
+    }
+
+  new_structure ("yy_union", 1, pos, typeinfo, o);
+  do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
+}
+\f
+static void process_gc_options PARAMS ((options_p, enum gc_used_enum, int *));
+static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum));
+static void set_gc_used PARAMS ((pair_p));
+
+static void
+process_gc_options (opt, level, maybe_undef)
+     options_p opt;
+     enum gc_used_enum level;
+     int *maybe_undef;
+{
+  options_p o;
+  for (o = opt; o; o = o->next)
+    if (strcmp (o->name, "ptr_alias") == 0 && level == GC_POINTED_TO)
+      set_gc_used_type ((type_p) o->info, GC_POINTED_TO);
+    else if (strcmp (o->name, "maybe_undef") == 0)
+      *maybe_undef = 1;
+}
+
+static void
+set_gc_used_type (t, level)
+     type_p t;
+     enum gc_used_enum level;
+{
+  if (t->gc_used >= level)
+    return;
+
+  t->gc_used = level;
+
+  switch (t->kind)
+    {
+    case TYPE_STRUCT:
+    case TYPE_UNION:
+      {
+       pair_p f;
+       int dummy;
+
+       process_gc_options (t->u.s.opt, level, &dummy);
+
+       for (f = t->u.s.fields; f; f = f->next)
+         {
+           int maybe_undef = 0;
+           process_gc_options (t->u.s.opt, level, &maybe_undef);
+           
+           if (maybe_undef && f->type->kind == TYPE_POINTER)
+             set_gc_used_type (f->type->u.p, GC_MAYBE_POINTED_TO);
+           else
+             set_gc_used_type (f->type, GC_USED);
+         }
+       break;
+      }
+
+    case TYPE_POINTER:
+      set_gc_used_type (t->u.p, GC_POINTED_TO);
+      break;
+
+    case TYPE_ARRAY:
+      set_gc_used_type (t->u.a.p, GC_USED);
+      break;
+      
+    case TYPE_LANG_STRUCT:
+      for (t = t->u.s.lang_struct; t; t = t->next)
+       set_gc_used_type (t, level);
+      break;
+
+    case TYPE_PARAM_STRUCT:
+      set_gc_used_type (t->u.param_struct.param, GC_POINTED_TO);
+      set_gc_used_type (t->u.param_struct.stru, GC_USED);
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+set_gc_used (variables)
+     pair_p variables;
+{
+  pair_p p;
+  for (p = variables; p; p = p->next)
+    set_gc_used_type (p->type, GC_USED);
+}
+\f
+/* File mapping routines.  For each input file, there is one output .c file
+   (but some output files have many input files), and there is one .h file
+   for the whole build.  */
+
+typedef struct filemap *filemap_p;
+
+struct filemap {
+  filemap_p next;
+  const char *input_name;
+  const char *output_name;
+  FILE *output;
+};
+
+static filemap_p files;
+FILE * header_file;
+
+enum {
+  BASE_FILE_C,
+  BASE_FILE_OBJC,
+  BASE_FILE_CPLUSPLUS
+};
+static const char *lang_names[] = {
+  "c", "objc", "cp", "f", "ada", "java"
+};
+#define NUM_BASE_FILES (sizeof (lang_names) / sizeof (lang_names[0]))
+FILE *base_files[NUM_BASE_FILES];
+
+static FILE * create_file PARAMS ((const char *));
+static const char * get_file_basename PARAMS ((const char *));
+
+static FILE *
+create_file (name)
+     const char *name;
+{
+  static const char *const hdr[] = {
+    "   Copyright (C) 2002 Free Software Foundation, Inc.\n",
+    "\n",
+    "This file is part of GCC.\n",
+    "\n",
+    "GCC is free software; you can redistribute it and/or modify it under\n",
+    "the terms of the GNU General Public License as published by the Free\n",
+    "Software Foundation; either version 2, or (at your option) any later\n",
+    "version.\n",
+    "\n",
+    "GCC is distributed in the hope that it will be useful, but WITHOUT ANY\n",
+    "WARRANTY; without even the implied warranty of MERCHANTABILITY or\n",
+    "FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n",
+    "for more details.\n",
+    "\n",
+    "You should have received a copy of the GNU General Public License\n",
+    "along with GCC; see the file COPYING.  If not, write to the Free\n",
+    "Software Foundation, 59 Temple Place - Suite 330, Boston, MA\n",
+    "02111-1307, USA.  */\n",
+    "\n",
+    "/* This file is machine generated.  Do not edit.  */\n"
+  };
+  FILE *f;
+  size_t i;
+  
+  f = tmpfile();
+  if (f == NULL)
+    {
+      perror ("couldn't create temporary file");
+      exit (1);
+    }
+  fprintf (f, "/* Type information for %s.\n", name);
+  for (i = 0; i < sizeof(hdr)/sizeof(hdr[0]); i++)
+    fputs (hdr[i], f);
+  return f;
+}
+
+static void
+open_base_files (void)
+{
+  size_t i;
+  
+  header_file = create_file ("GCC");
+
+  for (i = 0; i < NUM_BASE_FILES; i++)
+    {
+      filemap_p newf;
+      char *s;
+      
+      base_files[i] = create_file (lang_names[i]);
+      newf = xmalloc (sizeof (*newf));
+      newf->next = files;
+      files = newf;
+      newf->input_name = NULL;
+      newf->output = base_files[i];
+      newf->output_name = s = xmalloc (16);
+      sprintf (s, "gtype-%s.h", lang_names[i]);
+    }
+}
+
+#define startswith(len, c, s)  \
+  ((size_t)(len) >= strlen (s) && memcmp (c, s, strlen (s)) == 0)
+
+static const char *
+get_file_basename (f)
+     const char *f;
+{
+  size_t len;
+  const char *basename;
+  
+  /* Determine the output file name.  */
+  len = strlen (f);
+  basename = strrchr (f, '/');
+  if (basename == NULL)
+    basename = f;
+  else
+    basename++;
+  if (startswith (basename - f, basename-2, "f/"))
+    basename -= 2;
+  else if (startswith (basename - f, basename-3, "cp/"))
+    basename -= 3;
+  else if (startswith (basename - f, basename-4, "ada/"))
+    basename -= 4;
+  else if (startswith (basename - f, basename-5, "java/"))
+    basename -= 5;
+  else if (startswith (basename - f, basename-5, "objc/"))
+    basename -= 5;
+
+  return basename;
+}
+
+unsigned
+get_base_file_bitmap (input_file)
+     const char *input_file;
+{
+  const char *basename = get_file_basename (input_file);
+  const char *slashpos = strchr (basename, '/');
+  size_t len = strlen (basename);
+  
+  if (slashpos != NULL)
+    {
+      size_t i;
+      for (i = 0; i < NUM_BASE_FILES; i++)
+       if ((size_t)(slashpos - basename) == strlen (lang_names [i])
+           && memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0)
+         return 1 << i;
+    }
+  else if (strcmp (basename, "c-lang.c") == 0)
+    return 1 << BASE_FILE_C;
+  else if (strcmp (basename, "c-parse.in") == 0
+          || strcmp (basename, "c-tree.h") == 0
+          || strcmp (basename, "c-decl.c") == 0
+          || strcmp (basename, "c-objc-common.c") == 0)
+    return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC;
+  else if (startswith (len, basename, "c-"))
+    return 1 << BASE_FILE_C | 1 << BASE_FILE_OBJC | 1 << BASE_FILE_CPLUSPLUS;
+  else
+    return (1 << NUM_BASE_FILES) - 1;
+  abort ();
+}
+
+FILE *
+get_output_file_with_visibility (input_file)
+     const char *input_file;
+{
+  filemap_p fm, fmo;
+  size_t len;
+  const char *basename;
+
+  /* Do we already know the file?  */
+  for (fm = files; fm; fm = fm->next)
+    if (input_file == fm->input_name)
+      return fm->output;
+
+  /* No, we'll be creating a new filemap.  */
+  fm = xmalloc (sizeof (*fm));
+  fm->next = files;
+  files = fm;
+  fm->input_name = input_file;
+  
+  /* Determine the output file name.  */
+  basename = get_file_basename (input_file);
+
+  len = strlen (basename);
+  if ((len > 2 && memcmp (basename+len-2, ".c", 2) == 0)
+      || (len > 2 && memcmp (basename+len-2, ".y", 2) == 0)
+      || (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
+    {
+      char *s;
+      
+      fm->output_name = s = xmalloc (sizeof ("gt-") + len);
+      sprintf (s, "gt-%s", basename);
+      for (; *s != '.'; s++)
+       if (! isalnum (*s) && *s != '-')
+         *s = '-';
+      memcpy (s, ".h", sizeof (".h"));
+    }
+  else if (strcmp (basename, "c-common.h") == 0)
+    fm->output_name = "gt-c-common.h";
+  else if (strcmp (basename, "c-tree.h") == 0)
+    fm->output_name = "gt-c-decl.h";
+  else 
+    {
+      size_t i;
+      
+      fm->output_name = "gtype-desc.c";
+      for (i = 0; i < NUM_BASE_FILES; i++)
+       if (memcmp (basename, lang_names[i], strlen (lang_names[i])) == 0
+           && basename[strlen(lang_names[i])] == '/')
+         {
+           char *s;
+           
+           s = xmalloc (16);
+           sprintf (s, "gtype-%s.h", lang_names[i]);
+           fm->output_name = s;
+           break;
+         }
+    }
+
+  /* Look through to see if we've ever seen this output filename before.  */
+  for (fmo = fm->next; fmo; fmo = fmo->next)
+    if (strcmp (fmo->output_name, fm->output_name) == 0)
+      {
+       fm->output = fmo->output;
+       break;
+      }
+
+  /* If not, create it.  */
+  if (fmo == NULL)
+    {
+      fm->output = create_file (fm->output_name);
+      if (strcmp (fm->output_name, "gtype-desc.c") == 0)
+       {
+         fputs ("#include \"config.h\"\n", fm->output);
+         fputs ("#include \"system.h\"\n", fm->output);
+         fputs ("#include \"varray.h\"\n", fm->output);
+         fputs ("#include \"hashtab.h\"\n", fm->output);
+         fputs ("#include \"bitmap.h\"\n", fm->output);
+         fputs ("#include \"tree.h\"\n", fm->output);
+         fputs ("#include \"rtl.h\"\n", fm->output);
+         fputs ("#include \"function.h\"\n", fm->output);
+         fputs ("#include \"insn-config.h\"\n", fm->output);
+         fputs ("#include \"expr.h\"\n", fm->output);
+         fputs ("#include \"hard-reg-set.h\"\n", fm->output);
+         fputs ("#include \"basic-block.h\"\n", fm->output);
+         fputs ("#include \"cselib.h\"\n", fm->output);
+         fputs ("#include \"insn-addr.h\"\n", fm->output);
+         fputs ("#include \"ssa.h\"\n", fm->output);
+         fputs ("#include \"optabs.h\"\n", fm->output);
+         fputs ("#include \"libfuncs.h\"\n", fm->output);
+         fputs ("#include \"debug.h\"\n", fm->output);
+         fputs ("#include \"ggc.h\"\n", fm->output);
+       }
+    }
+
+  return fm->output;
+}
+
+const char *
+get_output_file_name (input_file)
+     const char *input_file;
+{
+  filemap_p fm;
+
+  for (fm = files; fm; fm = fm->next)
+    if (input_file == fm->input_name)
+      return fm->output_name;
+  (void) get_output_file_with_visibility (input_file);
+  return get_output_file_name (input_file);
+}
+
+static void
+close_output_files PARAMS ((void))
+{
+  filemap_p fm;
+  struct filemap header;
+  header.next = files;
+  header.output_name = "gtype-desc.h";
+  header.output = header_file;
+  
+  for (fm = &header; fm; fm = fm->next)
+    {
+      int no_write_p;
+      filemap_p ofm;
+      FILE *newfile;
+      
+      /* Handle each output file once.  */
+      if (fm->output == NULL)
+       continue;
+      
+      for (ofm = fm->next; ofm; ofm = ofm->next)
+       if (fm->output == ofm->output)
+         ofm->output = NULL;
+      
+      /* Compare the output file with the file to be created, avoiding
+        unnecessarily changing timestamps.  */
+      newfile = fopen (fm->output_name, "r");
+      if (newfile != NULL)
+       {
+         int ch1, ch2;
+         
+         rewind (fm->output);
+         do {
+           ch1 = fgetc (fm->output);
+           ch2 = fgetc (newfile);
+         } while (ch1 != EOF && ch1 == ch2);
+
+         fclose (newfile);
+         
+         no_write_p = ch1 == ch2;
+       }
+      else
+       no_write_p = 0;
+     
+      /* Nothing interesting to do.  Close the output file.  */
+      if (no_write_p)
+       {
+         fclose (fm->output);
+         continue;
+       }
+
+      newfile = fopen (fm->output_name, "w");
+      if (newfile == NULL)
+       {
+         perror ("opening output file");
+         exit (1);
+       }
+      {
+       int ch;
+       rewind (fm->output);
+       while ((ch = fgetc (fm->output)) != EOF)
+         fputc (ch, newfile);
+      }
+      fclose (newfile);
+      fclose (fm->output);
+    }
+}
+\f
+struct flist {
+  struct flist *next;
+  int started_p;
+  const char *name;
+  FILE *f;
+};
+
+static void output_escaped_param PARAMS ((FILE *, const char *, const char *,
+                                         const char *, const char *,
+                                         struct fileloc *));
+static void write_gc_structure_fields 
+  PARAMS ((FILE *, type_p, const char *, const char *, options_p, 
+          int, struct fileloc *, lang_bitmap, type_p));
+static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p));
+static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
+static void put_mangled_filename PARAMS ((FILE *, const char *));
+static void finish_root_table PARAMS ((struct flist *flp, const char *pfx, 
+                                      const char *tname, const char *lastname,
+                                      const char *name));
+static void write_gc_root PARAMS ((FILE *, pair_p, type_p, const char *, int,
+                                  struct fileloc *, const char *));
+static void write_gc_roots PARAMS ((pair_p));
+
+static int gc_counter;
+
+static void
+output_escaped_param (of, param, val, prev_val, oname, line)
+     FILE *of;
+     const char *param;
+     const char *val;
+     const char *prev_val;
+     const char *oname;
+     struct fileloc *line;
+{
+  const char *p;
+  
+  for (p = param; *p; p++)
+    if (*p != '%')
+      fputc (*p, of);
+    else if (*++p == 'h')
+      fprintf (of, "(%s)", val);
+    else if (*p == '0')
+      fputs ("(*x)", of);
+    else if (*p == '1')
+      fprintf (of, "(%s)", prev_val);
+    else
+      error_at_line (line, "`%s' option contains bad escape %c%c",
+                    oname, '%', *p);
+}
+
+static void
+write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
+                          param)
+     FILE *of;
+     type_p s;
+     const char *val;
+     const char *prev_val;
+     options_p opts;
+     int indent;
+     struct fileloc *line;
+     lang_bitmap bitmap;
+     type_p param;
+{
+  pair_p f;
+  int tagcounter = -1;
+
+  if (! s->u.s.line.file)
+    error_at_line (line, "incomplete structure `%s'", s->u.s.tag);
+  else if ((s->u.s.bitmap & bitmap) != bitmap)
+    {
+      error_at_line (line, "structure defined for mismatching languages");
+      error_at_line (&s->u.s.line, "one structure defined here");
+    }
+  
+  if (s->kind == TYPE_UNION)
+    {
+      const char *tagexpr = NULL;
+      options_p oo;
+      
+      tagcounter = ++gc_counter;
+      for (oo = opts; oo; oo = oo->next)
+       if (strcmp (oo->name, "desc") == 0)
+         tagexpr = (const char *)oo->info;
+      if (tagexpr == NULL)
+       {
+         tagexpr = "1";
+         error_at_line (line, "missing `desc' option");
+       }
+
+      fprintf (of, "%*s{\n", indent, "");
+      indent += 2;
+      fprintf (of, "%*sunsigned int tag%d = (", indent, "", tagcounter);
+      output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
+      fputs (");\n", of);
+    }
+  
+  for (f = s->u.s.fields; f; f = f->next)
+    {
+      const char *tagid = NULL;
+      const char *length = NULL;
+      const char *special = NULL;
+      int skip_p = 0;
+      int always_p = 0;
+      int maybe_undef_p = 0;
+      int use_param_p = 0;
+      options_p oo;
+      type_p t = f->type;
+      
+      if (t->kind == TYPE_SCALAR
+         || (t->kind == TYPE_ARRAY 
+             && t->u.a.p->kind == TYPE_SCALAR))
+       continue;
+      
+      for (oo = f->opt; oo; oo = oo->next)
+       if (strcmp (oo->name, "length") == 0)
+         length = (const char *)oo->info;
+       else if (strcmp (oo->name, "maybe_undef") == 0)
+         maybe_undef_p = 1;
+       else if (strcmp (oo->name, "tag") == 0)
+         tagid = (const char *)oo->info;
+       else if (strcmp (oo->name, "special") == 0)
+         special = (const char *)oo->info;
+       else if (strcmp (oo->name, "skip") == 0)
+         skip_p = 1;
+       else if (strcmp (oo->name, "always") == 0)
+         always_p = 1;
+       else if (strcmp (oo->name, "desc") == 0 && UNION_P (t))
+         ;
+       else if (strcmp (oo->name, "descbits") == 0 && UNION_P (t))
+         ;
+       else if (strcmp (oo->name, "param_is") == 0)
+         ;
+       else if (strcmp (oo->name, "use_param") == 0)
+         use_param_p = 1;
+       else
+         error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
+
+      if (skip_p)
+       continue;
+      
+      if (use_param_p)
+       {
+         if (param != NULL)
+           {
+             type_p t1;
+             type_p nt = param;
+             int arraycount = 0;
+             
+             for (t1 = t; t->kind == TYPE_ARRAY; t = t->u.a.p)
+               arraycount++;
+             for (; t->kind == TYPE_POINTER; t = t->u.p)
+               nt = create_pointer (nt);
+             while (arraycount-- > 0)
+               nt = create_array (nt, t->u.a.len);
+             t = nt;
+           }
+         else if (s->kind == TYPE_UNION && ! always_p && tagid)
+           ;
+         else
+           error_at_line (&f->line, "no parameter defined");
+       }
+
+      if (maybe_undef_p
+         && (t->kind != TYPE_POINTER
+             || t->u.p->kind != TYPE_STRUCT))
+       error_at_line (&f->line, 
+                      "field `%s' has invalid option `maybe_undef_p'\n",
+                      f->name);
+      if (s->kind == TYPE_UNION && ! always_p )
+       {
+         if (! tagid)
+           {
+             error_at_line (&f->line, "field `%s' has no tag", f->name);
+             continue;
+           }
+         fprintf (of, "%*sif (tag%d == (%s)) {\n", indent, "", 
+                  tagcounter, tagid);
+         indent += 2;
+       }
+      
+      switch (t->kind)
+       {
+       case TYPE_STRING:
+         /* Do nothing; strings go in the string pool.  */
+         break;
+
+       case TYPE_LANG_STRUCT:
+         {
+           type_p ti;
+           for (ti = t->u.s.lang_struct; ti; ti = ti->next)
+             if (ti->u.s.bitmap & bitmap)
+               {
+                 t = ti;
+                 break;
+               }
+           if (ti == NULL)
+             {
+               error_at_line (&f->line, 
+                              "structure not defined for this language");
+               break;
+             }
+         }
+         /* Fall through... */
+       case TYPE_STRUCT:
+       case TYPE_UNION:
+         {
+           char *newval;
+
+           newval = xmalloc (strlen (val) + sizeof (".") + strlen (f->name));
+           sprintf (newval, "%s.%s", val, f->name);
+           write_gc_structure_fields (of, t, newval, val, f->opt, indent, 
+                                      &f->line, bitmap, param);
+           free (newval);
+           break;
+         }
+
+       case TYPE_POINTER:
+         if (! length)
+           {
+             if (maybe_undef_p
+                 && t->u.p->u.s.line.file == NULL)
+               fprintf (of, "%*sif (%s.%s) abort();\n", indent, "",
+                        val, f->name);
+             else if (UNION_OR_STRUCT_P (t->u.p))
+               fprintf (of, "%*sgt_ggc_m_%s (%s.%s);\n", indent, "", 
+                        t->u.p->u.s.tag, val, f->name);
+             else if (t->u.p->kind == TYPE_PARAM_STRUCT)
+               fprintf (of, "%*sgt_ggc_mm_%d%s_%s (%s.%s);\n", indent, "",
+                        (int) strlen (t->u.p->u.param_struct.param->u.s.tag),
+                        t->u.p->u.param_struct.param->u.s.tag,
+                        t->u.p->u.param_struct.stru->u.s.tag,
+                        val, f->name);
+             else
+               error_at_line (&f->line, "field `%s' is pointer to scalar",
+                              f->name);
+             break;
+           }
+         else if (t->u.p->kind == TYPE_SCALAR
+                  || t->u.p->kind == TYPE_STRING)
+           fprintf (of, "%*sggc_mark (%s.%s);\n", indent, "", 
+                    val, f->name);
+         else
+           {
+             int loopcounter = ++gc_counter;
+             
+             fprintf (of, "%*sif (%s.%s != NULL) {\n", indent, "",
+                      val, f->name);
+             indent += 2;
+             fprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
+             fprintf (of, "%*sggc_set_mark (%s.%s);\n", indent, "", 
+                      val, f->name);
+             fprintf (of, "%*sfor (i%d = 0; i%d < (", indent, "", 
+                      loopcounter, loopcounter);
+             output_escaped_param (of, length, val, prev_val, "length", line);
+             fprintf (of, "); i%d++) {\n", loopcounter);
+             indent += 2;
+             switch (t->u.p->kind)
+               {
+               case TYPE_STRUCT:
+               case TYPE_UNION:
+                 {
+                   char *newval;
+                   
+                   newval = xmalloc (strlen (val) + 8 + strlen (f->name));
+                   sprintf (newval, "%s.%s[i%d]", val, f->name, loopcounter);
+                   write_gc_structure_fields (of, t->u.p, newval, val,
+                                              f->opt, indent, &f->line,
+                                              bitmap, param);
+                   free (newval);
+                   break;
+                 }
+               case TYPE_POINTER:
+                 if (UNION_OR_STRUCT_P (t->u.p->u.p))
+                   fprintf (of, "%*sgt_ggc_m_%s (%s.%s[i%d]);\n", indent, "", 
+                            t->u.p->u.p->u.s.tag, val, f->name,
+                            loopcounter);
+                 else
+                   error_at_line (&f->line, 
+                                  "field `%s' is array of pointer to scalar",
+                                  f->name);
+                 break;
+               default:
+                 error_at_line (&f->line, 
+                                "field `%s' is array of unimplemented type",
+                                f->name);
+                 break;
+               }
+             indent -= 2;
+             fprintf (of, "%*s}\n", indent, "");
+             indent -= 2;
+             fprintf (of, "%*s}\n", indent, "");
+           }
+         break;
+
+       case TYPE_ARRAY:
+         {
+           int loopcounter = ++gc_counter;
+           type_p ta;
+           int i;
+
+           if (! length &&
+               (strcmp (t->u.a.len, "0") == 0
+                || strcmp (t->u.a.len, "1") == 0))
+             error_at_line (&f->line, 
+                            "field `%s' is array of size %s",
+                            f->name, t->u.a.len);
+           
+           /* Arrays of scalars can be ignored.  */
+           for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
+             ;
+           if (ta->kind == TYPE_SCALAR
+               || ta->kind == TYPE_STRING)
+             break;
+
+           fprintf (of, "%*s{\n", indent, "");
+           indent += 2;
+
+           if (special != NULL && strcmp (special, "tree_exp") == 0)
+             {
+               fprintf (of, "%*sconst size_t tree_exp_size = (",
+                         indent, "");
+               output_escaped_param (of, length, val, prev_val,
+                                     "length", line);
+               fputs (");\n", of);
+
+               length = "first_rtl_op (TREE_CODE ((tree)&%h))";
+             }
+
+           for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+             {
+               fprintf (of, "%*ssize_t i%d_%d;\n", 
+                        indent, "", loopcounter, i);
+               fprintf (of, "%*sconst size_t ilimit%d_%d = (",
+                        indent, "", loopcounter, i);
+               if (i == 0 && length != NULL)
+                 output_escaped_param (of, length, val, prev_val, 
+                                       "length", line);
+               else
+                 fputs (ta->u.a.len, of);
+               fputs (");\n", of);
+             }
+               
+           for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+             {
+               fprintf (of, 
+                "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
+                        indent, "", loopcounter, i, loopcounter, i,
+                        loopcounter, i, loopcounter, i);
+               indent += 2;
+             }
+
+           if (ta->kind == TYPE_POINTER
+               && (ta->u.p->kind == TYPE_STRUCT
+                   || ta->u.p->kind == TYPE_UNION))
+             {
+               fprintf (of, "%*sgt_ggc_m_%s (%s.%s", 
+                        indent, "", ta->u.p->u.s.tag, val, f->name);
+               for (ta = t, i = 0; 
+                    ta->kind == TYPE_ARRAY; 
+                    ta = ta->u.a.p, i++)
+                 fprintf (of, "[i%d_%d]", loopcounter, i);
+               fputs (");\n", of);
+             }
+           else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
+             {
+               char *newval;
+               int len;
+               
+               len = strlen (val) + strlen (f->name) + 2;
+               for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
+                 len += sizeof ("[i_]") + 2*6;
+               
+               newval = xmalloc (len);
+               sprintf (newval, "%s.%s", val, f->name);
+               for (ta = t, i = 0; 
+                    ta->kind == TYPE_ARRAY; 
+                    ta = ta->u.a.p, i++)
+                 sprintf (newval + strlen (newval), "[i%d_%d]", 
+                          loopcounter, i);
+               write_gc_structure_fields (of, t->u.p, newval, val,
+                                          f->opt, indent, &f->line, bitmap,
+                                          param);
+               free (newval);
+             }
+           else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR
+                    && use_param_p && param == NULL)
+             fprintf (of, "%*sabort();\n", indent, "");
+           else
+             error_at_line (&f->line, 
+                            "field `%s' is array of unimplemented type",
+                            f->name);
+           for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+             {
+               indent -= 2;
+               fprintf (of, "%*s}\n", indent, "");
+             }
+
+           if (special != NULL && strcmp (special, "tree_exp") == 0)
+             {
+               fprintf (of, 
+                "%*sfor (; i%d_0 < tree_exp_size; i%d_0++)\n",
+                        indent, "", loopcounter, loopcounter);
+               fprintf (of, "%*s  gt_ggc_m_rtx_def (%s.%s[i%d_0]);\n",
+                        indent, "", val, f->name, loopcounter);
+               special = NULL;
+             }
+
+           indent -= 2;
+           fprintf (of, "%*s}\n", indent, "");
+           break;
+         }
+
+       default:
+         error_at_line (&f->line, 
+                        "field `%s' is unimplemented type",
+                        f->name);
+         break;
+       }
+      
+      if (s->kind == TYPE_UNION && ! always_p )
+       {
+         indent -= 2;
+         fprintf (of, "%*s}\n", indent, "");
+       }
+      if (special)
+       error_at_line (&f->line, "unhandled special `%s'", special);
+    }
+  if (s->kind == TYPE_UNION)
+    {
+      indent -= 2;
+      fprintf (of, "%*s}\n", indent, "");
+    }
+}
+
+static void
+write_gc_marker_routine_for_structure (s, param)
+     type_p s;
+     type_p param;
+{
+  FILE *f;
+  if (param == NULL)
+    f = get_output_file_with_visibility (s->u.s.line.file);
+  else
+    f = get_output_file_with_visibility (param->u.s.line.file);
+  
+  fputc ('\n', f);
+  fputs ("void\n", f);
+  if (param == NULL)
+    fprintf (f, "gt_ggc_mx_%s (x_p)\n", s->u.s.tag);
+  else
+    fprintf (f, "gt_ggc_mm_%d%s_%s (x_p)\n", (int) strlen (param->u.s.tag),
+            param->u.s.tag, s->u.s.tag);
+  fputs ("      void *x_p;\n", f);
+  fputs ("{\n", f);
+  fprintf (f, "  %s %s * const x = (%s %s *)x_p;\n",
+          s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+          s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+  fputs ("  if (! ggc_test_and_set_mark (x))\n", f);
+  fputs ("    return;\n", f);
+  
+  gc_counter = 0;
+  write_gc_structure_fields (f, s, "(*x)", "not valid postage",
+                            s->u.s.opt, 2, &s->u.s.line, s->u.s.bitmap,
+                            param);
+  
+  fputs ("}\n", f);
+}
+     
+
+static void
+write_gc_types (structures, param_structs)
+     type_p structures;
+     type_p param_structs;
+{
+  type_p s;
+  
+  fputs ("\n/* GC marker procedures.  */\n", header_file);
+  for (s = structures; s; s = s->next)
+    if (s->gc_used == GC_POINTED_TO
+       || s->gc_used == GC_MAYBE_POINTED_TO)
+      {
+       options_p opt;
+       
+       if (s->gc_used == GC_MAYBE_POINTED_TO
+           && s->u.s.line.file == NULL)
+         continue;
+
+       fprintf (header_file,
+                "#define gt_ggc_m_%s(X) do { \\\n", s->u.s.tag);
+       fprintf (header_file,
+                "  if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag);
+       fprintf (header_file,
+                "  } while (0)\n");
+       
+       for (opt = s->u.s.opt; opt; opt = opt->next)
+         if (strcmp (opt->name, "ptr_alias") == 0)
+           {
+             type_p t = (type_p) opt->info;
+             if (t->kind == TYPE_STRUCT 
+                 || t->kind == TYPE_UNION
+                 || t->kind == TYPE_LANG_STRUCT)
+               fprintf (header_file,
+                        "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
+                        s->u.s.tag, t->u.s.tag);
+             else
+               error_at_line (&s->u.s.line, 
+                              "structure alias is not a structure");
+             break;
+           }
+       if (opt)
+         continue;
+
+       /* Declare the marker procedure only once.  */
+       fprintf (header_file, 
+                "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
+                s->u.s.tag);
+  
+       if (s->u.s.line.file == NULL)
+         {
+           fprintf (stderr, "warning: structure `%s' used but not defined\n", 
+                    s->u.s.tag);
+           continue;
+         }
+  
+       if (s->kind == TYPE_LANG_STRUCT)
+         {
+           type_p ss;
+           for (ss = s->u.s.lang_struct; ss; ss = ss->next)
+             write_gc_marker_routine_for_structure (ss, NULL);
+         }
+       else
+         write_gc_marker_routine_for_structure (s, NULL);
+      }
+
+  for (s = param_structs; s; s = s->next)
+    if (s->gc_used == GC_POINTED_TO)
+      {
+       type_p param = s->u.param_struct.param;
+       type_p stru = s->u.param_struct.stru;
+
+       if (param->kind != TYPE_STRUCT && param->kind != TYPE_UNION
+           && param->kind != TYPE_LANG_STRUCT)
+         {
+           error_at_line (&s->u.param_struct.line,
+                          "unsupported parameter type");
+           continue;
+         }
+       
+       /* Declare the marker procedure.  */
+       fprintf (header_file, 
+                "extern void gt_ggc_mm_%d%s_%s PARAMS ((void *));\n",
+                (int) strlen (param->u.s.tag), param->u.s.tag,
+                stru->u.s.tag);
+  
+       if (stru->u.s.line.file == NULL)
+         {
+           fprintf (stderr, "warning: structure `%s' used but not defined\n", 
+                    s->u.s.tag);
+           continue;
+         }
+  
+       if (stru->kind == TYPE_LANG_STRUCT)
+         {
+           type_p ss;
+           for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
+             write_gc_marker_routine_for_structure (ss, param);
+         }
+       else
+         write_gc_marker_routine_for_structure (stru, param);
+      }
+}
+
+static void
+put_mangled_filename (f, fn)
+     FILE *f;
+     const char *fn;
+{
+  const char *name = get_output_file_name (fn);
+  for (; *name != 0; name++)
+    if (isalnum (*name))
+      fputc (*name, f);
+    else
+      fputc ('_', f);
+}
+
+static void
+finish_root_table (flp, pfx, lastname, tname, name)
+     struct flist *flp;
+     const char *pfx;
+     const char *tname;
+     const char *lastname;
+     const char *name;
+{
+  struct flist *fli2;
+  unsigned started_bitmap = 0;
+  
+  for (fli2 = flp; fli2; fli2 = fli2->next)
+    if (fli2->started_p)
+      {
+       fprintf (fli2->f, "  %s\n", lastname);
+       fputs ("};\n\n", fli2->f);
+      }
+
+  for (fli2 = flp; fli2; fli2 = fli2->next)
+    if (fli2->started_p)
+      {
+       lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
+       int fnum;
+
+       for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
+         if (bitmap & 1)
+           {
+             fprintf (base_files[fnum],
+                      "extern const struct %s gt_ggc_%s_",
+                      tname, pfx);
+             put_mangled_filename (base_files[fnum], fli2->name);
+             fputs ("[];\n", base_files[fnum]);
+           }
+      }
+
+  for (fli2 = flp; fli2; fli2 = fli2->next)
+    if (fli2->started_p)
+      {
+       lang_bitmap bitmap = get_base_file_bitmap (fli2->name);
+       int fnum;
+
+       fli2->started_p = 0;
+
+       for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
+         if (bitmap & 1)
+           {
+             if (! (started_bitmap & (1 << fnum)))
+               {
+                 fprintf (base_files [fnum],
+                          "const struct %s * const %s[] = {\n",
+                          tname, name);
+                 started_bitmap |= 1 << fnum;
+               }
+             fprintf (base_files[fnum], "  gt_ggc_%s_", pfx);
+             put_mangled_filename (base_files[fnum], fli2->name);
+             fputs (",\n", base_files[fnum]);
+           }
+      }
+
+  {
+    unsigned bitmap;
+    int fnum;
+    
+    for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
+      if (bitmap & 1)
+       {
+         fputs ("  NULL\n", base_files[fnum]);
+         fputs ("};\n\n", base_files[fnum]);
+       }
+  }
+}
+
+static void
+write_gc_root (f, v, type, name, has_length, line, if_marked)
+     FILE *f;
+     pair_p v;
+     type_p type;
+     const char *name;
+     int has_length;
+     struct fileloc *line;
+     const char *if_marked;
+{
+  switch (type->kind)
+    {
+    case TYPE_STRUCT:
+      {
+       pair_p fld;
+       for (fld = type->u.s.fields; fld; fld = fld->next)
+         {
+           int skip_p = 0;
+           const char *desc = NULL;
+           options_p o;
+           
+           for (o = fld->opt; o; o = o->next)
+             if (strcmp (o->name, "skip") == 0)
+               skip_p = 1;
+             else if (strcmp (o->name, "desc") == 0)
+               desc = (const char *)o->info;
+             else
+               error_at_line (line,
+                      "field `%s' of global `%s' has unknown option `%s'",
+                              fld->name, name, o->name);
+           
+           if (skip_p)
+             continue;
+           else if (desc && fld->type->kind == TYPE_UNION)
+             {
+               pair_p validf = NULL;
+               pair_p ufld;
+               
+               for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
+                 {
+                   const char *tag = NULL;
+                   options_p oo;
+                   
+                   for (oo = ufld->opt; oo; oo = oo->next)
+                     if (strcmp (oo->name, "tag") == 0)
+                       tag = (const char *)oo->info;
+                   if (tag == NULL || strcmp (tag, desc) != 0)
+                     continue;
+                   if (validf != NULL)
+                     error_at_line (line, 
+                          "both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
+                                    name, fld->name, validf->name,
+                                    name, fld->name, ufld->name,
+                                    tag);
+                   validf = ufld;
+                 }
+               if (validf != NULL)
+                 {
+                   char *newname;
+                   newname = xmalloc (strlen (name) + 3 + strlen (fld->name)
+                                      + strlen (validf->name));
+                   sprintf (newname, "%s.%s.%s", 
+                            name, fld->name, validf->name);
+                   write_gc_root (f, v, validf->type, newname, 0, line,
+                                  if_marked);
+                   free (newname);
+                 }
+             }
+           else if (desc)
+             error_at_line (line, 
+                    "global `%s.%s' has `desc' option but is not union",
+                            name, fld->name);
+           else
+             {
+               char *newname;
+               newname = xmalloc (strlen (name) + 2 + strlen (fld->name));
+               sprintf (newname, "%s.%s", name, fld->name);
+               write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
+               free (newname);
+             }
+         }
+      }
+      break;
+
+    case TYPE_ARRAY:
+      {
+       char *newname;
+       newname = xmalloc (strlen (name) + 4);
+       sprintf (newname, "%s[0]", name);
+       write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
+       free (newname);
+      }
+      break;
+      
+    case TYPE_POINTER:
+      {
+       type_p ap, tp;
+       
+       fputs ("  {\n", f);
+       fprintf (f, "    &%s,\n", name);
+       fputs ("    1", f);
+       
+       for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
+         if (ap->u.a.len[0])
+           fprintf (f, " * (%s)", ap->u.a.len);
+         else if (ap == v->type)
+           fprintf (f, " * (sizeof (%s) / sizeof (%s[0]))",
+                    v->name, v->name);
+       fputs (",\n", f);
+       fprintf (f, "    sizeof (%s", v->name);
+       for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
+         fputs ("[0]", f);
+       fputs ("),\n", f);
+       
+       tp = type->u.p;
+       
+       if (! has_length && UNION_OR_STRUCT_P (tp))
+         {
+           fprintf (f, "    &gt_ggc_mx_%s\n", tp->u.s.tag);
+         }
+       else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
+         {
+           fprintf (f, "    &gt_ggc_mm_%d%s_%s",
+                    (int) strlen (tp->u.param_struct.param->u.s.tag),
+                    tp->u.param_struct.param->u.s.tag,
+                    tp->u.param_struct.stru->u.s.tag);
+         }
+       else if (has_length
+                && tp->kind == TYPE_POINTER)
+         {
+           fprintf (f, "    &gt_ggc_ma_%s", name);
+         }
+       else
+         {
+           error_at_line (line, 
+                          "global `%s' is pointer to unimplemented type",
+                          name);
+         }
+       if (if_marked)
+         fprintf (f, ",\n    &%s", if_marked);
+       fputs ("\n  },\n", f);
+      }
+      break;
+
+    case TYPE_SCALAR:
+    case TYPE_STRING:
+      break;
+      
+    default:
+      error_at_line (line, 
+                    "global `%s' is unimplemented type",
+                    name);
+    }
+}
+
+static void
+write_gc_roots (variables)
+     pair_p variables;
+{
+  pair_p v;
+  struct flist *flp = NULL;
+
+  for (v = variables; v; v = v->next)
+    {
+      FILE *f = get_output_file_with_visibility (v->line.file);
+      struct flist *fli;
+      const char *length = NULL;
+      int deletable_p = 0;
+      options_p o;
+
+      for (o = v->opt; o; o = o->next)
+       if (strcmp (o->name, "length") == 0)
+         length = (const char *)o->info;
+       else if (strcmp (o->name, "deletable") == 0)
+         deletable_p = 1;
+       else if (strcmp (o->name, "param_is") == 0)
+         ;
+       else if (strcmp (o->name, "if_marked") == 0)
+         ;
+       else
+         error_at_line (&v->line, 
+                        "global `%s' has unknown option `%s'",
+                        v->name, o->name);
+
+      for (fli = flp; fli; fli = fli->next)
+       if (fli->f == f)
+         break;
+      if (fli == NULL)
+       {
+         fli = xmalloc (sizeof (*fli));
+         fli->f = f;
+         fli->next = flp;
+         fli->started_p = 0;
+         fli->name = v->line.file;
+         flp = fli;
+
+         fputs ("\n/* GC roots.  */\n\n", f);
+       }
+
+      if (! deletable_p
+         && length
+         && v->type->kind == TYPE_POINTER
+         && (v->type->u.p->kind == TYPE_POINTER
+             || v->type->u.p->kind == TYPE_STRUCT))
+       {
+         fprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
+                  v->name);
+         fprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n      void *x_p;\n",
+                  v->name);
+         fputs ("{\n", f);
+         fputs ("  size_t i;\n", f);
+
+         if (v->type->u.p->kind == TYPE_POINTER)
+           {
+             type_p s = v->type->u.p->u.p;
+
+             fprintf (f, "  %s %s ** const x = (%s %s **)x_p;\n",
+                      s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+                      s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+             fputs ("  if (ggc_test_and_set_mark (x))\n", f);
+             fprintf (f, "    for (i = 0; i < (%s); i++)\n", length);
+             if (s->kind != TYPE_STRUCT && s->kind != TYPE_UNION)
+               {
+                 error_at_line (&v->line, 
+                                "global `%s' has unsupported ** type",
+                                v->name);
+                 continue;
+               }
+
+             fprintf (f, "      gt_ggc_m_%s (x[i]);\n", s->u.s.tag);
+           }
+         else
+           {
+             type_p s = v->type->u.p;
+
+             fprintf (f, "  %s %s * const x = (%s %s *)x_p;\n",
+                      s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+                      s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+             fputs ("  if (ggc_test_and_set_mark (x))\n", f);
+             fprintf (f, "    for (i = 0; i < (%s); i++)\n", length);
+             fputs ("      {\n", f);
+             write_gc_structure_fields (f, s, "x[i]", "x[i]",
+                                        v->opt, 8, &v->line, s->u.s.bitmap,
+                                        NULL);
+             fputs ("      }\n", f);
+           }
+
+         fputs ("}\n\n", f);
+       }
+    }
+
+  for (v = variables; v; v = v->next)
+    {
+      FILE *f = get_output_file_with_visibility (v->line.file);
+      struct flist *fli;
+      int skip_p = 0;
+      int length_p = 0;
+      options_p o;
+      
+      for (o = v->opt; o; o = o->next)
+       if (strcmp (o->name, "length") == 0)
+         length_p = 1;
+       else if (strcmp (o->name, "deletable") == 0
+                || strcmp (o->name, "if_marked") == 0)
+         skip_p = 1;
+
+      if (skip_p)
+       continue;
+
+      for (fli = flp; fli; fli = fli->next)
+       if (fli->f == f)
+         break;
+      if (! fli->started_p)
+       {
+         fli->started_p = 1;
+
+         fputs ("const struct ggc_root_tab gt_ggc_r_", f);
+         put_mangled_filename (f, v->line.file);
+         fputs ("[] = {\n", f);
+       }
+
+      write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL);
+    }
+
+  finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab", 
+                    "gt_ggc_rtab");
+
+  for (v = variables; v; v = v->next)
+    {
+      FILE *f = get_output_file_with_visibility (v->line.file);
+      struct flist *fli;
+      int skip_p = 1;
+      options_p o;
+
+      for (o = v->opt; o; o = o->next)
+       if (strcmp (o->name, "deletable") == 0)
+         skip_p = 0;
+       else if (strcmp (o->name, "if_marked") == 0)
+         skip_p = 1;
+
+      if (skip_p)
+       continue;
+
+      for (fli = flp; fli; fli = fli->next)
+       if (fli->f == f)
+         break;
+      if (! fli->started_p)
+       {
+         fli->started_p = 1;
+
+         fputs ("const struct ggc_root_tab gt_ggc_rd_", f);
+         put_mangled_filename (f, v->line.file);
+         fputs ("[] = {\n", f);
+       }
+      
+      fprintf (f, "  { &%s, 1, sizeof (%s), NULL },\n",
+              v->name, v->name);
+    }
+  
+  finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+                    "gt_ggc_deletable_rtab");
+
+  for (v = variables; v; v = v->next)
+    {
+      FILE *f = get_output_file_with_visibility (v->line.file);
+      struct flist *fli;
+      const char *if_marked = NULL;
+      int length_p = 0;
+      options_p o;
+      
+      for (o = v->opt; o; o = o->next)
+       if (strcmp (o->name, "length") == 0)
+         length_p = 1;
+       else if (strcmp (o->name, "if_marked") == 0)
+         if_marked = (const char *) o->info;
+
+      if (if_marked == NULL)
+       continue;
+
+      if (v->type->kind != TYPE_POINTER
+         || v->type->u.p->kind != TYPE_PARAM_STRUCT
+         || v->type->u.p->u.param_struct.stru != find_structure ("htab", 0))
+       {
+         error_at_line (&v->line, "if_marked option used but not hash table");
+         continue;
+       }
+
+      for (fli = flp; fli; fli = fli->next)
+       if (fli->f == f)
+         break;
+      if (! fli->started_p)
+       {
+         fli->started_p = 1;
+
+         fputs ("const struct ggc_cache_tab gt_ggc_rc_", f);
+         put_mangled_filename (f, v->line.file);
+         fputs ("[] = {\n", f);
+       }
+      
+      write_gc_root (f, v, create_pointer (v->type->u.p->u.param_struct.param),
+                    v->name, length_p, &v->line, if_marked);
+    }
+  
+  finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
+                    "gt_ggc_cache_rtab");
+}
+
+\f
+extern int main PARAMS ((int argc, char **argv));
+int 
+main(argc, argv)
+     int argc;
+     char **argv;
+{
+  int i;
+  static struct fileloc pos = { __FILE__, __LINE__ };
+
+  do_typedef ("CUMULATIVE_ARGS",
+             create_scalar_type ("CUMULATIVE_ARGS", 
+                                 strlen ("CUMULATIVE_ARGS")),
+             &pos);
+  do_typedef ("REAL_VALUE_TYPE",
+             create_scalar_type ("REAL_VALUE_TYPE", 
+                                 strlen ("REAL_VALUE_TYPE")),
+             &pos);
+  do_typedef ("PTR", create_pointer (create_scalar_type ("void",
+                                                        strlen ("void"))),
+             &pos);
+
+  for (i = 1; i < argc; i++)
+    parse_file (argv[i]);
+
+  if (hit_error != 0)
+    exit (1);
+
+  set_gc_used (variables);
+
+  open_base_files ();
+  write_gc_types (structures, param_structs);
+  write_gc_roots (variables);
+  close_output_files ();
+
+  return (hit_error != 0);
+}
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
new file mode 100644 (file)
index 0000000..e5f92f2
--- /dev/null
@@ -0,0 +1,157 @@
+/* Process source files and output type information.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/* A file position, mostly for error messages.  
+   The FILE element may be compared using pointer equality.  */
+struct fileloc {
+  const char *file;
+  int line;
+};
+
+/* Kinds of types we can understand.  */
+enum typekind {
+  TYPE_SCALAR,
+  TYPE_STRING,
+  TYPE_STRUCT,
+  TYPE_UNION,
+  TYPE_POINTER,
+  TYPE_ARRAY,
+  TYPE_LANG_STRUCT,
+  TYPE_PARAM_STRUCT
+};
+
+/* A way to pass data through to the output end.  */
+typedef struct options {
+  struct options *next;
+  const char *name;
+  void *info;
+} *options_p;
+
+typedef struct pair *pair_p;
+typedef struct type *type_p;
+typedef unsigned lang_bitmap;
+
+/* A name and a type.  */
+struct pair {
+  pair_p next;
+  const char *name;
+  type_p type;
+  struct fileloc line;
+  options_p opt;
+};
+
+/* A description of a type.  */
+struct type {
+  enum typekind kind;
+  type_p next;
+  type_p pointer_to;
+  enum gc_used_enum {
+    GC_UNUSED = 0,
+    GC_USED,
+    GC_MAYBE_POINTED_TO,
+    GC_POINTED_TO
+  } gc_used;
+  union {
+    type_p p;
+    struct {
+      const char *tag;
+      struct fileloc line;
+      pair_p fields;
+      options_p opt;
+      lang_bitmap bitmap;
+      type_p lang_struct;
+    } s;
+    char *sc;
+    struct {
+      type_p p;
+      const char *len;
+    } a;
+    struct {
+      type_p stru;
+      type_p param;
+      struct fileloc line;
+    } param_struct;
+  } u;
+};
+
+#define UNION_P(x)                                     \
+ ((x)->kind == TYPE_UNION ||                           \
+  ((x)->kind == TYPE_LANG_STRUCT                       \
+   && (x)->u.s.lang_struct->kind == TYPE_UNION))
+#define UNION_OR_STRUCT_P(x)                   \
+ ((x)->kind == TYPE_UNION                      \
+  || (x)->kind == TYPE_STRUCT                  \
+  || (x)->kind == TYPE_LANG_STRUCT)
+
+/* The one and only TYPE_STRING.  */
+extern struct type string_type;
+
+/* Variables used to communicate between the lexer and the parser.  */
+extern int lexer_toplevel_done;
+extern struct fileloc lexer_line;
+
+/* Print an error message.  */
+extern void error_at_line 
+  VPARAMS ((struct fileloc *pos, const char *msg, ...));
+
+/* Constructor routines for types.  */
+extern void do_typedef PARAMS ((const char *s, type_p t, struct fileloc *pos));
+extern type_p resolve_typedef PARAMS ((const char *s, struct fileloc *pos));
+extern void new_structure PARAMS ((const char *name, int isunion, 
+                                  struct fileloc *pos, pair_p fields, 
+                                  options_p o));
+extern type_p find_structure PARAMS ((const char *s, int isunion));
+extern type_p create_scalar_type PARAMS ((const char *name, size_t name_len));
+extern type_p create_pointer PARAMS ((type_p t));
+extern type_p create_array PARAMS ((type_p t, const char *len));
+extern type_p adjust_field_type PARAMS ((type_p, options_p));
+extern void note_variable PARAMS ((const char *s, type_p t, options_p o,
+                                  struct fileloc *pos));
+extern void note_yacc_type PARAMS ((options_p o, pair_p fields,
+                                   pair_p typeinfo, struct fileloc *pos));
+
+/* Lexer and parser routines, most automatically generated.  */
+extern int yylex PARAMS((void));
+extern void yyerror PARAMS ((const char *));
+extern int yyparse PARAMS ((void));
+extern void parse_file PARAMS ((char *name));
+
+/* Output file handling.  */
+
+FILE *get_output_file PARAMS ((const char *input_file));
+const char *get_output_file_name PARAMS ((const char *));
+
+/* The output header file that is included into pretty much every
+   source file.  */
+extern FILE *header_file;
+
+/* An output file, suitable for definitions, that can see declarations
+   made in INPUT_FILE and is linked into every language that uses
+   INPUT_FILE.  */
+extern FILE *get_output_file_with_visibility PARAMS ((const char *input_file));
+
+/* A list of output files suitable for definitions.  There is one
+   BASE_FILES entry for each language.  */
+extern FILE *base_files[];
+
+/* A bitmap that specifies which of BASE_FILES should be used to
+   output a definition that is different for each language and must be
+   defined once in each language that uses INPUT_FILE.  */
+extern lang_bitmap get_base_file_bitmap PARAMS ((const char *input_file));
index f818fa1c808b47b1fc9349ffb3602a5fc3383f70..55543dd7970ea3eb2d9dbff8ffcfc5f164c346a4 100644 (file)
@@ -26,7 +26,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtl.h"
 #include "tree.h"
 #include "tm_p.h"
-#include "hash.h"
 #include "hashtab.h"
 #include "varray.h"
 #include "ggc.h"
@@ -35,19 +34,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 /* Statistics about the allocation.  */
 static ggc_statistics *ggc_stats;
 
-/* Trees that have been marked, but whose children still need marking.  */
-varray_type ggc_pending_trees;
-
 static void ggc_mark_rtx_children_1 PARAMS ((rtx));
-static void ggc_mark_rtx_ptr PARAMS ((void *));
-static void ggc_mark_tree_ptr PARAMS ((void *));
-static void ggc_mark_rtx_varray_ptr PARAMS ((void *));
-static void ggc_mark_tree_varray_ptr PARAMS ((void *));
-static void ggc_mark_tree_hash_table_ptr PARAMS ((void *));
 static int ggc_htab_delete PARAMS ((void **, void *));
-static void ggc_mark_trees PARAMS ((void));
-static bool ggc_mark_tree_hash_table_entry PARAMS ((struct hash_entry *,
-                                                   hash_table_key));
 
 /* Maintain global roots that are preserved during GC.  */
 
@@ -87,132 +75,6 @@ ggc_add_root (base, nelt, size, cb)
   roots = x;
 }
 
-/* Register an array of rtx as a GC root.  */
-
-void
-ggc_add_rtx_root (base, nelt)
-     rtx *base;
-     int nelt;
-{
-  ggc_add_root (base, nelt, sizeof (rtx), ggc_mark_rtx_ptr);
-}
-
-/* Register an array of trees as a GC root.  */
-
-void
-ggc_add_tree_root (base, nelt)
-     tree *base;
-     int nelt;
-{
-  ggc_add_root (base, nelt, sizeof (tree), ggc_mark_tree_ptr);
-}
-
-/* Register a varray of rtxs as a GC root.  */
-
-void
-ggc_add_rtx_varray_root (base, nelt)
-     varray_type *base;
-     int nelt;
-{
-  ggc_add_root (base, nelt, sizeof (varray_type), 
-               ggc_mark_rtx_varray_ptr);
-}
-
-/* Register a varray of trees as a GC root.  */
-
-void
-ggc_add_tree_varray_root (base, nelt)
-     varray_type *base;
-     int nelt;
-{
-  ggc_add_root (base, nelt, sizeof (varray_type), 
-               ggc_mark_tree_varray_ptr);
-}
-
-/* Register a hash table of trees as a GC root.  */
-
-void
-ggc_add_tree_hash_table_root (base, nelt)
-     struct hash_table **base;
-     int nelt;
-{
-  ggc_add_root (base, nelt, sizeof (struct hash_table *), 
-               ggc_mark_tree_hash_table_ptr);
-}
-
-/* Remove the previously registered GC root at BASE.  */
-
-void
-ggc_del_root (base)
-     void *base;
-{
-  struct ggc_root *x, **p;
-
-  p = &roots, x = roots;
-  while (x)
-    {
-      if (x->base == base)
-       {
-         *p = x->next;
-         free (x);
-         return;
-       }
-      p = &x->next;
-      x = x->next;
-    }
-
-  abort ();
-}
-
-/* Add a hash table to be scanned when all roots have been processed.  We
-   delete any entry in the table that has not been marked.  */
-
-struct d_htab_root
-{
-  struct d_htab_root *next;
-  htab_t htab;
-  ggc_htab_marked_p marked_p;
-  ggc_htab_mark mark;
-};
-
-static struct d_htab_root *d_htab_roots;
-
-/* Add X, an htab, to a list of htabs that contain objects which are allocated
-   from GC memory.  Once all other roots are marked, we check each object in
-   the htab to see if it has already been marked.  If not, it is deleted.
-
-   MARKED_P, if specified, is a function that returns 1 if the entry is to
-   be considered as "marked".  If not present, the data structure pointed to
-   by the htab slot is tested.  This function should be supplied if some
-   other object (such as something pointed to by that object) should be tested
-   in which case the function tests whether that object (or objects) are
-   marked (using ggc_marked_p) and returns nonzero if it is.
-
-   MARK, if specified, is a function that is passed the contents of a slot
-   that has been determined to have been "marked" (via the above function)
-   and marks any other objects pointed to by that object.  For example,
-   we might have a hash table of memory attribute blocks, which are pointed
-   to by a MEM RTL but have a pointer to a DECL.  MARKED_P in that case will
-   not be specified because we want to know if the attribute block is pointed
-   to by the MEM, but MARK must be specified because if the block has been
-   marked, we need to mark the DECL.  */
-
-void
-ggc_add_deletable_htab (x, marked_p, mark)
-     PTR x;
-     ggc_htab_marked_p marked_p;
-     ggc_htab_mark mark;
-{
-  struct d_htab_root *r
-    = (struct d_htab_root *) xmalloc (sizeof (struct d_htab_root));
-
-  r->next = d_htab_roots;
-  r->htab = (htab_t) x;
-  r->marked_p = marked_p ? marked_p : ggc_marked_p;
-  r->mark = mark;
-  d_htab_roots = r;
-}
-
 /* Process a slot of an htab by deleting it if it has not been marked.  */
 
 static int
@@ -220,12 +82,12 @@ ggc_htab_delete (slot, info)
      void **slot;
      void *info;
 {
-  struct d_htab_root *r = (struct d_htab_root *) info;
+  const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
 
   if (! (*r->marked_p) (*slot))
-    htab_clear_slot (r->htab, slot);
-  else if (r->mark)
-    (*r->mark) (*slot);
+    htab_clear_slot (*r->base, slot);
+  else
+    (*r->cb) (*slot);
 
   return 1;
 }
@@ -236,9 +98,20 @@ void
 ggc_mark_roots ()
 {
   struct ggc_root *x;
-  struct d_htab_root *y;
+  const struct ggc_root_tab *const *rt;
+  const struct ggc_root_tab *rti;
+  const struct ggc_cache_tab *const *ct;
+  const struct ggc_cache_tab *cti;
+  size_t i;
   
-  VARRAY_TREE_INIT (ggc_pending_trees, 4096, "ggc_pending_trees");
+  for (rt = gt_ggc_deletable_rtab; *rt; rt++)
+    for (rti = *rt; rti->base != NULL; rti++)
+      memset (rti->base, 0, rti->stride);
+
+  for (rt = gt_ggc_rtab; *rt; rt++)
+    for (rti = *rt; rti->base != NULL; rti++)
+      for (i = 0; i < rti->nelt; i++)
+       (*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
 
   for (x = roots; x != NULL; x = x->next)
     {
@@ -251,19 +124,11 @@ ggc_mark_roots ()
        (*cb)(elt);
     }
 
-  /* Mark all the queued up trees, and their children.  */
-  ggc_mark_trees ();
-  VARRAY_FREE (ggc_pending_trees);
-
   /* Now scan all hash tables that have objects which are to be deleted if
-     they are not already marked.  Since these may mark more trees, we need
-     to reinitialize that varray.  */
-  VARRAY_TREE_INIT (ggc_pending_trees, 1024, "ggc_pending_trees");
-
-  for (y = d_htab_roots; y != NULL; y = y->next)
-    htab_traverse (y->htab, ggc_htab_delete, (PTR) y);
-  ggc_mark_trees ();
-  VARRAY_FREE (ggc_pending_trees);
+     they are not already marked.  */
+  for (ct = gt_ggc_cache_rtab; *ct; ct++)
+    for (cti = *ct; cti->base != NULL; cti++)
+      htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
 }
 
 /* R had not been previously marked, but has now been marked via
@@ -332,7 +197,7 @@ ggc_mark_rtx_children_1 (r)
       switch (code)
        {
        case MEM:
-         ggc_mark (MEM_ATTRS (r));
+         gt_ggc_m_mem_attrs (MEM_ATTRS (r));
          break;
        case JUMP_INSN:
          ggc_mark_rtx (JUMP_LABEL (r));
@@ -387,7 +252,7 @@ ggc_mark_rtx_children_1 (r)
                } 
              break;
            case 'V': case 'E':
-             ggc_mark_rtvec (XVEC (r, i));
+             gt_ggc_m_rtvec_def (XVEC (r, i));
              break;
            }
        }
@@ -395,274 +260,51 @@ ggc_mark_rtx_children_1 (r)
   while ((r = next_rtx) != NULL);
 }
 
-/* V had not been previously marked, but has now been marked via
-   ggc_set_mark.  Now recurse and process the children.  */
-
+/* Various adaptor functions.  */
 void
-ggc_mark_rtvec_children (v)
-     rtvec v;
+gt_ggc_mx_rtx_def (x)
+     void *x;
 {
-  int i;
-
-  i = GET_NUM_ELEM (v);
-  while (--i >= 0)
-    ggc_mark_rtx (RTVEC_ELT (v, i));
+  ggc_mark_rtx((rtx)x);
 }
 
-/* Recursively set marks on all of the children of the
-   GCC_PENDING_TREES.  */
-
-static void
-ggc_mark_trees ()
-{
-  while (ggc_pending_trees->elements_used)
-    {
-      tree t;
-      enum tree_code code;
-
-      t = VARRAY_TOP_TREE (ggc_pending_trees);
-      VARRAY_POP (ggc_pending_trees);
-      code = TREE_CODE (t);
-
-      /* Collect statistics, if appropriate.  */
-      if (ggc_stats)
-       {
-         ++ggc_stats->num_trees[(int) code];
-         ggc_stats->size_trees[(int) code] += ggc_get_size (t);
-       }
-
-      /* Bits from common.  */
-      ggc_mark_tree (TREE_TYPE (t));
-      ggc_mark_tree (TREE_CHAIN (t));
-
-      /* Some nodes require special handling.  */
-      switch (code)
-       {
-       case TREE_LIST:
-         ggc_mark_tree (TREE_PURPOSE (t));
-         ggc_mark_tree (TREE_VALUE (t));
-         continue;
-
-       case TREE_VEC:
-         {
-           int i = TREE_VEC_LENGTH (t);
-
-           while (--i >= 0)
-             ggc_mark_tree (TREE_VEC_ELT (t, i));
-           continue;
-         }
-
-       case COMPLEX_CST:
-         ggc_mark_tree (TREE_REALPART (t));
-         ggc_mark_tree (TREE_IMAGPART (t));
-         break;
-
-       case REAL_CST:
-         ggc_mark (TREE_REAL_CST_PTR (t));
-         break;
-
-       case PARM_DECL:
-         ggc_mark_rtx (DECL_INCOMING_RTL (t));
-         break;
-
-       case FIELD_DECL:
-         ggc_mark_tree (DECL_FIELD_BIT_OFFSET (t));
-         break;
-
-       case IDENTIFIER_NODE:
-         (*lang_hooks.mark_tree) (t);
-         continue;
-
-       default:
-         break;
-       }
-  
-      /* But in general we can handle them by class.  */
-      switch (TREE_CODE_CLASS (code))
-       {
-       case 'd': /* A decl node.  */
-         ggc_mark_tree (DECL_SIZE (t));
-         ggc_mark_tree (DECL_SIZE_UNIT (t));
-         ggc_mark_tree (DECL_NAME (t));
-         ggc_mark_tree (DECL_CONTEXT (t));
-         ggc_mark_tree (DECL_ARGUMENTS (t));
-         ggc_mark_tree (DECL_RESULT_FLD (t));
-         ggc_mark_tree (DECL_INITIAL (t));
-         ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
-         ggc_mark_tree (DECL_SECTION_NAME (t));
-         ggc_mark_tree (DECL_ATTRIBUTES (t));
-         if (DECL_RTL_SET_P (t))
-           ggc_mark_rtx (DECL_RTL (t));
-         ggc_mark_rtx (DECL_LIVE_RANGE_RTL (t));
-         ggc_mark_tree (DECL_VINDEX (t));
-         if (DECL_ASSEMBLER_NAME_SET_P (t))
-           ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
-         if (TREE_CODE (t) == FUNCTION_DECL)
-           {
-             ggc_mark_tree (DECL_SAVED_TREE (t));
-             ggc_mark_tree (DECL_INLINED_FNS (t));
-             if (DECL_SAVED_INSNS (t))
-               ggc_mark_struct_function (DECL_SAVED_INSNS (t));
-           }
-         (*lang_hooks.mark_tree) (t);
-         break;
-
-       case 't': /* A type node.  */
-         ggc_mark_tree (TYPE_SIZE (t));
-         ggc_mark_tree (TYPE_SIZE_UNIT (t));
-         ggc_mark_tree (TYPE_ATTRIBUTES (t));
-         ggc_mark_tree (TYPE_VALUES (t));
-         ggc_mark_tree (TYPE_POINTER_TO (t));
-         ggc_mark_tree (TYPE_REFERENCE_TO (t));
-         ggc_mark_tree (TYPE_NAME (t));
-         ggc_mark_tree (TYPE_MIN_VALUE (t));
-         ggc_mark_tree (TYPE_MAX_VALUE (t));
-         ggc_mark_tree (TYPE_NEXT_VARIANT (t));
-         ggc_mark_tree (TYPE_MAIN_VARIANT (t));
-         ggc_mark_tree (TYPE_BINFO (t));
-         ggc_mark_tree (TYPE_CONTEXT (t));
-         (*lang_hooks.mark_tree) (t);
-         break;
-
-       case 'b': /* A lexical block.  */
-         ggc_mark_tree (BLOCK_VARS (t));
-         ggc_mark_tree (BLOCK_SUBBLOCKS (t));
-         ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
-         ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
-         break;
-
-       case 'c': /* A constant.  */
-         ggc_mark_rtx (TREE_CST_RTL (t));
-         break;
-
-       case 'r': case '<': case '1':
-       case '2': case 'e': case 's': /* Expressions.  */
-         {
-           int i = TREE_CODE_LENGTH (TREE_CODE (t));
-           int first_rtl = first_rtl_op (TREE_CODE (t));
-
-           while (--i >= 0)
-             {
-               if (i >= first_rtl)
-                 ggc_mark_rtx ((rtx) TREE_OPERAND (t, i));
-               else
-                 ggc_mark_tree (TREE_OPERAND (t, i));
-             }
-           break;      
-         }
-
-       case 'x':
-         (*lang_hooks.mark_tree) (t);
-         break;
-       }
-    }
-}
-
-/* Mark all the elements of the varray V, which contains rtxs.  */
-
-void
-ggc_mark_rtx_varray (v)
-     varray_type v;
-{
-  int i;
-
-  if (v)
-    for (i = v->num_elements - 1; i >= 0; --i) 
-      ggc_mark_rtx (VARRAY_RTX (v, i));
-}
-
-/* Mark all the elements of the varray V, which contains trees.  */
-
-void
-ggc_mark_tree_varray (v)
-     varray_type v;
-{
-  int 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.  Its key field is really a tree.  */
-
-static bool
-ggc_mark_tree_hash_table_entry (he, k)
-     struct hash_entry *he;
-     hash_table_key k ATTRIBUTE_UNUSED;
-{
-  ggc_mark_tree ((tree) he->key);
-  return true;
-}
-
-/* Mark all the elements of the hash-table H, which contains trees.  */
-
-void
-ggc_mark_tree_hash_table (ht)
-     struct hash_table *ht;
-{
-  hash_traverse (ht, ggc_mark_tree_hash_table_entry, /*info=*/0);
-}
-
-/* Type-correct function to pass to ggc_add_root.  It just forwards
-   *ELT (which is an rtx) to ggc_mark_rtx.  */
-
-static void
-ggc_mark_rtx_ptr (elt)
-     void *elt;
-{
-  ggc_mark_rtx (*(rtx *) elt);
-}
-
-/* Type-correct function to pass to ggc_add_root.  It just forwards
-   *ELT (which is a tree) to ggc_mark_tree.  */
-
-static void
-ggc_mark_tree_ptr (elt)
-     void *elt;
+/* Allocate a block of memory, then clear it.  */
+void *
+ggc_alloc_cleared (size)
+     size_t size;
 {
-  ggc_mark_tree (*(tree *) elt);
+  void *buf = ggc_alloc (size);
+  memset (buf, 0, size);
+  return buf;
 }
 
-/* Type-correct function to pass to ggc_add_root.  It just forwards
-   ELT (which is really a varray_type *) to ggc_mark_rtx_varray.  */
-
-static void
-ggc_mark_rtx_varray_ptr (elt)
-     void *elt;
+/* Resize a block of memory, possibly re-allocating it.  */
+void *
+ggc_realloc (x, size)
+     void *x;
+     size_t size;
 {
-  ggc_mark_rtx_varray (*(varray_type *) elt);
-}
+  void *r;
+  size_t old_size;
 
-/* Type-correct function to pass to ggc_add_root.  It just forwards
-   ELT (which is really a varray_type *) to ggc_mark_tree_varray.  */
+  if (x == NULL)
+    return ggc_alloc (size);
 
-static void
-ggc_mark_tree_varray_ptr (elt)
-     void *elt;
-{
-  ggc_mark_tree_varray (*(varray_type *) elt);
-}
+  old_size = ggc_get_size (x);
+  if (size <= old_size)
+    return x;
 
-/* Type-correct function to pass to ggc_add_root.  It just forwards
-   ELT (which is really a struct hash_table **) to
-   ggc_mark_tree_hash_table.  */
-
-static void
-ggc_mark_tree_hash_table_ptr (elt)
-     void *elt;
-{
-  ggc_mark_tree_hash_table (*(struct hash_table **) elt);
+  r = ggc_alloc (size);
+  memcpy (r, x, old_size);
+  return r;
 }
 
-/* Allocate a block of memory, then clear it.  */
+/* Like ggc_alloc_cleared, but performs a multiplication.  */
 void *
-ggc_alloc_cleared (size)
-     size_t size;
+ggc_calloc (s1, s2)
+     size_t s1, s2;
 {
-  void *buf = ggc_alloc (size);
-  memset (buf, 0, size);
-  return buf;
+  return ggc_alloc_cleared (s1 * s2);
 }
 
 /* Print statistics that are independent of the collector in use.  */
index ae3f6e9a971e2025cc73b51c48e085575ed18d0e..3711475dc0b27c2dfd53e7524c6c202a47c62bc8 100644 (file)
@@ -32,3 +32,18 @@ ggc_alloc (size)
 {
   return xmalloc (size);
 }
+
+void *
+ggc_alloc_cleared (size)
+     size_t size;
+{
+  return xcalloc (size, 1);
+}
+
+void *
+ggc_realloc (x, size)
+     void *x;
+     size_t size;
+{
+  return xrealloc (x, size);
+}
index 917b65e9a7fb58dc591c96929cffb7d0a3406af9..87a38549f4b011957072103612e99287ab9455a8 100644 (file)
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -19,72 +19,54 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
 #include "varray.h"
+#include "gtype-desc.h"
 
 /* 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 eh_status;
-struct emit_status;
-struct expr_status;
-struct hash_table;
-struct label_node;
-struct rtx_def;
-struct rtvec_def;
-struct stmt_status;
-union  tree_node;
-struct varasm_status;
-
 /* Constants for general use.  */
 extern const char empty_string[];      /* empty string */
 extern const char digit_vector[];      /* "0" .. "9" */
 #define digit_string(d) (digit_vector + ((d) * 2))
 
-/* Trees that have been marked, but whose children still need marking.  */
-extern varray_type ggc_pending_trees;
-
 /* Manipulate global roots that are needed between calls to gc.  */
 extern void ggc_add_root               PARAMS ((void *base, int nelt,
                                                 int size, void (*)(void *)));
-extern void ggc_add_rtx_root           PARAMS ((struct rtx_def **, int nelt));
-extern void ggc_add_tree_root          PARAMS ((union tree_node **,
-                                                int nelt));
-extern void ggc_add_rtx_varray_root    PARAMS ((struct varray_head_tag **,
-                                                int nelt));
-extern void ggc_add_tree_varray_root   PARAMS ((struct varray_head_tag **,
-                                                int nelt));
-extern void ggc_add_tree_hash_table_root PARAMS ((struct hash_table **,
-                                                 int nelt));
-extern void ggc_del_root               PARAMS ((void *base));
-
-/* Types used for mark test and marking functions, if specified, in call
-   below.  */
-typedef int (*ggc_htab_marked_p) PARAMS ((const void *));
-typedef void (*ggc_htab_mark) PARAMS ((const void *));
-
-/* Add a hash table to be scanned when all roots have been processed.  We
-   delete any entry in the table that has not been marked.  The argument is
-   really htab_t.  */
-extern void ggc_add_deletable_htab     PARAMS ((PTR, ggc_htab_marked_p,
-                                                ggc_htab_mark));
-
-/* Mark nodes from the gc_add_root callback.  These functions follow
-   pointers to mark other objects too.  */
-extern void ggc_mark_rtx_varray                PARAMS ((struct varray_head_tag *));
-extern void ggc_mark_tree_varray       PARAMS ((struct varray_head_tag *));
-extern void ggc_mark_tree_hash_table   PARAMS ((struct hash_table *));
+
+/* Structures for the easy way to mark roots.  
+   In an array, terminated by having base == NULL.*/
+struct ggc_root_tab {
+  void *base;
+  size_t nelt;
+  size_t stride;
+  void (*cb) PARAMS ((void *));
+};
+#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL }
+/* Pointers to arrays of ggc_root_tab, terminated by NULL.  */
+extern const struct ggc_root_tab * const gt_ggc_rtab[];
+extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
+
+/* Structure for hash table cache marking.  */
+struct htab;
+struct ggc_cache_tab {
+  struct htab * *base;
+  size_t nelt;
+  size_t stride;
+  void (*cb) PARAMS ((void *));
+  int (*marked_p) PARAMS ((const void *));
+};
+#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL }
+/* Pointers to arrays of ggc_cache_tab, terminated by NULL.  */
+extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
+
 extern void ggc_mark_roots             PARAMS ((void));
 
 extern void ggc_mark_rtx_children      PARAMS ((struct rtx_def *));
-extern void ggc_mark_rtvec_children    PARAMS ((struct rtvec_def *));
 
 /* If EXPR is not NULL and previously unmarked, mark it and evaluate
    to true.  Otherwise evaluate to false.  */
 #define ggc_test_and_set_mark(EXPR) \
-  ((EXPR) != NULL && ! ggc_set_mark (EXPR))
+  ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
 
 #define ggc_mark_rtx(EXPR)                      \
   do {                                          \
@@ -93,31 +75,12 @@ extern void ggc_mark_rtvec_children PARAMS ((struct rtvec_def *));
       ggc_mark_rtx_children (r__);              \
   } while (0)
 
-#define ggc_mark_tree(EXPR)                            \
-  do {                                                 \
-    tree const t__ = (EXPR);                           \
-    if (ggc_test_and_set_mark (t__))                   \
-      VARRAY_PUSH_TREE (ggc_pending_trees, t__);       \
-  } while (0)
-
-#define ggc_mark_nonnull_tree(EXPR)                    \
-  do {                                                 \
-    tree const t__ = (EXPR);                           \
-    if (! ggc_set_mark (t__))                          \
-      VARRAY_PUSH_TREE (ggc_pending_trees, t__);       \
-  } while (0)
-
-#define ggc_mark_rtvec(EXPR)                    \
-  do {                                          \
-    rtvec const v__ = (EXPR);                   \
-    if (ggc_test_and_set_mark (v__))            \
-      ggc_mark_rtvec_children (v__);            \
-  } while (0)
+#define ggc_mark_tree gt_ggc_m_tree_node
 
 #define ggc_mark(EXPR)                         \
   do {                                         \
     const void *const a__ = (EXPR);            \
-    if (a__ != NULL)                           \
+    if (a__ != NULL && a__ != (void *) 1)      \
       ggc_set_mark (a__);                      \
   } while (0)
 
@@ -141,6 +104,10 @@ extern void ggc_pop_context        PARAMS ((void));
 extern void *ggc_alloc         PARAMS ((size_t));
 /* Like ggc_alloc, but allocates cleared memory.  */
 extern void *ggc_alloc_cleared PARAMS ((size_t));
+/* Resize a block.  */
+extern void *ggc_realloc       PARAMS ((void *, size_t));
+/* Like ggc_alloc_cleared, but performs a multiplication.  */
+extern void *ggc_calloc                PARAMS ((size_t, size_t));
 
 #define ggc_alloc_rtx(NSLOTS)                                            \
   ((struct rtx_def *) ggc_alloc (sizeof (struct rtx_def)                 \
@@ -152,6 +119,9 @@ extern void *ggc_alloc_cleared      PARAMS ((size_t));
 
 #define ggc_alloc_tree(LENGTH) ((union tree_node *) ggc_alloc (LENGTH))
 
+#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
+  htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
+
 /* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
    If LENGTH is -1, then CONTENTS is assumed to be a
    null-terminated string and the memory sized accordingly.  */
@@ -177,15 +147,6 @@ extern int ggc_set_mark                    PARAMS ((const void *));
    static objects, stack variables, or memory allocated with malloc.  */
 extern int ggc_marked_p                        PARAMS ((const void *));
 
-/* Mark functions for various structs scattered about.  */
-
-void mark_eh_status                    PARAMS ((struct eh_status *));
-void mark_emit_status                  PARAMS ((struct emit_status *));
-void mark_expr_status                  PARAMS ((struct expr_status *));
-void mark_stmt_status                  PARAMS ((struct stmt_status *));
-void mark_varasm_status                        PARAMS ((struct varasm_status *));
-void mark_optab                                PARAMS ((void *));
-
 /* Statistics.  */
 
 /* This structure contains the statistics common to all collectors.
diff --git a/gcc/hash.c b/gcc/hash.c
deleted file mode 100644 (file)
index 5cf8397..0000000
+++ /dev/null
@@ -1,218 +0,0 @@
-/* hash.c -- hash table routines
-   Copyright (C) 1993, 1994, 1998, 2001 Free Software Foundation, Inc.
-   Written by Steve Chamberlain <sac@cygnus.com>
-
-This file was lifted from BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "hash.h"
-#include "obstack.h"
-#include "toplev.h"
-
-/* Obstack allocation and deallocation routines.  */
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-/* The default number of entries to use when creating a hash table.  */
-#define DEFAULT_SIZE 1009
-
-/* Create a new hash table, given a number of entries.  */
-
-void
-hash_table_init_n (table, newfunc, hash, comp, size)
-     struct hash_table *table;
-     struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
-                                           struct hash_table *,
-                                           hash_table_key));
-     unsigned long (*hash) PARAMS ((hash_table_key));
-     bool (*comp) PARAMS ((hash_table_key, hash_table_key));
-     unsigned int size;
-{
-  unsigned int alloc;
-
-  alloc = size * sizeof (struct hash_entry *);
-  obstack_begin (&table->memory, alloc);
-  table->table = ((struct hash_entry **)
-                 obstack_alloc (&table->memory, alloc));
-  memset ((PTR) table->table, 0, alloc);
-  table->size = size;
-  table->newfunc = newfunc;
-  table->hash = hash;
-  table->comp = comp;
-}
-
-/* Create a new hash table with the default number of entries.  */
-
-void
-hash_table_init (table, newfunc, hash, comp)
-     struct hash_table *table;
-     struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
-                                           struct hash_table *,
-                                           hash_table_key));
-     unsigned long (*hash) PARAMS ((hash_table_key));
-     bool (*comp) PARAMS ((hash_table_key, hash_table_key));
-{
-  hash_table_init_n (table, newfunc, hash, comp, DEFAULT_SIZE);
-}
-
-/* Free a hash table.  */
-
-void
-hash_table_free (table)
-     struct hash_table *table;
-{
-  obstack_free (&table->memory, (PTR) NULL);
-}
-
-/* Look up KEY in TABLE.  If CREATE is non-NULL a new entry is
-   created if one does not previously exist.  */
-
-struct hash_entry *
-hash_lookup (table, key, create, copy)
-     struct hash_table *table;
-     hash_table_key key;
-     int create;
-     hash_table_key (*copy) PARAMS ((struct obstack* memory, 
-                                    hash_table_key key));
-{
-  unsigned long hash;
-  struct hash_entry *hashp;
-  unsigned int index;
-  
-  hash = (*table->hash)(key);
-
-  index = hash % table->size;
-  for (hashp = table->table[index]; hashp != 0; hashp = hashp->next)
-    if (hashp->hash == hash
-       && (*table->comp)(hashp->key, key))
-      return hashp;
-
-  if (! create)
-    return 0;
-
-  hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key);
-  if (hashp == 0)
-    return 0;
-
-  if (copy)
-    key = (*copy) (&table->memory, key);
-
-  hashp->key = key;
-  hashp->hash = hash;
-  hashp->next = table->table[index];
-  table->table[index] = hashp;
-
-  return hashp;
-}
-
-/* Base method for creating a new hash table entry.  */
-
-struct hash_entry *
-hash_newfunc (entry, table, p)
-     struct hash_entry *entry;
-     struct hash_table *table;
-     hash_table_key p ATTRIBUTE_UNUSED;
-{
-  if (entry == 0)
-    entry = ((struct hash_entry *)
-            hash_allocate (table, sizeof (struct hash_entry)));
-  return entry;
-}
-
-/* Allocate space in a hash table.  */
-
-PTR
-hash_allocate (table, size)
-     struct hash_table *table;
-     unsigned int size;
-{
-  return obstack_alloc (&table->memory, size);
-}
-
-/* Traverse a hash table.  */
-
-void
-hash_traverse (table, func, info)
-     struct hash_table *table;
-     bool (*func) PARAMS ((struct hash_entry *, hash_table_key));
-     PTR info;
-{
-  unsigned int i;
-  struct hash_entry *p;
-
-  for (i = 0; i < table->size; i++)
-    for (p = table->table[i]; p != 0; p = p->next)
-      if (! (*func) (p, info))
-       return;
-}
-
-/* Hash a string.  Return a hash-code for the string.  */
-
-unsigned long
-string_hash (k)
-     hash_table_key k;
-{
-  const unsigned char *s;
-  unsigned long hash;
-  unsigned char c;
-  unsigned int len;
-
-  s = (const unsigned char *) k;
-  hash = 0;
-  len = 0;
-
-  while ((c = *s++) != '\0')
-    {
-      hash += c + (c << 17);
-      hash ^= hash >> 2;
-      ++len;
-    }
-
-  hash += len + (len << 17);
-  hash ^= hash >> 2;
-
-  return hash;
-}
-
-/* Compare two strings.  Return non-zero iff the two strings are
-   the same.  */
-
-bool
-string_compare (k1, k2)
-     hash_table_key k1;
-     hash_table_key k2;
-{
-  return (strcmp ((char*) k1, (char*) k2) == 0);
-}
-
-/* Copy K to OBSTACK.  */
-
-hash_table_key
-string_copy (memory, k)
-     struct obstack *memory;
-     hash_table_key k;
-{
-  char *new;
-  char *string = (char *) k;
-
-  new = (char *) obstack_alloc (memory, strlen (string) + 1);
-  strcpy (new, string);
-  
-  return new;
-}
diff --git a/gcc/hash.h b/gcc/hash.h
deleted file mode 100644 (file)
index bd75f94..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* Header file for generic hash table support.
-   Copyright (C) 1993, 1994, 1997, 1998, 2001 Free Software Foundation, Inc.
-   Written by Steve Chamberlain <sac@cygnus.com>
-
-This file was lifted from BFD, the Binary File Descriptor library.
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#ifndef IN_GCC
-#include <ansidecl.h>
-#endif /* ! IN_GCC */
-
-#include "obstack.h"
-
-typedef PTR hash_table_key;
-
-/* Hash table routines.  There is no way to free up a hash table.  */
-
-/* An element in the hash table.  Most uses will actually use a larger
-   structure, and an instance of this will be the first field.  */
-
-struct hash_entry
-{
-  /* Next entry for this hash code.  */
-  struct hash_entry *next;
-  /* The thing being hashed.  */
-  hash_table_key key;
-  /* Hash code.  This is the full hash code, not the index into the
-     table.  */
-  unsigned long hash;
-};
-
-/* A hash table.  */
-
-struct hash_table
-{
-  /* The hash array.  */
-  struct hash_entry **table;
-  /* The number of slots in the hash table.  */
-  unsigned int size;
-  /* A function used to create new elements in the hash table.  The
-     first entry is itself a pointer to an element.  When this
-     function is first invoked, this pointer will be NULL.  However,
-     having the pointer permits a hierarchy of method functions to be
-     built each of which calls the function in the superclass.  Thus
-     each function should be written to allocate a new block of memory
-     only if the argument is NULL.  */
-  struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
-                                        struct hash_table *,
-                                        hash_table_key));
-  /* A function to compute the hash code for a key in the hash table.  */
-  unsigned long (*hash) PARAMS ((hash_table_key));
-  /* A function to compare two keys.  */
-  bool (*comp) PARAMS ((hash_table_key, hash_table_key));
-  /* An obstack for this hash table.  */
-  struct obstack memory;
-};
-
-/* Initialize a hash table.  */
-extern void hash_table_init
-  PARAMS ((struct hash_table *,
-          struct hash_entry *(*) (struct hash_entry *,
-                                  struct hash_table *,
-                                  hash_table_key),
-          unsigned long (*hash) (hash_table_key),
-          bool (*comp) (hash_table_key, hash_table_key)));
-
-/* Initialize a hash table specifying a size.  */
-extern void hash_table_init_n
-  PARAMS ((struct hash_table *,
-          struct hash_entry *(*) (struct hash_entry *,
-                                  struct hash_table *,
-                                  hash_table_key),
-          unsigned long (*hash) (hash_table_key),
-          bool (*comp) (hash_table_key, hash_table_key),
-          unsigned int size));
-
-/* Free up a hash table.  */
-extern void hash_table_free PARAMS ((struct hash_table *));
-
-/* Look up KEY in a hash table.  If CREATE is true, a new entry
-   will be created for this KEY if one does not already exist.  If
-   COPY is non-NULL, it is used to copy the KEY before storing it in
-   the hash table.  */
-extern struct hash_entry *hash_lookup
-  PARAMS ((struct hash_table *, hash_table_key key, int create,
-          hash_table_key (*copy)(struct obstack*, hash_table_key)));
-
-/* Base method for creating a hash table entry.  */
-extern struct hash_entry *hash_newfunc
-  PARAMS ((struct hash_entry *, struct hash_table *, 
-          hash_table_key key));
-
-/* Grab some space for a hash table entry.  */
-extern PTR hash_allocate PARAMS ((struct hash_table *,
-                                 unsigned int));
-
-/* Traverse a hash table in a random order, calling a function on each
-   element.  If the function returns false, the traversal stops.  The
-   INFO argument is passed to the function.  */
-extern void hash_traverse PARAMS ((struct hash_table *,
-                                  bool (*) (struct hash_entry *,
-                                               hash_table_key),
-                                  hash_table_key info));
-
-/* Hash a string K, which is really of type `char*'.  */
-extern unsigned long string_hash PARAMS ((hash_table_key k));
-
-/* Compare two strings K1, K2 which are really of type `char*'.  */
-extern bool string_compare PARAMS ((hash_table_key k1, 
-                                      hash_table_key k2));
-
-/* Copy a string K, which is really of type `char*'.  */
-extern hash_table_key string_copy PARAMS ((struct obstack* memory,
-                                          hash_table_key k));
-
index cd6c7f0be06284832a9e4b097f60b4feeec3d304..899647b6d84854159efd967beaa5d439eb5c8580 100644 (file)
@@ -23,7 +23,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 /* This is what each hash table entry points to.  It may be embedded
    deeply within another object.  */
 typedef struct ht_identifier ht_identifier;
-struct ht_identifier
+struct ht_identifier GTY(())
 {
   unsigned int len;
   const unsigned char *str;
index 214df19d5734e2a2ba9fc2735b6c95f214e821a9..4403b0b2590b7b16c7152efbded389b323a02b27 100644 (file)
@@ -23,14 +23,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #include "varray.h"
 
-extern varray_type insn_addresses_;
+extern GTY(()) varray_type insn_addresses_;
 extern int insn_current_address;
 
 #define INSN_ADDRESSES_DEFN() varray_type insn_addresses_
 #define INSN_ADDRESSES(id) VARRAY_INT (insn_addresses_, (id))
 #define INSN_ADDRESSES_ALLOC(size) \
   VARRAY_INT_INIT (insn_addresses_, (size), "insn_addresses")
-#define INSN_ADDRESSES_FREE() VARRAY_FREE (insn_addresses_)
+#define INSN_ADDRESSES_FREE() (insn_addresses_ = 0)
 #define INSN_ADDRESSES_SET_P() (insn_addresses_ != 0)
 #define INSN_ADDRESSES_SIZE() VARRAY_SIZE (insn_addresses_)
 #define INSN_ADDRESSES_NEW(insn, addr) do \
index 47e33a7ad095c151deab22695e6c9356401d19cd..6a6c5432763880bf7978ae703fc74c6f201244d0 100644 (file)
@@ -68,14 +68,14 @@ extern struct obstack *function_maybepermanent_obstack;
 \f
 
 /* Private type used by {get/has}_func_hard_reg_initial_val.  */
-typedef struct initial_value_pair {
+typedef struct initial_value_pair GTY(()) {
   rtx hard_reg;
   rtx pseudo;
 } initial_value_pair;
-typedef struct initial_value_struct {
+typedef struct initial_value_struct GTY(()) {
   int num_entries;
   int max_entries;
-  initial_value_pair *entries;
+  initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
 } initial_value_struct;
 
 static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *));
@@ -663,7 +663,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
   rtx stack_save = 0;
   rtx temp;
   struct inline_remap *map = 0;
-  rtvec arg_vector = (rtvec) inl_f->original_arg_vector;
+  rtvec arg_vector = inl_f->original_arg_vector;
   rtx static_chain_value = 0;
   int inl_max_uid;
   int eh_region_offset;
@@ -1286,7 +1286,6 @@ expand_inline_function (fndecl, parms, target, ignore, type,
     free (real_label_map);
   VARRAY_FREE (map->const_equiv_varray);
   free (map->reg_map);
-  VARRAY_FREE (map->block_map);
   free (map->insn_map);
   free (map);
   free (arg_vals);
@@ -3057,20 +3056,20 @@ get_func_hard_reg_initial_val (fun, reg)
 
   if (ivs == 0)
     {
-      fun->hard_reg_initial_vals = (void *) xmalloc (sizeof (initial_value_struct));
+      fun->hard_reg_initial_vals = (void *) ggc_alloc (sizeof (initial_value_struct));
       ivs = fun->hard_reg_initial_vals;
       ivs->num_entries = 0;
       ivs->max_entries = 5;
-      ivs->entries = (initial_value_pair *) xmalloc (5 * sizeof (initial_value_pair));
+      ivs->entries = (initial_value_pair *) ggc_alloc (5 * sizeof (initial_value_pair));
     }
 
   if (ivs->num_entries >= ivs->max_entries)
     {
       ivs->max_entries += 5;
       ivs->entries = 
-       (initial_value_pair *) xrealloc (ivs->entries,
-                                        ivs->max_entries
-                                        * sizeof (initial_value_pair));
+       (initial_value_pair *) ggc_realloc (ivs->entries,
+                                           ivs->max_entries
+                                           * sizeof (initial_value_pair));
     }
 
   ivs->entries[ivs->num_entries].hard_reg = reg;
@@ -3095,23 +3094,6 @@ has_hard_reg_initial_val (mode, regno)
   return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
 }
 
-void
-mark_hard_reg_initial_vals (fun)
-     struct function *fun;
-{
-  struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
-  int i;
-
-  if (ivs == 0)
-    return;
-
-  for (i = 0; i < ivs->num_entries; i ++)
-    {
-      ggc_mark_rtx (ivs->entries[i].hard_reg);
-      ggc_mark_rtx (ivs->entries[i].pseudo);
-    }
-}
-
 static void
 setup_initial_hard_reg_value_integration (inl_f, remap)
      struct function *inl_f;
@@ -3181,3 +3163,5 @@ allocate_initial_values (reg_equiv_memory_loc)
     }
 #endif
 }
+
+#include "gt-integrate.h"
index 9ddefefc9567e6d7de22f43f75d0009a5523ca71..b4d622767c9bf9719c2fc7492170b377ff6672fd 100644 (file)
@@ -143,8 +143,6 @@ extern rtx has_hard_reg_initial_val         PARAMS ((enum machine_mode, int));
 /* If a pseudo represents an initial hard reg (or expression), return
    it, else return NULL_RTX.  */
 extern rtx get_hard_reg_initial_reg            PARAMS ((struct function *, rtx));
-/* This is for GC.  */
-extern void mark_hard_reg_initial_vals         PARAMS ((struct function *));
 /* Called from rest_of_compilation.  */
 extern void emit_initial_value_sets            PARAMS ((void));
 extern void allocate_initial_values            PARAMS ((rtx *));
index 1de79dfbe7c3910e6bc18685a8008b97a2fe165e..5a7fc589c517a252568f483219f41ef163881994 100644 (file)
@@ -1,3 +1,95 @@
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       * check-init.c (attach_initialized_static_class): Delete, unused.
+       * parse.y: Use htab_t instead of struct hashtable, update
+       all uses.
+       * java-tree.h: Include hashtab.h instead of hash.h.
+       (struct lang_decl_func): Use htab_t, set up for gengtype.
+       (struct init_test_hash_entry): Delete.
+       (struct treetreehash_entry): New.
+       (java_treetreehash_find): New 
+       (java_treetreehash_new): New prototype.
+       (java_treetreehash_create): New prototype.
+       (java_mark_tree): Delete prototype.
+       (java_hash_hash_tree_node): Delete prototype.
+       (java_hash_compare_tree_node): Delete prototype.
+       (attach_initialized_static_class): Delete prototype.
+       * expr.c (build_class_init): Update to use java_treetreehash
+       functions.
+       (java_expand_expr): Update to use htab_t.
+       (emit_init_test_initialization): Likewise.
+       * decl.c (java_mark_tree): Delete.
+       * class.c (init_test_hash_newfunc): Delete.
+       (java_hash_hash_tree_node): Delete.
+       (java_hash_compare_tree_node): Delete.
+       (add_method_1): Update to use java_treetreehash functions.
+       (JAVA_TREEHASHHASH_H): New macro.
+       (java_treetreehash_hash): New function.
+       (java_treetreehash_compare): New function.
+       (java_treetreehash_find): New function.
+       (java_treetreehash_new): New function.
+       (java_treetreehash_create): New function.
+       * Make-lang.in (JAVA_TREE_H): Replace hash.h by HASHTAB_H.
+
+       * Make-lang.in (java/parse.o): Depend on debug.h.
+       * java-tree.h (struct lang_identifier): Use gengtype.
+       (union lang_tree_node): New.
+       (struct lang_decl_func): Use gengtype.
+       (struct lang_decl_var): Likewise.
+       (struct lang_decl): Likewise.
+       * parse.y: Include debug.h.
+       * lang.c (LANG_HOOKS_MARK_TREE): Delete.
+
+       * lang.c (struct language_function): New dummy structure.
+
+       * java-tree.h (MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC): Set
+       descriminator for DECL_LANG_SPECIFIC.
+       (struct lang_decl_func): Rename from struct lang_decl.
+       (enum lang_decl_desc): New.
+       (struct lang_decl): Make it a union.  Update all the accessor macros.
+       (struct lang_type): Use gengtype.
+       * class.c (add_method_1): Set descriminator for DECL_LANG_SPECIFIC.
+       * decl.c (java_dup_lang_specific_decl): All lang_decl structures
+       are now the same size.
+       (lang_mark_tree): Use gengtype to mark TYPE_LANG_SPECIFIC;
+       use discriminator to mark DECL_LANG_SPECIFIC.
+
+       * Make-lang.in (gt-java-builtins.h): New rule.
+       (java/builtins.o): Add dependency on gt-<filename>.h.
+       * builtins.c: Use gengtype for roots.
+       (union string_or_tree): Use gengtype.
+       (struct builtin_record): Use gengtype.
+       * config-lang.in (gtfiles): Add builtins.c.
+
+       * Make-lang.in (gt-java-class.h, gt-java-constants.h,
+       gt-java-decl.h, gt-java-expr.h, gt-java-jcf-parse.h,
+       gt-java-jcf-write.h, gt-java-lang.h, gt-java-mangle.h,
+       gt-java-parse.h, gtype-java.h): Add rules to generate.
+       (parse.o): Add dependency on gt-java-parse.h, gt-java.h.
+       (class.o): Add dependency on gt-*.h.
+       (constants.o): Likewise.
+       (decl.o): Likewise.
+       (expr.o): Likewise.
+       (jcf-parse.o): Likewise.
+       (jcf-write.o): Likewise.
+       (lang.o): Likewise.
+       * config-lang.in (gtfiles): New.
+       * class.c: Replace uses of ggc_add_* with GTY markers.  Include gt-*.h.
+       * constants.c: Replace uses of ggc_add_* with GTY markers.
+       Include gt-*.h.
+       * decl.c: Replace uses of ggc_add_* with GTY markers.  Include gt-*.h.
+       * expr.c: Replace uses of ggc_add_* with GTY markers.  Include gt-*.h.
+       * java-tree.h: Replace uses of ggc_add_* with GTY markers.
+       * jcf-parse.c: Replace uses of ggc_add_* with GTY markers.
+       Include gt-*.h.
+       * jcf-write.c: Replace uses of ggc_add_* with GTY markers.
+       Include gt-*.h.
+       * lang.c: Replace uses of ggc_add_* with GTY markers.  Include gt-*.h.
+       * mangle.c: Replace uses of ggc_add_* with GTY markers.  Include
+       gt-*.h.
+       * parse.y: Replace uses of ggc_add_* with GTY markers.  Include gt-*.h.
+       Include gtype-java.h.
+
 2002-06-02  Tom Tromey  <tromey@redhat.com>
 
        Fix for PR java/5913:
index c8bce83cd67b98728fa193366ca5871c3469aa8a..05dc9ea44410ce09fbb50073c93401221438ee0e 100644 (file)
@@ -98,6 +98,11 @@ $(srcdir)/java/keyword.h: $(srcdir)/java/keyword.gperf
        exit 1; } ; \
        mv -f k$$$$.h keyword.h)
 
+gt-java-class.h gt-java-constants.h gt-java-decl.h : s-gtype ; @true
+gt-java-expr.h gt-java-jcf-parse.h gt-java-jcf-write.h : s-gtype ; @true
+gt-java-lang.h gt-java-mangle.h gt-java-parse.h : s-gtype ; @true
+gt-java-builtins.h gtype-java.h : s-gtype ; @true
+
 # Executables built by this Makefile:
 JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
   java/constants.o java/lang.o java/typeck.o java/except.o java/verify.o \
@@ -251,11 +256,12 @@ java.stage4: stage4-start
 
 #\f
 # .o:.h dependencies.
-JAVA_TREE_H = $(TREE_H) java/java-tree.h java/java-tree.def
+JAVA_TREE_H = $(TREE_H) $(HASHTAB_H) java/java-tree.h java/java-tree.def
 JAVA_LEX_C = java/lex.c java/keyword.h java/chartables.h
 
 java/parse.o: java/parse.c java/jcf-reader.c $(CONFIG_H) $(SYSTEM_H) \
-  function.h $(JAVA_TREE_H) $(JAVA_LEX_C) java/parse.h java/lex.h $(GGC_H)
+  function.h $(JAVA_TREE_H) $(JAVA_LEX_C) java/parse.h java/lex.h $(GGC_H) \
+  debug.h gt-java-parse.h gtype-java.h
 java/jcf-dump.o: $(CONFIG_H) $(SYSTEM_H) $(JAVA_TREE_H) java/jcf-dump.c \
   java/jcf-reader.c java/jcf.h java/javaop.h java/javaop.def version.h
 java/gjavah.o: $(CONFIG_H) $(SYSTEM_H) $(JAVA_TREE_H) java/gjavah.c \
@@ -264,37 +270,38 @@ java/boehm.o: java/boehm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(JAVA_TREE_H) \
   java/parse.h toplev.h
 java/buffer.o: java/buffer.c $(CONFIG_H) java/buffer.h $(SYSTEM_H) toplev.h
 java/builtins.o: java/builtins.c $(CONFIG_H) $(SYSTEM_H) $(JAVA_TREE_H) \
-  $(GGC_H) flags.h builtin-types.def langhooks.h
+  $(GGC_H) flags.h builtin-types.def langhooks.h gt-java-builtins.h
 java/check-init.o: java/check-init.c $(CONFIG_H) \
   $(JAVA_TREE_H) $(SYSTEM_H) toplev.h
 java/class.o: java/class.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
-  java/parse.h toplev.h $(SYSTEM_H) output.h $(GGC_H) $(TARGET_H) function.h
+  java/parse.h toplev.h $(SYSTEM_H) output.h $(GGC_H) $(TARGET_H) function.h \
+  gt-java-class.h
 java/constants.o: java/constants.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
-  toplev.h $(SYSTEM_H) $(GGC_H)
+  toplev.h $(SYSTEM_H) $(GGC_H) gt-java-constants.h
 java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
   toplev.h flags.h $(SYSTEM_H) function.h expr.h libfuncs.h except.h \
-  java/java-except.h $(GGC_H) real.h
+  java/java-except.h $(GGC_H) real.h gt-java-decl.h
 java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
   $(RTL_H) java/javaop.h java/java-opcodes.h except.h java/java-except.h \
   toplev.h $(SYSTEM_H) function.h 
 java/expr.o: java/expr.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
   $(RTL_H) $(EXPR_H) java/javaop.h java/java-opcodes.h except.h \
   java/java-except.h java/java-except.h java/parse.h toplev.h \
-  $(SYSTEM_H) $(GGC_H)
+  $(SYSTEM_H) $(GGC_H) gt-java-expr.h
 java/jcf-depend.o: java/jcf-depend.c $(CONFIG_H) $(SYSTEM_H) java/jcf.h
 java/jcf-parse.o: java/jcf-parse.c $(CONFIG_H) $(JAVA_TREE_H) flags.h \
   input.h java/java-except.h $(SYSTEM_H) toplev.h java/parse.h $(GGC_H) \
-  debug.h real.h
+  debug.h real.h gt-java-jcf-parse.h
 java/jcf-write.o: java/jcf-write.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
   $(RTL_H) java/java-opcodes.h java/parse.h java/buffer.h $(SYSTEM_H) \
-  toplev.h $(GGC_H)
+  toplev.h $(GGC_H) gt-java-jcf-write.h
 java/jv-scan.o: java/jv-scan.c $(CONFIG_H) $(SYSTEM_H) version.h
 java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H)
 java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
   toplev.h $(SYSTEM_H) $(RTL_H) $(EXPR_H) diagnostic.h langhooks.h \
-  langhooks-def.h
+  langhooks-def.h gt-java-lang.h
 java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
-  toplev.h $(GGC_H)
+  toplev.h $(GGC_H) gt-java-mangle.h
 java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
   $(SYSTEM_H) toplev.h $(GGC_H)
 java/parse-scan.o: $(CONFIG_H) $(SYSTEM_H) toplev.h $(JAVA_LEX_C) java/parse.h \
index 81be7e3d4576dbb3c0b10703500534bdc73f7a19..c167df5b16b930980dd9b7a1d85da3fdc6c0276f 100644 (file)
@@ -83,21 +83,21 @@ typedef tree builtin_creator_function PARAMS ((tree, tree));
 
 /* Hold a char*, before initialization, or a tree, after
    initialization.  */
-union string_or_tree
+union string_or_tree GTY(())
 {
-  const char *s;
-  tree t;
+  const char * GTY ((tag ("0"))) s;
+  tree GTY ((tag ("1"))) t;
 };
 
 /* Used to hold a single builtin record.  */
-struct builtin_record
+struct builtin_record GTY(())
 {
-  union string_or_tree class_name;
-  union string_or_tree method_name;
-  builtin_creator_function *creator;
+  union string_or_tree GTY ((desc ("1"))) class_name;
+  union string_or_tree GTY ((desc ("1"))) method_name;
+  builtin_creator_function * GTY((skip (""))) creator;
 };
 
-static struct builtin_record java_builtins[] =
+static GTY(()) struct builtin_record java_builtins[] =
 {
   { { "java.lang.Math" }, { "min" }, min_builtin },
   { { "java.lang.Math" }, { "max" }, max_builtin },
@@ -273,8 +273,6 @@ initialize_builtins ()
 
       java_builtins[i].class_name.t = klass_id;
       java_builtins[i].method_name.t = m;
-      ggc_add_tree_root (&java_builtins[i].class_name.t, 1);
-      ggc_add_tree_root (&java_builtins[i].method_name.t, 1);
     }
 
   void_list_node = end_params_node;
@@ -348,3 +346,5 @@ check_for_builtin (method, call)
     }
   return call;
 }
+
+#include "gt-java-builtins.h"
index 679353355c890d83d8b1c66ee7cadd10ed240683..e02237664bd3dee9fdab7a1c7d3cbc8075d9b465 100644 (file)
@@ -607,8 +607,10 @@ check_init (exp, before)
                  if (fndecl && METHOD_STATIC (fndecl)
                      && (DECL_INITIAL (decl) == boolean_true_node
                          || (index >= 0 && ASSIGNED_P (tmp, index))))
-                   hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
-                                DECL_FUNCTION_INIT_TEST_CLASS(decl), TRUE, NULL);  
+                   *(htab_find_slot 
+                     (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
+                      DECL_FUNCTION_INIT_TEST_CLASS (decl), INSERT)) =
+                     DECL_FUNCTION_INIT_TEST_CLASS (decl);
                }
              DECL_BIT_INDEX (decl) = -1;
            }
@@ -999,27 +1001,3 @@ check_for_initialization (body, mdecl)
 
   start_current_locals = num_current_locals = 0;
 }
-
-/* Call for every element in DECL_FUNCTION_INITIALIZED_CLASS_TABLE of
-   a method to consider whether the type indirectly described by ENTRY
-   is definitly initialized and thus remembered as such. */
-
-bool
-attach_initialized_static_class (entry, ptr)
-     struct hash_entry *entry;
-     PTR ptr;
-{
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
-  tree fndecl = DECL_CONTEXT (ite->init_test_decl);
-  int index = DECL_BIT_INDEX (ite->init_test_decl);
-
-  /* If the initializer flag has been definitly assigned (not taking
-     into account its first mandatory assignment which has been
-     already added but escaped analysis.) */
-  if (fndecl && METHOD_STATIC (fndecl)
-      && (DECL_INITIAL (ite->init_test_decl) == boolean_true_node
-         || (index >= 0 && ASSIGNED_P (((word *) ptr), index))))
-    hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
-                entry->key, TRUE, NULL);
-  return true;
-}
index 7b8c5e06c3a0a94ed1a185c3779368fdbdfecf30..0b9c6a9889e6f1fb21481bc56980f9fd49743332 100644 (file)
@@ -55,13 +55,10 @@ static tree get_dispatch_table PARAMS ((tree, tree));
 static void add_interface_do PARAMS ((tree, tree, int));
 static tree maybe_layout_super_class PARAMS ((tree, tree));
 static int assume_compiled PARAMS ((const char *));
-static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
-                                                         struct hash_table *,
-                                                         hash_table_key));
 static tree build_method_symbols_entry PARAMS ((tree));
 
-static rtx registerClass_libfunc;
-static rtx registerResource_libfunc;
+static GTY(()) rtx registerClass_libfunc;
+static GTY(()) rtx registerResource_libfunc;
 
 extern struct obstack permanent_obstack;
 struct obstack temporary_obstack;
@@ -95,8 +92,7 @@ static assume_compiled_node *find_assume_compiled_node
 
 static assume_compiled_node *assume_compiled_tree;
 
-static tree class_roots[5]
-= { NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE };
+static GTY(()) tree class_roots[5];
 #define registered_class class_roots[0]
 #define fields_ident class_roots[1]  /* get_identifier ("fields") */
 #define info_ident class_roots[2]  /* get_identifier ("info") */
@@ -625,43 +621,6 @@ build_java_method_type (fntype, this_class, access_flags)
   return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);
 }
 
-static struct hash_entry *
-init_test_hash_newfunc (entry, table, string)
-     struct hash_entry *entry;
-     struct hash_table *table;
-     hash_table_key string ATTRIBUTE_UNUSED;
-{
-  struct init_test_hash_entry *ret = (struct init_test_hash_entry *) entry;
-  if (ret == NULL)
-    {
-      ret = ((struct init_test_hash_entry *)
-            hash_allocate (table, sizeof (struct init_test_hash_entry)));
-      if (ret == NULL)
-       return NULL;
-    }
-  ret->init_test_decl = 0;
-  return (struct hash_entry *) ret;
-}
-
-/* Hash table helpers. Also reused in find_applicable_accessible_methods_list 
-   (parse.y). The hash of a tree node is its pointer value, comparison
-   is direct. */
-
-unsigned long
-java_hash_hash_tree_node (k)
-     hash_table_key k;
-{
-  return (long) k;
-}
-
-bool
-java_hash_compare_tree_node (k1, k2)
-     hash_table_key k1;
-     hash_table_key k2;
-{
-  return ((tree) k1 == (tree) k2);
-}
-
 tree
 add_method_1 (handle_class, access_flags, name, function_type)
      tree handle_class;
@@ -679,17 +638,17 @@ add_method_1 (handle_class, access_flags, name, function_type)
 
   DECL_LANG_SPECIFIC (fndecl)
     = (struct lang_decl *) ggc_alloc_cleared (sizeof (struct lang_decl));
+  DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
 
   /* Initialize the static initializer test table.  */
-  hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
-                  init_test_hash_newfunc, java_hash_hash_tree_node, 
-                  java_hash_compare_tree_node);
+  
+  DECL_FUNCTION_INIT_TEST_TABLE (fndecl) = 
+    java_treetreehash_create (10, 1);
 
   /* Initialize the initialized (static) class table. */
   if (access_flags & ACC_STATIC)
-    hash_table_init (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl),
-                    init_test_hash_newfunc, java_hash_hash_tree_node,
-                    java_hash_compare_tree_node);
+    DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
+      htab_create_ggc (50, htab_hash_pointer, htab_eq_pointer, NULL);
 
   /* Initialize the static method invocation compound list */
   DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND (fndecl) = NULL_TREE;
@@ -2327,12 +2286,85 @@ emit_offset_symbol_table ()
 void
 init_class_processing ()
 {
-  registerClass_libfunc = gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterClass");
+  registerClass_libfunc = gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterClass");
   registerResource_libfunc = 
-    gen_rtx (SYMBOL_REF, Pmode, "_Jv_RegisterResource");
-  ggc_add_tree_root (class_roots, ARRAY_SIZE (class_roots));
+    gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterResource");
   fields_ident = get_identifier ("fields");
   info_ident = get_identifier ("info");
-  ggc_add_rtx_root (&registerClass_libfunc, 1);
   gcc_obstack_init (&temporary_obstack);
 }
+\f
+static hashval_t java_treetreehash_hash PARAMS ((const void *));
+static int java_treetreehash_compare PARAMS ((const void *, const void *));
+
+/* A hash table mapping trees to trees.  Used generally.  */
+
+#define JAVA_TREEHASHHASH_H(t) ((hashval_t) (t))
+
+static hashval_t
+java_treetreehash_hash (k_p)
+     const void *k_p;
+{
+  struct treetreehash_entry *k = (struct treetreehash_entry *) k_p;
+  return JAVA_TREEHASHHASH_H (k->key);
+}
+
+static int
+java_treetreehash_compare (k1_p, k2_p)
+     const void * k1_p;
+     const void * k2_p;
+{
+  struct treetreehash_entry * k1 = (struct treetreehash_entry *) k1_p;
+  tree k2 = (tree) k2_p;
+  return (k1->key == k2);
+}
+
+tree 
+java_treetreehash_find (ht, t)
+     htab_t ht;
+     tree t;
+{
+  struct treetreehash_entry *e;
+  hashval_t hv = JAVA_TREEHASHHASH_H (t);
+  e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
+  if (e == NULL)
+    return NULL;
+  else
+    return e->value;
+}
+
+tree *
+java_treetreehash_new (ht, t)
+     htab_t ht;
+     tree t;
+{
+  PTR *e;
+  struct treetreehash_entry *tthe;
+  hashval_t hv = JAVA_TREEHASHHASH_H (t);
+
+  e = htab_find_slot_with_hash (ht, t, hv, INSERT);
+  if (*e == NULL)
+    {
+      tthe = (*ht->alloc_f) (1, sizeof (*tthe));
+      tthe->key = t;
+      *e = (PTR) tthe;
+    }
+  else
+    tthe = (struct treetreehash_entry *) *e;
+  return &tthe->value;
+}
+
+htab_t
+java_treetreehash_create (size, gc)
+     size_t size;
+     int gc;
+{
+  if (gc)
+    return htab_create_ggc (size, java_treetreehash_hash,
+                           java_treetreehash_compare, NULL);
+  else
+    return htab_create_alloc (size, java_treetreehash_hash,
+                             java_treetreehash_compare, free, xcalloc, free);
+}
+
+#include "gt-java-class.h"
index e4524fe3a6efec6abdba69680698cc13d2dd7baa..d4511b5c5546f8614ad869361bbf6054fc0f567d 100644 (file)
@@ -36,6 +36,8 @@ compilers="jc1\$(exeext) jvgenmain\$(exeext)"
 
 stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
 
+gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y"
+
 target_libs=${libgcj_saved}
 lang_dirs="zlib fastjar"
 #build_by_default=no
index c51cec9a7a409b11a9fff08e480dc1aef1a00a24..e3642d5d67dfa01aedf77eb527bf7c1361676de6 100644 (file)
@@ -326,20 +326,12 @@ write_constant_pool (cpool, buffer, length)
 
 CPool *outgoing_cpool;
 
+static GTY(()) tree tag_nodes[13];
 static tree
 get_tag_node (tag)
      int tag;
 {
   /* A Cache for build_int_2 (CONSTANT_XXX, 0). */
-  static tree tag_nodes[13];
-  static int initialized_p;
-
-  /* Register the TAG_NODES with the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (tag_nodes, 13);
-      initialized_p = 1;
-    }
 
   if (tag_nodes[tag] == NULL_TREE)
     tag_nodes[tag] = build_int_2 (tag, 0);
@@ -492,3 +484,5 @@ build_constants_constructor ()
   FINISH_RECORD_CONSTRUCTOR (cons);
   return cons;
 }
+
+#include "gt-java-constants.h"
index 7026dead71c47a36008ac7aa337157d1c652e89a..1b883caec361fdd1a6f6af2da6794c194b206183 100644 (file)
@@ -66,12 +66,12 @@ extern int always_initialize_class_p;
    DECL_LOCAL_SLOT_CHAIN; the index finds the TREE_VEC element, and then
    we search the chain for a decl with a matching TREE_TYPE. */
 
-tree decl_map;
+static GTY(()) tree decl_map;
 
 /* A list of local variables VAR_DECLs for this method that we have seen
    debug information, but we have not reached their starting (byte) PC yet. */
 
-static tree pending_local_decls = NULL_TREE;
+static GTY(()) tree pending_local_decls;
 
 /* Push a local variable or stack slot into the decl_map,
    and assign it an rtl. */
@@ -908,11 +908,6 @@ java_init_decl_processing ()
 
   init_jcf_parse ();
 
-  /* Register nodes with the garbage collector.  */
-  ggc_add_tree_root (java_global_trees, ARRAY_SIZE (java_global_trees));
-  ggc_add_tree_root (&decl_map, 1);
-  ggc_add_tree_root (&pending_local_decls, 1);
-
   initialize_builtins ();
 }
 
@@ -1553,10 +1548,7 @@ java_dup_lang_specific_decl (node)
   if (!DECL_LANG_SPECIFIC (node))
     return;
 
-  if (TREE_CODE (node) == VAR_DECL)
-    lang_decl_size = sizeof (struct lang_decl_var);
-  else
-    lang_decl_size = sizeof (struct lang_decl);
+  lang_decl_size = sizeof (struct lang_decl);
   x = (struct lang_decl *) ggc_alloc (lang_decl_size);
   memcpy (x, DECL_LANG_SPECIFIC (node), lang_decl_size);
   DECL_LANG_SPECIFIC (node) = x;
@@ -1829,64 +1821,4 @@ end_java_method ()
   current_function_decl = NULL_TREE;
 }
 
-/* Mark language-specific parts of T for garbage-collection.  */
-
-void
-java_mark_tree (t)
-     tree t;
-{
-  if (TREE_CODE (t) == IDENTIFIER_NODE)
-    {
-      struct lang_identifier *li = (struct lang_identifier *) t;
-      ggc_mark_tree (li->global_value);
-      ggc_mark_tree (li->local_value);
-      ggc_mark_tree (li->utf8_ref);
-    }
-  else if (TREE_CODE (t) == VAR_DECL
-          || TREE_CODE (t) == PARM_DECL
-          || TREE_CODE (t) == FIELD_DECL)
-    {
-      struct lang_decl_var *ldv = 
-       ((struct lang_decl_var *) DECL_LANG_SPECIFIC (t));
-      if (ldv)
-       {
-         ggc_mark (ldv);
-         ggc_mark_tree (ldv->slot_chain);
-         ggc_mark_tree (ldv->am);
-         ggc_mark_tree (ldv->wfl);
-       }
-    }
-  else if (TREE_CODE (t) == FUNCTION_DECL)
-    {
-      struct lang_decl *ld = DECL_LANG_SPECIFIC (t);
-      
-      if (ld)
-       {
-         ggc_mark (ld);
-         ggc_mark_tree (ld->wfl);
-         ggc_mark_tree (ld->throws_list);
-         ggc_mark_tree (ld->function_decl_body);
-         ggc_mark_tree (ld->called_constructor);
-         ggc_mark_tree (ld->inner_access);
-         ggc_mark_tree_hash_table (&ld->init_test_table);
-         ggc_mark_tree_hash_table (&ld->ict);
-         ggc_mark_tree (ld->smic);
-       }
-    }
-  else if (TYPE_P (t))
-    {
-      struct lang_type *lt = TYPE_LANG_SPECIFIC (t);
-      
-      if (lt)
-       {
-         ggc_mark (lt);
-         ggc_mark_tree (lt->signature);
-         ggc_mark_tree (lt->cpool_data_ref);
-         ggc_mark_tree (lt->finit_stmt_list);
-         ggc_mark_tree (lt->clinit_stmt_list);
-         ggc_mark_tree (lt->ii_block);
-         ggc_mark_tree (lt->dot_class);
-         ggc_mark_tree (lt->package_list);
-       }
-    }
-}
+#include "gt-java-decl.h"
index f17fef82ab951cd8de7b6572e4c20a910cabf0f1..34be4d52e646acff6899f7a1c51b65a0a9ce2932 100644 (file)
@@ -81,15 +81,15 @@ static tree build_java_throw_out_of_bounds_exception PARAMS ((tree));
 static tree build_java_check_indexed_type PARAMS ((tree, tree)); 
 static tree case_identity PARAMS ((tree, tree)); 
 static unsigned char peek_opcode_at_pc PARAMS ((struct JCF *, int, int));
-static bool emit_init_test_initialization PARAMS ((struct hash_entry *,
-                                                  PTR ptr));
+static int emit_init_test_initialization PARAMS ((void **entry,
+                                                 void * ptr));
 static int get_offset_table_index PARAMS ((tree));
 
-static tree operand_type[59];
+static GTY(()) tree operand_type[59];
 extern struct obstack permanent_obstack;
 
-static tree methods_ident = NULL_TREE;
-static tree ncode_ident = NULL_TREE;
+static GTY(()) tree methods_ident;
+static GTY(()) tree ncode_ident;
 tree dtable_ident = NULL_TREE;
 
 /* Set to non-zero value in order to emit class initilization code
@@ -123,10 +123,10 @@ int always_initialize_class_p;
    So dup cannot just add an extra element to the quick_stack, but iadd can.
 */
 
-static tree quick_stack = NULL_TREE;
+static GTY(()) tree quick_stack;
 
 /* A free-list of unused permamnet TREE_LIST nodes. */
-static tree tree_list_free_list = NULL_TREE;
+static GTY((deletable (""))) tree tree_list_free_list;
 
 /* The stack pointer of the Java virtual machine.
    This does include the size of the quick_stack. */
@@ -144,11 +144,6 @@ init_expr_processing()
   operand_type[23] = operand_type[56] = float_type_node;
   operand_type[24] = operand_type[57] = double_type_node;
   operand_type[25] = operand_type[58] = ptr_type_node;
-  ggc_add_tree_root (operand_type, 59);
-  ggc_add_tree_root (&methods_ident, 1);
-  ggc_add_tree_root (&ncode_ident, 1);
-  ggc_add_tree_root (&quick_stack, 1);
-  ggc_add_tree_root (&tree_list_free_list, 1);
 }
 
 tree
@@ -1756,7 +1751,6 @@ build_class_init (clas, expr)
      tree clas, expr;
 {
   tree init;
-  struct init_test_hash_entry *ite;
   if (inherits_from_p (current_class, clas))
     return expr;
 
@@ -1770,25 +1764,24 @@ build_class_init (clas, expr)
     }
   else
     {
-      ite = (struct init_test_hash_entry *)
-       hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
-                    (const hash_table_key) clas,
-                    TRUE, NULL);
-      
-      if (ite->init_test_decl == 0)
+      tree *init_test_decl;
+      init_test_decl = java_treetreehash_new
+       (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), clas);
+
+      if (*init_test_decl == NULL)
        {
          /* Build a declaration and mark it as a flag used to track
             static class initializations. */
-         ite->init_test_decl = build_decl (VAR_DECL, NULL_TREE,
-                                           boolean_type_node);
-         MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (ite->init_test_decl);
-         LOCAL_CLASS_INITIALIZATION_FLAG (ite->init_test_decl) = 1;
-         DECL_CONTEXT (ite->init_test_decl) = current_function_decl;
-         DECL_FUNCTION_INIT_TEST_CLASS (ite->init_test_decl) = clas;
+         *init_test_decl = build_decl (VAR_DECL, NULL_TREE,
+                                      boolean_type_node);
+         MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (*init_test_decl);
+         LOCAL_CLASS_INITIALIZATION_FLAG (*init_test_decl) = 1;
+         DECL_CONTEXT (*init_test_decl) = current_function_decl;
+         DECL_FUNCTION_INIT_TEST_CLASS (*init_test_decl) = clas;
          /* Tell the check-init code to ignore this decl when not
              optimizing class initialization. */
          if (!STATIC_CLASS_INIT_OPT_P ())
-           DECL_BIT_INDEX(ite->init_test_decl) = -1;
+           DECL_BIT_INDEX(*init_test_decl) = -1;
        }
 
       init = build (CALL_EXPR, void_type_node,
@@ -1798,12 +1791,12 @@ build_class_init (clas, expr)
       TREE_SIDE_EFFECTS (init) = 1;
       init = build (COND_EXPR, void_type_node,
                    build (EQ_EXPR, boolean_type_node, 
-                          ite->init_test_decl, boolean_false_node),
+                          *init_test_decl, boolean_false_node),
                    init, integer_zero_node);
       TREE_SIDE_EFFECTS (init) = 1;
       init = build (COMPOUND_EXPR, TREE_TYPE (expr), init, 
                    build (MODIFY_EXPR, boolean_type_node,
-                          ite->init_test_decl, boolean_true_node));
+                          *init_test_decl, boolean_true_node));
       TREE_SIDE_EFFECTS (init) = 1;
     }
 
@@ -1976,11 +1969,11 @@ build_invokevirtual (dtable, method)
   return func;
 }
 
+static GTY(()) tree class_ident;
 tree
 build_invokeinterface (dtable, method)
      tree dtable, method;
 {
-  static tree class_ident = NULL_TREE;
   tree lookup_arg;
   tree interface;
   tree idx;
@@ -1995,7 +1988,6 @@ build_invokeinterface (dtable, method)
   if (class_ident == NULL_TREE)
     {
       class_ident = get_identifier ("class");
-      ggc_add_tree_root (&class_ident, 1);
     }
 
   dtable = build_java_indirect_ref (dtable_type, dtable, flag_check_references);
@@ -2588,8 +2580,8 @@ java_expand_expr (exp, target, tmode, modifier)
          if (! always_initialize_class_p 
              && current_function_decl
              && found_class_initialization_flag)
-           hash_traverse 
-             (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
+           htab_traverse 
+             (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
               emit_init_test_initialization, NULL);
 
          /* Avoid deep recursion for long block.  */
@@ -3458,19 +3450,19 @@ force_evaluation_order (node)
 /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE of a
    method in order to emit initialization code for each test flag.  */
 
-static bool
-emit_init_test_initialization (entry, key)
-  struct hash_entry *entry;
-  hash_table_key key ATTRIBUTE_UNUSED;
+static int
+emit_init_test_initialization (entry, x)
+     void * * entry;
+     void * x ATTRIBUTE_UNUSED;
 {
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
-  tree klass = build_class_ref ((tree) entry->key);
+  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
+  tree klass = build_class_ref (ite->key);
   tree rhs;
 
   /* If the DECL_INITIAL of the test flag is set to true, it
      means that the class is already initialized the time it
      is in use. */
-  if (DECL_INITIAL (ite->init_test_decl) == boolean_true_node)
+  if (DECL_INITIAL (ite->value) == boolean_true_node)
     rhs = boolean_true_node;
   /* Otherwise, we initialize the class init check variable by looking
      at the `state' field of the class to see if it is already
@@ -3485,6 +3477,9 @@ emit_init_test_initialization (entry, key)
                 build_int_2 (JV_STATE_DONE, 0));
 
   expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node, 
-                          ite->init_test_decl, rhs));
+                          ite->value, rhs));
   return true;
 }
+
+#include "gt-java-expr.h"
+
index 29a7553b11ab5e551c2f834d1bcbcf562804b120..71a63887ce7be4b6d3ae8474363fa786622bc0b7 100644 (file)
@@ -26,7 +26,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 
 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
 
-#include "hash.h"
+#include "hashtab.h"
 
 /* Java language-specific tree codes.  */
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
@@ -404,7 +404,7 @@ enum java_tree_index
   JTI_MAX
 };
 
-extern tree java_global_trees[JTI_MAX];
+extern GTY(()) tree java_global_trees[JTI_MAX];
 
 /* "Promoted types" that are used for primitive types smaller
    than int.  We could use int_type_node, but then we would lose
@@ -679,16 +679,27 @@ extern struct CPool *outgoing_cpool;
 
 extern const char *cyclic_inheritance_report;
 
-struct lang_identifier
+struct lang_identifier GTY(())
 {
   struct tree_identifier ignore;
-  tree global_value, local_value;
+  tree global_value;
+  tree local_value;
 
   /* If non-NULL:  An ADDR_REF to a VAR_DECL that contains
    * the Utf8Const representation of the identifier.  */
   tree utf8_ref;
 };
 
+/* The resulting tree type.  */
+union lang_tree_node 
+  GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE")))
+{
+  union tree_node GTY ((tag ("0"), 
+                       desc ("tree_node_structure (&%h)"))) 
+    generic;
+  struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
 /* Macros for access to language-specific slots in an identifier.  */
 /* Unless specified, each of these slots contains a DECL node or null.  */
 
@@ -728,41 +739,43 @@ struct lang_identifier
 /* For a FUNCTION_DECL, if we are compiling a .class file, then this is
    the position in the .class file of the method code.
    Specifically, this is the code itself, not the code attribute. */
-#define DECL_CODE_OFFSET(DECL) (DECL_LANG_SPECIFIC(DECL)->code_offset)
+#define DECL_CODE_OFFSET(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.code_offset)
 /* Similarly, the length of the bytecode. */
-#define DECL_CODE_LENGTH(DECL) (DECL_LANG_SPECIFIC(DECL)->code_length)
+#define DECL_CODE_LENGTH(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.code_length)
 /* Similarly, the position of the LineNumberTable attribute. */
 #define DECL_LINENUMBERS_OFFSET(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->linenumbers_offset)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.linenumbers_offset)
 /* Similarly, the position of the LocalVariableTable attribute
    (following the standard attribute header). */
 #define DECL_LOCALVARIABLES_OFFSET(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->localvariables_offset)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.localvariables_offset)
 
-#define DECL_MAX_LOCALS(DECL) (DECL_LANG_SPECIFIC(DECL)->max_locals)
-#define DECL_MAX_STACK(DECL) (DECL_LANG_SPECIFIC(DECL)->max_stack)
+#define DECL_MAX_LOCALS(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.max_locals)
+#define DECL_MAX_STACK(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.max_stack)
 /* Number of local variable slots needed for the arguments of this function. */
-#define DECL_ARG_SLOT_COUNT(DECL) (DECL_LANG_SPECIFIC(DECL)->arg_slot_count)
+#define DECL_ARG_SLOT_COUNT(DECL) \
+  (DECL_LANG_SPECIFIC(DECL)->u.f.arg_slot_count)
 /* Information on declaration location */
-#define DECL_FUNCTION_WFL(DECL)  (DECL_LANG_SPECIFIC(DECL)->wfl)
+#define DECL_FUNCTION_WFL(DECL)  (DECL_LANG_SPECIFIC(DECL)->u.f.wfl)
 /* List of checked thrown exceptions, as specified with the `throws'
    keyword */
-#define DECL_FUNCTION_THROWS(DECL) (DECL_LANG_SPECIFIC(DECL)->throws_list)
+#define DECL_FUNCTION_THROWS(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.throws_list)
 /* List of other constructors of the same class that this constructor
    calls */
 #define DECL_CONSTRUCTOR_CALLS(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->called_constructor)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.called_constructor)
 /* When the function is an access function, the DECL it was trying to
    access */
 #define DECL_FUNCTION_ACCESS_DECL(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->called_constructor)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.called_constructor)
 /* The identifier of the access method used to invoke this method from
    an inner class.  */
 #define DECL_FUNCTION_INNER_ACCESS(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->inner_access)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.inner_access)
 /* Pointer to the function's current's COMPOUND_EXPR tree (while
    completing its body) or the function's block */
-#define DECL_FUNCTION_BODY(DECL) (DECL_LANG_SPECIFIC(DECL)->function_decl_body)
+#define DECL_FUNCTION_BODY(DECL) \
+  (DECL_LANG_SPECIFIC(DECL)->u.f.function_decl_body)
 /* How specific the function is (for method selection - Java source
    code front-end */
 #define DECL_SPECIFIC_COUNT(DECL) DECL_ARG_SLOT_COUNT(DECL)
@@ -771,31 +784,33 @@ struct lang_identifier
    boolean decls.  The variables are intended to be TRUE when the
    class has been initialized in this function, and FALSE otherwise.  */
 #define DECL_FUNCTION_INIT_TEST_TABLE(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->init_test_table)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.init_test_table)
 /* If LOCAL_CLASS_INITIALIZATION_FLAG_P(decl), give class it initializes. */
 #define DECL_FUNCTION_INIT_TEST_CLASS(DECL) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(DECL))->slot_chain)
+  (DECL_LANG_SPECIFIC(DECL)->u.v.slot_chain)
 /* For each static function decl, itc contains a hash table whose
    entries are keyed on class named that are definitively initialized
    in DECL.  */
 #define DECL_FUNCTION_INITIALIZED_CLASS_TABLE(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->ict)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.ict)
 /* A list of all the static method calls in the method DECL (if optimizing).
    Actually each TREE_VALUE points to a COMPONT_EXPR that wraps the
    invoation so we can later patch it. */
 #define DECL_FUNCTION_STATIC_METHOD_INVOCATION_COMPOUND(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->smic)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.smic)
 /* The Number of Artificial Parameters (NAP) DECL contains. this$<n>
    is excluded, because sometimes created as a parameter before the
    function decl exists. */
-#define DECL_FUNCTION_NAP(DECL) (DECL_LANG_SPECIFIC(DECL)->nap)
+#define DECL_FUNCTION_NAP(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.nap)
 /* True if DECL is a synthetic ctor.  */
 #define DECL_FUNCTION_SYNTHETIC_CTOR(DECL) \
-  (DECL_LANG_SPECIFIC(DECL)->synthetic_ctor)
-#define DECL_FIXED_CONSTRUCTOR_P(DECL) (DECL_LANG_SPECIFIC(DECL)->fixed_ctor)
+  (DECL_LANG_SPECIFIC(DECL)->u.f.synthetic_ctor)
+#define DECL_FIXED_CONSTRUCTOR_P(DECL) \
+  (DECL_LANG_SPECIFIC(DECL)->u.f.fixed_ctor)
 
 /* A constructor that calls this. */
-#define DECL_INIT_CALLS_THIS(DECL) (DECL_LANG_SPECIFIC(DECL)->init_calls_this)
+#define DECL_INIT_CALLS_THIS(DECL) \
+  (DECL_LANG_SPECIFIC(DECL)->u.f.init_calls_this)
 
 /* True when DECL aliases an outer context local variable.  */
 #define FIELD_LOCAL_ALIAS(DECL) DECL_LANG_FLAG_6 (DECL)
@@ -858,31 +873,31 @@ struct lang_identifier
 
 /* The slot number for this local variable. */
 #define DECL_LOCAL_SLOT_NUMBER(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->slot_number)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.slot_number)
 /* The start (bytecode) pc for the valid range of this local variable. */
 #define DECL_LOCAL_START_PC(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->start_pc)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.start_pc)
 /* The end (bytecode) pc for the valid range of this local variable. */
 #define DECL_LOCAL_END_PC(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->end_pc)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.end_pc)
 /* For a VAR_DECLor PARM_DECL, used to chain decls with the same
    slot_number in decl_map. */
 #define DECL_LOCAL_SLOT_CHAIN(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->slot_chain)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.slot_chain)
 /* For a FIELD_DECL, holds the name of the access method. Used to
    read/write the content of the field from an inner class.  */
 #define FIELD_INNER_ACCESS(DECL) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(DECL))->am)
+  (DECL_LANG_SPECIFIC(DECL)->u.v.am)
 /* Safely tests whether FIELD_INNER_ACCESS exists or not. */
 #define FIELD_INNER_ACCESS_P(DECL) \
   DECL_LANG_SPECIFIC (DECL) && FIELD_INNER_ACCESS (DECL)
 /* True if a final variable was initialized upon its declaration,
    or (if a field) in an initializer.  Set after definite assignment. */
 #define DECL_FIELD_FINAL_IUD(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->final_iud)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.final_iud)
 /* The original WFL of a final variable. */
 #define DECL_FIELD_FINAL_WFL(NODE) \
-  (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->wfl)
+  (DECL_LANG_SPECIFIC(NODE)->u.v.wfl)
 /* True if NODE is a local variable final. */
 #define LOCAL_FINAL_P(NODE) (DECL_LANG_SPECIFIC (NODE) && DECL_FINAL (NODE))
 /* True if NODE is a final field. */
@@ -893,7 +908,7 @@ struct lang_identifier
 /* True if NODE is a class initialization flag. This macro accesses
    the flag to read or set it.  */
 #define LOCAL_CLASS_INITIALIZATION_FLAG(NODE) \
-    (((struct lang_decl_var*)DECL_LANG_SPECIFIC(NODE))->cif)
+    (DECL_LANG_SPECIFIC(NODE)->u.v.cif)
 /* True if NODE is a class initialization flag. */
 #define LOCAL_CLASS_INITIALIZATION_FLAG_P(NODE) \
     (DECL_LANG_SPECIFIC (NODE) && LOCAL_CLASS_INITIALIZATION_FLAG(NODE))
@@ -903,7 +918,8 @@ struct lang_identifier
     {                                                          \
       DECL_LANG_SPECIFIC ((T))                                 \
        = ((struct lang_decl *)                                 \
-          ggc_alloc_cleared (sizeof (struct lang_decl_var)));  \
+          ggc_alloc_cleared (sizeof (struct lang_decl)));      \
+      DECL_LANG_SPECIFIC (T)->desc = LANG_DECL_VAR;            \
     }
 
 /* A ConstantExpression, after folding and name resolution. */
@@ -920,7 +936,7 @@ struct lang_identifier
 #define DECL_BIT_INDEX(DECL) (DECL_CHECK (DECL)->decl.pointer_alias_set)
 
 /* DECL_LANG_SPECIFIC for FUNCTION_DECLs. */
-struct lang_decl
+struct lang_decl_func GTY(())
 {
   /*  tree chain; not yet used. */
   long code_offset;
@@ -928,15 +944,21 @@ struct lang_decl
   long linenumbers_offset;
   long localvariables_offset;
   int arg_slots;
-  int max_locals, max_stack, arg_slot_count;
+  int max_locals;
+  int max_stack;
+  int arg_slot_count;
   tree wfl;                    /* Information on the original location */
   tree throws_list;            /* Exception specified by `throws' */
   tree function_decl_body;     /* Hold all function's statements */
   tree called_constructor;     /* When decl is a constructor, the
                                   list of other constructor it calls */
-  struct hash_table init_test_table;
-                               /* Class initialization test variables  */
-  struct hash_table ict;       /* Initialized (static) Class Table */
+
+  /* Class initialization test variables  */
+  htab_t GTY ((param_is (struct treetreehash_entry))) init_test_table;
+                               
+  /* Initialized (static) Class Table */
+  htab_t GTY ((param_is (union tree_node))) ict;
+
   tree smic;                   /* Static method invocation compound */
   tree inner_access;           /* The identifier of the access method
                                   used for invocation from inner classes */
@@ -949,16 +971,19 @@ struct lang_decl
   unsigned int strictfp : 1;
 };
 
-/* init_test_table hash table entry structure.  */
-struct init_test_hash_entry
+struct treetreehash_entry GTY(())
 {
-  struct hash_entry root;
-  tree init_test_decl;
+  tree key;
+  tree value;
 };
 
+extern tree java_treetreehash_find PARAMS ((htab_t, tree));
+extern tree * java_treetreehash_new PARAMS ((htab_t, tree));
+extern htab_t java_treetreehash_create PARAMS ((size_t size, int ggc));
+
 /* DECL_LANG_SPECIFIC for VAR_DECL, PARM_DECL and sometimes FIELD_DECL
    (access methods on outer class fields) and final fields. */
-struct lang_decl_var
+struct lang_decl_var GTY(())
 {
   int slot_number;
   int start_pc;
@@ -970,6 +995,22 @@ struct lang_decl_var
   unsigned int cif : 1;                /* True: decl is a class initialization flag */
 };
 
+/* This is what 'lang_decl' really points to.  */
+
+enum lang_decl_desc {
+  LANG_DECL_FUNC,
+  LANG_DECL_VAR
+};
+
+struct lang_decl GTY(())
+{
+  enum lang_decl_desc desc;
+  union lang_decl_u {
+    struct lang_decl_func GTY ((tag ("LANG_DECL_FUNC"))) f;
+    struct lang_decl_var GTY ((tag ("LANG_DECL_VAR"))) v;
+  } GTY ((desc ("%0.desc"))) u;
+};
+
 /* Macro to access fields in `struct lang_type'.  */
 
 #define TYPE_SIGNATURE(T) (TYPE_LANG_SPECIFIC(T)->signature)
@@ -997,11 +1038,11 @@ struct lang_decl_var
 #define TYPE_PROTECTED_INNER_CLASS(T) (TYPE_LANG_SPECIFIC(T)->poic)
 #define TYPE_STRICTFP(T) (TYPE_LANG_SPECIFIC(T)->strictfp)
 
-struct lang_type
+struct lang_type GTY(())
 {
   tree signature;
-  struct JCF *jcf;
-  struct CPool *cpool;
+  struct JCF * GTY ((skip (""))) jcf;
+  struct CPool * GTY ((skip (""))) cpool;
   tree cpool_data_ref;         /* Cached */
   tree finit_stmt_list;                /* List of statements finit$ will use */
   tree clinit_stmt_list;       /* List of statements <clinit> will use  */
@@ -1038,7 +1079,6 @@ struct lang_type
 #define JCF_u2 unsigned short
 
 extern void java_parse_file PARAMS ((int));
-extern void java_mark_tree PARAMS ((tree));
 extern bool java_mark_addressable PARAMS ((tree));
 extern tree java_type_for_mode PARAMS ((enum machine_mode, int));
 extern tree java_type_for_size PARAMS ((unsigned int, int));
@@ -1234,11 +1274,6 @@ extern void safe_layout_class PARAMS ((tree));
 
 extern tree get_boehm_type_descriptor PARAMS ((tree));
 extern bool class_has_finalize_method PARAMS ((tree));
-extern unsigned long java_hash_hash_tree_node PARAMS ((hash_table_key));
-extern bool java_hash_compare_tree_node PARAMS ((hash_table_key, 
-                                                   hash_table_key));
-extern bool attach_initialized_static_class PARAMS ((struct hash_entry *,
-                                                    PTR));
 extern void java_check_methods PARAMS ((tree));
 extern void init_jcf_parse PARAMS((void));
 extern void init_src_parse PARAMS((void));
@@ -1269,10 +1304,10 @@ struct rtx_def * java_expand_expr PARAMS ((tree, rtx, enum machine_mode,
 #define METHOD_STATIC(DECL) DECL_LANG_FLAG_2 (DECL)
 #define METHOD_FINAL(DECL) DECL_FINAL (DECL)
 #define METHOD_SYNCHRONIZED(DECL) DECL_LANG_FLAG_4 (DECL)
-#define METHOD_NATIVE(DECL) (DECL_LANG_SPECIFIC(DECL)->native)
+#define METHOD_NATIVE(DECL) (DECL_LANG_SPECIFIC(DECL)->u.f.native)
 #define METHOD_ABSTRACT(DECL) DECL_LANG_FLAG_5 (DECL)
 #define METHOD_TRANSIENT(DECL) DECL_LANG_FLAG_6 (DECL)
-#define METHOD_STRICTFP(DECL) (DECL_LANG_SPECIFIC (DECL)->strictfp)
+#define METHOD_STRICTFP(DECL) (DECL_LANG_SPECIFIC (DECL)->u.f.strictfp)
 
 #define JAVA_FILE_P(NODE) TREE_LANG_FLAG_2 (NODE)
 #define CLASS_FILE_P(NODE) TREE_LANG_FLAG_3 (NODE)
index b88270df923cad7536387e467bac9182da4c993d..af9022b9ec6b6118c0a45f634e72eeebe161494b 100644 (file)
@@ -74,7 +74,7 @@ extern struct obstack permanent_obstack;
    before static field references.  */
 extern int always_initialize_class_p;
 
-static tree parse_roots[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
+static GTY(()) tree parse_roots[3];
 
 /* The FIELD_DECL for the current field.  */
 #define current_field parse_roots[0]
@@ -1270,9 +1270,9 @@ void
 init_jcf_parse ()
 {
   /* Register roots with the garbage collector.  */
-  ggc_add_tree_root (parse_roots, ARRAY_SIZE (parse_roots));
-
   ggc_add_root (&current_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
 
   init_src_parse ();
 }
+
+#include "gt-java-jcf-parse.h"
index 491b561ed050c1b6370587c3e5acffd10634e0e5..7ddca448448fdec0af86c5f2ff69d234c9376a77 100644 (file)
@@ -2853,6 +2853,7 @@ release_jcf_state (state)
    in the .class file representation.  The list can be written to a
    .class file using write_chunks.  Allocate chunks from obstack WORK. */
 
+static GTY(()) tree SourceFile_node;
 static struct chunk *
 generate_classfile (clas, state)
      tree clas;
@@ -2866,7 +2867,6 @@ generate_classfile (clas, state)
   int fields_count = 0;
   char *methods_count_ptr;
   int methods_count = 0;
-  static tree SourceFile_node = NULL_TREE;
   tree part;
   int total_supers
     = clas == object_type_node ? 0
@@ -3154,7 +3154,6 @@ generate_classfile (clas, state)
   if (SourceFile_node == NULL_TREE) 
     {
       SourceFile_node = get_identifier ("SourceFile");
-      ggc_add_tree_root (&SourceFile_node, 1);
     }
 
   i = find_utf8_constant (&state->cpool, SourceFile_node);
@@ -3174,18 +3173,17 @@ generate_classfile (clas, state)
   return state->first;
 }
 
+static GTY(()) tree Synthetic_node;
 static unsigned char *
 append_synthetic_attribute (state)
      struct jcf_partial *state;
 {
-  static tree Synthetic_node = NULL_TREE;
   unsigned char *ptr = append_chunk (NULL, 6, state);
   int i;
 
   if (Synthetic_node == NULL_TREE)
     {
       Synthetic_node = get_identifier ("Synthetic");
-      ggc_add_tree_root (&Synthetic_node, 1);
     }
   i = find_utf8_constant (&state->cpool, Synthetic_node);
   PUT2 (i);            /* Attribute string index */
@@ -3212,12 +3210,12 @@ append_gcj_attribute (state, class)
   PUT4 (0);                    /* Attribute length */
 }
 
+static tree InnerClasses_node;
 static void
 append_innerclasses_attribute (state, class)
      struct jcf_partial *state;
      tree class;
 {
-  static tree InnerClasses_node = NULL_TREE;
   tree orig_decl = TYPE_NAME (class);
   tree current, decl;
   int length = 0, i;
@@ -3231,7 +3229,6 @@ append_innerclasses_attribute (state, class)
   if (InnerClasses_node == NULL_TREE) 
     {
       InnerClasses_node = get_identifier ("InnerClasses");
-      ggc_add_tree_root (&InnerClasses_node, 1);
     }
   i = find_utf8_constant (&state->cpool, InnerClasses_node);
   PUT2 (i);
@@ -3406,3 +3403,5 @@ write_classfile (clas)
    string concatenation
    synchronized statement
    */
+
+#include "gt-java-jcf-write.h"
index c699da3dd39e8664a318d422c7a395706cfe8a37..a0f823f75b7ac363011703ca80ef7e6ae82024c3 100644 (file)
@@ -213,6 +213,11 @@ static int dependency_tracking = 0;
 #define DEPEND_TARGET_SET 4
 #define DEPEND_FILE_ALREADY_SET 8
 
+struct language_function GTY(())
+{
+  int unused;
+};
+
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU Java"
 #undef LANG_HOOKS_INIT
@@ -225,8 +230,6 @@ static int dependency_tracking = 0;
 #define LANG_HOOKS_DECODE_OPTION java_decode_option
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE java_parse_file
-#undef LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE java_mark_tree
 #undef LANG_HOOKS_MARK_ADDRESSABLE
 #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
 #undef LANG_HOOKS_EXPAND_EXPR
@@ -694,24 +697,13 @@ lang_printable_name_wls (decl, v)
 /* Print on stderr the current class and method context.  This function
    is the value of the hook print_error_function. */
 
+static GTY(()) tree last_error_function_context;
+static GTY(()) tree last_error_function;
 static void
 java_print_error_function (context, file)
      diagnostic_context *context __attribute__((__unused__));
      const char *file;
 {
-  static tree last_error_function_context = NULL_TREE;
-  static tree last_error_function = NULL;
-  static int initialized_p;
-
-  /* Register LAST_ERROR_FUNCTION_CONTEXT and LAST_ERROR_FUNCTION with
-     the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&last_error_function_context, 1);
-      ggc_add_tree_root (&last_error_function, 1);
-      initialized_p = 1;
-    }
-
   /* Don't print error messages with bogus function prototypes.  */
   if (inhibit_error_function_printing)
     return;
@@ -770,3 +762,5 @@ java_init_options ()
   /* In Java floating point operations never trap.  */
   flag_trapping_math = 0;
 }
+
+#include "gt-java-lang.h"
index 590a9ad514357ab872acaa1ed1049299aa73e3b5..ef70ff9d2215bf3ee21121b8121b6d6ac12ddaa9 100644 (file)
@@ -245,7 +245,7 @@ mangle_type (type)
    COMPRESSION_NEXT is the index to the location of the next insertion
    of an element.  */
 
-static tree compression_table;
+static GTY(()) tree compression_table;
 static int  compression_next;
 
 /* Find a POINTER_TYPE in the compression table. Use a special
@@ -431,12 +431,12 @@ mangle_pointer_type (type)
    the template indicator where already used an compress appropriately.
    It handles pointers. */
 
+/* atms: array template mangled string. */
+static GTY(()) tree atms;
 static void
 mangle_array_type (p_type)
      tree p_type;
 {
-  /* atms: array template mangled string. */
-  static tree atms = NULL_TREE;
   tree type, elt_type;
   int match;
 
@@ -450,7 +450,6 @@ mangle_array_type (p_type)
   if (!atms)
     {
       atms = get_identifier ("6JArray");
-      ggc_add_tree_root (&atms, 1);
     }
 
   /* Maybe we have what we're looking in the compression table. */
@@ -602,9 +601,7 @@ compression_table_add (type)
       for (i = 0; i < compression_next; i++)
        TREE_VEC_ELT (new, i) = TREE_VEC_ELT (compression_table, i);
 
-      ggc_del_root (&compression_table);
       compression_table = new;
-      ggc_add_tree_root (&compression_table, 1);
     }
   TREE_VEC_ELT (compression_table, compression_next++) = type;
 }
@@ -624,9 +621,6 @@ init_mangling (obstack)
 
   /* Mangled name are to be suffixed */
   obstack_grow (mangle_obstack, "_Z", 2);
-
-  /* Register the compression table with the GC */
-  ggc_add_tree_root (&compression_table, 1);
 }
 
 /* Mangling finalization routine. The mangled name is returned as a
@@ -641,7 +635,6 @@ finish_mangling ()
     /* Mangling already finished.  */
     abort ();
 
-  ggc_del_root (&compression_table);
   compression_table = NULL_TREE;
   compression_next = 0;
   obstack_1grow (mangle_obstack, '\0');
@@ -652,3 +645,5 @@ finish_mangling ()
 #endif
   return result;
 }
+
+#include "gt-java-mangle.h"
index 197816feb1263e1e48866286fd2221f6b549b133..960bd9075da7e2d4c3fc5d5ec4d1e117b1957539 100644 (file)
@@ -66,6 +66,7 @@ definitions and other extensions.  */
 #include "function.h"
 #include "except.h"
 #include "ggc.h"
+#include "debug.h"
 
 #ifndef DIR_SEPARATOR
 #define DIR_SEPARATOR '/'
@@ -298,8 +299,7 @@ static tree maybe_make_nested_class_name PARAMS ((tree));
 static int make_nested_class_name PARAMS ((tree));
 static void set_nested_class_simple_name_value PARAMS ((tree, int));
 static void link_nested_class_to_enclosing PARAMS ((void));
-static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
-                                        tree *, tree));
+static tree resolve_inner_class PARAMS ((htab_t, tree, tree *, tree *, tree));
 static tree find_as_inner_class PARAMS ((tree, tree, tree));
 static tree find_as_inner_class_do PARAMS ((tree, tree));
 static int check_inner_class_redefinition PARAMS ((tree, tree));
@@ -334,9 +334,8 @@ static void create_new_parser_context PARAMS ((int));
 static void mark_parser_ctxt PARAMS ((void *));
 static tree maybe_build_class_init_for_field PARAMS ((tree, tree));
 
-static bool attach_init_test_initialization_flags PARAMS ((struct hash_entry *,
-                                                         PTR));
-static bool emit_test_initialization PARAMS ((struct hash_entry *, PTR));
+static int attach_init_test_initialization_flags PARAMS ((PTR *, PTR));
+static int emit_test_initialization PARAMS ((PTR *, PTR));
 
 static char *string_convert_int_cst PARAMS ((tree));
 
@@ -376,58 +375,58 @@ static const enum tree_code binop_lookup[19] =
 #define BINOP_COMPOUND_CANDIDATES 11
 
 /* The "$L" identifier we use to create labels.  */
-static tree label_id = NULL_TREE;
+static GTY(()) tree label_id;
 
 /* The "StringBuffer" identifier used for the String `+' operator. */
-static tree wfl_string_buffer = NULL_TREE
+static GTY(()) tree wfl_string_buffer
 
 /* The "append" identifier used for String `+' operator.  */
-static tree wfl_append = NULL_TREE;
+static GTY(()) tree wfl_append;
 
 /* The "toString" identifier used for String `+' operator. */
-static tree wfl_to_string = NULL_TREE;
+static GTY(()) tree wfl_to_string;
 
 /* The "java.lang" import qualified name.  */
-static tree java_lang_id = NULL_TREE;
+static GTY(()) tree java_lang_id;
 
 /* The generated `inst$' identifier used for generated enclosing
    instance/field access functions.  */
-static tree inst_id = NULL_TREE;
+static GTY(()) tree inst_id;
 
 /* The "java.lang.Cloneable" qualified name.  */
-static tree java_lang_cloneable = NULL_TREE;
+static GTY(()) tree java_lang_cloneable;
 
 /* The "java.io.Serializable" qualified name.  */
-static tree java_io_serializable = NULL_TREE
+static GTY(()) tree java_io_serializable
 
 /* Context and flag for static blocks */
-static tree current_static_block = NULL_TREE;
+static GTY(()) tree current_static_block;
 
 /* The generated `write_parm_value$' identifier.  */
-static tree wpv_id;
+static GTY(()) tree wpv_id;
 
 /* The list of all packages we've seen so far */
-static tree package_list = NULL_TREE;
+static GTY(()) tree package_list;
  
 /* Hold THIS for the scope of the current method decl.  */
-static tree current_this;
+static GTY(()) tree current_this;
 
 /* Hold a list of catch clauses list. The first element of this list is
    the list of the catch clauses of the currently analysed try block. */
-static tree currently_caught_type_list;
+static GTY(()) tree currently_caught_type_list;
 
 /* This holds a linked list of all the case labels for the current
    switch statement.  It is only used when checking to see if there
    are duplicate labels.  FIXME: probably this should just be attached
    to the switch itself; then it could be referenced via
    `ctxp->current_loop'.  */
-static tree case_label_list; 
+static GTY(()) tree case_label_list; 
 
 /* Anonymous class counter. Will be reset to 1 every time a non
    anonymous class gets created. */
 static int anonymous_class_counter = 1;
 
-static tree src_parse_roots[1];
+static GTY(()) tree src_parse_roots[1];
 
 /* All classes seen from source code */
 #define gclass_list src_parse_roots[0]
@@ -614,20 +613,6 @@ goal:
                 {
                  /* Register static variables with the garbage
                     collector.  */
-                 ggc_add_tree_root (&label_id, 1);
-                 ggc_add_tree_root (&wfl_string_buffer, 1);
-                 ggc_add_tree_root (&wfl_append, 1);
-                 ggc_add_tree_root (&wfl_to_string, 1);
-                 ggc_add_tree_root (&java_lang_id, 1);
-                 ggc_add_tree_root (&inst_id, 1);
-                 ggc_add_tree_root (&java_lang_cloneable, 1);
-                 ggc_add_tree_root (&java_io_serializable, 1);
-                 ggc_add_tree_root (&current_static_block, 1);
-                 ggc_add_tree_root (&wpv_id, 1);
-                 ggc_add_tree_root (&package_list, 1);
-                 ggc_add_tree_root (&current_this, 1);
-                 ggc_add_tree_root (&currently_caught_type_list, 1);
-                 ggc_add_tree_root (&case_label_list, 1);
                  ggc_add_root (&ctxp, 1, 
                                sizeof (struct parser_ctxt *),
                                mark_parser_ctxt);
@@ -3550,7 +3535,7 @@ check_inner_class_redefinition (raw_name, cl)
 
 static tree
 resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
-     struct hash_table *circularity_hash;
+     htab_t circularity_hash;
      tree cl, *enclosing, *super, class_type;
 {
   tree local_enclosing = *enclosing;
@@ -3560,8 +3545,8 @@ resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
     {
       tree intermediate, decl;
 
-      hash_lookup (circularity_hash, 
-                  (const  hash_table_key) local_enclosing, TRUE, NULL);
+      *htab_find_slot (circularity_hash, local_enclosing, INSERT) =
+       local_enclosing;
 
       if ((decl = find_as_inner_class (local_enclosing, class_type, cl)))
        return decl;
@@ -3589,8 +3574,7 @@ resolve_inner_class (circularity_hash, cl, enclosing, super, class_type)
 
       /* We may not have checked for circular inheritance yet, so do so
          here to prevent an infinite loop. */
-      if (hash_lookup (circularity_hash,
-                      (const hash_table_key) local_super, FALSE, NULL))
+      if (htab_find (circularity_hash, local_super) != NULL)
         {
           if (!cl)
             cl = lookup_cl (local_enclosing);
@@ -4840,32 +4824,23 @@ constructor_circularity_msg (from, to)
 /* Verify a circular call to METH. Return 1 if an error is found, 0
    otherwise.  */
 
+static GTY(()) tree vcc_list;
 static int
 verify_constructor_circularity (meth, current)
      tree meth, current;
 {
-  static tree list = NULL_TREE;
-  static int initialized_p;
   tree c;
 
-  /* If we haven't already registered LIST with the garbage collector,
-     do so now.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&list, 1);
-      initialized_p = 1;
-    }
-
   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
     {
       if (TREE_VALUE (c) == meth)
        {
          char *t;
-         if (list)
+         if (vcc_list)
            {
              tree liste;
-             list = nreverse (list);
-             for (liste = list; liste; liste = TREE_CHAIN (liste))
+             vcc_list = nreverse (vcc_list);
+             for (liste = vcc_list; liste; liste = TREE_CHAIN (liste))
                {
                  parse_error_context 
                    (TREE_PURPOSE (TREE_PURPOSE (liste)), "%s",
@@ -4879,16 +4854,16 @@ verify_constructor_circularity (meth, current)
                               "%s: recursive invocation of constructor `%s'",
                               constructor_circularity_msg (current, meth), t);
          free (t);
-         list = NULL_TREE;
+         vcc_list = NULL_TREE;
          return 1;
        }
     }
   for (c = DECL_CONSTRUCTOR_CALLS (current); c; c = TREE_CHAIN (c))
     {
-      list = tree_cons (c, current, list);
+      vcc_list = tree_cons (c, current, vcc_list);
       if (verify_constructor_circularity (meth, TREE_VALUE (c)))
        return 1;
-      list = TREE_CHAIN (list);
+      vcc_list = TREE_CHAIN (vcc_list);
     }
   return 0;
 }
@@ -5782,14 +5757,14 @@ do_resolve_class (enclosing, class_type, decl, cl)
   tree new_class_decl = NULL_TREE, super = NULL_TREE;
   tree saved_enclosing_type = enclosing ? TREE_TYPE (enclosing) : NULL_TREE;
   tree decl_result;
-  struct hash_table _ht, *circularity_hash = &_ht;
+  htab_t circularity_hash;
 
   /* This hash table is used to register the classes we're going
      through when searching the current class as an inner class, in
      order to detect circular references. Remember to free it before
      returning the section 0- of this function. */
-  hash_table_init (circularity_hash, hash_newfunc,
-                  java_hash_hash_tree_node, java_hash_compare_tree_node);
+  circularity_hash = htab_create (20, htab_hash_pointer, htab_eq_pointer, 
+                                 NULL);
 
   /* 0- Search in the current class as an inner class.
      Maybe some code here should be added to load the class or
@@ -5811,7 +5786,7 @@ do_resolve_class (enclosing, class_type, decl, cl)
        enclosing = NULL_TREE;
     }
 
-  hash_table_free (circularity_hash);
+  htab_delete (circularity_hash);
 
   if (new_class_decl)
     return new_class_decl;
@@ -6668,34 +6643,33 @@ lookup_java_method2 (clas, method_decl, do_interface)
 /* Return the line that matches DECL line number, and try its best to
    position the column number. Used during error reports.  */
 
+static GTY(()) tree cl_v;
 static tree
 lookup_cl (decl)
      tree decl;
 {
-  static tree cl = NULL_TREE;
   char *line, *found;
   
   if (!decl)
     return NULL_TREE;
 
-  if (cl == NULL_TREE)
+  if (cl_v == NULL_TREE)
     {
-      cl = build_expr_wfl (NULL_TREE, NULL, 0, 0);
-      ggc_add_tree_root (&cl, 1);
+      cl_v = build_expr_wfl (NULL_TREE, NULL, 0, 0);
     }
 
-  EXPR_WFL_FILENAME_NODE (cl) = get_identifier (DECL_SOURCE_FILE (decl));
-  EXPR_WFL_SET_LINECOL (cl, DECL_SOURCE_LINE_FIRST (decl), -1);
+  EXPR_WFL_FILENAME_NODE (cl_v) = get_identifier (DECL_SOURCE_FILE (decl));
+  EXPR_WFL_SET_LINECOL (cl_v, DECL_SOURCE_LINE_FIRST (decl), -1);
 
-  line = java_get_line_col (EXPR_WFL_FILENAME (cl), 
-                           EXPR_WFL_LINENO (cl), EXPR_WFL_COLNO (cl));
+  line = java_get_line_col (EXPR_WFL_FILENAME (cl_v), 
+                           EXPR_WFL_LINENO (cl_v), EXPR_WFL_COLNO (cl_v));
 
   found = strstr ((const char *)line, 
                  (const char *)IDENTIFIER_POINTER (DECL_NAME (decl)));
   if (found)
-    EXPR_WFL_SET_LINECOL (cl, EXPR_WFL_LINENO (cl), found - line);
+    EXPR_WFL_SET_LINECOL (cl_v, EXPR_WFL_LINENO (cl_v), found - line);
 
-  return cl;
+  return cl_v;
 }
 
 /* Look for a simple name in the single-type import list */
@@ -7044,19 +7018,17 @@ static void
 register_package (name)
      tree name;
 {
-  static struct hash_table _pht, *pht = NULL;
+  static htab_t pht;
+  PTR *e;
 
-  if (!pht)
-    {
-      hash_table_init (&_pht, hash_newfunc, 
-                      java_hash_hash_tree_node, java_hash_compare_tree_node);
-      pht = &_pht;
-    }
-  
-  if (!hash_lookup (pht, (const hash_table_key) name, FALSE, NULL))
+  if (pht == NULL)
+    pht = htab_create (50, htab_hash_pointer, htab_eq_pointer, NULL);
+
+  e = htab_find_slot (pht, name, INSERT);
+  if (*e == NULL)
     {
       package_list = chainon (package_list, build_tree_list (name, NULL));
-      hash_lookup (pht, (const hash_table_key) name, TRUE, NULL);
+      *e = name;
     }
 }
 
@@ -7559,20 +7531,12 @@ void java_layout_seen_class_methods ()
     }
 }
 
+static GTY(()) tree stop_reordering;
 void
 java_reorder_fields ()
 {
-  static tree stop_reordering = NULL_TREE;
-  static int initialized_p;
   tree current;
 
-  /* Register STOP_REORDERING with the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&stop_reordering, 1);
-      initialized_p = 1;
-    }
-
   for (current = gclass_list; current; current = TREE_CHAIN (current))
     {
       current_class = TREE_TYPE (TREE_VALUE (current));
@@ -8060,7 +8024,7 @@ java_complete_expand_method (mdecl)
       
       /* Before we check initialization, attached all class initialization
         variable to the block_body */
-      hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
+      htab_traverse (DECL_FUNCTION_INIT_TEST_TABLE (mdecl),
                     attach_init_test_initialization_flags, block_body);
       
       if (! flag_emit_xref && ! METHOD_NATIVE (mdecl))
@@ -8077,9 +8041,11 @@ java_complete_expand_method (mdecl)
                 MDECL. This used with caution helps removing extra
                 initialization of self. */
              if (METHOD_STATIC (mdecl))
-               hash_lookup (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
-                            (hash_table_key) DECL_CONTEXT (mdecl),
-                            TRUE, NULL);
+               {
+                 *(htab_find_slot 
+                   (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (mdecl),
+                    DECL_CONTEXT (mdecl), INSERT)) = DECL_CONTEXT (mdecl);
+               }
            }
        }
       ctxp->explicit_constructor_p = 0;
@@ -8147,7 +8113,7 @@ java_expand_method_bodies (class)
              /* For each class definitely initialized in
                 CALLED_METHOD, fill ASSIGNMENT_COMPOUND with
                 assignment to the class initialization flag. */
-             hash_traverse (&DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
+             htab_traverse (DECL_FUNCTION_INITIALIZED_CLASS_TABLE (called_method),
                             emit_test_initialization,
                             assignment_compound_list);
 
@@ -8635,27 +8601,19 @@ maybe_build_thisn_access_method (type)
    This function can be invoked with TYPE to NULL, available and then
    has to count the parser context.  */
 
+static GTY(()) tree saved_thisn;
+static GTY(()) tree saved_type;
+
 static tree
 build_current_thisn (type)
     tree type;
 {
   static int saved_i = -1;
-  static tree saved_thisn = NULL_TREE;
-  static tree saved_type = NULL_TREE;
   static int saved_type_i = 0;
-  static int initialized_p;
   tree decl;
   char buffer [24];
   int i = 0;
 
-  /* Register SAVED_THISN and SAVED_TYPE with the garbage collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&saved_thisn, 1);
-      ggc_add_tree_root (&saved_type, 1);
-      initialized_p = 1;
-    }
-
   if (type)
     {
       if (type == saved_type)
@@ -8712,6 +8670,9 @@ build_thisn_assign ()
         throw new NoClassDefFoundError(e.getMessage());}
     } */
 
+static GTY(()) tree get_message_wfl;
+static GTY(()) tree type_parm_wfl;
+
 static tree
 build_dot_class_method (class)
      tree class;
@@ -8721,14 +8682,10 @@ build_dot_class_method (class)
   tree args, tmp, saved_current_function_decl, mdecl;
   tree stmt, throw_stmt;
 
-  static tree get_message_wfl, type_parm_wfl;
-
   if (!get_message_wfl)
     {
       get_message_wfl = build_wfl_node (get_identifier ("getMessage"));
       type_parm_wfl = build_wfl_node (get_identifier ("type$"));
-      ggc_add_tree_root (&get_message_wfl, 1);
-      ggc_add_tree_root (&type_parm_wfl, 1);
     }
 
   /* Build the arguments */
@@ -8985,6 +8942,7 @@ verify_constructor_super (mdecl)
 
 /* Generate code for all context remembered for code generation.  */
 
+static GTY(()) tree reversed_class_list;
 void
 java_expand_classes ()
 {
@@ -9066,7 +9024,7 @@ java_expand_classes ()
   for (cur_ctxp = ctxp_for_generation; cur_ctxp; cur_ctxp = cur_ctxp->next)
     {
       tree current;
-      tree reversed_class_list = NULL;
+      reversed_class_list = NULL;
 
       ctxp = cur_ctxp;
 
@@ -9083,7 +9041,6 @@ java_expand_classes ()
           current = TREE_CHAIN (current))
        reversed_class_list
          = tree_cons (NULL_TREE, current, reversed_class_list);
-      ggc_add_tree_root (&reversed_class_list, 1);
 
       for (current = reversed_class_list; 
           current; 
@@ -9101,8 +9058,6 @@ java_expand_classes ()
              finish_class ();
            }
        }
-
-      ggc_del_root (&reversed_class_list);
     }
 }
 
@@ -10094,15 +10049,15 @@ check_deprecation (wfl, decl)
 
 /* Returns 1 if class was declared in the current package, 0 otherwise */
 
+static GTY(()) tree cicp_cache;
 static int
 class_in_current_package (class)
      tree class;
 {
-  static tree cache = NULL_TREE;
   int qualified_flag;
   tree left;
 
-  if (cache == class)
+  if (cicp_cache == class)
     return 1;
 
   qualified_flag = QUALIFIED_P (DECL_NAME (TYPE_NAME (class)));
@@ -10123,15 +10078,7 @@ class_in_current_package (class)
   breakdown_qualified (&left, NULL, DECL_NAME (TYPE_NAME (class)));
   if (ctxp->package == left)
     {
-      static int initialized_p;
-      /* Register CACHE with the garbage collector.  */
-      if (!initialized_p)
-       {
-         ggc_add_tree_root (&cache, 1);
-         initialized_p = 1;
-       }
-
-      cache = class;
+      cicp_cache = class;
       return 1;
     }
   return 0;
@@ -10939,7 +10886,7 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
      int lc;
      tree class, name, arglist;
 {
-  static struct hash_table t, *searched_classes = NULL;
+  static htab_t searched_classes;
   static int search_not_done = 0;
   tree list = NULL_TREE, all_list = NULL_TREE;
 
@@ -10947,20 +10894,17 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
      already. */
   if (searched_classes)
     {
-      if (hash_lookup (searched_classes, 
-                      (const hash_table_key) class, FALSE, NULL))
-       return NULL;
+      if (htab_find (searched_classes, class) != NULL)
+       return NULL;
     }
   else
     {
-      hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
-                      java_hash_compare_tree_node);
-      searched_classes = &t;
+      searched_classes = htab_create (10, htab_hash_pointer,
+                                     htab_eq_pointer, NULL);
     }
     
   search_not_done++;
-  hash_lookup (searched_classes, 
-              (const hash_table_key) class, TRUE, NULL);
+  *htab_find_slot (searched_classes, class, INSERT) = class;
 
   if (!CLASS_LOADED_P (class) && !CLASS_FROM_SOURCE_P (class))
     {
@@ -11040,15 +10984,13 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
     {
       if (!lc
          && TYPE_METHODS (object_type_node)
-         && !hash_lookup (searched_classes, 
-                           (const hash_table_key) object_type_node, 
-                           FALSE, NULL))
+         && htab_find (searched_classes, object_type_node) == NULL)
        {
           search_applicable_methods_list (lc, 
                                           TYPE_METHODS (object_type_node),
                                           name, arglist, &list, &all_list);
         }
-      hash_table_free (searched_classes);
+      htab_delete (searched_classes);
       searched_classes = NULL;
     }
 
@@ -11178,25 +11120,15 @@ find_most_specific_methods_list (list)
    corresponding parameter of M1. Implementation expects M2_OR_ARGLIST
    to change less often than M1. */
 
+static GTY(()) tree m2_arg_value;
+static GTY(()) tree m2_arg_cache;
+
 static int
 argument_types_convertible (m1, m2_or_arglist)
     tree m1, m2_or_arglist;
 {
-  static tree m2_arg_value = NULL_TREE;
-  static tree m2_arg_cache = NULL_TREE;
-  static int initialized_p;
-
   register tree m1_arg, m2_arg;
 
-  /* Register M2_ARG_VALUE and M2_ARG_CACHE with the garbage
-     collector.  */
-  if (!initialized_p)
-    {
-      ggc_add_tree_root (&m2_arg_value, 1);
-      ggc_add_tree_root (&m2_arg_cache, 1);
-      initialized_p = 1;
-    }
-
   SKIP_THIS_AND_ARTIFICIAL_PARMS (m1_arg, m1)
 
   if (m2_arg_value == m2_or_arglist)
@@ -16140,9 +16072,6 @@ mark_parser_ctxt (p)
 void
 init_src_parse ()
 {
-  /* Register roots with the garbage collector.  */
-  ggc_add_tree_root (src_parse_roots, ARRAY_SIZE (src_parse_roots));
-
   /* Sanity check; we've been bit by this before.  */
   if (ARRAY_SIZE (ctxp->modifier_ctx) != MODIFIER_TK - PUBLIC_TK)
     abort ();
@@ -16155,16 +16084,16 @@ init_src_parse ()
 
 /* Attach to PTR (a block) the declaration found in ENTRY. */
 
-static bool
+static int
 attach_init_test_initialization_flags (entry, ptr)
-     struct hash_entry *entry;
+     PTR *entry;
      PTR ptr;
 {
   tree block = (tree)ptr;
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry;
+  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
   
-  TREE_CHAIN (ite->init_test_decl) = BLOCK_EXPR_DECLS (block);
-  BLOCK_EXPR_DECLS (block) = ite->init_test_decl;
+  TREE_CHAIN (ite->value) = BLOCK_EXPR_DECLS (block);
+  BLOCK_EXPR_DECLS (block) = ite->value;
   return true;
 }
 
@@ -16174,28 +16103,29 @@ attach_init_test_initialization_flags (entry, ptr)
    initialized static class flags if a flag already existed, otherwise
    a new one is created.  */
 
-static bool
-emit_test_initialization (entry, info)
-     struct hash_entry *entry;
+static int
+emit_test_initialization (entry_p, info)
+     PTR *entry_p;
      PTR info;
 {
   tree l = (tree) info;
   tree decl, init;
-
-  struct init_test_hash_entry *ite = (struct init_test_hash_entry *)
-    hash_lookup (&DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl),
-                entry->key,
-                current_function_decl != TREE_PURPOSE (l), NULL);
+  tree key = (tree) *entry_p;
+  tree *ite;
+  htab_t cf_ht = DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl);
 
   /* If we haven't found a flag and we're dealing with self registered
      with current_function_decl, then don't do anything. Self is
      always added as definitely initialized but this information is
      valid only if used outside the current function. */
-  if (! ite)
+  if (current_function_decl == TREE_PURPOSE (l)
+      && java_treetreehash_find (cf_ht, key) == NULL)
     return true;
+    
+  ite = java_treetreehash_new (cf_ht, key);
 
   /* If we don't have a variable, create one and install it. */
-  if (! ite->init_test_decl)
+  if (*ite == NULL)
     {
       tree block;
       
@@ -16209,10 +16139,10 @@ emit_test_initialization (entry, info)
       block = BLOCK_SUBBLOCKS (GET_CURRENT_BLOCK (current_function_decl));
       TREE_CHAIN (decl) = BLOCK_EXPR_DECLS (block);
       BLOCK_EXPR_DECLS (block) = decl;
-      ite->init_test_decl = decl;
+      *ite = decl;
     }
   else
-    decl = ite->init_test_decl;
+    decl = *ite;
 
   /* Now simply augment the compound that holds all the assignments
      pertaining to this method invocation. */
@@ -16223,3 +16153,6 @@ emit_test_initialization (entry, info)
 
   return true;
 }
+
+#include "gt-java-parse.h"
+#include "gtype-java.h"
index 27ca72386fbbdcab2d26193dd46e251dc1453204..6715159bd53f7310ea2aa3bb662ffd8e20a5e9bd 100644 (file)
@@ -100,7 +100,6 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
 #define LANG_HOOKS_UNSAVE_EXPR_NOW     lhd_unsave_expr_now
 #define LANG_HOOKS_MAYBE_BUILD_CLEANUP lhd_return_null_tree
-#define LANG_HOOKS_MARK_TREE           lhd_do_nothing_t
 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
 #define LANG_HOOKS_HONOR_READONLY      false
 #define LANG_HOOKS_PRINT_STATISTICS    lhd_do_nothing
@@ -112,10 +111,9 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
 #define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
 
 #define LANG_HOOKS_FUNCTION_INIT       lhd_do_nothing_f
-#define LANG_HOOKS_FUNCTION_FREE       lhd_do_nothing_f
+#define LANG_HOOKS_FUNCTION_FINAL      lhd_do_nothing_f
 #define LANG_HOOKS_FUNCTION_ENTER_NESTED lhd_do_nothing_f
 #define LANG_HOOKS_FUNCTION_LEAVE_NESTED lhd_do_nothing_f
-#define LANG_HOOKS_FUNCTION_MARK       lhd_do_nothing_f
 
 /* Attribute hooks.  */
 #define LANG_HOOKS_ATTRIBUTE_TABLE             NULL
@@ -159,12 +157,11 @@ tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
   LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
 } \
 
-#define LANG_HOOKS_FUNCTION_INITIALIZER { \
-  LANG_HOOKS_FUNCTION_INIT, \
-  LANG_HOOKS_FUNCTION_FREE, \
-  LANG_HOOKS_FUNCTION_ENTER_NESTED, \
-  LANG_HOOKS_FUNCTION_LEAVE_NESTED, \
-  LANG_HOOKS_FUNCTION_MARK \
+#define LANG_HOOKS_FUNCTION_INITIALIZER {      \
+  LANG_HOOKS_FUNCTION_INIT,                    \
+  LANG_HOOKS_FUNCTION_FINAL,                   \
+  LANG_HOOKS_FUNCTION_ENTER_NESTED,            \
+  LANG_HOOKS_FUNCTION_LEAVE_NESTED             \
 }
 
 /* Tree dump hooks.  */
@@ -241,7 +238,6 @@ int lhd_tree_dump_type_quals                        PARAMS ((tree));
   LANG_HOOKS_DUP_LANG_SPECIFIC_DECL, \
   LANG_HOOKS_UNSAVE_EXPR_NOW, \
   LANG_HOOKS_MAYBE_BUILD_CLEANUP, \
-  LANG_HOOKS_MARK_TREE, \
   LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
   LANG_HOOKS_HONOR_READONLY, \
   LANG_HOOKS_PRINT_STATISTICS, \
index ffa351794068caf0b1993bc35844492ca5e89d3a..71ae251c4abaaa27f8405c4203d68956fa7295e1 100644 (file)
@@ -65,16 +65,13 @@ struct lang_hooks_for_functions
   void (*init) PARAMS ((struct function *));
 
   /* Called when leaving a function.  */
-  void (*free) PARAMS ((struct function *));
+  void (*final) PARAMS ((struct function *));
 
   /* Called when entering a nested function.  */
   void (*enter_nested) PARAMS ((struct function *));
 
   /* Called when leaving a nested function.  */
   void (*leave_nested) PARAMS ((struct function *));
-
-  /* Lang-specific function data marking for GC.  */
-  void (*mark) PARAMS ((struct function *));
 };
 
 /* The following hooks are used by tree-dump.c.  */
@@ -292,9 +289,6 @@ struct lang_hooks
      for the passed TARGET_EXPR.  Return NULL if there is none.  */
   tree (*maybe_build_cleanup) PARAMS ((tree));
 
-  /* Mark nodes held through the lang_specific hooks in the tree.  */
-  void (*mark_tree) PARAMS ((tree));
-
   /* Set the DECL_ASSEMBLER_NAME for a node.  If it is the sort of
      thing that the assembler should talk about, set
      DECL_ASSEMBLER_NAME to an appropriate IDENTIFIER_NODE.
index c3fa09e760c37bb42691ca39da42a80b0aa9bd2d..bb2aa17f3647bac0619f55bd575c245a019a2482 100644 (file)
@@ -148,7 +148,7 @@ enum libfunc_index
 
 /* SYMBOL_REF rtx's for the library functions that are called
    implicitly and not via optabs.  */
-extern rtx libfunc_table[LTI_MAX];
+extern GTY(()) rtx libfunc_table[LTI_MAX];
 
 /* Accessor macros for libfunc_table.  */
 #define extendsfdf2_libfunc    (libfunc_table[LTI_extendsfdf2])
index 88abc545ba1951ea48539bef5f94a863392b34e1..b57b138010d724b7ab8b62dea8ee16752a59fc74 100644 (file)
@@ -26,15 +26,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "ggc.h"
 
 static void free_list PARAMS ((rtx *, rtx *));
-static void zap_lists PARAMS ((void *));
 
 /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs.  */
 
 /* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
-static rtx unused_insn_list;
+static GTY ((deletable (""))) rtx unused_insn_list;
 
 /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
-static rtx unused_expr_list;
+static GTY ((deletable (""))) rtx unused_expr_list;
 
 
 /* This function will free an entire list of either EXPR_LIST or INSN_LIST
@@ -108,22 +107,6 @@ alloc_EXPR_LIST (kind, val, next)
   return r;
 }
 
-/* This function will initialize the EXPR_LIST and INSN_LIST caches.  */
-
-static void
-zap_lists (dummy)
-     void *dummy ATTRIBUTE_UNUSED;
-{
-  unused_expr_list = NULL;
-  unused_insn_list = NULL;
-}
-
-void
-init_EXPR_INSN_LIST_cache ()
-{
-  ggc_add_root (&unused_expr_list, 1, 1, zap_lists);
-}
-
 /* This function will free up an entire list of EXPR_LIST nodes.  */
 void
 free_EXPR_LIST_list (listp)
@@ -161,3 +144,5 @@ free_INSN_LIST_node (ptr)
   XEXP (ptr, 1) = unused_insn_list;
   unused_insn_list = ptr;
 }
+
+#include "gt-lists.h"
index f0d97ec8c628898d477f9353eb7d0e0ec3a59385..5b86b79f8b940d9c12da5cb2573ab9fc49e4a453 100644 (file)
@@ -50,6 +50,7 @@ typedef struct rtvec_def *rtvec;
 union tree_node;
 typedef union tree_node *tree;
 #endif
+#define GTY(x)
 EOF
         ;;
 esac
index da26dba52b3f46be2a591ad5dcd33840873ceb8c..86b3dabc08424334ecba7dae4e575c596dc56520 100644 (file)
@@ -93,10 +93,12 @@ objc-act.o : $(srcdir)/objc/objc-act.c \
    $(C_COMMON_H) $(srcdir)/c-tree.h \
    $(srcdir)/toplev.h $(srcdir)/flags.h $(srcdir)/objc/objc-act.h \
    $(srcdir)/input.h $(srcdir)/function.h $(srcdir)/output.h $(srcdir)/debug.h \
-   $(srcdir)/langhooks.h $(LANGHOOKS_DEF_H)
+   $(srcdir)/langhooks.h $(LANGHOOKS_DEF_H) gtype-objc.h
        $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
        -c $(srcdir)/objc/objc-act.c
 
+gtype-objc.h : s-gtype ; @true
+
 #\f
 # Build hooks:
 
index 57066a4877bcf28db2183c4564f083751230bef8..62ff455f3d172c0625acd58462dc4cbed59f954b 100644 (file)
@@ -32,3 +32,5 @@ compilers="cc1obj\$(exeext)"
 stagestuff=""
 
 target_libs=target-libobjc
+
+gtfiles="\$(srcdir)/objc/objc-act.h"
index 132c28e8e07cc79dfc9c2e91ce5777b6b8b467e7..2835f835b30a521ffbb197f70c23f76943dc6281 100644 (file)
@@ -294,9 +294,6 @@ static void generate_classref_translation_entry     PARAMS ((tree));
 static void handle_class_ref                   PARAMS ((tree));
 static void generate_struct_by_value_array     PARAMS ((void))
      ATTRIBUTE_NORETURN;
-static void objc_act_parse_init                        PARAMS ((void));
-static void ggc_mark_imp_list                  PARAMS ((void *));
-static void ggc_mark_hash_table                        PARAMS ((void *));
 
 /*** Private Interface (data) ***/
 
@@ -516,8 +513,6 @@ objc_init (filename)
   if (print_struct_values)
     generate_struct_by_value_array ();
 
-  objc_act_parse_init ();
-
   return filename;
 }
 
@@ -1234,8 +1229,6 @@ build_objc_string_object (strings)
        VARRAY_PUSH_TREE (vstrings, strings);
 
       string = combine_strings (vstrings);
-
-      VARRAY_FREE (vstrings);
     }
   else
     string = strings;
@@ -5279,8 +5272,8 @@ hash_func (sel_name)
 static void
 hash_init ()
 {
-  nst_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
-  cls_method_hash_list = (hash *) xcalloc (SIZEHASHTABLE, sizeof (hash));
+  nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
+  cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
 }
 
 /* WARNING!!!!  hash_enter is called with a method, and will peek
@@ -5293,18 +5286,10 @@ hash_enter (hashlist, method)
      hash *hashlist;
      tree method;
 {
-  static hash  hash_alloc_list = 0;
-  static int   hash_alloc_index = 0;
   hash obj;
   int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
 
-  if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE)
-    {
-      hash_alloc_index = 0;
-      hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry)
-                                       * HASH_ALLOC_LIST_SIZE);
-    }
-  obj = &hash_alloc_list[hash_alloc_index++];
+  obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
   obj->list = 0;
   obj->next = hashlist[slot];
   obj->key = method;
@@ -5336,17 +5321,9 @@ hash_add_attr (entry, value)
      hash entry;
      tree value;
 {
-  static attr  attr_alloc_list = 0;
-  static int   attr_alloc_index = 0;
   attr obj;
 
-  if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE)
-    {
-      attr_alloc_index = 0;
-      attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute)
-                                       * ATTR_ALLOC_LIST_SIZE);
-    }
-  obj = &attr_alloc_list[attr_alloc_index++];
+  obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
   obj->next = entry->list;
   obj->value = value;
 
@@ -6147,7 +6124,7 @@ continue_class (class)
       if (!objc_class_template)
        build_class_template ();
 
-      imp_entry = (struct imp_entry *) xmalloc (sizeof (struct imp_entry));
+      imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
 
       imp_entry->next = imp_list;
       imp_entry->imp_context = class;
@@ -8319,51 +8296,6 @@ handle_impent (impent)
     }
 }
 \f
-static void
-ggc_mark_imp_list (arg)
-     void *arg;
-{
-  struct imp_entry *impent;
-
-  for (impent = *(struct imp_entry **)arg; impent; impent = impent->next)
-    {
-      ggc_mark_tree (impent->imp_context);
-      ggc_mark_tree (impent->imp_template);
-      ggc_mark_tree (impent->class_decl);
-      ggc_mark_tree (impent->meta_decl);
-    }
-}
-
-static void
-ggc_mark_hash_table (arg)
-     void *arg;
-{
-  hash *hash_table = *(hash **)arg;
-  hash hst;
-  attr list;
-  int i;
-
-  if (hash_table == NULL)
-    return;
-  for (i = 0; i < SIZEHASHTABLE; i++)
-    for (hst = hash_table [i]; hst; hst = hst->next)
-      {
-       ggc_mark_tree (hst->key);
-       for (list = hst->list; list; list = list->next)
-         ggc_mark_tree (list->value);
-      }
-}
-
-/* Add GC roots for variables local to this file.  */
-static void
-objc_act_parse_init ()
-{
-  ggc_add_tree_root (objc_global_trees, OCTI_MAX);
-  ggc_add_root (&imp_list, 1, sizeof imp_list, ggc_mark_imp_list);
-  ggc_add_root (&nst_method_hash_list, 1, sizeof nst_method_hash_list, ggc_mark_hash_table);
-  ggc_add_root (&cls_method_hash_list, 1, sizeof cls_method_hash_list, ggc_mark_hash_table);
-}
-
 /* Look up ID as an instance variable.  */
 tree
 lookup_objc_ivar (id)
@@ -8384,3 +8316,5 @@ lookup_objc_ivar (id)
   else
     return 0;
 }
+
+#include "gtype-objc.h"
index b4917f7a9e46186e9c3c1f16ee2117d8b69bd8d5..17e5bd58c4d2b558892094e78e06c042768fad26 100644 (file)
@@ -133,28 +133,26 @@ enum objc_tree_code {
 typedef struct hashed_entry    *hash;
 typedef struct hashed_attribute        *attr;
 
-struct hashed_attribute
+struct hashed_attribute GTY(())
 {
   attr next;
   tree value;
 };
-struct hashed_entry
+struct hashed_entry GTY(())
 {
   attr list;
   hash next;
   tree key;
 };
 
-extern hash *nst_method_hash_list;
-extern hash *cls_method_hash_list;
+extern GTY ((length ("SIZEHASHTABLE"))) hash *nst_method_hash_list;
+extern GTY ((length ("SIZEHASHTABLE"))) hash *cls_method_hash_list;
 
-#define HASH_ALLOC_LIST_SIZE   170
-#define ATTR_ALLOC_LIST_SIZE   170
 #define SIZEHASHTABLE          257
 
 /* Objective-C/Objective-C++ @implementation list.  */
 
-struct imp_entry
+struct imp_entry GTY(())
 {
   struct imp_entry *next;
   tree imp_context;
@@ -163,7 +161,7 @@ struct imp_entry
   tree meta_decl;              /* _OBJC_METACLASS_<my_name>; */
 };
 
-extern struct imp_entry *imp_list;
+extern GTY(()) struct imp_entry *imp_list;
 extern int imp_count;  /* `@implementation' */
 extern int cat_count;  /* `@category' */
 
@@ -248,7 +246,7 @@ enum objc_tree_index
     OCTI_MAX
 };
 
-extern tree objc_global_trees[OCTI_MAX];
+extern GTY(()) tree objc_global_trees[OCTI_MAX];
 
 /* List of classes with list of their static instances.  */
 #define objc_static_instances  objc_global_trees[OCTI_STATIC_NST]
index 647baf3e329dc53cd424e5d0246bc26e6fb22849..f5b74486750a3761dafe6657fa47934ec6a051a9 100644 (file)
@@ -45,8 +45,6 @@ static void objc_init_options                   PARAMS ((void));
 #define LANG_HOOKS_POST_OPTIONS c_common_post_options
 #undef LANG_HOOKS_PARSE_FILE
 #define LANG_HOOKS_PARSE_FILE c_common_parse_file
-#undef LANG_HOOKS_MARK_TREE
-#define LANG_HOOKS_MARK_TREE c_mark_tree
 #undef LANG_HOOKS_EXPAND_EXPR
 #define LANG_HOOKS_EXPAND_EXPR c_expand_expr
 #undef LANG_HOOKS_MARK_ADDRESSABLE
@@ -74,8 +72,6 @@ static void objc_init_options                   PARAMS ((void));
 #define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
 #undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
 #define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
-#undef LANG_HOOKS_FUNCTION_MARK
-#define LANG_HOOKS_FUNCTION_MARK c_mark_function_context
 
 /* Attribute hooks.  */
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
index da72ffddac9750eb382eca634c47803506c689ef..2b366ad61f0aac3db6bc3b05259a2d74b852e33f 100644 (file)
@@ -1208,7 +1208,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
       && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
     {
-      int i;
+      unsigned int i;
       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
       int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
       rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
@@ -1296,7 +1296,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
          carry_in = carry_out;
        }       
 
-      if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
+      if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
        {
          if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
            {
@@ -4733,7 +4733,7 @@ static optab
 new_optab ()
 {
   int i;
-  optab op = (optab) xmalloc (sizeof (struct optab));
+  optab op = (optab) ggc_alloc (sizeof (struct optab));
   for (i = 0; i < NUM_MACHINE_MODES; i++)
     {
       op->handlers[i].insn_code = CODE_FOR_nothing;
@@ -4865,19 +4865,6 @@ init_one_libfunc (name)
   return XEXP (DECL_RTL (decl), 0);
 }
 
-/* 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.  */
 
@@ -5228,18 +5215,15 @@ init_optabs ()
   /* 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);
 }
 \f
+static GTY(()) rtx trap_rtx;
+
 #ifdef HAVE_conditional_trap
 /* The insn generating function can not take an rtx_code argument.
    TRAP_RTX is used as an rtx argument.  Its code is replaced with
    the code to be used in the trap insn and all other fields are
    ignored.  */
-static rtx trap_rtx;
 
 static void
 init_traps ()
@@ -5247,7 +5231,6 @@ init_traps ()
   if (HAVE_conditional_trap)
     {
       trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-      ggc_add_rtx_root (&trap_rtx, 1);
     }
 }
 #endif
@@ -5286,3 +5269,5 @@ gen_cond_trap (code, op1, op2, tcode)
 
   return 0;
 }
+
+#include "gt-optabs.h"
index 0c488b8bc5a37c6fa91ef5b033aede69ed08d392..08dbec1e80a4b2c34b333de43e2ec4f31fde417d 100644 (file)
@@ -38,14 +38,15 @@ Boston, MA 02111-1307, USA.  */
    A few optabs, such as move_optab and cmp_optab, are used
    by special code.  */
 
-typedef struct optab
+struct optab GTY(())
 {
   enum rtx_code code;
-  struct {
+  struct optab_handlers {
     enum insn_code insn_code;
     rtx libfunc;
   } handlers [NUM_MACHINE_MODES];
-} * optab;
+};
+typedef struct optab * optab;
 
 /* Given an enum insn_code, access the function to construct
    the body of that kind of insn.  */
@@ -152,7 +153,7 @@ enum optab_index
   OTI_MAX
 };
 
-extern optab optab_table[OTI_MAX];
+extern GTY(()) optab optab_table[OTI_MAX];
 
 #define add_optab (optab_table[OTI_add])
 #define sub_optab (optab_table[OTI_sub])
index 35229c3cf5db9130aab1fec1590a74c60d440161..53ed810972709c25e9eac1673ce588fdb0cd12c5 100644 (file)
@@ -349,7 +349,7 @@ extern bool assemble_integer                PARAMS ((rtx, unsigned, unsigned, int));
 #define assemble_aligned_integer(SIZE, VALUE) \
   assemble_integer (VALUE, SIZE, (SIZE) * BITS_PER_UNIT, 1)
 
-#ifdef REAL_VALUE_TYPE
+#ifdef REAL_VALUE_TYPE_SIZE
 /* Assemble the floating-point constant D into an object of size MODE.  */
 extern void assemble_real              PARAMS ((REAL_VALUE_TYPE,
                                                 enum machine_mode,
index 8f7d5ef97a60aa8807857f65335de61139746a4f..8470a1d2aab8eecb66f8a6a5fdcabe32b32b5f6a 100644 (file)
@@ -1258,7 +1258,7 @@ end_branch_prob ()
 \f
 /* The label used by the edge profiling code.  */
 
-static rtx profiler_label;
+static GTY(()) rtx profiler_label;
 
 /* Initialize the profiler_label.  */
 
@@ -1269,7 +1269,6 @@ init_edge_profiler ()
   char buf[20];
   ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
   profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
-  ggc_add_rtx_root (&profiler_label, 1);
 }
 
 /* Output instructions as RTL to increment the edge execution count.  */
@@ -1386,3 +1385,5 @@ output_func_start_profiler ()
     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
                                     DEFAULT_INIT_PRIORITY);
 }
+
+#include "gt-profile.h"
index 143261eff81c3aca15426d9ef8d1126f03b30fc2..174d2c46abff1d6e64b0e593114231196f54ad2b 100644 (file)
@@ -89,7 +89,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define REAL_WIDTH \
   (REAL_VALUE_TYPE_SIZE/HOST_BITS_PER_WIDE_INT \
    + (REAL_VALUE_TYPE_SIZE%HOST_BITS_PER_WIDE_INT ? 1 : 0)) /* round up */
-struct realvaluetype {
+struct realvaluetype GTY(()) {
   HOST_WIDE_INT r[REAL_WIDTH];
 };
 /* Various headers condition prototypes on #ifdef REAL_VALUE_TYPE, so it needs
index a938b7d712344ef142321883c0f21073704393ba..90a3cbf002897a937d59df86338a83bcfe796016 100644 (file)
 #include "basic-block.h"
 #include "varray.h"
 #include "reload.h"
+#include "ggc.h"
+
+/* We use this array to cache info about insns, because otherwise we
+   spend too much time in stack_regs_mentioned_p.
+
+   Indexed by insn UIDs.  A value of zero is uninitialized, one indicates
+   the insn uses stack registers, two indicates the insn does not use
+   stack registers.  */
+static GTY(()) varray_type stack_regs_mentioned_data;
 
 #ifdef STACK_REGS
 
@@ -210,14 +219,6 @@ enum emit_where
   EMIT_BEFORE
 };
 
-/* We use this array to cache info about insns, because otherwise we
-   spend too much time in stack_regs_mentioned_p.
-
-   Indexed by insn UIDs.  A value of zero is uninitialized, one indicates
-   the insn uses stack registers, two indicates the insn does not use
-   stack registers.  */
-static varray_type stack_regs_mentioned_data;
-
 /* The block we're currently working on.  */
 static basic_block current_block;
 
@@ -423,11 +424,7 @@ reg_to_stack (first, file)
   int max_uid;
 
   /* Clean up previous run.  */
-  if (stack_regs_mentioned_data)
-    {
-      VARRAY_FREE (stack_regs_mentioned_data);
-      stack_regs_mentioned_data = 0;
-    }
+  stack_regs_mentioned_data = 0;
 
   if (!optimize)
     split_all_insns (0);
@@ -2862,3 +2859,5 @@ convert_regs (file)
   return inserted;
 }
 #endif /* STACK_REGS */
+
+#include "gt-reg-stack.h"
index 57672baf3c4d867e9754b0fdf236526f02dc9aad..84c7ba330bbe058af3745232c2951c956aac04d2 100644 (file)
@@ -242,13 +242,9 @@ static regset reg_changes_mode;
 
 #endif /* CLASS_CANNOT_CHANGE_MODE */
 
-#ifdef HAVE_SECONDARY_RELOADS
-
 /* Sample MEM values for use by memory_move_secondary_cost.  */
 
-static rtx top_of_stack[MAX_MACHINE_MODE];
-
-#endif /* HAVE_SECONDARY_RELOADS */
+static GTY(()) rtx top_of_stack[MAX_MACHINE_MODE];
 
 /* Linked list of reg_info structures allocated for reg_n_info array.
    Grouping all of the allocated structures together in one lump
@@ -614,7 +610,6 @@ init_regs ()
 
     for (i = 0; i < MAX_MACHINE_MODE; i++)
       top_of_stack[i] = gen_rtx_MEM (i, stack_pointer_rtx);
-    ggc_add_rtx_root (top_of_stack, MAX_MACHINE_MODE);
   }
 #endif
 }
@@ -2598,3 +2593,5 @@ regset_release_memory ()
 {
   bitmap_release_memory ();
 }
+
+#include "gt-regclass.h"
index ff7f1c0d5aa3bafd5e9a0c9516ec57690d2f11a7..35e1f2fc5289e3eba4ce4ca9694ddbedd983e9ef 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -89,7 +89,7 @@ typedef struct
    so MEMs that the same attributes share a data structure.  This means
    they cannot be modified in place.  If any element is nonzero, it means
    the value of the corresponding attribute is unknown.  */
-typedef struct
+typedef struct mem_attrs GTY(())
 {
   HOST_WIDE_INT alias;         /* Memory alias set.  */
   tree expr;                   /* expr corresponding to MEM.  */
@@ -212,9 +212,9 @@ struct rtx_def
    for a variable number of things.  The principle use is inside
    PARALLEL expressions.  */
 
-struct rtvec_def {
+struct rtvec_def GTY(()) {
   int num_elem;                /* number of elements */
-  rtx elem[1];
+  rtx GTY ((length ("%h.num_elem"))) elem[1];
 };
 
 #define NULL_RTVEC (rtvec) 0
@@ -1677,7 +1677,9 @@ extern bool keep_with_call_p              PARAMS ((rtx));
 /* flow.c */
 
 extern rtx find_use_as_address         PARAMS ((rtx, rtx, HOST_WIDE_INT));
-void init_EXPR_INSN_LIST_cache         PARAMS ((void));
+
+/* lists.c */
+
 void free_EXPR_LIST_list               PARAMS ((rtx *));
 void free_INSN_LIST_list               PARAMS ((rtx *));
 void free_EXPR_LIST_node               PARAMS ((rtx));
@@ -1711,15 +1713,15 @@ extern void split_all_insns             PARAMS ((int));
 extern void split_all_insns_noflow     PARAMS ((void));
 
 #define MAX_SAVED_CONST_INT 64
-extern rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
+extern GTY(()) rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
 
 #define const0_rtx     (const_int_rtx[MAX_SAVED_CONST_INT])
 #define const1_rtx     (const_int_rtx[MAX_SAVED_CONST_INT+1])
 #define const2_rtx     (const_int_rtx[MAX_SAVED_CONST_INT+2])
 #define constm1_rtx    (const_int_rtx[MAX_SAVED_CONST_INT-1])
-extern rtx const_true_rtx;
+extern GTY(()) rtx const_true_rtx;
 
-extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
+extern GTY(()) rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
 
 /* Returns a constant 0 rtx in mode MODE.  Integer modes are treated the
    same as VOIDmode.  */
@@ -1776,7 +1778,7 @@ enum global_rtl_index
 };
 
 /* Pointers to standard pieces of rtx are stored here.  */
-extern rtx global_rtl[GR_MAX];
+extern GTY(()) rtx global_rtl[GR_MAX];
 
 /* Standard pieces of rtx, to be substituted directly into things.  */
 #define pc_rtx                  (global_rtl[GR_PC])
@@ -1790,12 +1792,12 @@ extern rtx global_rtl[GR_MAX];
 #define hard_frame_pointer_rtx (global_rtl[GR_HARD_FRAME_POINTER])
 #define arg_pointer_rtx                (global_rtl[GR_ARG_POINTER])
 
-extern rtx pic_offset_table_rtx;
-extern rtx struct_value_rtx;
-extern rtx struct_value_incoming_rtx;
-extern rtx static_chain_rtx;
-extern rtx static_chain_incoming_rtx;
-extern rtx return_address_pointer_rtx;
+extern GTY(()) rtx pic_offset_table_rtx;
+extern GTY(()) rtx struct_value_rtx;
+extern GTY(()) rtx struct_value_incoming_rtx;
+extern GTY(()) rtx static_chain_rtx;
+extern GTY(()) rtx static_chain_incoming_rtx;
+extern GTY(()) rtx return_address_pointer_rtx;
 
 /* Include the RTL generation functions.  */
 
@@ -2278,7 +2280,7 @@ extern int stack_regs_mentioned           PARAMS ((rtx insn));
 #endif
 
 /* In toplev.c */
-extern rtx stack_limit_rtx;
+extern GTY(()) rtx stack_limit_rtx;
 
 /* In regrename.c */
 extern void regrename_optimize         PARAMS ((void));
index 08d8abe455c44e1b6e20f1c53bce3605c05e0895..0ec5abb5631cb3b8a16caacd35e60ddc262bf912 100644 (file)
@@ -42,11 +42,15 @@ AT&T C compiler.  From the example below I would conclude the following:
 */
 
 #include "config.h"
+#include "system.h"
+#include "debug.h"
+#include "tree.h"
+#include "ggc.h"
+
+static GTY(()) tree anonymous_types;
 
 #ifdef SDB_DEBUGGING_INFO
 
-#include "system.h"
-#include "tree.h"
 #include "rtl.h"
 #include "regs.h"
 #include "flags.h"
@@ -54,10 +58,8 @@ AT&T C compiler.  From the example below I would conclude the following:
 #include "reload.h"
 #include "output.h"
 #include "toplev.h"
-#include "ggc.h"
 #include "tm_p.h"
 #include "gsyms.h"
-#include "debug.h"
 #include "langhooks.h"
 
 /* 1 if PARM is passed to this function in memory.  */
@@ -989,8 +991,6 @@ sdbout_toplevel_data (decl)
 
 /* Machinery to record and output anonymous types.  */
 
-static tree anonymous_types;
-
 static void
 sdbout_queue_anonymous_type (type)
      tree type;
@@ -1759,11 +1759,14 @@ sdbout_init (input_file_name)
     if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0
        && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
       sdbout_symbol (t, 0);
-#endif
-
-#ifdef SDB_ALLOW_FORWARD_REFERENCES
-  ggc_add_tree_root (&anonymous_types, 1);
-#endif
+#endif  
 }
 
+#else  /* SDB_DEBUGGING_INFO */
+
+/* This should never be used, but its address is needed for comparisons.  */
+const struct gcc_debug_hooks sdb_debug_hooks;
+
 #endif /* SDB_DEBUGGING_INFO */
+
+#include "gt-sdbout.h"
index 148a3153d77943b9119d58856628d220e9928277..4f89941fa8599c448fbe3251a20f060f992364f8 100644 (file)
@@ -734,7 +734,6 @@ ssa_eliminate_dead_code ()
     RESURRECT_INSN (insn);
   if (VARRAY_ACTIVE_SIZE (unprocessed_instructions) != 0)
     abort ();
-  VARRAY_FREE (unprocessed_instructions);
   control_dependent_block_to_edge_map_free (cdbte);
   free ((PTR) pdom);
   free_edge_list (el);
index b81a8ac78312200051f177d4dac0ec3baabc40f9..4c989d764e404e8e1c42da18cc066ceea96575bf 100644 (file)
--- a/gcc/ssa.c
+++ b/gcc/ssa.c
@@ -2220,7 +2220,7 @@ convert_from_ssa ()
   count_or_remove_death_notes (NULL, 1);
 
   /* Deallocate the data structures.  */
-  VARRAY_FREE (ssa_definition);
+  ssa_definition = 0;
   ssa_rename_from_free ();
 }
 
index a0fc1377681073f36b948ca707eb38aa0c215fbd..cbea11c3d5cccbf3d50ee50e6c813f1c5050fb3c 100644 (file)
--- a/gcc/ssa.h
+++ b/gcc/ssa.h
@@ -44,7 +44,7 @@ extern void ssa_const_prop            PARAMS ((void));
 extern int in_ssa_form;
 
 /* Element I is the single instruction that sets register I.  */
-extern varray_type ssa_definition;
+extern GTY(()) varray_type ssa_definition;
 
 /* Element I is an INSN_LIST of instructions that use register I.  */
 extern varray_type ssa_uses;
index cbe2da0b9607793558809592dfedb79fc2c7301e..4994fe21c3b40ef046fadff2035101b523c652c4 100644 (file)
@@ -56,10 +56,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "langhooks.h"
 #include "predict.h"
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-struct obstack stmt_obstack;
-
 /* Assume that case vectors are not pc-relative.  */
 #ifndef CASE_VECTOR_PC_RELATIVE
 #define CASE_VECTOR_PC_RELATIVE 0
@@ -89,7 +85,7 @@ struct obstack stmt_obstack;
    and nodes on the right having higher values.  We then output the tree
    in order.  */
 
-struct case_node
+struct case_node GTY(())
 {
   struct case_node     *left;  /* Left son in binary tree */
   struct case_node     *right; /* Right son in binary tree; also node chain */
@@ -139,16 +135,22 @@ static int cost_table_initialized;
    The construct is visible if the `exit_label' field is non-null.
    In that case, the value should be a CODE_LABEL rtx.  */
 
-struct nesting
+struct nesting GTY(())
 {
   struct nesting *all;
   struct nesting *next;
   int depth;
   rtx exit_label;
-  union
+  enum nesting_desc {
+    COND_NESTING,
+    LOOP_NESTING,
+    BLOCK_NESTING,
+    CASE_NESTING
+  } desc;
+  union nesting_u
     {
       /* For conds (if-then and if-then-else statements).  */
-      struct
+      struct nesting_cond
        {
          /* Label for the end of the if construct.
             There is none if EXITFLAG was not set
@@ -157,9 +159,9 @@ struct nesting
          /* Label for the end of this alternative.
             This may be the end of the if or the next else/elseif.  */
          rtx next_label;
-       } cond;
+       } GTY ((tag ("COND_NESTING"))) cond;
       /* For loops.  */
-      struct
+      struct nesting_loop
        {
          /* Label at the top of the loop; place to loop back to.  */
          rtx start_label;
@@ -171,9 +173,9 @@ struct nesting
          /* Label for `continue' statement to jump to;
             this is in front of the stepper of the loop.  */
          rtx continue_label;
-       } loop;
+       } GTY ((tag ("LOOP_NESTING"))) loop;
       /* For variable binding contours.  */
-      struct
+      struct nesting_block
        {
          /* Sequence number of this binding contour within the function,
             in order of entry.  */
@@ -223,14 +225,10 @@ struct nesting
             the start of the last unconditional cleanup, and before any
             conditional branch points.  */
          rtx last_unconditional_cleanup;
-         /* When in a conditional context, this is the specific
-            cleanup list associated with last_unconditional_cleanup,
-            where we place the conditionalized cleanups.  */
-         tree *cleanup_ptr;
-       } block;
+       } GTY ((tag ("BLOCK_NESTING"))) block;
       /* For switch (C) or case (Pascal) statements,
         and also for dummies (see `expand_start_case_dummy').  */
-      struct
+      struct nesting_case
        {
          /* The insn after which the case dispatch should finally
             be emitted.  Zero for a dummy.  */
@@ -251,14 +249,14 @@ struct nesting
             We set this to -1 when we see the first case label in this
             case statement.  */
          int line_number_status;
-       } case_stmt;
-    } data;
+       } GTY ((tag ("CASE_NESTING"))) case_stmt;
+    } GTY ((desc ("%1.desc"))) data;
 };
 
 /* Allocate and return a new `struct nesting'.  */
 
 #define ALLOC_NESTING() \
- (struct nesting *) obstack_alloc (&stmt_obstack, sizeof (struct nesting))
+ (struct nesting *) ggc_alloc (sizeof (struct nesting))
 
 /* Pop the nesting stack element by element until we pop off
    the element which is at the top of STACK.
@@ -280,8 +278,7 @@ do { struct nesting *target = STACK;                        \
          if (case_stack == this)                       \
            case_stack = case_stack->next;              \
          nesting_depth = nesting_stack->depth - 1;     \
-         nesting_stack = this->all;                    \
-         obstack_free (&stmt_obstack, this); }         \
+         nesting_stack = this->all; }                  \
      while (this != target); } while (0)
 \f
 /* In some cases it is impossible to generate code for a forward goto
@@ -292,7 +289,7 @@ do { struct nesting *target = STACK;                        \
    we check each fixup.
    If the target label has now been defined, we can insert the proper code.  */
 
-struct goto_fixup
+struct goto_fixup GTY(())
 {
   /* Points to following fixup.  */
   struct goto_fixup *next;
@@ -326,36 +323,36 @@ struct goto_fixup
 /* Within any binding contour that must restore a stack level,
    all labels are recorded with a chain of these structures.  */
 
-struct label_chain
+struct label_chain GTY(())
 {
   /* Points to following fixup.  */
   struct label_chain *next;
   tree label;
 };
 
-struct stmt_status
+struct stmt_status GTY(())
 {
   /* Chain of all pending binding contours.  */
-  struct nesting *x_block_stack;
+  struct nesting * x_block_stack;
 
   /* If any new stacks are added here, add them to POPSTACKS too.  */
 
   /* Chain of all pending binding contours that restore stack levels
      or have cleanups.  */
-  struct nesting *x_stack_block_stack;
+  struct nesting * x_stack_block_stack;
 
   /* Chain of all pending conditional statements.  */
-  struct nesting *x_cond_stack;
+  struct nesting * x_cond_stack;
 
   /* Chain of all pending loops.  */
-  struct nesting *x_loop_stack;
+  struct nesting * x_loop_stack;
 
   /* Chain of all pending case or switch statements.  */
-  struct nesting *x_case_stack;
+  struct nesting * x_case_stack;
 
   /* Separate chain including all of the above,
      chained through the `all' field.  */
-  struct nesting *x_nesting_stack;
+  struct nesting * x_nesting_stack;
 
   /* Number of entries on nesting_stack now.  */
   int x_nesting_depth;
@@ -431,13 +428,6 @@ static int node_is_bounded         PARAMS ((case_node_ptr, tree));
 static void emit_jump_if_reachable     PARAMS ((rtx));
 static void emit_case_nodes            PARAMS ((rtx, case_node_ptr, rtx, tree));
 static struct case_node *case_tree2list        PARAMS ((case_node *, case_node *));
-static void mark_cond_nesting           PARAMS ((struct nesting *));
-static void mark_loop_nesting           PARAMS ((struct nesting *));
-static void mark_block_nesting          PARAMS ((struct nesting *));
-static void mark_case_nesting           PARAMS ((struct nesting *));
-static void mark_case_node             PARAMS ((struct case_node *));
-static void mark_goto_fixup             PARAMS ((struct goto_fixup *));
-static void free_case_nodes             PARAMS ((case_node_ptr));
 \f
 void
 using_eh_for_cleanups ()
@@ -445,176 +435,10 @@ 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 (l);
-         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)
-    {
-      ggc_mark_rtx (n->exit_label);
-      ggc_mark_rtx (n->data.case_stmt.start);
-
-      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);
-
-      mark_case_node (n->data.case_stmt.case_list);
-      n = n->next;
-    }
-}
-
-/* Mark C for GC.  */
-
-static void
-mark_case_node (c)
-     struct case_node *c;
-{
-  if (c != 0)
-    {
-      ggc_mark_tree (c->low);
-      ggc_mark_tree (c->high);
-      ggc_mark_tree (c->code_label);
-
-      mark_case_node (c->right);
-      mark_case_node (c->left);
-    }
-}
-
-/* Mark G for GC.  */
-
-static void
-mark_goto_fixup (g)
-     struct goto_fixup *g;
-{
-  while (g)
-    {
-      ggc_mark (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;
-    }
-}
-
-/* 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.  */
-
-void
-free_stmt_status (f)
-     struct function *f;
-{
-  /* 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.  */
-  if (f->stmt)
-    free (f->stmt);
-  f->stmt = NULL;
-}
-
-/* Mark P for GC.  */
-
-void
-mark_stmt_status (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
-init_stmt ()
-{
-  gcc_obstack_init (&stmt_obstack);
-}
-
 void
 init_stmt_for_function ()
 {
-  cfun->stmt = (struct stmt_status *) xmalloc (sizeof (struct stmt_status));
+  cfun->stmt = ((struct stmt_status *)ggc_alloc (sizeof (struct stmt_status)));
 
   /* We are not currently within any block, conditional, loop or case.  */
   block_stack = 0;
@@ -632,8 +456,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;
+  clear_last_expr ();
 }
 \f
 /* Return nonzero if anything is pushed on the loop, condition, or case
@@ -1296,7 +1119,7 @@ expand_asm (body)
 
   emit_insn (gen_rtx_ASM_INPUT (VOIDmode,
                                TREE_STRING_POINTER (body)));
-  last_expr_type = 0;
+  clear_last_expr ();
 }
 
 /* Parse the output constraint pointed to by *CONSTRAINT_P.  It is the
@@ -1648,7 +1471,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
        error ("unknown register name `%s' in `asm'", regname);
     }
 
-  last_expr_type = 0;
+  clear_last_expr ();
 
   /* First pass over inputs and outputs checks validity and sets
      mark_addressable if needed.  */
@@ -2404,7 +2227,8 @@ warn_if_unused_value (exp)
 void
 clear_last_expr ()
 {
-  last_expr_type = 0;
+  last_expr_type = NULL_TREE;
+  last_expr_value = NULL_RTX;
 }
 
 /* Begin a statement-expression, i.e., a series of statements which
@@ -2430,7 +2254,6 @@ expand_start_stmt_expr (has_scope)
     start_sequence ();
   NO_DEFER_POP;
   expr_stmts_for_value++;
-  last_expr_value = NULL_RTX;
   return t;
 }
 
@@ -2476,7 +2299,7 @@ expand_end_stmt_expr (t)
   /* Propagate volatility of the actual RTL expr.  */
   TREE_THIS_VOLATILE (t) = volatile_refs_p (last_expr_value);
 
-  last_expr_type = 0;
+  clear_last_expr ();
   expr_stmts_for_value--;
 
   return t;
@@ -2497,6 +2320,7 @@ expand_start_cond (cond, exitflag)
 
   /* Make an entry on cond_stack for the cond we are entering.  */
 
+  thiscond->desc = COND_NESTING;
   thiscond->next = cond_stack;
   thiscond->all = nesting_stack;
   thiscond->depth = ++nesting_depth;
@@ -2567,7 +2391,7 @@ expand_end_cond ()
     emit_label (thiscond->data.cond.endif_label);
 
   POPSTACK (cond_stack);
-  last_expr_type = 0;
+  clear_last_expr ();
 }
 \f
 /* Generate RTL for the start of a loop.  EXIT_FLAG is nonzero if this
@@ -2585,6 +2409,7 @@ expand_start_loop (exit_flag)
 
   /* Make an entry on loop_stack for the loop we are entering.  */
 
+  thisloop->desc = LOOP_NESTING;
   thisloop->next = loop_stack;
   thisloop->all = nesting_stack;
   thisloop->depth = ++nesting_depth;
@@ -2626,6 +2451,7 @@ expand_start_null_loop ()
 
   /* Make an entry on loop_stack for the loop we are entering.  */
 
+  thisloop->desc = LOOP_NESTING;
   thisloop->next = loop_stack;
   thisloop->all = nesting_stack;
   thisloop->depth = ++nesting_depth;
@@ -2801,7 +2627,7 @@ expand_end_loop ()
 
   POPSTACK (loop_stack);
 
-  last_expr_type = 0;
+  clear_last_expr ();
 }
 
 /* Finish a null loop, aka do { } while (0).  */
@@ -2814,7 +2640,7 @@ expand_end_null_loop ()
 
   POPSTACK (loop_stack);
 
-  last_expr_type = 0;
+  clear_last_expr ();
 }
 
 /* Generate a jump to the current loop's continue-point.
@@ -2831,7 +2657,7 @@ expand_continue_loop (whichloop)
 
   note = emit_note (NULL, NOTE_INSN_PREDICTION);
   NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_CONTINUE, IS_TAKEN);
-  last_expr_type = 0;
+  clear_last_expr ();
   if (whichloop == 0)
     whichloop = loop_stack;
   if (whichloop == 0)
@@ -2848,7 +2674,7 @@ int
 expand_exit_loop (whichloop)
      struct nesting *whichloop;
 {
-  last_expr_type = 0;
+  clear_last_expr ();
   if (whichloop == 0)
     whichloop = loop_stack;
   if (whichloop == 0)
@@ -2868,7 +2694,7 @@ expand_exit_loop_if_false (whichloop, cond)
 {
   rtx label = gen_label_rtx ();
   rtx last_insn;
-  last_expr_type = 0;
+  clear_last_expr ();
 
   if (whichloop == 0)
     whichloop = loop_stack;
@@ -2955,7 +2781,7 @@ int
 expand_exit_something ()
 {
   struct nesting *n;
-  last_expr_type = 0;
+  clear_last_expr ();
   for (n = nesting_stack; n; n = n->all)
     if (n->exit_label != 0)
       {
@@ -3073,7 +2899,7 @@ expand_null_return_1 (last_insn)
 
   clear_pending_stack_adjust ();
   do_pending_stack_adjust ();
-  last_expr_type = 0;
+  clear_last_expr ();
 
   if (end_label == 0)
      end_label = return_label = gen_label_rtx ();
@@ -3459,6 +3285,7 @@ expand_start_bindings_and_block (flags, block)
 
   /* Make an entry on block_stack for the block we are entering.  */
 
+  thisblock->desc = BLOCK_NESTING;
   thisblock->next = block_stack;
   thisblock->all = nesting_stack;
   thisblock->depth = ++nesting_depth;
@@ -3477,7 +3304,6 @@ expand_start_bindings_and_block (flags, block)
      instructions inserted after the last unconditional cleanup are
      never the last instruction.  */
   emit_note (NULL, NOTE_INSN_DELETED);
-  thisblock->data.block.cleanup_ptr = &thisblock->data.block.cleanups;
 
   if (block_stack
       && !(block_stack->data.block.cleanups == NULL_TREE
@@ -4183,7 +4009,7 @@ expand_decl_cleanup (decl, cleanup)
                           cleanup, integer_zero_node);
          cleanup = fold (cleanup);
 
-         cleanups = thisblock->data.block.cleanup_ptr;
+         cleanups = &thisblock->data.block.cleanups;
        }
 
       cleanup = unsave_expr (cleanup);
@@ -4224,7 +4050,6 @@ expand_decl_cleanup (decl, cleanup)
             instructions inserted after the last unconditional cleanup are
             never the last instruction.  */
          emit_note (NULL, NOTE_INSN_DELETED);
-         thisblock->data.block.cleanup_ptr = &thisblock->data.block.cleanups;
        }
     }
   return 1;
@@ -4488,6 +4313,7 @@ expand_start_case (exit_flag, expr, type, printname)
 
   /* Make an entry on case_stack for the case we are entering.  */
 
+  thiscase->desc = CASE_NESTING;
   thiscase->next = case_stack;
   thiscase->all = nesting_stack;
   thiscase->depth = ++nesting_depth;
@@ -4525,6 +4351,7 @@ expand_start_case_dummy ()
 
   /* Make an entry on case_stack for the dummy.  */
 
+  thiscase->desc = CASE_NESTING;
   thiscase->next = case_stack;
   thiscase->all = nesting_stack;
   thiscase->depth = ++nesting_depth;
@@ -4776,7 +4603,7 @@ add_case_node (low, high, label, duplicate)
 
   /* Add this label to the chain, and succeed.  */
 
-  r = (struct case_node *) xmalloc (sizeof (struct case_node));
+  r = (struct case_node *) ggc_alloc (sizeof (struct case_node));
   r->low = low;
 
   /* If the bounds are equal, turn this into the one-value case.  */
@@ -5289,20 +5116,6 @@ check_for_full_enumeration_handling (type)
     }
 }
 
-/* Free CN, and its children.  */
-
-static void
-free_case_nodes (cn)
-     case_node_ptr cn;
-{
-  if (cn)
-    {
-      free_case_nodes (cn->left);
-      free_case_nodes (cn->right);
-      free (cn);
-    }
-}
-
 \f
 
 /* Terminate a case (Pascal) or switch (C) statement
@@ -5616,7 +5429,6 @@ expand_end_case_type (orig_index, orig_type)
   if (thiscase->exit_label)
     emit_label (thiscase->exit_label);
 
-  free_case_nodes (case_stack->data.case_stmt.case_list);
   POPSTACK (case_stack);
 
   free_temp_slots ();
@@ -6409,3 +6221,5 @@ emit_case_nodes (index, node, default_label, index_type)
        }
     }
 }
+
+#include "gt-stmt.h"
index 8bbf4fea11f44b48726b9ed4d86407c4b2586ba6..8569ca2538dc8d00d9dcba757bd0e1454576a282 100644 (file)
@@ -64,7 +64,7 @@ extern void debug_rli                 PARAMS ((record_layout_info));
 \f
 /* SAVE_EXPRs for sizes of types and decls, waiting to be expanded.  */
 
-static tree pending_sizes;
+static GTY(()) tree pending_sizes;
 
 /* Nonzero means cannot safely call expand_expr now,
    so put variable sizes onto `pending_sizes' instead.  */
@@ -1823,8 +1823,6 @@ set_sizetype (type)
       TYPE_REFERENCE_TO (sizetype_tab[i]) = 0;
     }
 
-  ggc_add_tree_root ((tree *) &sizetype_tab, ARRAY_SIZE (sizetype_tab));
-
   /* Go down each of the types we already made and set the proper type
      for the sizes in them.  */
   for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
@@ -1980,10 +1978,4 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
   return mode;
 }
 
-/* This function is run once to initialize stor-layout.c.  */
-
-void
-init_stor_layout_once ()
-{
-  ggc_add_tree_root (&pending_sizes, 1);
-}
+#include "gt-stor-layout.h"
index 13f90ca3b0113e0acbdde5551231c37db273fbef..639048625d969f86d4cac3c078b7b0af0e4bbc7d 100644 (file)
@@ -158,7 +158,7 @@ mark_ident (pfile, h, v)
      hashnode h;
      const PTR v ATTRIBUTE_UNUSED;
 {
-  ggc_mark_nonnull_tree (HT_IDENT_TO_GCC_IDENT (h));
+  ggc_mark_tree (HT_IDENT_TO_GCC_IDENT (h));
   return 1;
 }
 
index d7be2e806f06b136349d560b31f6d560c7247e22..e028df177e3296180ee79d83f3ce1136481cbea2 100644 (file)
@@ -579,11 +579,19 @@ typedef char _Bool;
    compiling gcc, so that the autoconf declaration tests for malloc
    etc don't spuriously fail.  */
 #ifdef IN_GCC
-#undef malloc
-#undef realloc
 #undef calloc
 #undef strdup
- #pragma GCC poison malloc realloc calloc strdup
+ #pragma GCC poison calloc strdup
+
+#if defined(FLEX_SCANNER) || defined (YYBISON)
+/* Flex and bison use malloc and realloc.  Yuk.  */
+#define malloc xmalloc
+#define realloc xrealloc
+#else
+#undef malloc
+#undef realloc
+ #pragma GCC poison malloc realloc
+#endif
 
 /* Old target macros that have moved to the target hooks structure.  */
  #pragma GCC poison ASM_OPEN_PAREN ASM_CLOSE_PAREN                     \
@@ -598,7 +606,7 @@ typedef char _Bool;
        WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \
        ENCODE_SECTION_INFO STRIP_NAME_ENCODING
 
-/* And other obsolete target macros, or macros that used to be in target
+/* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
    been used.  */
  #pragma GCC poison INT_ASM_OP ASM_OUTPUT_EH_REGION_BEG                           \
@@ -614,6 +622,10 @@ typedef char _Bool;
        FUNCTION_BLOCK_PROFILER_EXIT MACHINE_STATE_SAVE                    \
        MACHINE_STATE_RESTORE
 
+/* Hooks that are no longer used.  */
+ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE  \
+       LANG_HOOKS_MARK_TREE
+
 #endif /* IN_GCC */
 
 /* Note: not all uses of the `index' token (e.g. variable names and
index fe06eba0f9bccdedd3641febc60e9ddecf413532..b2111dcf4d5f0b3e885001e6be0db57d1eab149c 100644 (file)
@@ -24,7 +24,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "config.h"
 #include "system.h"
 #include "intl.h"
-#include "hash.h"
+#include "obstack.h"
+#include "hashtab.h"
 #include "demangle.h"
 #include "collect2.h"
 
@@ -39,12 +40,12 @@ extern int prepends_underscore;
 
 static int tlink_verbose;
 \f
-/* Hash table boilerplate for working with hash.[ch].  We have hash tables
+/* Hash table boilerplate for working with htab_t.  We have hash tables
    for symbol names, file names, and demangled symbols.  */
 
 typedef struct symbol_hash_entry
 {
-  struct hash_entry root;
+  const char *key;
   struct file_hash_entry *file;
   int chosen;
   int tweaking;
@@ -53,7 +54,7 @@ typedef struct symbol_hash_entry
 
 typedef struct file_hash_entry
 {
-  struct hash_entry root;
+  const char *key;
   const char *args;
   const char *dir;
   const char *main;
@@ -62,24 +63,38 @@ typedef struct file_hash_entry
 
 typedef struct demangled_hash_entry
 {
-  struct hash_entry root;
+  const char *key;
   const char *mangled;
 } demangled;
 
-static struct hash_table symbol_table;
+/* Hash and comparison functions for these hash tables.  */
+
+static int hash_string_eq PARAMS ((const void *, const void *));
+static hashval_t hash_string_hash PARAMS ((const void *));
+
+static int
+hash_string_eq (s1_p, s2_p)
+     const void *s1_p;
+     const void *s2_p;
+{
+  const char *const *s1 = (const char *const *)s1_p;
+  const char *s2 = (const char *)s2_p;
+  return strcmp (*s1, s2) == 0;
+}
+
+static hashval_t
+hash_string_hash (s_p)
+     const void *s_p;
+{
+  const char *const *s = (const char *const *)s_p;
+  return (*htab_hash_string) (*s);
+}
+
+static htab_t symbol_table;
 
-static struct hash_entry * symbol_hash_newfunc PARAMS ((struct hash_entry *,
-                                                       struct hash_table *,
-                                                       hash_table_key));
 static struct symbol_hash_entry * symbol_hash_lookup PARAMS ((const char *,
                                                              int));
-static struct hash_entry * file_hash_newfunc PARAMS ((struct hash_entry *,
-                                                     struct hash_table *,
-                                                     hash_table_key));
 static struct file_hash_entry * file_hash_lookup PARAMS ((const char *));
-static struct hash_entry * demangled_hash_newfunc PARAMS ((struct hash_entry *,
-                                                          struct hash_table *,
-                                                          hash_table_key));
 static struct demangled_hash_entry *
   demangled_hash_lookup PARAMS ((const char *, int));
 static void symbol_push PARAMS ((symbol *));
@@ -100,30 +115,6 @@ static int read_repo_files PARAMS ((char **));
 static void demangle_new_symbols PARAMS ((void));
 static int scan_linker_output PARAMS ((const char *));
 
-/* Create a new entry for the symbol hash table.
-   Passed to hash_table_init.  */
-
-static struct hash_entry *
-symbol_hash_newfunc (entry, table, string)
-     struct hash_entry *entry;
-     struct hash_table *table;
-     hash_table_key string ATTRIBUTE_UNUSED;
-{
-  struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry;
-  if (ret == NULL)
-    {
-      ret = ((struct symbol_hash_entry *)
-            hash_allocate (table, sizeof (struct symbol_hash_entry)));
-      if (ret == NULL)
-       return NULL;
-    }
-  ret->file = NULL;
-  ret->chosen = 0;
-  ret->tweaking = 0;
-  ret->tweaked = 0;
-  return (struct hash_entry *) ret;
-}
-
 /* Look up an entry in the symbol hash table.  */
 
 static struct symbol_hash_entry *
@@ -131,71 +122,44 @@ symbol_hash_lookup (string, create)
      const char *string;
      int create;
 {
-  return ((struct symbol_hash_entry *)
-         hash_lookup (&symbol_table, (const hash_table_key) string,
-                      create, string_copy));
-}
-
-static struct hash_table file_table;
-
-/* Create a new entry for the file hash table.
-   Passed to hash_table_init.  */
-
-static struct hash_entry *
-file_hash_newfunc (entry, table, string)
-     struct hash_entry *entry;
-     struct hash_table *table;
-     hash_table_key string ATTRIBUTE_UNUSED;
-{
-   struct file_hash_entry *ret = (struct file_hash_entry *) entry;
-  if (ret == NULL)
+  PTR *e;
+  e = htab_find_slot_with_hash (symbol_table, string,
+                               (*htab_hash_string)(string),
+                               create ? INSERT : NO_INSERT);
+  if (e == NULL)
+    return NULL;
+  if (*e == NULL)
     {
-      ret = ((struct file_hash_entry *)
-            hash_allocate (table, sizeof (struct file_hash_entry)));
-      if (ret == NULL)
-       return NULL;
+      struct symbol_hash_entry *v;
+      *e = v = xcalloc (1, sizeof (*v));
+      v->key = xstrdup (string);
     }
-  ret->args = NULL;
-  ret->dir = NULL;
-  ret->main = NULL;
-  ret->tweaking = 0;
-  return (struct hash_entry *) ret;
+  return *e;
 }
 
+static htab_t file_table;
+
 /* Look up an entry in the file hash table.  */
 
 static struct file_hash_entry *
 file_hash_lookup (string)
      const char *string;
 {
-  return ((struct file_hash_entry *)
-         hash_lookup (&file_table, (const hash_table_key) string, true,
-                      string_copy));
-}
-
-static struct hash_table demangled_table;
-
-/* Create a new entry for the demangled name hash table.
-   Passed to hash_table_init.  */
-
-static struct hash_entry *
-demangled_hash_newfunc (entry, table, string)
-     struct hash_entry *entry;
-     struct hash_table *table;
-     hash_table_key string ATTRIBUTE_UNUSED;
-{
-  struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry;
-  if (ret == NULL)
+  PTR *e;
+  e = htab_find_slot_with_hash (file_table, string,
+                               (*htab_hash_string)(string),
+                               INSERT);
+  if (*e == NULL)
     {
-      ret = ((struct demangled_hash_entry *)
-            hash_allocate (table, sizeof (struct demangled_hash_entry)));
-      if (ret == NULL)
-       return NULL;
+      struct file_hash_entry *v;
+      *e = v = xcalloc (1, sizeof (*v));
+      v->key = xstrdup (string);
     }
-  ret->mangled = NULL;
-  return (struct hash_entry *) ret;
+  return *e;
 }
 
+static htab_t demangled_table;
+
 /* Look up an entry in the demangled name hash table.  */
 
 static struct demangled_hash_entry *
@@ -203,9 +167,19 @@ demangled_hash_lookup (string, create)
      const char *string;
      int create;
 {
-  return ((struct demangled_hash_entry *)
-         hash_lookup (&demangled_table, (const hash_table_key) string,
-                      create, string_copy));
+  PTR *e;
+  e = htab_find_slot_with_hash (demangled_table, string,
+                               (*htab_hash_string)(string),
+                               create ? INSERT : NO_INSERT);
+  if (e == NULL)
+    return NULL;
+  if (*e == NULL)
+    {
+      struct demangled_hash_entry *v;
+      *e = v = xcalloc (1, sizeof (*v));
+      v->key = xstrdup (string);
+    }
+  return *e;
 }
 \f
 /* Stack code.  */
@@ -290,12 +264,13 @@ tlink_init ()
 {
   const char *p;
 
-  hash_table_init (&symbol_table, symbol_hash_newfunc, string_hash,
-                  string_compare);
-  hash_table_init (&file_table, file_hash_newfunc, string_hash,
-                  string_compare);
-  hash_table_init (&demangled_table, demangled_hash_newfunc,
-                  string_hash, string_compare);
+  symbol_table = htab_create (500, hash_string_hash, hash_string_eq,
+                             NULL);
+  file_table = htab_create (500, hash_string_hash, hash_string_eq,
+                           NULL);
+  demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
+                                NULL);
+  
   obstack_begin (&symbol_stack_obstack, 0);
   obstack_begin (&file_stack_obstack, 0);
 
@@ -422,11 +397,10 @@ read_repo_file (f)
      file *f;
 {
   char c;
-  FILE *stream = fopen ((char*) f->root.key, "r");
+  FILE *stream = fopen (f->key, "r");
 
   if (tlink_verbose >= 2)
-    fprintf (stderr, _("collect: reading %s\n"),
-            (char*) f->root.key);
+    fprintf (stderr, _("collect: reading %s\n"), f->key);
 
   while (fscanf (stream, "%c ", &c) == 1)
     {
@@ -501,8 +475,8 @@ recompile_files ()
   while ((f = file_pop ()) != NULL)
     {
       char *line, *command;
-      FILE *stream = fopen ((char*) f->root.key, "r");
-      const char *const outname = frob_extension ((char*) f->root.key, ".rnw");
+      FILE *stream = fopen (f->key, "r");
+      const char *const outname = frob_extension (f->key, ".rnw");
       FILE *output = fopen (outname, "w");
 
       while ((line = tfgets (stream)) != NULL)
@@ -517,7 +491,7 @@ recompile_files ()
        }
       fclose (stream);
       fclose (output);
-      rename (outname, (char*) f->root.key);
+      rename (outname, f->key);
 
       obstack_grow (&temporary_obstack, "cd ", 3);
       obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
@@ -587,14 +561,13 @@ demangle_new_symbols ()
   while ((sym = symbol_pop ()) != NULL)
     {
       demangled *dem;
-      const char *p = cplus_demangle ((char*) sym->root.key,
-                                     DMGL_PARAMS | DMGL_ANSI);
+      const char *p = cplus_demangle (sym->key, DMGL_PARAMS | DMGL_ANSI);
 
       if (! p)
        continue;
 
       dem = demangled_hash_lookup (p, true);
-      dem->mangled = (char*) sym->root.key;
+      dem->mangled = sym->key;
     }
 }
 
@@ -696,7 +669,7 @@ scan_linker_output (fname)
        {
          if (tlink_verbose >= 2)
            fprintf (stderr, _("collect: tweaking %s in %s\n"),
-                    (char*) sym->root.key, (char*) sym->file->root.key);
+                    sym->key, sym->file->key);
          sym->tweaking = 1;
          file_push (sym->file);
        }
index 702937591b18dde9db73c74a9d174522b34d240f..9dd6468aebb17700e38a62c1721ad1e2e953748b 100644 (file)
@@ -5046,9 +5046,6 @@ lang_independent_init ()
 {
   /* Initialize the garbage-collector, and string pools.  */
   init_ggc ();
-  ggc_add_rtx_root (&stack_limit_rtx, 1);
-  ggc_add_tree_root (&current_function_decl, 1);
-  ggc_add_tree_root (&current_function_func_begin_label, 1);
 
   init_stringpool ();
   init_obstacks ();
@@ -5063,13 +5060,10 @@ lang_independent_init ()
                    || warn_notreached);
   init_regs ();
   init_alias_once ();
-  init_stmt ();
   init_loop ();
   init_reload ();
   init_function_once ();
-  init_stor_layout_once ();
   init_varasm_once ();
-  init_EXPR_INSN_LIST_cache ();
 
   /* The following initialization functions need to generate rtl, so
      provide a dummy function context for them.  */
index 94852430d03f532735999b293530a2a69dbdf98d..145cfe8f75cf02950c54417cf4d598d9b6055368 100644 (file)
@@ -1071,8 +1071,6 @@ optimize_inline_calls (fn)
 
   /* Clean up.  */
   htab_delete (id.tree_pruner);
-  VARRAY_FREE (id.fns);
-  VARRAY_FREE (id.target_exprs);
   if (DECL_LANG_SPECIFIC (fn))
     {
       tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns));
@@ -1081,7 +1079,6 @@ optimize_inline_calls (fn)
              VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree));
       DECL_INLINED_FNS (fn) = ifn;
     }
-  VARRAY_FREE (id.inlined_fns);
 }
 
 /* FN is a function that has a complete body, and CLONE is a function
@@ -1111,9 +1108,6 @@ clone_body (clone, fn, arg_map)
 
   /* Actually copy the body.  */
   TREE_CHAIN (DECL_SAVED_TREE (clone)) = copy_body (&id);
-
-  /* Clean up.  */
-  VARRAY_FREE (id.fns);
 }
 
 /* Apply FUNC to all the sub-trees of TP in a pre-order traversal.
index 04ae6ce53480bae19a8b3546e69f8952a25bf3d6..1ee045b906565b3121b2479d5805be909a5feb3b 100644 (file)
@@ -105,7 +105,7 @@ static int next_type_uid = 1;
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
 
-struct type_hash
+struct type_hash GTY(())
 {
   unsigned long hash;
   tree type;
@@ -121,7 +121,8 @@ struct type_hash
    same table, they are completely independent, and the hash code is
    computed differently for each of these.  */
 
-htab_t type_hash_table;
+static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
+     htab_t type_hash_table;
 
 static void set_type_quals PARAMS ((tree, int));
 static void append_random_chars PARAMS ((char *));
@@ -131,8 +132,6 @@ static void print_type_hash_statistics PARAMS((void));
 static void finish_vector_type PARAMS((tree));
 static tree make_vector PARAMS ((enum machine_mode, tree, int));
 static int type_hash_marked_p PARAMS ((const void *));
-static void type_hash_mark PARAMS ((const void *));
-static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
@@ -147,10 +146,6 @@ init_obstacks ()
   /* Initialize the hash table of types.  */
   type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
                                 type_hash_eq, 0);
-  ggc_add_deletable_htab (type_hash_table, type_hash_marked_p,
-                         type_hash_mark);
-  ggc_add_tree_root (global_trees, TI_MAX);
-  ggc_add_tree_root (integer_types, itk_none);
 }
 
 \f
@@ -1527,6 +1522,44 @@ first_rtl_op (code)
     }
 }
 
+/* Return which tree structure is used by T.  */
+
+enum tree_node_structure_enum
+tree_node_structure (t)
+     tree t;
+{
+  enum tree_code code = TREE_CODE (t);
+  
+  switch (TREE_CODE_CLASS (code))
+    {
+    case 'd':  return TS_DECL;
+    case 't':  return TS_TYPE;
+    case 'b':  return TS_BLOCK;
+    case 'r': case '<': case '1': case '2': case 'e': case 's': 
+      return TS_EXP;
+    default:  /* 'c' and 'x' */
+      break;
+    }
+  switch (code)
+    {
+      /* 'c' cases.  */
+    case INTEGER_CST:          return TS_INT_CST;
+    case REAL_CST:             return TS_REAL_CST;
+    case COMPLEX_CST:          return TS_COMPLEX;
+    case VECTOR_CST:           return TS_VECTOR;
+    case STRING_CST:           return TS_STRING;
+      /* 'x' cases.  */
+    case ERROR_MARK:           return TS_COMMON;
+    case IDENTIFIER_NODE:      return TS_IDENTIFIER;
+    case TREE_LIST:            return TS_LIST;
+    case TREE_VEC:             return TS_VEC;
+    case PLACEHOLDER_EXPR:     return TS_COMMON;
+
+    default:
+      abort ();
+    }
+}
+
 /* Perform any modifications to EXPR required when it is unsaved.  Does
    not recurse into EXPR's subtrees.  */
 
@@ -3044,41 +3077,6 @@ type_hash_marked_p (p)
   return ggc_marked_p (type) || TYPE_SYMTAB_POINTER (type);
 }
 
-/* Mark the entry in the type hash table the type it points to is marked.
-   Also mark the type in case we are considering this entry "marked" by
-   virtue of TYPE_SYMTAB_POINTER being set.  */
-
-static void
-type_hash_mark (p)
-     const void *p;
-{
-  ggc_mark (p);
-  ggc_mark_tree (((struct type_hash *) p)->type);
-}
-
-/* Mark the hashtable slot pointed to by ENTRY (which is really a
-   `tree**') for GC.  */
-
-static int
-mark_tree_hashtable_entry (entry, data)
-     void **entry;
-     void *data ATTRIBUTE_UNUSED;
-{
-  ggc_mark_tree ((tree) *entry);
-  return 1;
-}
-
-/* Mark ARG (which is really a htab_t whose slots are trees) for
-   GC.  */
-
-void
-mark_tree_hashtable (arg)
-     void *arg;
-{
-  htab_t t = *(htab_t *) arg;
-  htab_traverse (t, mark_tree_hashtable_entry, 0);
-}
-
 static void
 print_type_hash_statistics ()
 {
@@ -4865,3 +4863,5 @@ initializer_zerop (init)
       return false;
     }
 }
+
+#include "gt-tree.h"
index d215d392fec19b49325f22af203bac3c79b4cf27..4888bc72fe7a4d1b5b8207f53888dcb491954ed6 100644 (file)
@@ -118,7 +118,7 @@ extern tree built_in_decls[(int) END_BUILTINS];
    See the accessor macros, defined below, for documentation of the
    fields.  */
 
-struct tree_common
+struct tree_common GTY(())
 {
   tree chain;
   tree type;
@@ -701,8 +701,8 @@ extern void tree_class_check_failed PARAMS ((const tree, int,
    || (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A)         \
        == (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B))      \
        && TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
-
-struct tree_int_cst
+struct tree_int_cst GTY(())
 {
   struct tree_common common;
   rtx rtl;     /* acts as link to register transfer language
@@ -710,7 +710,7 @@ struct tree_int_cst
   /* A sub-struct is necessary here because the function `const_hash'
      wants to scan both words as a unit and taking the address of the
      sub-struct yields the properly inclusive bounded pointer.  */
-  struct {
+  struct tree_int_cst_lowhi {
     unsigned HOST_WIDE_INT low;
     HOST_WIDE_INT high;
   } int_cst;
@@ -730,18 +730,18 @@ struct realvaluetype;
 #define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr)
 #define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
 
-struct tree_real_cst
+struct tree_real_cst GTY(())
 {
   struct tree_common common;
   rtx rtl;     /* acts as link to register transfer language (rtl) info */
-  struct realvaluetype *real_cst_ptr;
+  struct realvaluetype * real_cst_ptr;
 };
 
 /* In a STRING_CST */
 #define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)->string.length)
 #define TREE_STRING_POINTER(NODE) (STRING_CST_CHECK (NODE)->string.pointer)
 
-struct tree_string
+struct tree_string GTY(())
 {
   struct tree_common common;
   rtx rtl;     /* acts as link to register transfer language (rtl) info */
@@ -753,7 +753,7 @@ struct tree_string
 #define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real)
 #define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
 
-struct tree_complex
+struct tree_complex GTY(())
 {
   struct tree_common common;
   rtx rtl;     /* acts as link to register transfer language (rtl) info */
@@ -764,7 +764,7 @@ struct tree_complex
 /* In a VECTOR_CST node.  */
 #define TREE_VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elements)
 
-struct tree_vector
+struct tree_vector GTY(())
 {
   struct tree_common common;
   rtx rtl;
@@ -787,7 +787,7 @@ struct tree_vector
   ((tree) ((char *) (NODE) - sizeof (struct tree_common)))
 #define GCC_IDENT_TO_HT_IDENT(NODE) (&((struct tree_identifier *) (NODE))->id)
 
-struct tree_identifier
+struct tree_identifier GTY(())
 {
   struct tree_common common;
   struct ht_identifier id;
@@ -797,7 +797,7 @@ struct tree_identifier
 #define TREE_PURPOSE(NODE) (TREE_LIST_CHECK (NODE)->list.purpose)
 #define TREE_VALUE(NODE) (TREE_LIST_CHECK (NODE)->list.value)
 
-struct tree_list
+struct tree_list GTY(())
 {
   struct tree_common common;
   tree purpose;
@@ -810,11 +810,11 @@ struct tree_list
 #define TREE_VEC_END(NODE) \
   ((void) TREE_VEC_CHECK (NODE), &((NODE)->vec.a[(NODE)->vec.length]))
 
-struct tree_vec
+struct tree_vec GTY(())
 {
   struct tree_common common;
   int length;
-  tree a[1];
+  tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
 };
 
 /* Define fields and accessors for some nodes that represent expressions.  */
@@ -880,11 +880,13 @@ struct tree_vec
 #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND (TARGET_EXPR_CHECK (NODE), 1)
 #define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND (TARGET_EXPR_CHECK (NODE), 2)
 
-struct tree_exp
+struct tree_exp GTY(())
 {
   struct tree_common common;
   int complexity;
-  tree operands[1];
+  tree GTY ((special ("tree_exp"), 
+            length ("TREE_CODE_LENGTH (TREE_CODE ((tree) &%h))"))) 
+    operands[1];
 };
 \f
 /* In a BLOCK node.  */
@@ -932,7 +934,7 @@ struct tree_exp
 #define BLOCK_FRAGMENT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.fragment_origin)
 #define BLOCK_FRAGMENT_CHAIN(NODE) (BLOCK_CHECK (NODE)->block.fragment_chain)
 
-struct tree_block
+struct tree_block GTY(())
 {
   struct tree_common common;
 
@@ -972,6 +974,7 @@ struct tree_block
 #define TYPE_PRECISION(NODE) (TYPE_CHECK (NODE)->type.precision)
 #define TYPE_SYMTAB_ADDRESS(NODE) (TYPE_CHECK (NODE)->type.symtab.address)
 #define TYPE_SYMTAB_POINTER(NODE) (TYPE_CHECK (NODE)->type.symtab.pointer)
+#define TYPE_SYMTAB_DIE(NODE) (TYPE_CHECK (NODE)->type.symtab.die)
 #define TYPE_NAME(NODE) (TYPE_CHECK (NODE)->type.name)
 #define TYPE_NEXT_VARIANT(NODE) (TYPE_CHECK (NODE)->type.next_variant)
 #define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type.main_variant)
@@ -1209,7 +1212,9 @@ struct tree_block
 #define MAX_POINTER_DEPTH 2
 #define VA_LIST_POINTER_DEPTH 3
 
-struct tree_type
+struct die_struct;
+
+struct tree_type GTY(())
 {
   struct tree_common common;
   tree values;
@@ -1241,7 +1246,12 @@ struct tree_type
   unsigned int align;
   tree pointer_to;
   tree reference_to;
-  union {int address; char *pointer; } symtab;
+  union tree_type_symtab {
+    int address; 
+    char * GTY ((tag ("1"))) pointer; 
+    struct die_struct * GTY ((tag ("2"), skip (""))) die;
+  } GTY ((desc ("debug_hooks == &sdb_debug_hooks ? 1 : debug_hooks == &dwarf2_debug_hooks ? 2 : 0"), 
+         descbits ("2"))) symtab;
   tree name;
   tree minval;
   tree maxval;
@@ -1757,7 +1767,7 @@ struct tree_type
 
 struct function;
 
-struct tree_decl
+struct tree_decl GTY(())
 {
   struct tree_common common;
   const char *filename;
@@ -1808,7 +1818,7 @@ struct tree_decl
   unsigned lang_flag_6 : 1;
   unsigned lang_flag_7 : 1;
 
-  union {
+  union tree_decl_u1 {
     /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
        DECL_FUNCTION_CODE.  */
     enum built_in_function f;
@@ -1817,8 +1827,11 @@ struct tree_decl
     HOST_WIDE_INT i;
     /* DECL_ALIGN and DECL_OFFSET_ALIGN.  (These are not used for
        FUNCTION_DECLs).  */
-    struct {unsigned int align : 24; unsigned int off_align : 8;} a;
-  } u1;
+    struct tree_decl_u1_a {
+      unsigned int align : 24; 
+      unsigned int off_align : 8;
+    } a;
+  } GTY ((skip (""))) u1;
 
   tree size_unit;
   tree name;
@@ -1838,12 +1851,12 @@ struct tree_decl
      In PARM_DECL, holds an RTL for the stack slot
      of register where the data was actually passed.
      Used by Chill and Java in LABEL_DECL and by C++ and Java in VAR_DECL.  */
-  union {
-    struct function *f;
-    rtx r;
-    tree t;
+  union tree_decl_u2 {
+    struct function * GTY ((tag ("FUNCTION_DECL"))) f;
+    rtx GTY ((tag ("PARM_DECL"))) r;
+    tree GTY ((tag ("FIELD_DECL"))) t;
     int i;
-  } u2;
+  } GTY ((desc ("TREE_CODE((tree) &(%0))"))) u2;
 
   /* In a FUNCTION_DECL, this is DECL_SAVED_TREE.  */
   tree saved_tree;
@@ -1858,25 +1871,43 @@ struct tree_decl
   struct lang_decl *lang_specific;
 };
 \f
+enum tree_node_structure_enum {
+  TS_COMMON,
+  TS_INT_CST,
+  TS_REAL_CST,
+  TS_VECTOR,
+  TS_STRING,
+  TS_COMPLEX,
+  TS_IDENTIFIER,
+  TS_DECL,
+  TS_TYPE,
+  TS_LIST,
+  TS_VEC,
+  TS_EXP,
+  TS_BLOCK,
+  LAST_TS_ENUM
+};
+
 /* Define the overall contents of a tree node.
    It may be any of the structures declared above
    for various types of node.  */
 
-union tree_node
+union tree_node GTY ((ptr_alias (union lang_tree_node),
+                     desc ("tree_node_structure (&%h)")))
 {
-  struct tree_common common;
-  struct tree_int_cst int_cst;
-  struct tree_real_cst real_cst;
-  struct tree_vector vector;
-  struct tree_string string;
-  struct tree_complex complex;
-  struct tree_identifier identifier;
-  struct tree_decl decl;
-  struct tree_type type;
-  struct tree_list list;
-  struct tree_vec vec;
-  struct tree_exp exp;
-  struct tree_block block;
+  struct tree_common GTY ((tag ("TS_COMMON"))) common;
+  struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
+  struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
+  struct tree_vector GTY ((tag ("TS_VECTOR"))) vector;
+  struct tree_string GTY ((tag ("TS_STRING"))) string;
+  struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex;
+  struct tree_identifier GTY ((tag ("TS_IDENTIFIER"))) identifier;
+  struct tree_decl GTY ((tag ("TS_DECL"))) decl;
+  struct tree_type GTY ((tag ("TS_TYPE"))) type;
+  struct tree_list GTY ((tag ("TS_LIST"))) list;
+  struct tree_vec GTY ((tag ("TS_VEC"))) vec;
+  struct tree_exp GTY ((tag ("TS_EXP"))) exp;
+  struct tree_block GTY ((tag ("TS_BLOCK"))) block;
  };
 \f
 /* Standard named or nameless data types of the C compiler.  */
@@ -1952,7 +1983,7 @@ enum tree_index
   TI_MAX
 };
 
-extern tree global_trees[TI_MAX];
+extern GTY(()) tree global_trees[TI_MAX];
 
 #define error_mark_node                        global_trees[TI_ERROR_MARK]
 
@@ -2050,7 +2081,7 @@ typedef enum integer_type_kind integer_type_kind;
 
 /* The standard C integer types.  Use integer_type_kind to index into
    this array.  */
-extern tree integer_types[itk_none];
+extern GTY(()) tree integer_types[itk_none];
 
 #define char_type_node                 integer_types[itk_char]
 #define signed_char_type_node          integer_types[itk_signed_char]
@@ -2438,7 +2469,7 @@ enum size_type_kind
   UBITSIZETYPE,                /* Unsifgned representation of sizes in bits.  */
   TYPE_KIND_LAST};
 
-extern tree sizetype_tab[(int) TYPE_KIND_LAST];
+extern GTY(()) tree sizetype_tab[(int) TYPE_KIND_LAST];
 
 #define sizetype sizetype_tab[(int) SIZETYPE]
 #define bitsizetype sizetype_tab[(int) BITSIZETYPE]
@@ -2550,6 +2581,10 @@ extern tree save_expr                    PARAMS ((tree));
 
 extern int first_rtl_op                        PARAMS ((enum tree_code));
 
+/* Return which tree structure is used by T.  */
+
+enum tree_node_structure_enum tree_node_structure PARAMS ((tree));
+
 /* unsave_expr (EXP) returns an expression equivalent to EXP but it
    can be used multiple times and will evaluate EXP in its entirety
    each time.  */
@@ -2677,10 +2712,10 @@ extern int immediate_size_expand;
 
 /* Points to the FUNCTION_DECL of the function whose body we are reading.  */
 
-extern tree current_function_decl;
+extern GTY(()) tree current_function_decl;
 
 /* Nonzero means a FUNC_BEGIN label was emitted.  */
-extern tree current_function_func_begin_label;
+extern GTY(()) tree current_function_func_begin_label;
 
 /* Nonzero means all ..._TYPE nodes should be allocated permanently.  */
 
@@ -2857,7 +2892,6 @@ extern void gcc_obstack_init              PARAMS ((struct obstack *));
 extern void init_obstacks              PARAMS ((void));
 extern void build_common_tree_nodes    PARAMS ((int));
 extern void build_common_tree_nodes_2  PARAMS ((int));
-extern void mark_tree_hashtable         PARAMS ((void *));
 
 /* In function.c */
 extern void setjmp_protect_args                PARAMS ((void));
@@ -2890,7 +2924,6 @@ extern void push_function_context PARAMS ((void));
 extern void pop_function_context       PARAMS ((void));
 extern void push_function_context_to   PARAMS ((tree));
 extern void pop_function_context_from  PARAMS ((tree));
-extern void ggc_mark_struct_function   PARAMS ((struct function *));
 
 /* In print-rtl.c */
 #ifdef BUFSIZ
@@ -2969,7 +3002,6 @@ extern bool parse_output_constraint     PARAMS ((const char **,
 extern void expand_asm_operands                PARAMS ((tree, tree, tree, tree, int,
                                                 const char *, int));
 extern int any_pending_cleanups                PARAMS ((int));
-extern void init_stmt                  PARAMS ((void));
 extern void init_stmt_for_function     PARAMS ((void));
 extern int drop_through_at_end_p       PARAMS ((void));
 extern void expand_start_target_temps  PARAMS ((void));
index a0b1a3397376ddad7da45ba5aa42679310e2deee..1b728bb2549edacaa75e3e855936e116e22e65ab 100644 (file)
@@ -39,7 +39,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "output.h"
 #include "real.h"
 #include "toplev.h"
-#include "obstack.h"
 #include "hashtab.h"
 #include "c-pragma.h"
 #include "c-tree.h"
@@ -66,17 +65,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 const char *first_global_object_name;
 const char *weak_global_object_name;
 
-extern struct obstack permanent_obstack;
-#define obstack_chunk_alloc xmalloc
-
 struct addr_const;
-struct constant_descriptor;
+struct constant_descriptor_rtx;
 struct rtx_const;
 struct pool_constant;
 
 #define MAX_RTX_HASH_TABLE 61
 
-struct varasm_status
+struct varasm_status GTY(())
 {
   /* Hash facility for making memory-constants
      from constant rtl-expressions.  It is used on RISC machines
@@ -86,11 +82,14 @@ struct varasm_status
      This pool of constants is reinitialized for each function
      so each function gets its own constants-pool that comes right before
      it.  */
-  struct constant_descriptor **x_const_rtx_hash_table;
-  struct pool_constant **x_const_rtx_sym_hash_table;
+  struct constant_descriptor_rtx ** GTY ((length ("MAX_RTX_HASH_TABLE"))) 
+    x_const_rtx_hash_table;
+  struct pool_constant ** GTY ((length ("MAX_RTX_HASH_TABLE")))
+    x_const_rtx_sym_hash_table;
 
   /* Pointers to first and last constant in pool.  */
-  struct pool_constant *x_first_pool, *x_last_pool;
+  struct pool_constant *x_first_pool;
+  struct pool_constant *x_last_pool;
 
   /* Current offset in constant pool (does not include any machine-specific
      header).  */
@@ -138,20 +137,16 @@ static const char *strip_reg_name PARAMS ((const char *));
 static int contains_pointers_p         PARAMS ((tree));
 static void decode_addr_const          PARAMS ((tree, struct addr_const *));
 static int const_hash                  PARAMS ((tree));
-static int compare_constant            PARAMS ((tree,
-                                              struct constant_descriptor *));
-static const unsigned char *compare_constant_1  PARAMS ((tree, const unsigned char *));
-static struct constant_descriptor *record_constant PARAMS ((tree));
-static void record_constant_1          PARAMS ((tree));
+static int compare_constant            PARAMS ((tree, tree));
 static tree copy_constant              PARAMS ((tree));
 static void output_constant_def_contents  PARAMS ((tree, int, int));
 static void decode_rtx_const           PARAMS ((enum machine_mode, rtx,
                                               struct rtx_const *));
 static int const_hash_rtx              PARAMS ((enum machine_mode, rtx));
-static int compare_constant_rtx                PARAMS ((enum machine_mode, rtx,
-                                              struct constant_descriptor *));
-static struct constant_descriptor *record_constant_rtx PARAMS ((enum machine_mode,
-                                                             rtx));
+static int compare_constant_rtx        
+  PARAMS ((enum machine_mode, rtx, struct constant_descriptor_rtx *));
+static struct constant_descriptor_rtx * record_constant_rtx 
+  PARAMS ((enum machine_mode, rtx));
 static struct pool_constant *find_pool_constant PARAMS ((struct function *, rtx));
 static void mark_constant_pool         PARAMS ((void));
 static void mark_constants             PARAMS ((rtx));
@@ -175,13 +170,8 @@ static void asm_output_aligned_bss PARAMS ((FILE *, tree, const char *,
                                                 int, int));
 #endif
 #endif /* BSS_SECTION_ASM_OP */
-static void mark_pool_constant          PARAMS ((struct pool_constant *));
-static void mark_const_hash_entry      PARAMS ((void *));
-static int mark_const_str_htab_1       PARAMS ((void **, void *));
-static void mark_const_str_htab                PARAMS ((void *));
 static hashval_t const_str_htab_hash   PARAMS ((const void *x));
 static int const_str_htab_eq           PARAMS ((const void *x, const void *y));
-static void const_str_htab_del         PARAMS ((void *));
 static void asm_emit_uninitialised     PARAMS ((tree, const char*, int, int));
 static void resolve_unique_section     PARAMS ((tree, int, int));
 static void mark_weak                   PARAMS ((tree));
@@ -2104,7 +2094,7 @@ assemble_real (d, mode, align)
    Store them both in the structure *VALUE.
    Abort if EXP does not reduce.  */
 
-struct addr_const
+struct addr_const GTY(())
 {
   rtx base;
   HOST_WIDE_INT offset;
@@ -2175,51 +2165,48 @@ decode_addr_const (exp, value)
 }
 \f
 /* We do RTX_UNSPEC + XINT (blah), so nothing can go after RTX_UNSPEC.  */
-enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_INT, RTX_VECTOR, RTX_UNSPEC };
-struct rtx_const
+enum kind { RTX_UNKNOWN, RTX_DOUBLE, RTX_VECTOR, RTX_INT, RTX_UNSPEC };
+struct rtx_const GTY(())
 {
   ENUM_BITFIELD(kind) kind : 16;
   ENUM_BITFIELD(machine_mode) mode : 16;
-  union {
+  union rtx_const_un {
     REAL_VALUE_TYPE du;
-    struct addr_const addr;
-    struct {HOST_WIDE_INT high, low;} di;
+    struct addr_const GTY ((tag ("1"))) addr;
+    struct rtx_const_u_di { 
+      HOST_WIDE_INT high;
+      HOST_WIDE_INT low; 
+    } GTY ((tag ("0"))) di;
 
     /* The max vector size we have is 8 wide.  This should be enough.  */
     HOST_WIDE_INT veclo[16];
     HOST_WIDE_INT vechi[16];
-  } un;
+  } GTY ((desc ("%1.kind >= RTX_INT"), descbits ("1"))) un;
 };
 
 /* Uniquize all constants that appear in memory.
    Each constant in memory thus far output is recorded
-   in `const_hash_table' with a `struct constant_descriptor'
-   that contains a polish representation of the value of
-   the constant.
-
-   We cannot store the trees in the hash table
-   because the trees may be temporary.  */
+   in `const_hash_table'.  */
 
-struct constant_descriptor
+struct constant_descriptor_tree GTY(())
 {
-  struct constant_descriptor *next;
+  /* More constant_descriptors with the same hash code.  */
+  struct constant_descriptor_tree *next;
+
+  /* The label of the constant.  */
   const char *label;
+
+  /* A MEM for the constant.  */
   rtx rtl;
-  /* Make sure the data is reasonably aligned.  */
-  union
-  {
-    unsigned char contents[1];
-#ifdef HAVE_LONG_DOUBLE
-    long double d;
-#else
-    double d;
-#endif
-  } u;
+
+  /* The value of the constant.  */
+  tree value;
 };
 
 #define HASHBITS 30
 #define MAX_HASH_TABLE 1009
-static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
+static GTY(()) struct constant_descriptor_tree *
+  const_hash_table[MAX_HASH_TABLE];
 
 /* We maintain a hash table of STRING_CST values.  Unless we are asked to force
    out a string constant, we defer output of the constants until we know
@@ -2228,50 +2215,14 @@ static struct constant_descriptor *const_hash_table[MAX_HASH_TABLE];
 
 #define STRHASH(x) ((hashval_t) ((long) (x) >> 3))
 
-struct deferred_string
+struct deferred_string GTY(())
 {
   const char *label;
   tree exp;
   int labelno;
 };
 
-static htab_t const_str_htab;
-
-/* Mark a const_hash_table descriptor for GC.  */
-
-static void
-mark_const_hash_entry (ptr)
-     void *ptr;
-{
-  struct constant_descriptor *desc = * (struct constant_descriptor **) ptr;
-
-  while (desc)
-    {
-      ggc_mark_rtx (desc->rtl);
-      desc = desc->next;
-    }
-}
-
-/* Mark the hash-table element X (which is really a pointer to an
-   struct deferred_string *).  */
-
-static int
-mark_const_str_htab_1 (x, data)
-     void **x;
-     void *data ATTRIBUTE_UNUSED;
-{
-  ggc_mark_tree (((struct deferred_string *) *x)->exp);
-  return 1;
-}
-
-/* Mark a const_str_htab for GC.  */
-
-static void
-mark_const_str_htab (htab)
-     void *htab;
-{
-  htab_traverse (*((htab_t *) htab), mark_const_str_htab_1, NULL);
-}
+static GTY ((param_is (struct deferred_string))) htab_t const_str_htab;
 
 /* Returns a hash code for X (which is a really a
    struct deferred_string *).  */
@@ -2295,15 +2246,6 @@ const_str_htab_eq (x, y)
   return (((const struct deferred_string *) x)->label == (const char *) y);
 }
 
-/* Delete the hash table entry dfsp.  */
-
-static void
-const_str_htab_del (dfsp)
-     void *dfsp;
-{
-  free (dfsp);
-}
-
 /* Compute a hash code for a constant expression.  */
 
 static int
@@ -2422,457 +2364,158 @@ const_hash (exp)
   hi %= MAX_HASH_TABLE;
   return hi;
 }
-\f
-/* Compare a constant expression EXP with a constant-descriptor DESC.
-   Return 1 if DESC describes a constant with the same value as EXP.  */
-
-static int
-compare_constant (exp, desc)
-     tree exp;
-     struct constant_descriptor *desc;
-{
-  return 0 != compare_constant_1 (exp, desc->u.contents);
-}
 
-/* Compare constant expression EXP with a substring P of a constant descriptor.
-   If they match, return a pointer to the end of the substring matched.
-   If they do not match, return 0.
+/* Compare t1 and t2, and return 1 only if they are known to result in
+   the same bit pattern on output.  */
 
-   Since descriptors are written in polish prefix notation,
-   this function can be used recursively to test one operand of EXP
-   against a subdescriptor, and if it succeeds it returns the
-   address of the subdescriptor for the next operand.  */
-
-static const unsigned char *
-compare_constant_1 (exp, p)
-     tree exp;
-     const unsigned char *p;
+static int
+compare_constant (t1, t2)
+     tree t1;
+     tree t2;
 {
-  const unsigned char *strp;
-  int len;
-  enum tree_code code = TREE_CODE (exp);
+  enum tree_code typecode;
 
-  if (code != (enum tree_code) *p++)
+  if (t1 == NULL_TREE)
+    return t2 == NULL_TREE;
+  if (t2 == NULL_TREE)
     return 0;
 
-  /* Either set STRP, P and LEN to pointers and length to compare and exit the
-     switch, or return the result of the comparison.  */
+  if (TREE_CODE (t1) != TREE_CODE (t2))
+    return 0;
 
-  switch (code)
+  switch (TREE_CODE (t1))
     {
     case INTEGER_CST:
       /* Integer constants are the same only if the same width of type.  */
-      if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
+      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
        return 0;
-
-      strp = (unsigned char *) &TREE_INT_CST (exp);
-      len = sizeof TREE_INT_CST (exp);
-      break;
+      return tree_int_cst_equal (t1, t2);
 
     case REAL_CST:
       /* Real constants are the same only if the same width of type.  */
-      if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
+      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
        return 0;
 
-      strp = (unsigned char *) &TREE_REAL_CST (exp);
-      len = sizeof TREE_REAL_CST (exp);
-      break;
+      return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
 
     case STRING_CST:
       if (flag_writable_strings)
        return 0;
 
-      if ((enum machine_mode) *p++ != TYPE_MODE (TREE_TYPE (exp)))
-       return 0;
-
-      strp = (const unsigned char *) TREE_STRING_POINTER (exp);
-      len = TREE_STRING_LENGTH (exp);
-      if (memcmp ((char *) &TREE_STRING_LENGTH (exp), p,
-                 sizeof TREE_STRING_LENGTH (exp)))
+      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
        return 0;
 
-      p += sizeof TREE_STRING_LENGTH (exp);
-      break;
+      return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
+             && ! memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
+                        TREE_STRING_LENGTH (t1)));
 
     case COMPLEX_CST:
-      p = compare_constant_1 (TREE_REALPART (exp), p);
-      if (p == 0)
-       return 0;
-
-      return compare_constant_1 (TREE_IMAGPART (exp), p);
+      return (compare_constant (TREE_REALPART (t1), TREE_REALPART (t2))
+             && compare_constant (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
 
     case CONSTRUCTOR:
-      if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
-       {
-         int xlen = len = int_size_in_bytes (TREE_TYPE (exp));
-         unsigned char *tmp = (unsigned char *) alloca (len);
-
-         get_set_constructor_bytes (exp, tmp, len);
-         strp = (unsigned char *) tmp;
-         if (memcmp ((char *) &xlen, p, sizeof xlen))
-           return 0;
+      typecode = TREE_CODE (TREE_TYPE (t1));
+      if (typecode != TREE_CODE (TREE_TYPE (t2)))
+       return 0;
 
-         p += sizeof xlen;
-         break;
-       }
-      else
+      if (typecode == SET_TYPE)
        {
-         tree link;
-         int length = list_length (CONSTRUCTOR_ELTS (exp));
-         tree type;
-         enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
-         int have_purpose = 0;
-
-         for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-           if (TREE_PURPOSE (link))
-             have_purpose = 1;
+         int len = int_size_in_bytes (TREE_TYPE (t2));
+         unsigned char *tmp1, *tmp2;
 
-         if (memcmp ((char *) &length, p, sizeof length))
+         if (int_size_in_bytes (TREE_TYPE (t1)) != len)
            return 0;
 
-         p += sizeof length;
+         tmp1 = (unsigned char *) alloca (len);
+         tmp2 = (unsigned char *) alloca (len);
 
-         /* For record constructors, insist that the types match.
-            For arrays, just verify both constructors are for arrays.
-            Then insist that either both or none have any TREE_PURPOSE
-            values.  */
-         if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-           type = TREE_TYPE (exp);
-         else
-           type = 0;
-
-         if (memcmp ((char *) &type, p, sizeof type))
+         if (get_set_constructor_bytes (t1, tmp1, len) != NULL_TREE)
+           return 0;
+         if (get_set_constructor_bytes (t2, tmp2, len) != NULL_TREE)
            return 0;
+         
+         return memcmp (tmp1, tmp2, len) != 0;
+       }
+      else
+       {
+         tree l1, l2;
 
-         if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+         if (typecode == ARRAY_TYPE)
            {
-             if (memcmp ((char *) &mode, p, sizeof mode))
+             HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
+             /* For arrays, check that the sizes all match.  */
+             if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
+                 || size_1 == -1
+                 || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
                return 0;
-
-             p += sizeof mode;
            }
-
-         p += sizeof type;
-
-         if (memcmp ((char *) &have_purpose, p, sizeof have_purpose))
-           return 0;
-
-         p += sizeof have_purpose;
-
-         /* For arrays, insist that the size in bytes match.  */
-         if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+         else
            {
-             HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-
-             if (memcmp ((char *) &size, p, sizeof size))
+             /* For record and union constructors, require exact type
+                 equality.  */
+             if (TREE_TYPE (t1) != TREE_TYPE (t2))
                return 0;
-
-             p += sizeof size;
            }
 
-         for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
+         for (l1 = CONSTRUCTOR_ELTS (t1), l2 = CONSTRUCTOR_ELTS (t2);
+              l1 && l2;
+              l1 = TREE_CHAIN (l1), l2 = TREE_CHAIN (l2))
            {
-             if (TREE_VALUE (link))
+             /* Check that each value is the same... */
+             if (! compare_constant (TREE_VALUE (l1), TREE_VALUE (l2)))
+               return 0;
+             /* ... and that they apply to the same fields!  */
+             if (typecode == ARRAY_TYPE)
                {
-                 if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
+                 if (! compare_constant (TREE_PURPOSE (l1),
+                                         TREE_PURPOSE (l2)))
                    return 0;
                }
              else
                {
-                 tree zero = 0;
-
-                 if (memcmp ((char *) &zero, p, sizeof zero))
+                 if (TREE_PURPOSE (l1) != TREE_PURPOSE (l2))
                    return 0;
-
-                 p += sizeof zero;
-               }
-
-             if (TREE_PURPOSE (link)
-                 && TREE_CODE (TREE_PURPOSE (link)) == FIELD_DECL)
-               {
-                 if (memcmp ((char *) &TREE_PURPOSE (link), p,
-                             sizeof TREE_PURPOSE (link)))
-                   return 0;
-
-                 p += sizeof TREE_PURPOSE (link);
-               }
-             else if (TREE_PURPOSE (link))
-               {
-                 if ((p = compare_constant_1 (TREE_PURPOSE (link), p)) == 0)
-                   return 0;
-               }
-             else if (have_purpose)
-               {
-                 int zero = 0;
-
-                 if (memcmp ((char *) &zero, p, sizeof zero))
-                   return 0;
-
-                 p += sizeof zero;
                }
            }
-
-         return p;
+         
+         return l1 == NULL_TREE && l2 == NULL_TREE;
        }
 
     case ADDR_EXPR:
       {
-       struct addr_const value;
+       struct addr_const value1, value2;
 
-       decode_addr_const (exp, &value);
-       strp = (unsigned char *) &value.offset;
-       len = sizeof value.offset;
-       /* Compare the offset.  */
-       while (--len >= 0)
-         if (*p++ != *strp++)
-           return 0;
-
-       /* Compare symbol name.  */
-       strp = (const unsigned char *) XSTR (value.base, 0);
-       len = strlen ((const char *) strp) + 1;
+       decode_addr_const (t1, &value1);
+       decode_addr_const (t2, &value2);
+       return (value1.offset == value2.offset
+               && strcmp (XSTR (value1.base, 0), XSTR (value2.base, 0)) == 0);
       }
-      break;
 
     case PLUS_EXPR:
     case MINUS_EXPR:
     case RANGE_EXPR:
-      p = compare_constant_1 (TREE_OPERAND (exp, 0), p);
-      if (p == 0)
-       return 0;
-
-      return compare_constant_1 (TREE_OPERAND (exp, 1), p);
+      return (compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
+             && compare_constant(TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)));
 
     case NOP_EXPR:
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
-      return compare_constant_1 (TREE_OPERAND (exp, 0), p);
+      return compare_constant (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
 
     default:
       {
-       tree new = (*lang_hooks.expand_constant) (exp);
-
-       if (new != exp)
-         return compare_constant_1 (new, p);
+       tree nt1, nt2;
+       nt1 = (*lang_hooks.expand_constant) (t1);
+       nt2 = (*lang_hooks.expand_constant) (t2);
+       if (nt1 != t1 || nt2 != t2)
+         return compare_constant (nt1, nt2);
        else
          return 0;
       }
     }
 
-  /* Compare constant contents.  */
-  while (--len >= 0)
-    if (*p++ != *strp++)
-      return 0;
-
-  return p;
-}
-\f
-/* Construct a constant descriptor for the expression EXP.
-   It is up to the caller to enter the descriptor in the hash table.  */
-
-static struct constant_descriptor *
-record_constant (exp)
-     tree exp;
-{
-  struct constant_descriptor *next = 0;
-  char *label = 0;
-  rtx rtl = 0;
-  int pad;
-
-  /* Make a struct constant_descriptor.  The first three pointers will
-     be filled in later.  Here we just leave space for them.  */
-
-  obstack_grow (&permanent_obstack, (char *) &next, sizeof next);
-  obstack_grow (&permanent_obstack, (char *) &label, sizeof label);
-  obstack_grow (&permanent_obstack, (char *) &rtl, sizeof rtl);
-
-  /* Align the descriptor for the data payload.  */
-  pad = (offsetof (struct constant_descriptor, u)
-        - offsetof(struct constant_descriptor, rtl)
-        - sizeof(next->rtl));
-  if (pad > 0)
-    obstack_blank (&permanent_obstack, pad);
-
-  record_constant_1 (exp);
-  return (struct constant_descriptor *) obstack_finish (&permanent_obstack);
-}
-
-/* Add a description of constant expression EXP
-   to the object growing in `permanent_obstack'.
-   No need to return its address; the caller will get that
-   from the obstack when the object is complete.  */
-
-static void
-record_constant_1 (exp)
-     tree exp;
-{
-  const unsigned char *strp;
-  int len;
-  enum tree_code code = TREE_CODE (exp);
-
-  obstack_1grow (&permanent_obstack, (unsigned int) code);
-
-  switch (code)
-    {
-    case INTEGER_CST:
-      obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
-      strp = (unsigned char *) &TREE_INT_CST (exp);
-      len = sizeof TREE_INT_CST (exp);
-      break;
-
-    case REAL_CST:
-      obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
-      strp = (unsigned char *) &TREE_REAL_CST (exp);
-      len = sizeof TREE_REAL_CST (exp);
-      break;
-
-    case STRING_CST:
-      if (flag_writable_strings)
-       return;
-
-      obstack_1grow (&permanent_obstack, TYPE_MODE (TREE_TYPE (exp)));
-      strp = (const unsigned char *) TREE_STRING_POINTER (exp);
-      len = TREE_STRING_LENGTH (exp);
-      obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
-                   sizeof TREE_STRING_LENGTH (exp));
-      break;
-
-    case COMPLEX_CST:
-      record_constant_1 (TREE_REALPART (exp));
-      record_constant_1 (TREE_IMAGPART (exp));
-      return;
-
-    case CONSTRUCTOR:
-      if (TREE_CODE (TREE_TYPE (exp)) == SET_TYPE)
-       {
-         int nbytes = int_size_in_bytes (TREE_TYPE (exp));
-         obstack_grow (&permanent_obstack, &nbytes, sizeof (nbytes));
-         obstack_blank (&permanent_obstack, nbytes);
-         get_set_constructor_bytes
-           (exp, (unsigned char *) permanent_obstack.next_free - nbytes,
-            nbytes);
-         return;
-       }
-      else
-       {
-         tree link;
-         int length = list_length (CONSTRUCTOR_ELTS (exp));
-         enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
-         tree type;
-         int have_purpose = 0;
-
-         for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-           if (TREE_PURPOSE (link))
-             have_purpose = 1;
-
-         obstack_grow (&permanent_obstack, (char *) &length, sizeof length);
-
-         /* For record constructors, insist that the types match.
-            For arrays, just verify both constructors are for arrays
-            of the same mode.  Then insist that either both or none
-            have any TREE_PURPOSE values.  */
-         if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-           type = TREE_TYPE (exp);
-         else
-           type = 0;
-
-         obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
-         if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
-           obstack_grow (&permanent_obstack, &mode, sizeof mode);
-
-         obstack_grow (&permanent_obstack, (char *) &have_purpose,
-                       sizeof have_purpose);
-
-         /* For arrays, insist that the size in bytes match.  */
-         if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
-           {
-             HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
-             obstack_grow (&permanent_obstack, (char *) &size, sizeof size);
-           }
-
-         for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-           {
-             if (TREE_VALUE (link))
-               record_constant_1 (TREE_VALUE (link));
-             else
-               {
-                 tree zero = 0;
-
-                 obstack_grow (&permanent_obstack,
-                               (char *) &zero, sizeof zero);
-               }
-
-             if (TREE_PURPOSE (link)
-                 && TREE_CODE (TREE_PURPOSE (link)) == FIELD_DECL)
-               obstack_grow (&permanent_obstack,
-                             (char *) &TREE_PURPOSE (link),
-                             sizeof TREE_PURPOSE (link));
-             else if (TREE_PURPOSE (link))
-               record_constant_1 (TREE_PURPOSE (link));
-             else if (have_purpose)
-               {
-                 int zero = 0;
-
-                 obstack_grow (&permanent_obstack,
-                               (char *) &zero, sizeof zero);
-               }
-           }
-       }
-      return;
-
-    case ADDR_EXPR:
-      {
-       struct addr_const value;
-
-       decode_addr_const (exp, &value);
-       /* Record the offset.  */
-       obstack_grow (&permanent_obstack,
-                     (char *) &value.offset, sizeof value.offset);
-
-       switch (GET_CODE (value.base))
-         {
-         case SYMBOL_REF:
-           /* Record the symbol name.  */
-           obstack_grow (&permanent_obstack, XSTR (value.base, 0),
-                         strlen (XSTR (value.base, 0)) + 1);
-           break;
-         case LABEL_REF:
-           /* Record the address of the CODE_LABEL.  It may not have
-              been emitted yet, so it's UID may be zero.  But pointer
-              identity is good enough.  */
-           obstack_grow (&permanent_obstack, &XEXP (value.base, 0),
-                         sizeof (rtx));
-           break;
-         default:
-           abort ();
-         }
-      }
-      return;
-
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case RANGE_EXPR:
-      record_constant_1 (TREE_OPERAND (exp, 0));
-      record_constant_1 (TREE_OPERAND (exp, 1));
-      return;
-
-    case NOP_EXPR:
-    case CONVERT_EXPR:
-    case NON_LVALUE_EXPR:
-      record_constant_1 (TREE_OPERAND (exp, 0));
-      return;
-
-    default:
-      {
-       tree new = (*lang_hooks.expand_constant) (exp);
-
-       if (new != exp)
-         record_constant_1 (new);
-       return;
-      }
-    }
-
-  /* Record constant contents.  */
-  obstack_grow (&permanent_obstack, strp, len);
+  /* Should not get here.  */
+  abort ();
 }
 \f
 /* Record a list of constant expressions that were passed to
@@ -2944,9 +2587,8 @@ output_after_function_constants ()
   after_function_constants = 0;
 }
 
-/* Make a copy of the whole tree structure for a constant.
-   This handles the same types of nodes that compare_constant
-   and record_constant handle.  */
+/* Make a copy of the whole tree structure for a constant.  This
+   handles the same types of nodes that compare_constant handles.  */
 
 static tree
 copy_constant (exp)
@@ -3002,7 +2644,14 @@ copy_constant (exp)
       }
 
     default:
-      abort ();
+      {
+       tree t;
+       t = (*lang_hooks.expand_constant) (exp);
+       if (t != exp)
+         return copy_constant (t);
+       else
+         abort ();
+      }
     }
 }
 \f
@@ -3026,7 +2675,7 @@ output_constant_def (exp, defer)
      int defer;
 {
   int hash;
-  struct constant_descriptor *desc;
+  struct constant_descriptor_tree *desc;
   struct deferred_string **defstr;
   char label[256];
   int reloc;
@@ -3035,7 +2684,7 @@ output_constant_def (exp, defer)
   int labelno = -1;
   rtx rtl;
 
-  /* We can't just use the saved RTL if this is a defererred string constant
+  /* We can't just use the saved RTL if this is a deferred string constant
      and we are not to defer anymore.  */
   if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp)
       && (defer || !STRING_POOL_ADDRESS_P (XEXP (TREE_CST_RTL (exp), 0))))
@@ -3053,7 +2702,7 @@ output_constant_def (exp, defer)
   hash = const_hash (exp) % MAX_HASH_TABLE;
 
   for (desc = const_hash_table[hash]; desc; desc = desc->next)
-    if (compare_constant (exp, desc))
+    if (compare_constant (exp, desc->value))
       break;
 
   if (desc == 0)
@@ -3067,9 +2716,10 @@ output_constant_def (exp, defer)
       labelno = const_labelno++;
       ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
 
-      desc = record_constant (exp);
+      desc = ggc_alloc (sizeof (*desc));
       desc->next = const_hash_table[hash];
       desc->label = ggc_strdup (label);
+      desc->value = copy_constant (exp);
       const_hash_table[hash] = desc;
 
       /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
@@ -3139,7 +2789,7 @@ output_constant_def (exp, defer)
            = (struct deferred_constant *)
              xmalloc (sizeof (struct deferred_constant));
 
-         p->exp = copy_constant (exp);
+         p->exp = desc->value;
          p->reloc = reloc;
          p->labelno = labelno;
          if (after_function)
@@ -3172,9 +2822,9 @@ output_constant_def (exp, defer)
                  struct deferred_string *p;
 
                  p = (struct deferred_string *)
-                     xmalloc (sizeof (struct deferred_string));
+                     ggc_alloc (sizeof (struct deferred_string));
 
-                 p->exp = copy_constant (exp);
+                 p->exp = desc->value;
                  p->label = desc->label;
                  p->labelno = labelno;
                  *defstr = p;
@@ -3227,15 +2877,36 @@ output_constant_def_contents (exp, reloc, labelno)
 
 }
 \f
+/* Used in the hash tables to avoid outputting the same constant
+   twice.  Unlike 'struct constant_descriptor_tree', RTX constants
+   are output once per function, not once per file; there seems
+   to be no reason for the difference.  */
+
+struct constant_descriptor_rtx GTY(())
+{
+  /* More constant_descriptors with the same hash code.  */
+  struct constant_descriptor_rtx *next;
+
+  /* The label of the constant.  */
+  const char *label;
+
+  /* A MEM for the constant.  */
+  rtx rtl;
+
+  /* The value of the constant.  */
+  struct rtx_const value;
+};
+
 /* Structure to represent sufficient information about a constant so that
    it can be output when the constant pool is output, so that function
    integration can be done, and to simplify handling on machines that reference
    constant pool as base+displacement.  */
 
-struct pool_constant
+struct pool_constant GTY(())
 {
-  struct constant_descriptor *desc;
-  struct pool_constant *next, *next_sym;
+  struct constant_descriptor_rtx *desc;
+  struct pool_constant *next;
+  struct pool_constant *next_sym;
   rtx constant;
   enum machine_mode mode;
   int labelno;
@@ -3257,80 +2928,20 @@ init_varasm_status (f)
      struct function *f;
 {
   struct varasm_status *p;
-  p = (struct varasm_status *) xmalloc (sizeof (struct varasm_status));
+  p = (struct varasm_status *) ggc_alloc (sizeof (struct varasm_status));
   f->varasm = p;
   p->x_const_rtx_hash_table
-    = ((struct constant_descriptor **)
-       xcalloc (MAX_RTX_HASH_TABLE, sizeof (struct constant_descriptor *)));
+    = ((struct constant_descriptor_rtx **)
+       ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+                         * sizeof (struct constant_descriptor_rtx *)));
   p->x_const_rtx_sym_hash_table
     = ((struct pool_constant **)
-       xcalloc (MAX_RTX_HASH_TABLE, sizeof (struct pool_constant *)));
+       ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+                         * sizeof (struct pool_constant *)));
 
   p->x_first_pool = p->x_last_pool = 0;
   p->x_pool_offset = 0;
 }
-
-/* Mark PC for GC.  */
-
-static void
-mark_pool_constant (pc)
-     struct pool_constant *pc;
-{
-  while (pc)
-    {
-      ggc_mark (pc);
-      ggc_mark_rtx (pc->constant);
-      ggc_mark_rtx (pc->desc->rtl);
-      pc = pc->next;
-    }
-}
-
-/* Mark P for GC.  */
-
-void
-mark_varasm_status (p)
-     struct varasm_status *p;
-{
-  if (p == NULL)
-    return;
-
-  mark_pool_constant (p->x_first_pool);
-}
-
-/* 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.  */
-
-void
-free_varasm_status (f)
-     struct function *f;
-{
-  struct varasm_status *p;
-  int i;
-
-  p = f->varasm;
-
-  /* Clear out the hash tables.  */
-  for (i = 0; i < MAX_RTX_HASH_TABLE; ++i)
-    {
-      struct constant_descriptor *cd;
-
-      cd = p->x_const_rtx_hash_table[i];
-      while (cd)
-       {
-         struct constant_descriptor *next = cd->next;
-
-         free (cd);
-         cd = next;
-       }
-    }
-
-  free (p->x_const_rtx_hash_table);
-  free (p->x_const_rtx_sym_hash_table);
-  free (p);
-
-  f->varasm = NULL;
-}
 \f
 
 /* Express an rtx for a constant integer (perhaps symbolic)
@@ -3447,11 +3058,13 @@ decode_rtx_const (mode, x, value)
   if (value->kind > RTX_DOUBLE && value->un.addr.base != 0)
     switch (GET_CODE (value->un.addr.base))
       {
+#if 0
       case SYMBOL_REF:
        /* Use the string's address, not the SYMBOL_REF's address,
           for the sake of addresses of library routines.  */
        value->un.addr.base = (rtx) XSTR (value->un.addr.base, 0);
        break;
+#endif
 
       case LABEL_REF:
        /* For a LABEL_REF, compare labels.  */
@@ -3512,39 +3125,28 @@ static int
 compare_constant_rtx (mode, x, desc)
      enum machine_mode mode;
      rtx x;
-     struct constant_descriptor *desc;
+     struct constant_descriptor_rtx *desc;
 {
-  int *p = (int *) desc->u.contents;
-  int *strp;
-  int len;
   struct rtx_const value;
 
   decode_rtx_const (mode, x, &value);
-  strp = (int *) &value;
-  len = sizeof value / sizeof (int);
 
   /* Compare constant contents.  */
-  while (--len >= 0)
-    if (*p++ != *strp++)
-      return 0;
-
-  return 1;
+  return memcmp (&value, &desc->value, sizeof (struct rtx_const)) == 0;
 }
 
 /* Construct a constant descriptor for the rtl-expression X.
    It is up to the caller to enter the descriptor in the hash table.  */
 
-static struct constant_descriptor *
+static struct constant_descriptor_rtx *
 record_constant_rtx (mode, x)
      enum machine_mode mode;
      rtx x;
 {
-  struct constant_descriptor *ptr;
+  struct constant_descriptor_rtx *ptr;
 
-  ptr = ((struct constant_descriptor *)
-        xcalloc (1, (offsetof (struct constant_descriptor, u)
-                     + sizeof (struct rtx_const))));
-  decode_rtx_const (mode, x, (struct rtx_const *) ptr->u.contents);
+  ptr = (struct constant_descriptor_rtx *) ggc_alloc (sizeof (*ptr));
+  decode_rtx_const (mode, x, &ptr->value);
 
   return ptr;
 }
@@ -3557,7 +3159,7 @@ mem_for_const_double (x)
      rtx x;
 {
   enum machine_mode mode = GET_MODE (x);
-  struct constant_descriptor *desc;
+  struct constant_descriptor_rtx *desc;
 
   for (desc = const_rtx_hash_table[const_hash_rtx (mode, x)]; desc;
        desc = desc->next)
@@ -3576,7 +3178,7 @@ force_const_mem (mode, x)
      rtx x;
 {
   int hash;
-  struct constant_descriptor *desc;
+  struct constant_descriptor_rtx *desc;
   char label[256];
   rtx def;
   struct pool_constant *pool;
@@ -4789,7 +4391,7 @@ output_constructor (exp, size, align)
 
 /* This TREE_LIST contains any weak symbol declarations waiting
    to be emitted.  */
-static tree weak_decls;
+static GTY(()) tree weak_decls;
 
 /* Mark DECL as weak.  */
 
@@ -5075,17 +4677,11 @@ make_decl_one_only (decl)
 void
 init_varasm_once ()
 {
-  const_str_htab = htab_create (128, const_str_htab_hash, const_str_htab_eq,
-                               const_str_htab_del);
+  const_str_htab = htab_create_ggc (128, const_str_htab_hash, 
+                                   const_str_htab_eq, NULL);
   in_named_htab = htab_create (31, in_named_entry_hash,
                               in_named_entry_eq, NULL);
 
-  ggc_add_root (const_hash_table, MAX_HASH_TABLE, sizeof const_hash_table[0],
-               mark_const_hash_entry);
-  ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
-               mark_const_str_htab);
-  ggc_add_tree_root (&weak_decls, 1);
-
   const_alias_set = new_alias_set ();
 }
 
@@ -5631,3 +5227,5 @@ default_binds_local_p (exp)
 
   return local_p;
 }
+
+#include "gt-varasm.h"
index eef2234099a18b970feeb2bbb72cff1a16aaba89..51e3e8bc142ed9d5c6a848874c31101fbaeea304 100644 (file)
 #include "config.h"
 #include "errors.h"
 #include "system.h"
-#include "rtl.h"
-#include "tree.h"
-#include "bitmap.h"
 #include "varray.h"
+#include "ggc.h"
 
 #define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
 
+static const size_t element_size[NUM_VARRAY_DATA] = {
+  sizeof (char),
+  sizeof (unsigned char),
+  sizeof (short),
+  sizeof (unsigned short),
+  sizeof (int),
+  sizeof (unsigned int),
+  sizeof (long),
+  sizeof (unsigned long),
+  sizeof (HOST_WIDE_INT),
+  sizeof (unsigned HOST_WIDE_INT),
+  sizeof (PTR),
+  sizeof (char *),
+  sizeof (struct rtx_def *),
+  sizeof (struct rtvec_def *),
+  sizeof (union tree_node *),
+  sizeof (struct bitmap_head_def *),
+  sizeof (struct reg_info_def *),
+  sizeof (struct const_equiv_data),
+  sizeof (struct basic_block_def *),
+  sizeof (struct elt_list *)
+};
+
+static const int uses_ggc[NUM_VARRAY_DATA] = {
+  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* unsigned HOST_WIDE_INT */
+  1, /* PTR */
+  1, 1, 1, 1, 1, /* bitmap_head_def */
+  0, 0, 0, 1
+};
+
 /* Allocate a virtual array with NUM_ELEMENT elements, each of which is
    ELEMENT_SIZE bytes long, named NAME.  Array elements are zeroed.  */
 varray_type
-varray_init (num_elements, element_size, name)
+varray_init (num_elements, element_kind, name)
      size_t num_elements;
-     size_t element_size;
+     enum varray_data_enum element_kind;
      const char *name;
 {
-  size_t data_size = num_elements * element_size;
-  varray_type ptr = (varray_type) xcalloc (VARRAY_HDR_SIZE + data_size, 1);
+  size_t data_size = num_elements * element_size[element_kind];
+  varray_type ptr;
+  if (uses_ggc [element_kind])
+    ptr = (varray_type) ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
+  else
+    ptr = (varray_type) xcalloc (VARRAY_HDR_SIZE + data_size, 1);
 
   ptr->num_elements = num_elements;
   ptr->elements_used = 0;
-  ptr->element_size = element_size;
+  ptr->type = element_kind;
   ptr->name = name;
   return ptr;
 }
@@ -58,11 +90,14 @@ varray_grow (va, n)
 
   if (n != old_elements)
     {
-      size_t element_size = va->element_size;
-      size_t old_data_size = old_elements * element_size;
-      size_t data_size = n * element_size;
-
-      va = (varray_type) xrealloc ((char *) va, VARRAY_HDR_SIZE + data_size);
+      size_t elem_size = element_size[va->type];
+      size_t old_data_size = old_elements * elem_size;
+      size_t data_size = n * elem_size;
+
+      if (uses_ggc[va->type])
+       va = (varray_type) ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
+      else
+       va = (varray_type) xrealloc ((char *) va, VARRAY_HDR_SIZE + data_size);
       va->num_elements = n;
       if (n > old_elements)
        memset (&va->data.c[old_data_size], 0, data_size - old_data_size);
@@ -71,6 +106,17 @@ varray_grow (va, n)
   return va;
 }
 
+/* Reset a varray to its original state.  */
+void
+varray_clear (va)
+     varray_type va;
+{
+  size_t data_size = element_size[va->type] * va->num_elements;
+
+  memset (va->data.c, 0, data_size);
+  va->elements_used = 0;
+}
+
 /* Check the bounds of a varray access.  */
 
 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
index 630a0a3581abf7e80bcaf51eda80919756a9df35..8d4dafb6ca66797fa145526634e5eed571a31bc2 100644 (file)
@@ -33,7 +33,7 @@
 /* Auxiliary structure used inside the varray structure, used for
    function integration data.  */
 
-struct const_equiv_data {
+struct const_equiv_data GTY(()) {
   /* Map pseudo reg number in calling function to equivalent constant.  We
      cannot in general substitute constants into parameter pseudo registers,
      since some machine descriptions (many RISCs) won't always handle
@@ -54,107 +54,153 @@ struct const_equiv_data {
   unsigned age;
 };
 
+/* Enum indicating what the varray contains.  
+   If this is changed, `element_size' in varray.c needs to be updated.  */
+
+enum varray_data_enum {
+  VARRAY_DATA_C,
+  VARRAY_DATA_UC,
+  VARRAY_DATA_S,
+  VARRAY_DATA_US,
+  VARRAY_DATA_I,
+  VARRAY_DATA_U,
+  VARRAY_DATA_L,
+  VARRAY_DATA_UL,
+  VARRAY_DATA_HINT,
+  VARRAY_DATA_UHINT,
+  VARRAY_DATA_GENERIC,
+  VARRAY_DATA_CPTR,
+  VARRAY_DATA_RTX,
+  VARRAY_DATA_RTVEC,
+  VARRAY_DATA_TREE,
+  VARRAY_DATA_BITMAP,
+  VARRAY_DATA_REG,
+  VARRAY_DATA_CONST_EQUIV,
+  VARRAY_DATA_BB,
+  VARRAY_DATA_TE,
+  NUM_VARRAY_DATA
+};
+
 /* Union of various array types that are used.  */
-typedef union varray_data_tag {
-  char                  c[1];
-  unsigned char                 uc[1];
-  short                         s[1];
-  unsigned short        us[1];
-  int                   i[1];
-  unsigned int          u[1];
-  long                  l[1];
-  unsigned long                 ul[1];
-  HOST_WIDE_INT                 hint[1];
-  unsigned HOST_WIDE_INT uhint[1];
-  PTR                   generic[1];
-  char                  *cptr[1];
-  struct rtx_def        *rtx[1];
-  struct rtvec_def      *rtvec[1];
-  union tree_node       *tree[1];
-  struct bitmap_head_def *bitmap[1];
-  struct sched_info_tag         *sched[1];
-  struct reg_info_def   *reg[1];
-  struct const_equiv_data const_equiv[1];
-  struct basic_block_def *bb[1];
-  struct elt_list       *te[1];
+typedef union varray_data_tag GTY (()) {
+  char                   GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_C")))         c[1];
+  unsigned char                  GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_UC")))        uc[1];
+  short                          GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_S")))         s[1];
+  unsigned short         GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_US")))        us[1];
+  int                    GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_I")))         i[1];
+  unsigned int           GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_U")))         u[1];
+  long                   GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_L")))         l[1];
+  unsigned long                  GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_UL")))        ul[1];
+  HOST_WIDE_INT                  GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_HINT")))      hint[1];
+  unsigned HOST_WIDE_INT  GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_UHINT")))     uhint[1];
+  PTR                    GTY ((length ("%0.num_elements"), use_param (""),
+                               tag ("VARRAY_DATA_GENERIC")))   generic[1];
+  char                  *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_CPTR")))      cptr[1];
+  struct rtx_def        *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_RTX")))       rtx[1];
+  struct rtvec_def      *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_RTVEC")))     rtvec[1];
+  union tree_node       *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_TREE")))      tree[1];
+  struct bitmap_head_def *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_BITMAP")))    bitmap[1];
+  struct reg_info_def   *GTY ((length ("%0.num_elements"), skip (""),
+                               tag ("VARRAY_DATA_REG")))       reg[1];
+  struct const_equiv_data GTY ((length ("%0.num_elements"),
+                       tag ("VARRAY_DATA_CONST_EQUIV")))       const_equiv[1];
+  struct basic_block_def *GTY ((length ("%0.num_elements"), skip (""),
+                               tag ("VARRAY_DATA_BB")))        bb[1];
+  struct elt_list       *GTY ((length ("%0.num_elements"),
+                               tag ("VARRAY_DATA_TE")))        te[1];
 } varray_data;
 
 /* Virtual array of pointers header.  */
-typedef struct varray_head_tag {
-  size_t       num_elements;   /* maximum element number allocated */
-  size_t        elements_used;  /* the number of elements used, if
+struct varray_head_tag GTY(()) {
+  size_t       num_elements;   /* Maximum element number allocated.  */
+  size_t        elements_used;  /* The number of elements used, if
                                   using VARRAY_PUSH/VARRAY_POP.  */
-  size_t       element_size;   /* size of each data element */
+  enum varray_data_enum type;  /* The kind of elements in the varray.  */
   const char   *name;          /* name of the varray for reporting errors */
-  varray_data  data;           /* data elements follow, must be last */
-} *varray_type;
+  varray_data  GTY ((desc ("%0.type"))) data;  /* The data elements follow, 
+                                                  must be last.  */
+};
+typedef struct varray_head_tag *varray_type;
 
 /* Allocate a virtual array with NUM elements, each of which is SIZE bytes
    long, named NAME.  Array elements are zeroed.  */
-extern varray_type varray_init PARAMS ((size_t, size_t, const char *));
+extern varray_type varray_init PARAMS ((size_t, enum varray_data_enum, 
+                                        const char *));
 
 #define VARRAY_CHAR_INIT(va, num, name) \
-  va = varray_init (num, sizeof (char), name)
+  va = varray_init (num, VARRAY_DATA_C, name)
 
 #define VARRAY_UCHAR_INIT(va, num, name) \
-  va = varray_init (num, sizeof (unsigned char), name)
+  va = varray_init (num, VARRAY_DATA_UC, name)
 
 #define VARRAY_SHORT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (short), name)
+  va = varray_init (num, VARRAY_DATA_S, name)
 
 #define VARRAY_USHORT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (unsigned short), name)
+  va = varray_init (num, VARRAY_DATA_US, name)
 
 #define VARRAY_INT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (int), name)
+  va = varray_init (num, VARRAY_DATA_I, name)
 
 #define VARRAY_UINT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (unsigned int), name)
+  va = varray_init (num, VARRAY_DATA_U, name)
 
 #define VARRAY_LONG_INIT(va, num, name) \
-  va = varray_init (num, sizeof (long), name)
+  va = varray_init (num, VARRAY_DATA_L, name)
 
 #define VARRAY_ULONG_INIT(va, num, name) \
-  va = varray_init (num, sizeof (unsigned long), name)
+  va = varray_init (num, VARRAY_DATA_UL, name)
 
 #define VARRAY_WIDE_INT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (HOST_WIDE_INT), name)
+  va = varray_init (num, VARRAY_DATA_HINT, name)
 
 #define VARRAY_UWIDE_INT_INIT(va, num, name) \
-  va = varray_init (num, sizeof (unsigned HOST_WIDE_INT), name)
+  va = varray_init (num, VARRAY_DATA_UHINT, name)
 
 #define VARRAY_GENERIC_PTR_INIT(va, num, name) \
-  va = varray_init (num, sizeof (PTR), name)
+  va = varray_init (num, VARRAY_DATA_GENERIC, name)
 
 #define VARRAY_CHAR_PTR_INIT(va, num, name) \
-  va = varray_init (num, sizeof (char *), name)
+  va = varray_init (num, VARRAY_DATA_CPTR, name)
 
 #define VARRAY_RTX_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct rtx_def *), name)
+  va = varray_init (num, VARRAY_DATA_RTX, name)
 
 #define VARRAY_RTVEC_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct rtvec_def), name)
+  va = varray_init (num, VARRAY_DATA_RTVEC, name)
 
 #define VARRAY_TREE_INIT(va, num, name) \
-  va = varray_init (num, sizeof (union tree_node *), name)
+  va = varray_init (num, VARRAY_DATA_TREE, name)
 
 #define VARRAY_BITMAP_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct bitmap_head_def *), name)
-
-#define VARRAY_SCHED_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct sched_info_tag *), name)
+  va = varray_init (num, VARRAY_DATA_BITMAP, name)
 
 #define VARRAY_REG_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct reg_info_def *), name)
+  va = varray_init (num, VARRAY_DATA_REG, name)
 
 #define VARRAY_CONST_EQUIV_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct const_equiv_data), name)
+  va = varray_init (num, VARRAY_DATA_CONST_EQUIV, name)
 
 #define VARRAY_BB_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct basic_block_def *), name)
+  va = varray_init (num, VARRAY_DATA_BB, name)
 
 #define VARRAY_ELT_LIST_INIT(va, num, name) \
-  va = varray_init (num, sizeof (struct elt_list *), name)
+  va = varray_init (num, VARRAY_DATA_TE, name)
 
 /* Free up memory allocated by the virtual array, but do not free any of the
    elements involved.  */
@@ -171,6 +217,10 @@ extern varray_type varray_grow     PARAMS ((varray_type, size_t));
 #define VARRAY_ACTIVE_SIZE(VA) ((VA)->elements_used)
 #define VARRAY_POP_ALL(VA)     ((VA)->elements_used = 0)
 
+#define VARRAY_CLEAR(VA) varray_clear(VA)
+
+extern void varray_clear       PARAMS ((varray_type));
+
 /* Check for VARRAY_xxx macros being in bound.  */
 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
 extern void varray_check_failed PARAMS ((varray_type, size_t,
@@ -221,7 +271,6 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
 #define VARRAY_RTVEC(VA, N)            VARRAY_CHECK (VA, N, rtvec)
 #define VARRAY_TREE(VA, N)             VARRAY_CHECK (VA, N, tree)
 #define VARRAY_BITMAP(VA, N)           VARRAY_CHECK (VA, N, bitmap)
-#define VARRAY_SCHED(VA, N)            VARRAY_CHECK (VA, N, sched)
 #define VARRAY_REG(VA, N)              VARRAY_CHECK (VA, N, reg)
 #define VARRAY_CONST_EQUIV(VA, N)      VARRAY_CHECK (VA, N, const_equiv)
 #define VARRAY_BB(VA, N)               VARRAY_CHECK (VA, N, bb)
@@ -244,7 +293,6 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
 #define VARRAY_PUSH_RTVEC(VA, X)       VARRAY_PUSH (VA, rtvec, X)
 #define VARRAY_PUSH_TREE(VA, X)                VARRAY_PUSH (VA, tree, X)
 #define VARRAY_PUSH_BITMAP(VA, X)      VARRAY_PUSH (VA, bitmap, X)
-#define VARRAY_PUSH_SCHED(VA, X)       VARRAY_PUSH (VA, sched, X)
 #define VARRAY_PUSH_REG(VA, X)         VARRAY_PUSH (VA, reg, X)
 #define VARRAY_PUSH_CONST_EQUIV(VA, X) VARRAY_PUSH (VA, const_equiv, X)
 #define VARRAY_PUSH_BB(VA, X)          VARRAY_PUSH (VA, bb, X)
@@ -266,7 +314,6 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
 #define VARRAY_TOP_RTVEC(VA)           VARRAY_TOP (VA, rtvec)
 #define VARRAY_TOP_TREE(VA)            VARRAY_TOP (VA, tree)
 #define VARRAY_TOP_BITMAP(VA)          VARRAY_TOP (VA, bitmap)
-#define VARRAY_TOP_SCHED(VA)           VARRAY_TOP (VA, sched)
 #define VARRAY_TOP_REG(VA)             VARRAY_TOP (VA, reg)
 #define VARRAY_TOP_CONST_EQUIV(VA)     VARRAY_TOP (VA, const_equiv)
 #define VARRAY_TOP_BB(VA)              VARRAY_TOP (VA, bb)
index 060899a3bc65939118e2f24e729d335fc711880a..75ce45ab2764df1797490ab31dab00261acc2304 100644 (file)
@@ -1,3 +1,18 @@
+2002-05-22  Geoffrey Keating  <geoffk@redhat.com>
+
+       * hashtab.h (struct htab): Update for change to length specifier.
+
+2002-05-10  Geoffrey Keating  <geoffk@redhat.com>
+
+       * hashtab.h (GTY): Define if undefined.
+       (htab_alloc): New typedef.
+       (htab_free): New typedef.
+       (struct htab): Support gengtype; allow user-specified memory
+       allocation.
+       (htab_create_alloc): New.
+       (htab_create): Replace with #define.
+       (htab_try_create): Delete.
+
 2002-04-16  David S. Miller  <davem@redhat.com>
 
        * xregex2.h (__restrict_arr): Define to __restrict on GCC
index 8871710e5d8b1694a760f17730d85045f7cbc0ea..a3ae5ae37fa7622e243309c03b0ed497ce29e336 100644 (file)
@@ -38,6 +38,10 @@ extern "C" {
 
 #include <ansidecl.h>
 
+#ifndef GTY
+#define GTY(X)
+#endif
+
 /* The type for a hash code.  */
 typedef unsigned int hashval_t;
 
@@ -63,12 +67,21 @@ typedef void (*htab_del) PARAMS ((void *));
    htab_traverse.  Return 1 to continue scan, 0 to stop.  */
 typedef int (*htab_trav) PARAMS ((void **, void *));
 
+/* Memory-allocation function, with the same functionality as calloc().
+   Iff it returns NULL, the hash table implementation will pass an error
+   code back to the user, so if your code doesn't handle errors,
+   best if you use xcalloc instead.  */
+typedef PTR (*htab_alloc) PARAMS ((size_t, size_t));
+
+/* We also need a free() routine.  */
+typedef void (*htab_free) PARAMS ((PTR));
+
 /* Hash tables are of the following type.  The structure
    (implementation) of this type is not needed for using the hash
    tables.  All work with hash table should be executed only through
    functions mentioned below. */
 
-struct htab
+struct htab GTY(())
 {
   /* Pointer to hash function.  */
   htab_hash hash_f;
@@ -79,8 +92,12 @@ struct htab
   /* Pointer to cleanup function.  */
   htab_del del_f;
 
+  /* Pointers to allocate/free functions.  */
+  htab_alloc alloc_f;
+  htab_free free_f;
+  
   /* Table itself.  */
-  PTR *entries;
+  PTR * GTY ((use_param (""), length ("%h.size"))) entries;
 
   /* Current size (in entries) of the hash table */
   size_t size;
@@ -98,10 +115,6 @@ struct htab
   /* The following member is used for debugging.  Its value is number
      of collisions fixed for time of work with the hash table. */
   unsigned int collisions;
-
-  /* This is non-zero if we are allowed to return NULL for function calls
-     that allocate memory.  */
-  int return_allocation_failure;
 };
 
 typedef struct htab *htab_t;
@@ -111,14 +124,14 @@ enum insert_option {NO_INSERT, INSERT};
 
 /* The prototypes of the package functions. */
 
-extern htab_t  htab_create     PARAMS ((size_t, htab_hash,
-                                        htab_eq, htab_del));
+extern htab_t  htab_create_alloc       PARAMS ((size_t, htab_hash,
+                                                htab_eq, htab_del,
+                                                htab_alloc, htab_free));
+
+/* Provided for convenience... */
+#define htab_create(SIZE, HASH, EQ, DEL) \
+  htab_create_alloc (SIZE, HASH, EQ, DEL, xcalloc, free)
 
-/* This function is like htab_create, but may return NULL if memory
-   allocation fails, and also signals that htab_find_slot_with_hash and
-   htab_find_slot are allowed to return NULL when inserting.  */
-extern htab_t  htab_try_create PARAMS ((size_t, htab_hash,
-                                        htab_eq, htab_del));
 extern void    htab_delete     PARAMS ((htab_t));
 extern void    htab_empty      PARAMS ((htab_t));
 
index cd112f9875a28b450b8987be6e31dfe3bbace757..5abfbebaa26736355466c381f64b847b462a420b 100644 (file)
@@ -1,3 +1,11 @@
+2002-06-03  Geoffrey Keating  <geoffk@redhat.com>
+
+       * hashtab.c (htab_create): Delete.
+       (htab_try_create): Delete.
+       (htab_create_alloc): New.
+       (htab_delete): Support user-specified memory allocation.
+       (htab_expand): Likewise.
+
 2002-05-22  Roman Lechtchinsky  <rl@cs.tu-berlin.de>
 
        * configure.in: Fix typo in the code checking for sys_errlist.
index 7477c35c3bc0b93eb65f2dca76bbd73a681d2e3d..06e41ac29e5021162b77be0e21e78afcffc781fb 100644 (file)
@@ -158,59 +158,36 @@ eq_pointer (p1, p2)
 /* This function creates table with length slightly longer than given
    source length.  Created hash table is initiated as empty (all the
    hash table entries are EMPTY_ENTRY).  The function returns the
-   created hash table.  Memory allocation must not fail.  */
+   created hash table, or NULL if memory allocation fails.  */
 
 htab_t
-htab_create (size, hash_f, eq_f, del_f)
+htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f)
      size_t size;
      htab_hash hash_f;
      htab_eq eq_f;
      htab_del del_f;
+     htab_alloc alloc_f;
+     htab_free free_f;
 {
   htab_t result;
 
   size = higher_prime_number (size);
-  result = (htab_t) xcalloc (1, sizeof (struct htab));
-  result->entries = (PTR *) xcalloc (size, sizeof (PTR));
-  result->size = size;
-  result->hash_f = hash_f;
-  result->eq_f = eq_f;
-  result->del_f = del_f;
-  result->return_allocation_failure = 0;
-  return result;
-}
-
-/* This function creates table with length slightly longer than given
-   source length.  The created hash table is initiated as empty (all the
-   hash table entries are EMPTY_ENTRY).  The function returns the created
-   hash table.  Memory allocation may fail; it may return NULL.  */
-
-htab_t
-htab_try_create (size, hash_f, eq_f, del_f)
-     size_t size;
-     htab_hash hash_f;
-     htab_eq eq_f;
-     htab_del del_f;
-{
-  htab_t result;
-
-  size = higher_prime_number (size);
-  result = (htab_t) calloc (1, sizeof (struct htab));
+  result = (htab_t) (*alloc_f) (1, sizeof (struct htab));
   if (result == NULL)
     return NULL;
-
-  result->entries = (PTR *) calloc (size, sizeof (PTR));
+  result->entries = (PTR *) (*alloc_f) (size, sizeof (PTR));
   if (result->entries == NULL)
     {
-      free (result);
+      if (free_f != NULL)
+       (*free_f) (result);
       return NULL;
     }
-
   result->size = size;
   result->hash_f = hash_f;
   result->eq_f = eq_f;
   result->del_f = del_f;
-  result->return_allocation_failure = 1;
+  result->alloc_f = alloc_f;
+  result->free_f = free_f;
   return result;
 }
 
@@ -229,8 +206,11 @@ htab_delete (htab)
          && htab->entries[i] != DELETED_ENTRY)
        (*htab->del_f) (htab->entries[i]);
 
-  free (htab->entries);
-  free (htab);
+  if (htab->free_f != NULL)
+    {
+      (*htab->free_f) (htab->entries);
+      (*htab->free_f) (htab);
+    }
 }
 
 /* This function clears all entries in the given hash table.  */
@@ -302,21 +282,17 @@ htab_expand (htab)
   PTR *oentries;
   PTR *olimit;
   PTR *p;
+  PTR *nentries;
 
   oentries = htab->entries;
   olimit = oentries + htab->size;
 
   htab->size = higher_prime_number (htab->size * 2);
 
-  if (htab->return_allocation_failure)
-    {
-      PTR *nentries = (PTR *) calloc (htab->size, sizeof (PTR *));
-      if (nentries == NULL)
-       return 0;
-      htab->entries = nentries;
-    }
-  else
-    htab->entries = (PTR *) xcalloc (htab->size, sizeof (PTR *));
+  nentries = (PTR *) (*htab->alloc_f) (htab->size, sizeof (PTR *));
+  if (nentries == NULL)
+    return 0;
+  htab->entries = nentries;
 
   htab->n_elements -= htab->n_deleted;
   htab->n_deleted = 0;
@@ -337,7 +313,8 @@ htab_expand (htab)
     }
   while (p < olimit);
 
-  free (oentries);
+  if (htab->free_f != NULL)
+    (*htab->free_f) (oentries);
   return 1;
 }