This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PCH] handle free lists; more random GGCing.
- From: Geoffrey Keating <geoffk at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 11 Mar 2002 10:32:25 -0800
- Subject: [PCH] handle free lists; more random GGCing.
Just another brick in the wall...
Oh, except for ggc_add_deletable_root, which is a useful new feature.
Bootstrapped & tested with gcac on i686-pc-linux-gnu.
--
Geoff Keating <geoffk@redhat.com>
===File ~/patches/pchbranch-moregc1.patch===================
2002-03-11 Geoffrey Keating <geoffk@redhat.com>
* 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.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.822.2.4
diff -p -u -p -r1.822.2.4 Makefile.in
--- Makefile.in 2002/03/10 21:37:33 1.822.2.4
+++ Makefile.in 2002/03/11 17:55:20
@@ -1150,7 +1150,7 @@ $(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) c-lex.h flags.h function.h output.h $(EXPR_H) \
- debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H)
+ debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_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) \
@@ -1167,7 +1167,7 @@ c-aux-info.o : c-aux-info.c $(CONFIG_H)
flags.h toplev.h
c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.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-pragma.h toplev.h output.h $(GGC_H) $(TM_P_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
@@ -1776,10 +1776,12 @@ s-preds: genpreds$(build_exeext) $(srcdi
GTFILES = config.h \
$(srcdir)/function.h $(srcdir)/rtl.h $(srcdir)/optabs.h \
$(srcdir)/except.c $(srcdir)/function.c $(srcdir)/integrate.c \
- $(srcdir)/stmt.c $(srcdir)/tree.c $(srcdir)/varasm.c
+ $(srcdir)/stmt.c $(srcdir)/tree.c $(srcdir)/varasm.c \
+ $(srcdir)/c-decl.c $(srcdir)/c-pragma.c
gtype-desc.h gtype-desc.c gtype-c.h gt-except.h gt-function.h : s-gtype; @true
gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h : s-gtype; @true
+gt-c-decl.h gt-c-pragma.h : s-gtype; @true
s-gtype: gengtype$(build_exeext) $(GTFILES)
./gengtype $(GTFILES)
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.288.2.2
diff -p -u -p -r1.288.2.2 c-decl.c
--- c-decl.c 2002/02/19 06:11:25 1.288.2.2
+++ c-decl.c 2002/03/11 17:55:21
@@ -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.
@@ -271,7 +271,8 @@ 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 gt_ggc_mp_binding_level PARAMS ((void *));
static void clear_limbo_values PARAMS ((tree));
static int duplicate_decls PARAMS ((tree, tree, int));
static int redeclaration_error_message PARAMS ((tree, tree));
@@ -853,13 +854,33 @@ finish_incomplete_decl (decl)
}
}
-/* 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. */
@@ -927,18 +948,8 @@ pushlevel (tag_transparent)
named_labels = 0;
}
- /* Reuse or create a struct for this binding level. */
+ newlevel = make_binding_level ();
- if (free_binding_level)
- {
- newlevel = free_binding_level;
- free_binding_level = free_binding_level->level_chain;
- }
- else
- {
- newlevel = make_binding_level ();
- }
-
/* Add this level to the front of the chain (stack) of levels that
are active. */
@@ -1157,14 +1168,8 @@ 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 (¤t_binding_level);
/* Dispose of the block that we just made inside some higher level. */
if (functionbody)
@@ -1243,18 +1248,8 @@ push_label_level ()
{
struct binding_level *newlevel;
- /* Reuse or create a struct for this binding level. */
+ newlevel = make_binding_level ();
- if (free_binding_level)
- {
- newlevel = free_binding_level;
- free_binding_level = free_binding_level->level_chain;
- }
- else
- {
- newlevel = make_binding_level ();
- }
-
/* Add this level to the front of the chain (stack) of label levels. */
newlevel->level_chain = label_level_chain;
@@ -1315,9 +1310,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);
}
/* Push a definition or a declaration of struct, union or enum tag "name".
@@ -3011,20 +3004,10 @@ lookup_name_current_level (name)
/* Mark ARG for GC. */
static void
-mark_binding_level (arg)
+gt_ggc_mp_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);
- }
+ gt_ggc_m_binding_level (*(struct binding_level **) arg);
}
/* Create the predefined scalar types of C,
@@ -3141,9 +3124,10 @@ c_init_decl_processing ()
ggc_add_tree_root (&named_labels, 1);
ggc_add_tree_root (&shadowed_labels, 1);
ggc_add_root (¤t_binding_level, 1, sizeof current_binding_level,
- mark_binding_level);
+ gt_ggc_mp_binding_level);
ggc_add_root (&label_level_chain, 1, sizeof label_level_chain,
- mark_binding_level);
+ gt_ggc_mp_binding_level);
+ ggc_add_deletable_root (&free_binding_level, sizeof (free_binding_level));
ggc_add_tree_root (&static_ctors, 1);
ggc_add_tree_root (&static_dtors, 1);
}
@@ -7306,7 +7290,7 @@ mark_c_function_context (f)
mark_c_language_function (&p->base);
ggc_mark_tree (p->shadowed_labels);
ggc_mark_tree (p->named_labels);
- mark_binding_level (&p->binding_level);
+ gt_ggc_m_binding_level (p->binding_level);
}
/* Copy the DECL_LANG_SPECIFIC data associated with NODE. */
@@ -7466,3 +7450,5 @@ build_void_list_node ()
tree t = build_tree_list (NULL_TREE, void_type_node);
return t;
}
+
+#include "gt-c-decl.h"
Index: c-pragma.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pragma.c,v
retrieving revision 1.46
diff -p -u -p -r1.46 c-pragma.c
--- c-pragma.c 2001/11/13 03:20:58 1.46
+++ c-pragma.c 2002/03/11 17:55:21
@@ -39,8 +39,7 @@ Software Foundation, 59 Temple Place - S
#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,6 +47,7 @@ typedef struct align_stack
struct align_stack * prev;
} align_stack;
+#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
static struct align_stack * alignment_stack = NULL;
/* If we have a "global" #pragma pack(<n>) in effect when the first
@@ -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
@@ -76,7 +75,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;
@@ -138,23 +137,15 @@ pop_alignment (id)
else
maximum_field_alignment = entry->alignment;
- free (alignment_stack);
-
alignment_stack = entry;
}
}
static void
-mark_align_stack (p)
+gt_ggc_mp_align_stack (p)
void *p;
{
- align_stack *a = *(align_stack **) p;
-
- while (a)
- {
- ggc_mark_tree (a->id);
- a = a->prev;
- }
+ gt_ggc_m_align_stack (*(align_stack **) p);
}
#else /* not HANDLE_PRAGMA_PACK_PUSH_POP */
#define SET_GLOBAL_ALIGNMENT(ALIGN) (maximum_field_alignment = (ALIGN))
@@ -317,6 +308,8 @@ init_pragma ()
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
ggc_add_root (&alignment_stack, 1, sizeof(alignment_stack),
- mark_align_stack);
+ gt_ggc_mp_align_stack);
#endif
}
+
+#include "gt-c-pragma.h"
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.242.4.4
diff -p -u -p -r1.242.4.4 emit-rtl.c
--- emit-rtl.c 2002/03/10 21:37:34 1.242.4.4
+++ emit-rtl.c 2002/03/11 17:55:22
@@ -4244,6 +4244,9 @@ emit (x)
abort ();
}
+/* Space for free sequence stack entries. */
+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
@@ -4257,7 +4260,13 @@ start_sequence ()
{
struct sequence_stack *tem;
- tem = (struct sequence_stack *) ggc_alloc (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;
@@ -4373,6 +4382,10 @@ end_sequence ()
last_insn = tem->last;
seq_rtl_expr = tem->sequence_rtl_expr;
seq_stack = tem->next;
+
+ 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
@@ -4911,6 +4924,8 @@ init_emit_once (line_numbers)
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);
+
+ ggc_add_deletable_root (&free_sequence_stack, sizeof (free_sequence_stack));
}
/* Query and clear/ restore no_line_numbers. This is used by the
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.341.4.6
diff -p -u -p -r1.341.4.6 function.c
--- function.c 2002/03/09 10:56:17 1.341.4.6
+++ function.c 2002/03/11 17:55:23
@@ -7921,7 +7921,7 @@ ggc_mark_struct_function (f)
mark_function_status (f);
mark_eh_status (f->eh);
- mark_stmt_status (f->stmt);
+ gt_ggc_m_stmt_status (f->stmt);
gt_ggc_m_expr_status (f->expr);
gt_ggc_m_emit_status (f->emit);
gt_ggc_m_varasm_status (f->varasm);
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.46.4.3
diff -p -u -p -r1.46.4.3 ggc-common.c
--- ggc-common.c 2002/03/10 21:37:35 1.46.4.3
+++ ggc-common.c 2002/03/11 17:55:23
@@ -234,15 +234,40 @@ ggc_htab_delete (slot, info)
return 1;
}
+struct ggc_deletable_root {
+ struct ggc_deletable_root *next;
+ void *base;
+ size_t size;
+};
+
+static struct ggc_deletable_root *deletables;
+
+void
+ggc_add_deletable_root (x, size)
+ PTR x;
+ size_t size;
+{
+ struct ggc_deletable_root *d = xmalloc (sizeof (d));
+ d->base = x;
+ d->size = size;
+ d->next = deletables;
+ deletables = d;
+}
+
+
/* Iterate through all registered roots and mark each element. */
void
ggc_mark_roots ()
{
+ struct ggc_deletable_root *d;
struct ggc_root *x;
struct d_htab_root *y;
VARRAY_TREE_INIT (ggc_pending_trees, 4096, "ggc_pending_trees");
+
+ for (d = deletables; d != NULL; d = d->next)
+ memset (d->base, 0, d->size);
for (x = roots; x != NULL; x = x->next)
{
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.39.6.3
diff -p -u -p -r1.39.6.3 ggc.h
--- ggc.h 2002/03/10 21:37:35 1.39.6.3
+++ ggc.h 2002/03/11 17:55:23
@@ -72,6 +72,10 @@ typedef void (*ggc_htab_mark) PARAMS ((c
extern void ggc_add_deletable_htab PARAMS ((PTR, ggc_htab_marked_p,
ggc_htab_mark));
+/* Add a variable to be cleared when collection starts. The variable
+ would usually be a pointer to a `free list' of reusable objects. */
+extern void ggc_add_deletable_root PARAMS ((PTR, size_t));
+
/* 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 *));
@@ -201,7 +205,6 @@ extern void (*lang_mark_false_label_stac
/* Mark functions for various structs scattered about. */
void mark_eh_status PARAMS ((struct eh_status *));
-void mark_stmt_status PARAMS ((struct stmt_status *));
/* Statistics. */
Index: lists.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/lists.c,v
retrieving revision 1.10
diff -p -u -p -r1.10 lists.c
--- lists.c 2001/10/11 03:15:53 1.10
+++ lists.c 2002/03/11 17:55:23
@@ -26,7 +26,6 @@ Software Foundation, 59 Temple Place - S
#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. */
@@ -108,20 +107,11 @@ 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);
+ ggc_add_deletable_root (&unused_expr_list, sizeof (unused_expr_list));
+ ggc_add_deletable_root (&unused_insn_list, sizeof (unused_insn_list));
}
/* This function will free up an entire list of EXPR_LIST nodes. */
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.242.4.4
diff -p -u -p -r1.242.4.4 stmt.c
--- stmt.c 2002/03/09 10:56:20 1.242.4.4
+++ stmt.c 2002/03/11 17:55:24
@@ -54,10 +54,6 @@ Software Foundation, 59 Temple Place - S
#include "output.h"
#include "ggc.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
@@ -256,7 +252,7 @@ struct nesting
/* 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.
@@ -278,8 +274,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)
/* In some cases it is impossible to generate code for a forward goto
@@ -448,9 +443,10 @@ gt_ggc_mr_nesting_cond (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);
+ ggc_set_mark (n);
+ gt_ggc_m_rtx_def (n->exit_label);
+ gt_ggc_m_rtx_def (n->data.cond.endif_label);
+ gt_ggc_m_rtx_def (n->data.cond.next_label);
n = n->next;
}
@@ -465,11 +461,12 @@ gt_ggc_mr_nesting_loop (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);
+ ggc_set_mark (n);
+ gt_ggc_m_rtx_def (n->exit_label);
+ gt_ggc_m_rtx_def (n->data.loop.start_label);
+ gt_ggc_m_rtx_def (n->data.loop.end_label);
+ gt_ggc_m_rtx_def (n->data.loop.alt_end_label);
+ gt_ggc_m_rtx_def (n->data.loop.continue_label);
n = n->next;
}
@@ -483,17 +480,16 @@ gt_ggc_mr_nesting_block (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);
+ ggc_set_mark (n);
+ gt_ggc_m_rtx_def (n->exit_label);
+ gt_ggc_m_rtx_def (n->data.block.stack_level);
+ gt_ggc_m_rtx_def (n->data.block.first_insn);
+ gt_ggc_m_tree_node (n->data.block.cleanups);
+ gt_ggc_m_tree_node (n->data.block.outer_cleanups);
gt_ggc_m_label_chain (n->data.block.label_chain);
- ggc_mark_rtx (n->data.block.last_unconditional_cleanup);
+ gt_ggc_m_rtx_def (n->data.block.last_unconditional_cleanup);
/* ??? cleanup_ptr never points outside the stack, does it? */
@@ -509,48 +505,20 @@ gt_ggc_mr_nesting_case_stmt (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);
+ ggc_set_mark (n);
+ gt_ggc_m_rtx_def (n->exit_label);
+ gt_ggc_m_rtx_def (n->data.case_stmt.start);
+
+ gt_ggc_m_tree_node (n->data.case_stmt.default_label);
+ gt_ggc_m_tree_node (n->data.case_stmt.index_expr);
+ gt_ggc_m_tree_node (n->data.case_stmt.nominal_type);
gt_ggc_m_case_node (n->data.case_stmt.case_list);
n = n->next;
}
}
-/* Mark P for GC. */
-
void
-mark_stmt_status (p)
- struct stmt_status *p;
-{
- if (p == 0)
- return;
-
- ggc_mark (p);
- gt_ggc_mr_nesting_block (p->x_block_stack);
- gt_ggc_mr_nesting_cond (p->x_cond_stack);
- gt_ggc_mr_nesting_loop (p->x_loop_stack);
- gt_ggc_mr_nesting_case_stmt (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);
-
- gt_ggc_m_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 *)ggc_alloc (sizeof (struct stmt_status)));
@@ -571,8 +539,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 ();
}
/* Return nonzero if anything is pushed on the loop, condition, or case
@@ -1235,7 +1202,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
@@ -1587,7 +1554,7 @@ expand_asm_operands (string, outputs, in
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. */
@@ -2343,7 +2310,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 which will return a value.
@@ -2362,7 +2330,6 @@ expand_start_stmt_expr ()
start_sequence_for_rtl_expr (t);
NO_DEFER_POP;
expr_stmts_for_value++;
- last_expr_value = NULL_RTX;
return t;
}
@@ -2408,7 +2375,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;
@@ -2499,7 +2466,7 @@ expand_end_cond ()
emit_label (thiscond->data.cond.endif_label);
POPSTACK (cond_stack);
- last_expr_type = 0;
+ clear_last_expr ();
}
/* Generate RTL for the start of a loop. EXIT_FLAG is nonzero if this
@@ -2733,7 +2700,7 @@ expand_end_loop ()
POPSTACK (loop_stack);
- last_expr_type = 0;
+ clear_last_expr ();
}
/* Finish a null loop, aka do { } while (0). */
@@ -2746,7 +2713,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.
@@ -2758,7 +2725,7 @@ int
expand_continue_loop (whichloop)
struct nesting *whichloop;
{
- last_expr_type = 0;
+ clear_last_expr ();
if (whichloop == 0)
whichloop = loop_stack;
if (whichloop == 0)
@@ -2775,7 +2742,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)
@@ -2795,7 +2762,7 @@ expand_exit_loop_if_false (whichloop, co
{
rtx label = gen_label_rtx ();
rtx last_insn;
- last_expr_type = 0;
+ clear_last_expr ();
if (whichloop == 0)
whichloop = loop_stack;
@@ -2882,7 +2849,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)
{
@@ -2954,7 +2921,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 ();
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.571.2.1
diff -p -u -p -r1.571.2.1 toplev.c
--- toplev.c 2002/02/13 23:35:42 1.571.2.1
+++ toplev.c 2002/03/11 17:55:25
@@ -5034,7 +5034,6 @@ lang_independent_init ()
|| warn_notreached);
init_regs ();
init_alias_once ();
- init_stmt ();
init_loop ();
init_reload ();
init_function_once ();
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.299.2.3
diff -p -u -p -r1.299.2.3 tree.h
--- tree.h 2002/03/09 21:59:37 1.299.2.3
+++ tree.h 2002/03/11 17:55:25
@@ -3066,7 +3066,6 @@ extern bool parse_output_constraint
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));
============================================================