Commit a3770a81 by Richard Henderson Committed by Mark Mitchell

Makefile.in (ggc-simple.o): Depend on varray.h.

	* Makefile.in (ggc-simple.o): Depend on varray.h.
	(rtl.o): Depend on ggc.h.
	(genattrtab.o): Depend on ggc.h.
	(print-tree.o): Likewise.
	(fold-const.o): Likewise.
	* emit-rtl.c (sequence_element_free_list): Remove, and all references.
	(make_insn_raw): Don't cache insns when GC'ing.
	(emit_insn_before): Likewise.
	(emit_insn_after): Likewise.
	(emit_insn): Likewise.
	(start_sequence): Use xmalloc to allocate the sequence_stack.
	(end_sequence): Add free to free it.
	(gen_sequence): Don't cache insns when GC'ing.
	(clear_emit_caches): Don't use sequence_element_free_list.
	(init_emit): Use xcalloc, not xmalloc+bzero.
	* fold-const.c (size_int_wide): Kill the cache, when GC'ing.
	* function.c (pop_function_context_from): Use free to free the
	fixup_var_refs_queue.
	(put_reg_into_stack): Allocate it with xmalloc.
	* genattrtab.c: Include ggc.h.
	(operate_exp): Don't use obstack_free when GC'ing.
	(simplify_cond): Likewise.
	(simplify_text_exp): Likewise.
	(optimize_attrs): Likewise.
	* gengentrtl.c (gendef): Use ggc_alloc_rtx to allocate RTL, when
	GC'ing.
	(gencode): Generate a #include for ggc.h.
	* ggc-callbacks.c (ggc_p): Define it to zero.
	* ggc-none.c (ggc_p): Likewise.
	* ggc-simple.c: Include varray.h.
	(ggc_mark_tree_varray): New function.
	(ggc_add_tree_varray_root): Likewise.
	(ggc_mark_tree_varray_ptr): Likewise.
	* ggc.h (ggc_p): Declare.
	(varray_head_tag): Likewise.
	(ggc_add_tree_varray_root): Declare.
	* print-tree.c (print_node): Don't check for TREE_PERMANENT
	inconsistencies when GC'ing.
	* rtl.c: Include ggc.h.
	(rtvec_alloc): Use ggc_alloc_rtvec when GC'ing.
	(rtx_alloc): Use ggc_alloc_rtx when GC'ing.
	(rtx_free): Don't call obstack_free when GC'ing.
	* toplev.c (rest_of_compilation): Call ggc_collect after every
	pass, if GC'ing.
	* tree.c (push_obstacks): Do nothing, if GC'ing.
	(pop_obstacks_nochange): Likewise.
	(pop_obstacks): Likewise.
	(make_node): Use ggc_alloc_tree when GC'ing.
	(copy_node): Likewise.
	(get_identifier): Use ggc_alloc_string when GC'ing.
	(build_string): Likewise.
	(make_tree_vec): Use ggc_alloc_tree when GC'ing.
	(tree_cons): Likewise.
	(build1): Likewise.
	(type_hash_canon): Don't call obstack_free when GC'ing.

Co-Authored-By: Bernd Schmidt <bernds@cygnus.co.uk>
Co-Authored-By: Mark Mitchell <mark@codesourcery.com>

