Commit ecaebb9e by Nathan Sidwell Committed by Nathan Sidwell

builtins.c (expand_builtin_setjmp_setup): Update comment.

	* builtins.c (expand_builtin_setjmp_setup): Update comment.
	* function.h (struct function): Move va_list_gpr_size,
	va_list_fpr_size, function_frequency to front of bitfields.  Add
	calls_unwind_init.
	(current_function_calls_unwind_init): New.
	* except.c (expand_builtin_unwind_init): Set
	current_function_calls_unwind_init not
	current_function_has_nonlocal_label.
	* reload1.c (has_nonexceptional_receiver): New.
	(reload): Use it and current_function_calls_unwind_init to
	determine whether call-saved regs must be saved.

From-SVN: r124898
parent 2a0ab51c
2007-05-21 Nathan Sidwell <nathan@codesourcery.com>
* builtins.c (expand_builtin_setjmp_setup): Update comment.
* function.h (struct function): Move va_list_gpr_size,
va_list_fpr_size, function_frequency to front of bitfields. Add
calls_unwind_init.
(current_function_calls_unwind_init): New.
* except.c (expand_builtin_unwind_init): Set
current_function_calls_unwind_init not
current_function_has_nonlocal_label.
* reload1.c (has_nonexceptional_receiver): New.
(reload): Use it and current_function_calls_unwind_init to
determine whether call-saved regs must be saved.
2007-05-20 Jan Hubicka <jh@suse.cz> 2007-05-20 Jan Hubicka <jh@suse.cz>
* gengtype.c (adjust_field_rtx_def): Use NOTE_KIND instead of * gengtype.c (adjust_field_rtx_def): Use NOTE_KIND instead of
......
...@@ -696,8 +696,7 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label) ...@@ -696,8 +696,7 @@ expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
need to go on during alloca. */ need to go on during alloca. */
current_function_calls_setjmp = 1; current_function_calls_setjmp = 1;
/* Set this so all the registers get saved in our frame; we need to be /* We have a nonlocal label. */
able to copy the saved values for any registers from frames we unwind. */
current_function_has_nonlocal_label = 1; current_function_has_nonlocal_label = 1;
} }
......
...@@ -2859,7 +2859,7 @@ expand_builtin_unwind_init (void) ...@@ -2859,7 +2859,7 @@ expand_builtin_unwind_init (void)
{ {
/* Set this so all the registers get saved in our frame; we need to be /* Set this so all the registers get saved in our frame; we need to be
able to copy the saved values for any registers from frames we unwind. */ able to copy the saved values for any registers from frames we unwind. */
current_function_has_nonlocal_label = 1; current_function_calls_unwind_init = 1;
#ifdef SETUP_FRAME_ADDRESSES #ifdef SETUP_FRAME_ADDRESSES
SETUP_FRAME_ADDRESSES (); SETUP_FRAME_ADDRESSES ();
......
...@@ -374,6 +374,19 @@ struct function GTY(()) ...@@ -374,6 +374,19 @@ struct function GTY(())
/* Collected bit flags. */ /* Collected bit flags. */
/* Number of units of general registers that need saving in stdarg
function. What unit is depends on the backend, either it is number
of bytes, or it can be number of registers. */
unsigned int va_list_gpr_size : 8;
/* Number of units of floating point registers that need saving in stdarg
function. */
unsigned int va_list_fpr_size : 8;
/* How commonly executed the function is. Initialized during branch
probabilities pass. */
ENUM_BITFIELD (function_frequency) function_frequency : 2;
/* Nonzero if function being compiled needs to be given an address /* Nonzero if function being compiled needs to be given an address
where the value should be stored. */ where the value should be stored. */
unsigned int returns_struct : 1; unsigned int returns_struct : 1;
...@@ -403,6 +416,9 @@ struct function GTY(()) ...@@ -403,6 +416,9 @@ struct function GTY(())
from nested functions. */ from nested functions. */
unsigned int has_nonlocal_label : 1; unsigned int has_nonlocal_label : 1;
/* Nonzero if function calls builtin_unwind_init. */
unsigned int calls_unwind_init : 1;
/* Nonzero if function being compiled has nonlocal gotos to parent /* Nonzero if function being compiled has nonlocal gotos to parent
function. */ function. */
unsigned int has_nonlocal_goto : 1; unsigned int has_nonlocal_goto : 1;
...@@ -459,19 +475,6 @@ struct function GTY(()) ...@@ -459,19 +475,6 @@ struct function GTY(())
/* Set when the tail call has been produced. */ /* Set when the tail call has been produced. */
unsigned int tail_call_emit : 1; unsigned int tail_call_emit : 1;
/* How commonly executed the function is. Initialized during branch
probabilities pass. */
ENUM_BITFIELD (function_frequency) function_frequency : 2;
/* Number of units of general registers that need saving in stdarg
function. What unit is depends on the backend, either it is number
of bytes, or it can be number of registers. */
unsigned int va_list_gpr_size : 8;
/* Number of units of floating point registers that need saving in stdarg
function. */
unsigned int va_list_fpr_size : 8;
/* FIXME tuples: This bit is temporarily here to mark when a /* FIXME tuples: This bit is temporarily here to mark when a
function has been gimplified, so we can make sure we're not function has been gimplified, so we can make sure we're not
creating non GIMPLE tuples after gimplification. */ creating non GIMPLE tuples after gimplification. */
...@@ -520,6 +523,7 @@ extern int trampolines_created; ...@@ -520,6 +523,7 @@ extern int trampolines_created;
#define current_function_uses_const_pool (cfun->uses_const_pool) #define current_function_uses_const_pool (cfun->uses_const_pool)
#define current_function_epilogue_delay_list (cfun->epilogue_delay_list) #define current_function_epilogue_delay_list (cfun->epilogue_delay_list)
#define current_function_has_nonlocal_label (cfun->has_nonlocal_label) #define current_function_has_nonlocal_label (cfun->has_nonlocal_label)
#define current_function_calls_unwind_init (cfun->calls_unwind_init)
#define current_function_has_nonlocal_goto (cfun->has_nonlocal_goto) #define current_function_has_nonlocal_goto (cfun->has_nonlocal_goto)
#define return_label (cfun->x_return_label) #define return_label (cfun->x_return_label)
......
...@@ -622,6 +622,61 @@ replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage) ...@@ -622,6 +622,61 @@ replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage)
replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage); replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage);
} }
/* Determine if the current function has an exception receiver block
that reaches the exit block via non-exceptional edges */
static bool
has_nonexceptional_receiver (void)
{
edge e;
edge_iterator ei;
basic_block *tos, *worklist, bb;
/* If we're not optimizing, then just err on the safe side. */
if (!optimize)
return true;
/* First determine which blocks can reach exit via normal paths. */
tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
FOR_EACH_BB (bb)
bb->flags &= ~BB_REACHABLE;
/* Place the exit block on our worklist. */
EXIT_BLOCK_PTR->flags |= BB_REACHABLE;
*tos++ = EXIT_BLOCK_PTR;
/* Iterate: find everything reachable from what we've already seen. */
while (tos != worklist)
{
bb = *--tos;
FOR_EACH_EDGE (e, ei, bb->preds)
if (!(e->flags & EDGE_ABNORMAL))
{
basic_block src = e->src;
if (!(src->flags & BB_REACHABLE))
{
src->flags |= BB_REACHABLE;
*tos++ = src;
}
}
}
free (worklist);
/* Now see if there's a reachable block with an exceptional incoming
edge. */
FOR_EACH_BB (bb)
if (bb->flags & BB_REACHABLE)
FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_ABNORMAL)
return true;
/* No exceptional block reached exit unexceptionally. */
return false;
}
/* Global variables used by reload and its subroutines. */ /* Global variables used by reload and its subroutines. */
...@@ -688,9 +743,12 @@ reload (rtx first, int global) ...@@ -688,9 +743,12 @@ reload (rtx first, int global)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
mark_home_live (i); mark_home_live (i);
/* A function that receives a nonlocal goto must save all call-saved /* A function that has a nonlocal label that can reach the exit
block via non-exceptional paths must save all call-saved
registers. */ registers. */
if (current_function_has_nonlocal_label) if (current_function_calls_unwind_init
|| (current_function_has_nonlocal_label
&& has_nonexceptional_receiver ()))
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i)) if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
regs_ever_live[i] = 1; regs_ever_live[i] = 1;
......
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