Commit d1485032 by Jason Merrill Committed by Jason Merrill

tree.c (restore_tree_status): Also free up temporary storage when we finish a toplevel function.

	* tree.c (restore_tree_status): Also free up temporary storage
	when we finish a toplevel function.
	(dump_tree_statistics): Print stats for backend obstacks.

	* libgcc2.c (__throw): Don't copy the return address.
	* dwarf2out.c (expand_builtin_dwarf_reg_size): Ignore return address.

	* except.c (exceptions_via_longjmp): Initialize to 2 (uninitialized).
	* toplev.c (main): Initialize exceptions_via_longjmp.

	* tree.c: Add extra_inline_obstacks.
	(save_tree_status): Use it.
	(restore_tree_status): If this is a toplevel inline obstack and we
	didn't want to save anything on it, recycle it.
	(print_inline_obstack_statistics): New fn.
	* function.c (pop_function_context_from): Pass context to
	restore_tree_status.
	* obstack.h (obstack_empty_p): New macro.

From-SVN: r16050
parent 6bd35f86
Sat Oct 18 13:47:15 1997 Jason Merrill <jason@yorick.cygnus.com>
* tree.c (restore_tree_status): Also free up temporary storage
when we finish a toplevel function.
(dump_tree_statistics): Print stats for backend obstacks.
Sat Oct 18 12:47:31 1997 Doug Evans <dje@canuck.cygnus.com> Sat Oct 18 12:47:31 1997 Doug Evans <dje@canuck.cygnus.com>
* expr.c (use_group_regs): Don't call use_reg for MEMs. * expr.c (use_group_regs): Don't call use_reg for MEMs.
Sat Oct 18 09:49:46 1997 Jason Merrill <jason@yorick.cygnus.com>
* libgcc2.c (__throw): Don't copy the return address.
* dwarf2out.c (expand_builtin_dwarf_reg_size): Ignore return address.
* except.c (exceptions_via_longjmp): Initialize to 2 (uninitialized).
* toplev.c (main): Initialize exceptions_via_longjmp.
* tree.c: Add extra_inline_obstacks.
(save_tree_status): Use it.
(restore_tree_status): If this is a toplevel inline obstack and we
didn't want to save anything on it, recycle it.
(print_inline_obstack_statistics): New fn.
* function.c (pop_function_context_from): Pass context to
restore_tree_status.
* obstack.h (obstack_empty_p): New macro.
Sat Oct 18 00:43:59 1997 Jeffrey A Law (law@cygnus.com) Sat Oct 18 00:43:59 1997 Jeffrey A Law (law@cygnus.com)
* i386/freebsd.h (ASM_COMMENT_START): Fix. * i386/freebsd.h (ASM_COMMENT_START): Fix.
......
...@@ -520,27 +520,31 @@ expand_builtin_dwarf_reg_size (reg_tree, target) ...@@ -520,27 +520,31 @@ expand_builtin_dwarf_reg_size (reg_tree, target)
tree reg_tree; tree reg_tree;
rtx target; rtx target;
{ {
int i, n_ranges, size; int size;
struct reg_size_range ranges[5]; struct reg_size_range ranges[5];
tree t, t2; tree t, t2;
ranges[0].beg = 0; int i = 0;
ranges[0].size = GET_MODE_SIZE (reg_raw_mode[0]); int n_ranges = 0;
n_ranges = 1; int last_size = -1;
for (i = 1; i < FIRST_PSEUDO_REGISTER; ++i) for (; i < FIRST_PSEUDO_REGISTER; ++i)
{ {
/* The return address is out of order on the MIPS, and we don't use
copy_reg for it anyway, so we don't care here how large it is. */
if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
continue;
size = GET_MODE_SIZE (reg_raw_mode[i]); size = GET_MODE_SIZE (reg_raw_mode[i]);
if (size != ranges[n_ranges-1].size) if (size != last_size)
{ {
ranges[n_ranges-1].end = i-1;
ranges[n_ranges].beg = i; ranges[n_ranges].beg = i;
ranges[n_ranges].size = GET_MODE_SIZE (reg_raw_mode[i]); ranges[n_ranges].size = last_size = GET_MODE_SIZE (reg_raw_mode[i]);
++n_ranges; ++n_ranges;
assert (n_ranges < 5); assert (n_ranges < 5);
} }
ranges[n_ranges-1].end = i;
} }
ranges[n_ranges-1].end = i-1;
/* The usual case: fp regs surrounded by general regs. */ /* The usual case: fp regs surrounded by general regs. */
if (n_ranges == 3 && ranges[0].size == ranges[2].size) if (n_ranges == 3 && ranges[0].size == ranges[2].size)
......
...@@ -98,7 +98,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -98,7 +98,7 @@ Boston, MA 02111-1307, USA. */
is stored in a section named .eh_frame and the information for the is stored in a section named .eh_frame and the information for the
entire shared object or program is registered with a call to entire shared object or program is registered with a call to
__register_frame. On other targets, the information for each __register_frame. On other targets, the information for each
translation unit is registered separately with a static constructor. translation unit is registered from the file generated by collect2.
__register_frame is defined in frame.c, and is responsible for __register_frame is defined in frame.c, and is responsible for
recording all of the unwind regions into one list (which is kept in a recording all of the unwind regions into one list (which is kept in a
static variable named unwind_table_list). static variable named unwind_table_list).
...@@ -409,11 +409,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -409,11 +409,7 @@ Boston, MA 02111-1307, USA. */
/* One to use setjmp/longjmp method of generating code for exception /* One to use setjmp/longjmp method of generating code for exception
handling. */ handling. */
#if DWARF2_UNWIND_INFO int exceptions_via_longjmp = 2;
int exceptions_via_longjmp = 0;
#else
int exceptions_via_longjmp = 1;
#endif
/* One to enable asynchronous exception support. */ /* One to enable asynchronous exception support. */
......
...@@ -610,7 +610,7 @@ pop_function_context_from (context) ...@@ -610,7 +610,7 @@ pop_function_context_from (context)
reg_renumber = 0; reg_renumber = 0;
current_function_args_info = p->args_info; current_function_args_info = p->args_info;
restore_tree_status (p); restore_tree_status (p, context);
restore_storage_status (p); restore_storage_status (p);
restore_expr_status (p); restore_expr_status (p);
restore_emit_status (p); restore_emit_status (p);
......
...@@ -3733,7 +3733,7 @@ label: ...@@ -3733,7 +3733,7 @@ label:
sub_udata = p; sub_udata = p;
for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
if (udata->saved[i]) if (i != udata->retaddr_column && udata->saved[i])
{ {
#ifdef INCOMING_REGNO #ifdef INCOMING_REGNO
/* If you modify the saved value of the return address /* If you modify the saved value of the return address
......
...@@ -332,6 +332,11 @@ int obstack_chunk_size (struct obstack *obstack); ...@@ -332,6 +332,11 @@ int obstack_chunk_size (struct obstack *obstack);
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
(unsigned) (__o->chunk_limit - __o->next_free); }) (unsigned) (__o->chunk_limit - __o->next_free); })
#define obstack_empty_p(OBSTACK) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
(__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
#define obstack_grow(OBSTACK,where,length) \ #define obstack_grow(OBSTACK,where,length) \
__extension__ \ __extension__ \
({ struct obstack *__o = (OBSTACK); \ ({ struct obstack *__o = (OBSTACK); \
...@@ -460,6 +465,9 @@ __extension__ \ ...@@ -460,6 +465,9 @@ __extension__ \
#define obstack_room(h) \ #define obstack_room(h) \
(unsigned) ((h)->chunk_limit - (h)->next_free) (unsigned) ((h)->chunk_limit - (h)->next_free)
#define obstack_empty_p(h) \
((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
/* Note that the call to _obstack_newchunk is enclosed in (..., 0) /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
so that we can avoid having void expressions so that we can avoid having void expressions
in the arms of the conditional expression. in the arms of the conditional expression.
......
...@@ -4294,6 +4294,15 @@ main (argc, argv, envp) ...@@ -4294,6 +4294,15 @@ main (argc, argv, envp)
OVERRIDE_OPTIONS; OVERRIDE_OPTIONS;
#endif #endif
if (exceptions_via_longjmp == 2)
{
#ifdef DWARF2_UNWIND_INFO
exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
#else
exceptions_via_longjmp = 1;
#endif
}
if (profile_block_flag == 3) if (profile_block_flag == 3)
{ {
warning ("`-ax' and `-a' are conflicting options. `-a' ignored."); warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
......
...@@ -81,6 +81,10 @@ struct obstack maybepermanent_obstack; ...@@ -81,6 +81,10 @@ struct obstack maybepermanent_obstack;
struct simple_obstack_stack *toplev_inline_obstacks; struct simple_obstack_stack *toplev_inline_obstacks;
/* Former elements of toplev_inline_obstacks that have been recycled. */
struct simple_obstack_stack *extra_inline_obstacks;
/* This is a list of function_maybepermanent_obstacks for inline functions /* This is a list of function_maybepermanent_obstacks for inline functions
nested in the current function that were compiled in the middle of nested in the current function that were compiled in the middle of
compiling other functions. */ compiling other functions. */
...@@ -381,12 +385,22 @@ save_tree_status (p, context) ...@@ -381,12 +385,22 @@ save_tree_status (p, context)
head = &f->inline_obstacks; head = &f->inline_obstacks;
} }
current = ((struct simple_obstack_stack *) if (context == NULL_TREE && extra_inline_obstacks)
xmalloc (sizeof (struct simple_obstack_stack))); {
current = extra_inline_obstacks;
extra_inline_obstacks = current->next;
}
else
{
current = ((struct simple_obstack_stack *)
xmalloc (sizeof (struct simple_obstack_stack)));
current->obstack
= (struct obstack *) xmalloc (sizeof (struct obstack));
gcc_obstack_init (current->obstack);
}
current->obstack = (struct obstack *) xmalloc (sizeof (struct obstack));
function_maybepermanent_obstack = current->obstack; function_maybepermanent_obstack = current->obstack;
gcc_obstack_init (function_maybepermanent_obstack);
current->next = *head; current->next = *head;
*head = current; *head = current;
...@@ -411,8 +425,9 @@ save_tree_status (p, context) ...@@ -411,8 +425,9 @@ save_tree_status (p, context)
This is used after a nested function. */ This is used after a nested function. */
void void
restore_tree_status (p) restore_tree_status (p, context)
struct function *p; struct function *p;
tree context;
{ {
all_types_permanent = p->all_types_permanent; all_types_permanent = p->all_types_permanent;
momentary_stack = p->momentary_stack; momentary_stack = p->momentary_stack;
...@@ -428,6 +443,29 @@ restore_tree_status (p) ...@@ -428,6 +443,29 @@ restore_tree_status (p)
past the nested function's end. */ past the nested function's end. */
obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj); obstack_free (function_maybepermanent_obstack, maybepermanent_firstobj);
/* If we were compiling a toplevel function, we can free this space now. */
if (context == NULL_TREE)
{
obstack_free (&temporary_obstack, temporary_firstobj);
obstack_free (&momentary_obstack, momentary_function_firstobj);
}
/* If we were compiling a toplevel function that we don't actually want
to save anything from, return the obstack to the pool. */
if (context == NULL_TREE
&& obstack_empty_p (function_maybepermanent_obstack))
{
struct simple_obstack_stack *current, **p = &toplev_inline_obstacks;
while ((*p)->obstack != function_maybepermanent_obstack)
p = &((*p)->next);
current = *p;
*p = current->next;
current->next = extra_inline_obstacks;
extra_inline_obstacks = current;
}
obstack_free (function_obstack, 0); obstack_free (function_obstack, 0);
free (function_obstack); free (function_obstack);
...@@ -4469,24 +4507,58 @@ decl_type_context (decl) ...@@ -4469,24 +4507,58 @@ decl_type_context (decl)
return NULL_TREE; return NULL_TREE;
} }
/* Print debugging information about the size of the
toplev_inline_obstacks. */
void
print_inline_obstack_statistics ()
{
struct simple_obstack_stack *current = toplev_inline_obstacks;
int n_obstacks = 0;
unsigned long n_alloc = 0;
int n_chunks = 0;
for (; current; current = current->next, ++n_obstacks)
{
struct obstack *o = current->obstack;
struct _obstack_chunk *chunk = o->chunk;
n_alloc += o->next_free - chunk->contents;
chunk = chunk->prev;
++n_chunks;
for (; chunk; chunk = chunk->prev, ++n_chunks)
n_alloc += chunk->limit - &chunk->contents[0];
}
fprintf (stderr, "inline obstacks: %d obstacks, %lu bytes, %d chunks\n",
n_obstacks, n_alloc, n_chunks);
}
/* Print debugging information about the obstack O, named STR. */
void void
print_obstack_statistics (str, o) print_obstack_statistics (str, o)
char *str; char *str;
struct obstack *o; struct obstack *o;
{ {
struct _obstack_chunk *chunk = o->chunk; struct _obstack_chunk *chunk = o->chunk;
int n_chunks = 0; int n_chunks = 1;
int n_alloc = 0; unsigned long n_alloc = 0;
n_alloc += o->next_free - chunk->contents;
chunk = chunk->prev;
while (chunk) while (chunk)
{ {
n_chunks += 1; n_chunks += 1;
n_alloc += chunk->limit - &chunk->contents[0]; n_alloc += chunk->limit - &chunk->contents[0];
chunk = chunk->prev; chunk = chunk->prev;
} }
fprintf (stderr, "obstack %s: %d bytes, %d chunks\n", fprintf (stderr, "obstack %s: %lu bytes, %d chunks\n",
str, n_alloc, n_chunks); str, n_alloc, n_chunks);
} }
/* Print debugging information about tree nodes generated during the compile,
and any language-specific information. */
void void
dump_tree_statistics () dump_tree_statistics ()
{ {
...@@ -4512,6 +4584,12 @@ dump_tree_statistics () ...@@ -4512,6 +4584,12 @@ dump_tree_statistics ()
#else #else
fprintf (stderr, "(No per-node statistics)\n"); fprintf (stderr, "(No per-node statistics)\n");
#endif #endif
print_obstack_statistics ("permanent_obstack", &permanent_obstack);
print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
print_obstack_statistics ("temporary_obstack", &temporary_obstack);
print_obstack_statistics ("momentary_obstack", &momentary_obstack);
print_obstack_statistics ("temp_decl_obstack", &temp_decl_obstack);
print_inline_obstack_statistics ();
print_lang_statistics (); print_lang_statistics ();
} }
......
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