From-SVN: r29125
parent 616aedda
Sun Sep 5 00:35:17 1999 Richard Henderson <rth@cygnus.com>
Bernd Schmidt <bernds@cygnus.co.uk>
Mark Mitchell <mark@codesourcery.com>
* Makefile.in (ggc-simple.o): Depend on varray.h.
(rtl.o): Depend on ggc.h.
(genattrtab.o): Depend on ggc.h.
(print-tree.o): Likewise.
(fold-const.o): Likewise.
* emit-rtl.c (sequence_element_free_list): Remove, and all references.
(make_insn_raw): Don't cache insns when GC'ing.
(emit_insn_before): Likewise.
(emit_insn_after): Likewise.
(emit_insn): Likewise.
(start_sequence): Use xmalloc to allocate the sequence_stack.
(end_sequence): Add free to free it.
(gen_sequence): Don't cache insns when GC'ing.
(clear_emit_caches): Don't use sequence_element_free_list.
(init_emit): Use xcalloc, not xmalloc+bzero.
* fold-const.c (size_int_wide): Kill the cache, when GC'ing.
* function.c (pop_function_context_from): Use free to free the
fixup_var_refs_queue.
(put_reg_into_stack): Allocate it with xmalloc.
* genattrtab.c: Include ggc.h.
(operate_exp): Don't use obstack_free when GC'ing.
(simplify_cond): Likewise.
(simplify_text_exp): Likewise.
(optimize_attrs): Likewise.
* gengentrtl.c (gendef): Use ggc_alloc_rtx to allocate RTL, when
GC'ing.
(gencode): Generate a #include for ggc.h.
* ggc-callbacks.c (ggc_p): Define it to zero.
* ggc-none.c (ggc_p): Likewise.
* ggc-simple.c: Include varray.h.
(ggc_mark_tree_varray): New function.
(ggc_add_tree_varray_root): Likewise.
(ggc_mark_tree_varray_ptr): Likewise.
* ggc.h (ggc_p): Declare.
(varray_head_tag): Likewise.
(ggc_add_tree_varray_root): Declare.
* print-tree.c (print_node): Don't check for TREE_PERMANENT
inconsistencies when GC'ing.
* rtl.c: Include ggc.h.
(rtvec_alloc): Use ggc_alloc_rtvec when GC'ing.
(rtx_alloc): Use ggc_alloc_rtx when GC'ing.
(rtx_free): Don't call obstack_free when GC'ing.
* toplev.c (rest_of_compilation): Call ggc_collect after every
pass, if GC'ing.
* tree.c (push_obstacks): Do nothing, if GC'ing.
(pop_obstacks_nochange): Likewise.
(pop_obstacks): Likewise.
(make_node): Use ggc_alloc_tree when GC'ing.
(copy_node): Likewise.
(get_identifier): Use ggc_alloc_string when GC'ing.
(build_string): Likewise.
(make_tree_vec): Use ggc_alloc_tree when GC'ing.
(tree_cons): Likewise.
(build1): Likewise.
(type_hash_canon): Don't call obstack_free when GC'ing.
Sat Sep 4 21:52:32 1999 Richard Henderson <rth@cygnus.com> Sat Sep 4 21:52:32 1999 Richard Henderson <rth@cygnus.com>
* haifa-sched.c (schedule_block): Use next_nonnote_insn instead * haifa-sched.c (schedule_block): Use next_nonnote_insn instead
......
...@@ -1432,7 +1432,8 @@ dumpvers: dumpvers.c ...@@ -1432,7 +1432,8 @@ dumpvers: dumpvers.c
version.o: version.c version.o: version.c
ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_BASE_H) $(TREE_H) flags.h ggc.h ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_BASE_H) $(TREE_H) flags.h \
ggc.h varray.h
ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_BASE_H) ggc.h ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_BASE_H) ggc.h
...@@ -1452,11 +1453,11 @@ convert.o: convert.c $(CONFIG_H) $(TREE_H) flags.h convert.h toplev.h ...@@ -1452,11 +1453,11 @@ convert.o: convert.c $(CONFIG_H) $(TREE_H) flags.h convert.h toplev.h
tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h \ tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h \
ggc.h ggc.h
print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) ggc.h
stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \ stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
function.h $(EXPR_H) $(RTL_H) toplev.h ggc.h function.h $(EXPR_H) $(RTL_H) toplev.h ggc.h
fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \ fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
$(RTL_H) $(RTL_H) ggc.h
toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \ flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \ insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \
...@@ -1466,7 +1467,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \ ...@@ -1466,7 +1467,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
-DTARGET_NAME=\"$(target_alias)\" \ -DTARGET_NAME=\"$(target_alias)\" \
-c `echo $(srcdir)/toplev.c | sed 's,^\./,,'` -c `echo $(srcdir)/toplev.c | sed 's,^\./,,'`
rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h ggc.h
print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h basic-block.h print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h basic-block.h
rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H) rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H)
...@@ -1845,7 +1846,7 @@ genattrtab : genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_RTLANA ...@@ -1845,7 +1846,7 @@ genattrtab : genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_RTLANA
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_RTLANAL) $(HOST_LIBS) genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_RTLANAL) $(HOST_LIBS)
genattrtab.o : genattrtab.c $(RTL_H) $(build_xm_file) system.h insn-config.h errors.h genattrtab.o : genattrtab.c $(RTL_H) $(build_xm_file) system.h insn-config.h errors.h ggc.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c
genoutput : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS) genoutput : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
......
...@@ -158,21 +158,18 @@ struct rtx_def const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1]; ...@@ -158,21 +158,18 @@ struct rtx_def const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
/* start_sequence and gen_sequence can make a lot of rtx expressions which are /* start_sequence and gen_sequence can make a lot of rtx expressions which are
shortly thrown away. We use two mechanisms to prevent this waste: shortly thrown away. We use two mechanisms to prevent this waste:
First, we keep a list of the expressions used to represent the sequence For sizes up to 5 elements, we keep a SEQUENCE and its associated
stack in sequence_element_free_list. rtvec for use by gen_sequence. One entry for each size is
sufficient because most cases are calls to gen_sequence followed by
Second, for sizes up to 5 elements, we keep a SEQUENCE and its associated immediately emitting the SEQUENCE. Reuse is safe since emitting a
rtvec for use by gen_sequence. One entry for each size is sufficient sequence is destructive on the insn in it anyway and hence can't be
because most cases are calls to gen_sequence followed by immediately redone.
emitting the SEQUENCE. Reuse is safe since emitting a sequence is
destructive on the insn in it anyway and hence can't be redone.
We do not bother to save this cached data over nested function calls. We do not bother to save this cached data over nested function calls.
Instead, we just reinitialize them. */ Instead, we just reinitialize them. */
#define SEQUENCE_RESULT_SIZE 5 #define SEQUENCE_RESULT_SIZE 5
static struct sequence_stack *sequence_element_free_list;
static rtx sequence_result[SEQUENCE_RESULT_SIZE]; static rtx sequence_result[SEQUENCE_RESULT_SIZE];
/* During RTL generation, we also keep a list of free INSN rtl codes. */ /* During RTL generation, we also keep a list of free INSN rtl codes. */
...@@ -2256,7 +2253,7 @@ make_insn_raw (pattern) ...@@ -2256,7 +2253,7 @@ make_insn_raw (pattern)
register rtx insn; register rtx insn;
/* If in RTL generation phase, see if FREE_INSN can be used. */ /* If in RTL generation phase, see if FREE_INSN can be used. */
if (free_insn != 0 && rtx_equal_function_value_matters) if (!ggc_p && free_insn != 0 && rtx_equal_function_value_matters)
{ {
insn = free_insn; insn = free_insn;
free_insn = NEXT_INSN (free_insn); free_insn = NEXT_INSN (free_insn);
...@@ -2600,7 +2597,7 @@ emit_insn_before (pattern, before) ...@@ -2600,7 +2597,7 @@ emit_insn_before (pattern, before)
insn = XVECEXP (pattern, 0, i); insn = XVECEXP (pattern, 0, i);
add_insn_before (insn, before); add_insn_before (insn, before);
} }
if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) if (!ggc_p && XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
sequence_result[XVECLEN (pattern, 0)] = pattern; sequence_result[XVECLEN (pattern, 0)] = pattern;
} }
else else
...@@ -2720,7 +2717,7 @@ emit_insn_after (pattern, after) ...@@ -2720,7 +2717,7 @@ emit_insn_after (pattern, after)
add_insn_after (insn, after); add_insn_after (insn, after);
after = insn; after = insn;
} }
if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) if (!ggc_p && XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
sequence_result[XVECLEN (pattern, 0)] = pattern; sequence_result[XVECLEN (pattern, 0)] = pattern;
} }
else else
...@@ -2868,7 +2865,7 @@ emit_insn (pattern) ...@@ -2868,7 +2865,7 @@ emit_insn (pattern)
insn = XVECEXP (pattern, 0, i); insn = XVECEXP (pattern, 0, i);
add_insn (insn); add_insn (insn);
} }
if (XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE) if (!ggc_p && XVECLEN (pattern, 0) < SEQUENCE_RESULT_SIZE)
sequence_result[XVECLEN (pattern, 0)] = pattern; sequence_result[XVECLEN (pattern, 0)] = pattern;
} }
else else
...@@ -3188,14 +3185,7 @@ start_sequence () ...@@ -3188,14 +3185,7 @@ start_sequence ()
{ {
struct sequence_stack *tem; struct sequence_stack *tem;
if (sequence_element_free_list) tem = (struct sequence_stack *) xmalloc (sizeof (struct sequence_stack));
{
/* Reuse a previously-saved struct sequence_stack. */
tem = sequence_element_free_list;
sequence_element_free_list = tem->next;
}
else
tem = (struct sequence_stack *) permalloc (sizeof (struct sequence_stack));
tem->next = seq_stack; tem->next = seq_stack;
tem->first = first_insn; tem->first = first_insn;
...@@ -3298,8 +3288,7 @@ end_sequence () ...@@ -3298,8 +3288,7 @@ end_sequence ()
seq_rtl_expr = tem->sequence_rtl_expr; seq_rtl_expr = tem->sequence_rtl_expr;
seq_stack = tem->next; seq_stack = tem->next;
tem->next = sequence_element_free_list; free (tem);
sequence_element_free_list = tem;
} }
/* Return 1 if currently emitting into a sequence. */ /* Return 1 if currently emitting into a sequence. */
...@@ -3340,14 +3329,18 @@ gen_sequence () ...@@ -3340,14 +3329,18 @@ gen_sequence ()
|| (GET_CODE (first_insn) == CALL_INSN || (GET_CODE (first_insn) == CALL_INSN
&& CALL_INSN_FUNCTION_USAGE (first_insn) == NULL_RTX))) && CALL_INSN_FUNCTION_USAGE (first_insn) == NULL_RTX)))
{ {
NEXT_INSN (first_insn) = free_insn; if (!ggc_p)
free_insn = first_insn; {
NEXT_INSN (first_insn) = free_insn;
free_insn = first_insn;
}
return PATTERN (first_insn); return PATTERN (first_insn);
} }
/* Put them in a vector. See if we already have a SEQUENCE of the /* Put them in a vector. See if we already have a SEQUENCE of the
appropriate length around. */ appropriate length around. */
if (len < SEQUENCE_RESULT_SIZE && (result = sequence_result[len]) != 0) if (!ggc_p && len < SEQUENCE_RESULT_SIZE
&& (result = sequence_result[len]) != 0)
sequence_result[len] = 0; sequence_result[len] = 0;
else else
{ {
...@@ -3385,7 +3378,6 @@ clear_emit_caches () ...@@ -3385,7 +3378,6 @@ clear_emit_caches ()
int i; int i;
/* Clear the start_sequence/gen_sequence cache. */ /* Clear the start_sequence/gen_sequence cache. */
sequence_element_free_list = 0;
for (i = 0; i < SEQUENCE_RESULT_SIZE; i++) for (i = 0; i < SEQUENCE_RESULT_SIZE; i++)
sequence_result[i] = 0; sequence_result[i] = 0;
free_insn = 0; free_insn = 0;
...@@ -3418,17 +3410,15 @@ init_emit () ...@@ -3418,17 +3410,15 @@ init_emit ()
f->emit->regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101; f->emit->regno_pointer_flag_length = LAST_VIRTUAL_REGISTER + 101;
f->emit->regno_pointer_flag f->emit->regno_pointer_flag
= (char *) xmalloc (f->emit->regno_pointer_flag_length); = (char *) xcalloc (f->emit->regno_pointer_flag_length, sizeof (char));
bzero (f->emit->regno_pointer_flag, f->emit->regno_pointer_flag_length);
f->emit->regno_pointer_align f->emit->regno_pointer_align
= (char *) xmalloc (f->emit->regno_pointer_flag_length); = (char *) xcalloc (f->emit->regno_pointer_flag_length,
bzero (f->emit->regno_pointer_align, f->emit->regno_pointer_flag_length); sizeof (char));
regno_reg_rtx regno_reg_rtx
= (rtx *) xmalloc (f->emit->regno_pointer_flag_length * sizeof (rtx)); = (rtx *) xcalloc (f->emit->regno_pointer_flag_length * sizeof (rtx),
bzero ((char *) regno_reg_rtx, sizeof (rtx));
f->emit->regno_pointer_flag_length * sizeof (rtx));
/* Put copies of all the virtual register rtx into regno_reg_rtx. */ /* Put copies of all the virtual register rtx into regno_reg_rtx. */
init_virtual_regs (f->emit); init_virtual_regs (f->emit);
......
...@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */
#include "tree.h" #include "tree.h"
#include "rtl.h" #include "rtl.h"
#include "toplev.h" #include "toplev.h"
#include "ggc.h"
static void encode PROTO((HOST_WIDE_INT *, static void encode PROTO((HOST_WIDE_INT *,
HOST_WIDE_INT, HOST_WIDE_INT)); HOST_WIDE_INT, HOST_WIDE_INT));
...@@ -1692,29 +1693,32 @@ size_int_wide (number, high, bit_p) ...@@ -1692,29 +1693,32 @@ size_int_wide (number, high, bit_p)
unsigned HOST_WIDE_INT number, high; unsigned HOST_WIDE_INT number, high;
int bit_p; int bit_p;
{ {
register tree t; tree t;
/* Type-size nodes already made for small sizes. */
static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1][2]; if (!ggc_p)
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high
&& size_table[number][bit_p] != 0)
return size_table[number][bit_p];
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high)
{
push_obstacks_nochange ();
/* Make this a permanent node. */
end_temporary_allocation ();
t = build_int_2 (number, 0);
TREE_TYPE (t) = bit_p ? bitsizetype : sizetype;
size_table[number][bit_p] = t;
pop_obstacks ();
}
else
{ {
t = build_int_2 (number, high); /* Type-size nodes already made for small sizes. */
TREE_TYPE (t) = bit_p ? bitsizetype : sizetype; static tree size_table[2*HOST_BITS_PER_WIDE_INT + 1][2];
TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0);
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high
&& size_table[number][bit_p] != 0)
return size_table[number][bit_p];
if (number < 2*HOST_BITS_PER_WIDE_INT + 1 && ! high)
{
push_obstacks_nochange ();
/* Make this a permanent node. */
end_temporary_allocation ();
t = build_int_2 (number, 0);
TREE_TYPE (t) = bit_p ? bitsizetype : sizetype;
size_table[number][bit_p] = t;
pop_obstacks ();
return t;
}
} }
t = build_int_2 (number, high);
TREE_TYPE (t) = bit_p ? bitsizetype : sizetype;
TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0);
return t; return t;
} }
......
...@@ -350,6 +350,7 @@ pop_function_context_from (context) ...@@ -350,6 +350,7 @@ pop_function_context_from (context)
{ {
struct function *p = outer_function_chain; struct function *p = outer_function_chain;
struct var_refs_queue *queue; struct var_refs_queue *queue;
struct var_refs_queue *next;
current_function = p; current_function = p;
outer_function_chain = p->next; outer_function_chain = p->next;
...@@ -367,9 +368,14 @@ pop_function_context_from (context) ...@@ -367,9 +368,14 @@ pop_function_context_from (context)
/* Finish doing put_var_into_stack for any of our variables /* Finish doing put_var_into_stack for any of our variables
which became addressable during the nested function. */ which became addressable during the nested function. */
for (queue = p->fixup_var_refs_queue; queue; queue = queue->next) for (queue = p->fixup_var_refs_queue; queue; queue = next)
fixup_var_refs (queue->modified, queue->promoted_mode, {
queue->unsignedp, 0); next = queue->next;
fixup_var_refs (queue->modified, queue->promoted_mode,
queue->unsignedp, 0);
free (queue);
}
p->fixup_var_refs_queue = 0;
/* Reset variables that have known state during rtx generation. */ /* Reset variables that have known state during rtx generation. */
rtx_equal_function_value_matters = 1; rtx_equal_function_value_matters = 1;
...@@ -1337,20 +1343,13 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p, ...@@ -1337,20 +1343,13 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
{ {
struct var_refs_queue *temp; struct var_refs_queue *temp;
/* Variable is inherited; fix it up when we get back to its function. */
push_obstacks (function->function_obstack,
function->function_maybepermanent_obstack);
/* See comment in restore_tree_status in tree.c for why this needs to be
on saveable obstack. */
temp temp
= (struct var_refs_queue *) savealloc (sizeof (struct var_refs_queue)); = (struct var_refs_queue *) xmalloc (sizeof (struct var_refs_queue));
temp->modified = reg; temp->modified = reg;
temp->promoted_mode = promoted_mode; temp->promoted_mode = promoted_mode;
temp->unsignedp = TREE_UNSIGNED (type); temp->unsignedp = TREE_UNSIGNED (type);
temp->next = function->fixup_var_refs_queue; temp->next = function->fixup_var_refs_queue;
function->fixup_var_refs_queue = temp; function->fixup_var_refs_queue = temp;
pop_obstacks ();
} }
else if (used_p) else if (used_p)
/* Variable is local; fix it up now. */ /* Variable is local; fix it up now. */
......
...@@ -99,6 +99,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -99,6 +99,7 @@ Boston, MA 02111-1307, USA. */
#include "system.h" #include "system.h"
#include "rtl.h" #include "rtl.h"
#include "insn-config.h" /* For REGISTER_CONSTRAINTS */ #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
#include "ggc.h"
#ifdef HAVE_SYS_RESOURCE_H #ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h> # include <sys/resource.h>
...@@ -1726,7 +1727,8 @@ operate_exp (op, left, right) ...@@ -1726,7 +1727,8 @@ operate_exp (op, left, right)
give the same value), optimize it away. */ give the same value), optimize it away. */
if (allsame) if (allsame)
{ {
obstack_free (rtl_obstack, newexp); if (!ggc_p)
obstack_free (rtl_obstack, newexp);
return operate_exp (op, left, XEXP (right, 1)); return operate_exp (op, left, XEXP (right, 1));
} }
...@@ -1734,7 +1736,8 @@ operate_exp (op, left, right) ...@@ -1734,7 +1736,8 @@ operate_exp (op, left, right)
just use that. */ just use that. */
if (rtx_equal_p (newexp, right)) if (rtx_equal_p (newexp, right))
{ {
obstack_free (rtl_obstack, newexp); if (!ggc_p)
obstack_free (rtl_obstack, newexp);
return right; return right;
} }
...@@ -1783,7 +1786,8 @@ operate_exp (op, left, right) ...@@ -1783,7 +1786,8 @@ operate_exp (op, left, right)
optimize it away. */ optimize it away. */
if (allsame) if (allsame)
{ {
obstack_free (rtl_obstack, newexp); if (!ggc_p)
obstack_free (rtl_obstack, newexp);
return operate_exp (op, XEXP (left, 1), right); return operate_exp (op, XEXP (left, 1), right);
} }
...@@ -1791,7 +1795,8 @@ operate_exp (op, left, right) ...@@ -1791,7 +1795,8 @@ operate_exp (op, left, right)
just use that. */ just use that. */
if (rtx_equal_p (newexp, left)) if (rtx_equal_p (newexp, left))
{ {
obstack_free (rtl_obstack, newexp); if (!ggc_p)
obstack_free (rtl_obstack, newexp);
return left; return left;
} }
...@@ -2609,14 +2614,16 @@ simplify_cond (exp, insn_code, insn_index) ...@@ -2609,14 +2614,16 @@ simplify_cond (exp, insn_code, insn_index)
if (len == 0) if (len == 0)
{ {
obstack_free (rtl_obstack, first_spacer); if (!ggc_p)
obstack_free (rtl_obstack, first_spacer);
if (GET_CODE (defval) == COND) if (GET_CODE (defval) == COND)
return simplify_cond (defval, insn_code, insn_index); return simplify_cond (defval, insn_code, insn_index);
return defval; return defval;
} }
else if (allsame) else if (allsame)
{ {
obstack_free (rtl_obstack, first_spacer); if (!ggc_p)
obstack_free (rtl_obstack, first_spacer);
return exp; return exp;
} }
else else
...@@ -3146,14 +3153,16 @@ simplify_test_exp (exp, insn_code, insn_index) ...@@ -3146,14 +3153,16 @@ simplify_test_exp (exp, insn_code, insn_index)
SIMPLIFY_ALTERNATIVE (left); SIMPLIFY_ALTERNATIVE (left);
if (left == false_rtx) if (left == false_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return false_rtx; return false_rtx;
} }
right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (right); SIMPLIFY_ALTERNATIVE (right);
if (left == false_rtx) if (left == false_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return false_rtx; return false_rtx;
} }
...@@ -3185,7 +3194,8 @@ simplify_test_exp (exp, insn_code, insn_index) ...@@ -3185,7 +3194,8 @@ simplify_test_exp (exp, insn_code, insn_index)
if (left == false_rtx || right == false_rtx) if (left == false_rtx || right == false_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return false_rtx; return false_rtx;
} }
else if (left == true_rtx) else if (left == true_rtx)
...@@ -3244,14 +3254,16 @@ simplify_test_exp (exp, insn_code, insn_index) ...@@ -3244,14 +3254,16 @@ simplify_test_exp (exp, insn_code, insn_index)
SIMPLIFY_ALTERNATIVE (left); SIMPLIFY_ALTERNATIVE (left);
if (left == true_rtx) if (left == true_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return true_rtx; return true_rtx;
} }
right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
SIMPLIFY_ALTERNATIVE (right); SIMPLIFY_ALTERNATIVE (right);
if (right == true_rtx) if (right == true_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return true_rtx; return true_rtx;
} }
...@@ -3261,7 +3273,8 @@ simplify_test_exp (exp, insn_code, insn_index) ...@@ -3261,7 +3273,8 @@ simplify_test_exp (exp, insn_code, insn_index)
if (right == true_rtx || left == true_rtx) if (right == true_rtx || left == true_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return true_rtx; return true_rtx;
} }
else if (left == false_rtx) else if (left == false_rtx)
...@@ -3348,12 +3361,14 @@ simplify_test_exp (exp, insn_code, insn_index) ...@@ -3348,12 +3361,14 @@ simplify_test_exp (exp, insn_code, insn_index)
if (left == false_rtx) if (left == false_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return true_rtx; return true_rtx;
} }
else if (left == true_rtx) else if (left == true_rtx)
{ {
obstack_free (rtl_obstack, spacer); if (!ggc_p)
obstack_free (rtl_obstack, spacer);
return false_rtx; return false_rtx;
} }
...@@ -3515,7 +3530,8 @@ optimize_attrs () ...@@ -3515,7 +3530,8 @@ optimize_attrs ()
insert_insn_ent (av, ie); insert_insn_ent (av, ie);
something_changed = 1; something_changed = 1;
} }
obstack_free (temp_obstack, spacer); if (!ggc_p)
obstack_free (temp_obstack, spacer);
} }
} }
} }
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "tree.h" #include "tree.h"
#include "ggc.h" #include "ggc.h"
int ggc_p = 0;
void void
lang_mark_tree (t) lang_mark_tree (t)
union tree_node *t ATTRIBUTE_UNUSED; union tree_node *t ATTRIBUTE_UNUSED;
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#include "rtl.h" #include "rtl.h"
#include "ggc.h" #include "ggc.h"
/* For now, keep using the old obstack scheme in the gen* programs. */
int ggc_p = 0;
rtx rtx
ggc_alloc_rtx (nslots) ggc_alloc_rtx (nslots)
int nslots; int nslots;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "tree.h" #include "tree.h"
#include "ggc.h" #include "ggc.h"
#include "flags.h" #include "flags.h"
#include "varray.h"
/* Debugging flags. */ /* Debugging flags. */
#undef GGC_DUMP #undef GGC_DUMP
...@@ -96,6 +97,7 @@ static void ggc_free_rtx PROTO ((struct ggc_rtx *r)); ...@@ -96,6 +97,7 @@ static void ggc_free_rtx PROTO ((struct ggc_rtx *r));
static void ggc_free_tree PROTO ((struct ggc_tree *t)); static void ggc_free_tree PROTO ((struct ggc_tree *t));
static void ggc_mark_rtx_ptr PROTO ((void *elt)); static void ggc_mark_rtx_ptr PROTO ((void *elt));
static void ggc_mark_tree_ptr PROTO ((void *elt)); static void ggc_mark_tree_ptr PROTO ((void *elt));
static void ggc_mark_tree_varray_ptr PROTO ((void *elt));
/* These allocators are dreadfully simple, with no caching whatsoever so /* These allocators are dreadfully simple, with no caching whatsoever so
that Purify-like tools that do allocation versioning can catch errors. that Purify-like tools that do allocation versioning can catch errors.
...@@ -472,6 +474,18 @@ ggc_mark_tree (t) ...@@ -472,6 +474,18 @@ ggc_mark_tree (t)
} }
} }
/* Mark all the elements of the varray V, which contains trees. */
void
ggc_mark_tree_varray (v)
varray_type v;
{
int i;
for (i = v->num_elements - 1; i >= 0; --i)
ggc_mark_tree (VARRAY_TREE (v, i));
}
void void
ggc_mark_string (s) ggc_mark_string (s)
char *s; char *s;
...@@ -645,6 +659,17 @@ ggc_add_tree_root (base, nelt) ...@@ -645,6 +659,17 @@ ggc_add_tree_root (base, nelt)
ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr); ggc_add_root (base, nelt, sizeof(tree), ggc_mark_tree_ptr);
} }
/* Add vV (a varray full of trees) to the list of GC roots. */
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);
}
void void
ggc_del_root (base) ggc_del_root (base)
void *base; void *base;
...@@ -681,6 +706,16 @@ ggc_mark_tree_ptr (elt) ...@@ -681,6 +706,16 @@ ggc_mark_tree_ptr (elt)
ggc_mark_tree (*(tree *)elt); ggc_mark_tree (*(tree *)elt);
} }
/* Type-correct function to pass to ggc_add_root. It just forwards
ELT (which is really a varray_type *) to ggc_mark_tree_varray. */
static void
ggc_mark_tree_varray_ptr (elt)
void *elt;
{
ggc_mark_tree_varray (*(varray_type *)elt);
}
#ifdef GGC_DUMP #ifdef GGC_DUMP
/* Don't enable this unless you want a really really lot of data. */ /* Don't enable this unless you want a really really lot of data. */
static void __attribute__((constructor)) static void __attribute__((constructor))
......
...@@ -23,6 +23,10 @@ ...@@ -23,6 +23,10 @@
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with /* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
an external gc library that might be linked in. */ an external gc library that might be linked in. */
/* Language-specific code defines this variable to be either one (if
it wants garbage collection), or zero (if it does not). */
extern int ggc_p;
/* These structures are defined in various headers throughout the /* These structures are defined in various headers throughout the
compiler. However, rather than force everyone who includes this compiler. However, rather than force everyone who includes this
header to include all the headers in which they are declared, we header to include all the headers in which they are declared, we
...@@ -32,6 +36,7 @@ struct eh_status; ...@@ -32,6 +36,7 @@ struct eh_status;
struct emit_status; struct emit_status;
struct stmt_status; struct stmt_status;
struct varasm_status; struct varasm_status;
struct varray_head_tag;
/* Startup */ /* Startup */
...@@ -54,6 +59,7 @@ void ggc_add_root PROTO ((void *base, int nelt, int size, ...@@ -54,6 +59,7 @@ void ggc_add_root PROTO ((void *base, int nelt, int size,
void (*)(void *))); void (*)(void *)));
void ggc_add_rtx_root PROTO ((struct rtx_def **, int nelt)); void ggc_add_rtx_root PROTO ((struct rtx_def **, int nelt));
void ggc_add_tree_root PROTO ((union tree_node **, int nelt)); void ggc_add_tree_root PROTO ((union tree_node **, int nelt));
void ggc_add_tree_varray_root PROTO ((struct varray_head_tag **, int nelt));
void ggc_del_root PROTO ((void *base)); void ggc_del_root PROTO ((void *base));
/* Mark nodes from the gc_add_root callback. */ /* Mark nodes from the gc_add_root callback. */
......
...@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -22,6 +22,7 @@ Boston, MA 02111-1307, USA. */
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "tree.h" #include "tree.h"
#include "ggc.h"
void print_node (); void print_node ();
void indent_to (); void indent_to ();
...@@ -274,7 +275,7 @@ print_node (file, prefix, node, indent) ...@@ -274,7 +275,7 @@ print_node (file, prefix, node, indent)
} }
/* If a permanent object is in the wrong obstack, or the reverse, warn. */ /* If a permanent object is in the wrong obstack, or the reverse, warn. */
if (object_permanent_p (node) != TREE_PERMANENT (node)) if (!ggc_p && object_permanent_p (node) != TREE_PERMANENT (node))
{ {
if (TREE_PERMANENT (node)) if (TREE_PERMANENT (node))
fputs (" !!permanent object in non-permanent obstack!!", file); fputs (" !!permanent object in non-permanent obstack!!", file);
......
...@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h" #include "rtl.h"
#include "real.h" #include "real.h"
#include "bitmap.h" #include "bitmap.h"
#include "ggc.h"
#include "obstack.h" #include "obstack.h"
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
...@@ -244,18 +244,23 @@ rtvec_alloc (n) ...@@ -244,18 +244,23 @@ rtvec_alloc (n)
int n; int n;
{ {
rtvec rt; rtvec rt;
int i;
if (ggc_p)
rt = (rtvec) obstack_alloc (rtl_obstack, rt = ggc_alloc_rtvec (n);
sizeof (struct rtvec_def) else
+ (( n - 1) * sizeof (rtx))); {
int i;
/* clear out the vector */ rt = (rtvec) obstack_alloc (rtl_obstack,
PUT_NUM_ELEM (rt, n); sizeof (struct rtvec_def)
+ (( n - 1) * sizeof (rtx)));
for (i = 0; i < n; i++) /* clear out the vector */
rt->elem[i] = 0; for (i = 0; i < n; i++)
rt->elem[i] = 0;
}
PUT_NUM_ELEM (rt, n);
return rt; return rt;
} }
...@@ -267,34 +272,40 @@ rtx_alloc (code) ...@@ -267,34 +272,40 @@ rtx_alloc (code)
RTX_CODE code; RTX_CODE code;
{ {
rtx rt; rtx rt;
register struct obstack *ob = rtl_obstack;
register int nelts = GET_RTX_LENGTH (code);
register int length = sizeof (struct rtx_def)
+ (nelts - 1) * sizeof (rtunion);
/* This function is called more than any other in GCC,
so we manipulate the obstack directly.
Even though rtx objects are word aligned, we may be sharing an obstack if (ggc_p)
with tree nodes, which may have to be double-word aligned. So align rt = ggc_alloc_rtx (GET_RTX_LENGTH (code));
our length to the alignment mask in the obstack. */ else
{
length = (length + ob->alignment_mask) & ~ ob->alignment_mask; register struct obstack *ob = rtl_obstack;
register int nelts = GET_RTX_LENGTH (code);
if (ob->chunk_limit - ob->next_free < length) register int length = sizeof (struct rtx_def)
_obstack_newchunk (ob, length); + (nelts - 1) * sizeof (rtunion);
rt = (rtx)ob->object_base;
ob->next_free += length; /* This function is called more than any other in GCC, so we
ob->object_base = ob->next_free; manipulate the obstack directly.
/* We want to clear everything up to the FLD array. Normally, this is Even though rtx objects are word aligned, we may be sharing
one int, but we don't want to assume that and it isn't very portable an obstack with tree nodes, which may have to be double-word
anyway; this is. */ aligned. So align our length to the alignment mask in the
obstack. */
memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
if (ob->chunk_limit - ob->next_free < length)
_obstack_newchunk (ob, length);
rt = (rtx)ob->object_base;
ob->next_free += length;
ob->object_base = ob->next_free;
/* We want to clear everything up to the FLD array. Normally,
this is one int, but we don't want to assume that and it
isn't very portable anyway; this is. */
memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
}
PUT_CODE (rt, code); PUT_CODE (rt, code);
return rt; return rt;
} }
...@@ -304,7 +315,8 @@ void ...@@ -304,7 +315,8 @@ void
rtx_free (x) rtx_free (x)
rtx x; rtx x;
{ {
obstack_free (rtl_obstack, x); if (!ggc_p)
obstack_free (rtl_obstack, x);
} }
/* Create a new copy of an rtx. /* Create a new copy of an rtx.
......
...@@ -3801,6 +3801,9 @@ rest_of_compilation (decl) ...@@ -3801,6 +3801,9 @@ rest_of_compilation (decl)
if (jump_opt_dump) if (jump_opt_dump)
dump_rtl (".jump", decl, print_rtl, insns); dump_rtl (".jump", decl, print_rtl, insns);
if (ggc_p)
ggc_collect ();
/* Perform common subexpression elimination. /* Perform common subexpression elimination.
Nonzero value from `cse_main' means that jumps were simplified Nonzero value from `cse_main' means that jumps were simplified
and some code may now be unreachable, so do and some code may now be unreachable, so do
...@@ -3846,6 +3849,9 @@ rest_of_compilation (decl) ...@@ -3846,6 +3849,9 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".addressof", insns); print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
} }
if (ggc_p)
ggc_collect ();
/* Perform global cse. */ /* Perform global cse. */
if (optimize > 0 && flag_gcse) if (optimize > 0 && flag_gcse)
...@@ -3870,6 +3876,9 @@ rest_of_compilation (decl) ...@@ -3870,6 +3876,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".gcse", insns); print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
} }
if (ggc_p)
ggc_collect ();
} }
/* Move constant computations out of loops. */ /* Move constant computations out of loops. */
...@@ -3909,6 +3918,9 @@ rest_of_compilation (decl) ...@@ -3909,6 +3918,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".loop", insns); print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
} }
if (ggc_p)
ggc_collect ();
} }
if (optimize > 0) if (optimize > 0)
...@@ -3953,6 +3965,9 @@ rest_of_compilation (decl) ...@@ -3953,6 +3965,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".cse2", insns); print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
} }
if (ggc_p)
ggc_collect ();
} }
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
...@@ -3972,6 +3987,9 @@ rest_of_compilation (decl) ...@@ -3972,6 +3987,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".bp", insns); print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
} }
if (ggc_p)
ggc_collect ();
} }
/* We are no longer anticipating cse in this function, at least. */ /* We are no longer anticipating cse in this function, at least. */
...@@ -4030,6 +4048,9 @@ rest_of_compilation (decl) ...@@ -4030,6 +4048,9 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".flow", insns); print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
} }
if (ggc_p)
ggc_collect ();
/* The first life analysis pass has finished. From now on we can not /* The first life analysis pass has finished. From now on we can not
generate any new pseudos. */ generate any new pseudos. */
no_new_pseudos = 1; no_new_pseudos = 1;
...@@ -4048,6 +4069,9 @@ rest_of_compilation (decl) ...@@ -4048,6 +4069,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".combine", insns); print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
} }
if (ggc_p)
ggc_collect ();
} }
/* Register allocation pre-pass, to reduce number of moves /* Register allocation pre-pass, to reduce number of moves
...@@ -4066,6 +4090,9 @@ rest_of_compilation (decl) ...@@ -4066,6 +4090,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".regmove", insns); print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
} }
if (ggc_p)
ggc_collect ();
} }
/* Print function header into sched dump now /* Print function header into sched dump now
...@@ -4089,6 +4116,9 @@ rest_of_compilation (decl) ...@@ -4089,6 +4116,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".sched", insns); print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
} }
if (ggc_p)
ggc_collect ();
} }
/* Determine if the current function is a leaf before running reload /* Determine if the current function is a leaf before running reload
...@@ -4126,6 +4156,9 @@ rest_of_compilation (decl) ...@@ -4126,6 +4156,9 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".lreg", insns); print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
} }
if (ggc_p)
ggc_collect ();
if (global_reg_dump) if (global_reg_dump)
open_dump_file (".greg", decl_printable_name (decl, 2)); open_dump_file (".greg", decl_printable_name (decl, 2));
...@@ -4145,6 +4178,9 @@ rest_of_compilation (decl) ...@@ -4145,6 +4178,9 @@ rest_of_compilation (decl)
if (failure) if (failure)
goto exit_rest_of_compilation; goto exit_rest_of_compilation;
if (ggc_p)
ggc_collect ();
/* Do a very simple CSE pass over just the hard registers. */ /* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0) if (optimize > 0)
reload_cse_regs (insns); reload_cse_regs (insns);
...@@ -4203,6 +4239,9 @@ rest_of_compilation (decl) ...@@ -4203,6 +4239,9 @@ rest_of_compilation (decl)
find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1); find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
life_analysis (insns, max_reg_num (), rtl_dump_file, 1); life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
}); });
if (ggc_p)
ggc_collect ();
} }
flow2_completed = 1; flow2_completed = 1;
...@@ -4256,6 +4295,9 @@ rest_of_compilation (decl) ...@@ -4256,6 +4295,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".sched2", insns); print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
} }
if (ggc_p)
ggc_collect ();
} }
#ifdef LEAF_REGISTERS #ifdef LEAF_REGISTERS
...@@ -4297,6 +4339,9 @@ rest_of_compilation (decl) ...@@ -4297,6 +4339,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".mach", insns); print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
} }
if (ggc_p)
ggc_collect ();
#endif #endif
/* If a scheduling pass for delayed branches is to be done, /* If a scheduling pass for delayed branches is to be done,
...@@ -4317,6 +4362,9 @@ rest_of_compilation (decl) ...@@ -4317,6 +4362,9 @@ rest_of_compilation (decl)
print_rtl_graph_with_bb (dump_base_name, ".dbr", insns); print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
} }
} }
if (ggc_p)
ggc_collect ();
#endif #endif
/* Shorten branches. */ /* Shorten branches. */
...@@ -4337,6 +4385,9 @@ rest_of_compilation (decl) ...@@ -4337,6 +4385,9 @@ rest_of_compilation (decl)
if (graph_dump_format != no_graph) if (graph_dump_format != no_graph)
print_rtl_graph_with_bb (dump_base_name, ".stack", insns); print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
} }
if (ggc_p)
ggc_collect ();
#endif #endif
/* Now turn the rtl into assembler code. */ /* Now turn the rtl into assembler code. */
...@@ -4373,6 +4424,9 @@ rest_of_compilation (decl) ...@@ -4373,6 +4424,9 @@ rest_of_compilation (decl)
regset_release_memory (); regset_release_memory ();
}); });
if (ggc_p)
ggc_collect ();
/* Write DBX symbols if requested */ /* Write DBX symbols if requested */
/* Note that for those inline functions where we don't initially /* Note that for those inline functions where we don't initially
...@@ -4458,6 +4512,10 @@ rest_of_compilation (decl) ...@@ -4458,6 +4512,10 @@ rest_of_compilation (decl)
if (! DECL_DEFER_OUTPUT (decl)) if (! DECL_DEFER_OUTPUT (decl))
free_after_compilation (current_function); free_after_compilation (current_function);
current_function = 0;
ggc_collect ();
/* The parsing time is all the time spent in yyparse /* The parsing time is all the time spent in yyparse
*except* what is spent in this function. */ *except* what is spent in this function. */
......
...@@ -474,8 +474,12 @@ void ...@@ -474,8 +474,12 @@ void
push_obstacks (current, saveable) push_obstacks (current, saveable)
struct obstack *current, *saveable; struct obstack *current, *saveable;
{ {
struct obstack_stack *p struct obstack_stack *p;
= (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
if (ggc_p)
return;
p = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
(sizeof (struct obstack_stack))); (sizeof (struct obstack_stack)));
p->current = current_obstack; p->current = current_obstack;
...@@ -495,8 +499,12 @@ push_obstacks (current, saveable) ...@@ -495,8 +499,12 @@ push_obstacks (current, saveable)
void void
push_obstacks_nochange () push_obstacks_nochange ()
{ {
struct obstack_stack *p struct obstack_stack *p;
= (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
if (ggc_p)
return;
p = (struct obstack_stack *) obstack_alloc (&obstack_stack_obstack,
(sizeof (struct obstack_stack))); (sizeof (struct obstack_stack)));
p->current = current_obstack; p->current = current_obstack;
...@@ -512,7 +520,12 @@ push_obstacks_nochange () ...@@ -512,7 +520,12 @@ push_obstacks_nochange ()
void void
pop_obstacks () pop_obstacks ()
{ {
struct obstack_stack *p = obstack_stack; struct obstack_stack *p;
if (ggc_p)
return;
p = obstack_stack;
obstack_stack = p->next; obstack_stack = p->next;
current_obstack = p->current; current_obstack = p->current;
...@@ -1005,8 +1018,13 @@ make_node (code) ...@@ -1005,8 +1018,13 @@ make_node (code)
abort (); abort ();
} }
t = (tree) obstack_alloc (obstack, length); if (ggc_p)
bzero ((PTR) t, length); t = ggc_alloc_tree (length);
else
{
t = (tree) obstack_alloc (obstack, length);
bzero ((PTR) t, length);
}
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)kind]++; tree_node_counts[(int)kind]++;
...@@ -1119,8 +1137,13 @@ copy_node (node) ...@@ -1119,8 +1137,13 @@ copy_node (node)
length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *); length += (TREE_VEC_LENGTH (node) - 1) * sizeof (char *);
} }
t = (tree) obstack_alloc (current_obstack, length); if (ggc_p)
memcpy (t, node, length); t = ggc_alloc_tree (length);
else
{
t = (tree) obstack_alloc (current_obstack, length);
memcpy (t, node, length);
}
/* EXPR_WITH_FILE_LOCATION must keep filename info stored in TREE_CHAIN */ /* EXPR_WITH_FILE_LOCATION must keep filename info stored in TREE_CHAIN */
if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION) if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION)
...@@ -1230,7 +1253,10 @@ get_identifier (text) ...@@ -1230,7 +1253,10 @@ get_identifier (text)
id_string_size += len; id_string_size += len;
#endif #endif
IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len); if (ggc_p)
IDENTIFIER_POINTER (idp) = ggc_alloc_string (text, len);
else
IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len);
TREE_CHAIN (idp) = hash_table[hi]; TREE_CHAIN (idp) = hash_table[hi];
hash_table[hi] = idp; hash_table[hi] = idp;
...@@ -1469,7 +1495,10 @@ build_string (len, str) ...@@ -1469,7 +1495,10 @@ build_string (len, str)
register tree s = make_node (STRING_CST); register tree s = make_node (STRING_CST);
TREE_STRING_LENGTH (s) = len; TREE_STRING_LENGTH (s) = len;
TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len); if (ggc_p)
TREE_STRING_POINTER (s) = ggc_alloc_string (str, len);
else
TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
return s; return s;
} }
...@@ -1509,8 +1538,13 @@ make_tree_vec (len) ...@@ -1509,8 +1538,13 @@ make_tree_vec (len)
tree_node_sizes[(int)vec_kind] += length; tree_node_sizes[(int)vec_kind] += length;
#endif #endif
t = (tree) obstack_alloc (obstack, length); if (ggc_p)
bzero ((PTR) t, length); t = ggc_alloc_tree (length);
else
{
t = (tree) obstack_alloc (obstack, length);
bzero ((PTR) t, length);
}
TREE_SET_CODE (t, TREE_VEC); TREE_SET_CODE (t, TREE_VEC);
TREE_VEC_LENGTH (t) = len; TREE_VEC_LENGTH (t) = len;
...@@ -2011,15 +2045,21 @@ tree_cons (purpose, value, chain) ...@@ -2011,15 +2045,21 @@ tree_cons (purpose, value, chain)
#if 0 #if 0
register tree node = make_node (TREE_LIST); register tree node = make_node (TREE_LIST);
#else #else
register int i; register tree node;
register tree node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
if (ggc_p)
node = ggc_alloc_tree (sizeof (struct tree_list));
else
{
node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
bzero (node, sizeof (struct tree_common));
}
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)x_kind]++; tree_node_counts[(int)x_kind]++;
tree_node_sizes[(int)x_kind] += sizeof (struct tree_list); tree_node_sizes[(int)x_kind] += sizeof (struct tree_list);
#endif #endif
for (i = (sizeof (struct tree_common) / sizeof (int)) - 1; i >= 0; i--)
((int *) node)[i] = 0;
TREE_SET_CODE (node, TREE_LIST); TREE_SET_CODE (node, TREE_LIST);
if (current_obstack == &permanent_obstack) if (current_obstack == &permanent_obstack)
...@@ -3028,7 +3068,10 @@ build1 (code, type, node) ...@@ -3028,7 +3068,10 @@ build1 (code, type, node)
length = sizeof (struct tree_exp); length = sizeof (struct tree_exp);
t = (tree) obstack_alloc (obstack, length); if (ggc_p)
t = ggc_alloc_tree (length);
else
t = (tree) obstack_alloc (obstack, length);
bzero ((PTR) t, length); bzero ((PTR) t, length);
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
...@@ -3706,7 +3749,8 @@ type_hash_canon (hashcode, type) ...@@ -3706,7 +3749,8 @@ type_hash_canon (hashcode, type)
t1 = type_hash_lookup (hashcode, type); t1 = type_hash_lookup (hashcode, type);
if (t1 != 0) if (t1 != 0)
{ {
obstack_free (TYPE_OBSTACK (type), type); if (!ggc_p)
obstack_free (TYPE_OBSTACK (type), type);
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
tree_node_counts[(int)t_kind]--; tree_node_counts[(int)t_kind]--;
tree_node_sizes[(int)t_kind] -= sizeof (struct tree_type); tree_node_sizes[(int)t_kind] -= sizeof (struct tree_type);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment