function.h (struct function): Add flag all_throwers_are_sibcalls.

2002-08-24  Stuart Hastings  <stuart@apple.com>

        * function.h (struct function): Add flag
        all_throwers_are_sibcalls.
        * except.c (set_nothrow_function_flags): Replaces
        nothrow_function_p. Set new flag.
        * except.h (set_nothrow_function_flags): Replaces
        nothrow_function_p.
        * dwarf2out.c (struct dw_fde_struct): Add flag
        all_throwers_are_sibcalls.
        (output_call_frame_info): Test it.
        (dwarf2out_begin_prologue) Propagate it from cfun to
        dw_fde_struct.
        * toplev.c (rest_of_compilation): Update calls to
        nothrow_function_p.

From-SVN: r56561
This commit is contained in:
Stuart Hastings 2002-08-25 05:21:11 +00:00 committed by Stan Shebs
parent 13d3f0b659
commit b6128b8c31
6 changed files with 66 additions and 15 deletions

View File

@ -1,3 +1,19 @@
2002-08-24 Stuart Hastings <stuart@apple.com>
* function.h (struct function): Add flag
all_throwers_are_sibcalls.
* except.c (set_nothrow_function_flags): Replaces
nothrow_function_p. Set new flag.
* except.h (set_nothrow_function_flags): Replaces
nothrow_function_p.
* dwarf2out.c (struct dw_fde_struct): Add flag
all_throwers_are_sibcalls.
(output_call_frame_info): Test it.
(dwarf2out_begin_prologue) Propagate it from cfun to
dw_fde_struct.
* toplev.c (rest_of_compilation): Update calls to
nothrow_function_p.
2002-08-23 Zack Weinberg <zack@codesourcery.com>
* ggc-page.c (compute_inverse): Short circuit calculation for

View File

@ -203,6 +203,7 @@ typedef struct dw_fde_struct
const char *dw_fde_end;
dw_cfi_ref dw_fde_cfi;
unsigned funcdef_number;
unsigned all_throwers_are_sibcalls : 1;
unsigned nothrow : 1;
unsigned uses_eh_lsda : 1;
}
@ -1952,8 +1953,9 @@ output_call_frame_info (for_eh)
fde = &fde_table[i];
/* Don't emit EH unwind info for leaf functions that don't need it. */
if (!flag_asynchronous_unwind_tables && for_eh && fde->nothrow
&& ! fde->uses_eh_lsda)
if (!flag_asynchronous_unwind_tables && for_eh
&& (fde->nothrow || fde->all_throwers_are_sibcalls)
&& !fde->uses_eh_lsda)
continue;
ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
@ -2115,6 +2117,7 @@ dwarf2out_begin_prologue (line, file)
fde->funcdef_number = current_function_funcdef_no;
fde->nothrow = current_function_nothrow;
fde->uses_eh_lsda = cfun->uses_eh_lsda;
fde->all_throwers_are_sibcalls = cfun->all_throwers_are_sibcalls;
args_size = old_args_size = 0;

View File

@ -2893,25 +2893,50 @@ can_throw_external (insn)
return true;
}
/* True if nothing in this function can throw outside this function. */
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
bool
nothrow_function_p ()
void
set_nothrow_function_flags ()
{
rtx insn;
current_function_nothrow = 1;
/* Assume cfun->all_throwers_are_sibcalls until we encounter
something that can throw an exception. We specifically exempt
CALL_INSNs that are SIBLING_CALL_P, as these are really jumps,
and can't throw. Most CALL_INSNs are not SIBLING_CALL_P, so this
is optimistic. */
cfun->all_throwers_are_sibcalls = 1;
if (! flag_exceptions)
return true;
return;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (can_throw_external (insn))
return false;
{
current_function_nothrow = 0;
if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
{
cfun->all_throwers_are_sibcalls = 0;
return;
}
}
for (insn = current_function_epilogue_delay_list; insn;
insn = XEXP (insn, 1))
if (can_throw_external (XEXP (insn, 0)))
return false;
if (can_throw_external (insn))
{
current_function_nothrow = 0;
return true;
if (GET_CODE (insn) != CALL_INSN || !SIBLING_CALL_P (insn))
{
cfun->all_throwers_are_sibcalls = 0;
return;
}
}
}

View File

@ -91,8 +91,8 @@ extern void for_each_eh_label PARAMS ((void (*) (rtx)));
extern bool can_throw_internal PARAMS ((rtx));
extern bool can_throw_external PARAMS ((rtx));
/* Return nonzero if nothing in this function can throw. */
extern bool nothrow_function_p PARAMS ((void));
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
extern void set_nothrow_function_flags PARAMS ((void));
/* After initial rtl generation, call back to finish generating
exception support code. */

View File

@ -437,6 +437,13 @@ struct function GTY(())
we should try to cut corners where we can. */
unsigned int is_thunk : 1;
/* This bit is used by the exception handling logic. It is set if all
calls (if any) are sibling calls. Such functions do not have to
have EH tables generated, as they cannot throw. A call to such a
function, however, should be treated as throwing if any of its callees
can throw. */
unsigned int all_throwers_are_sibcalls : 1;
/* Nonzero if instrumentation calls for function entry and exit should be
generated. */
unsigned int instrument_entry_exit : 1;

View File

@ -2506,7 +2506,7 @@ rest_of_compilation (decl)
free_bb_for_insn ();
}
current_function_nothrow = nothrow_function_p ();
set_nothrow_function_flags ();
if (current_function_nothrow)
/* Now we know that this can't throw; set the flag for the benefit
of other functions later in this translation unit. */
@ -3528,7 +3528,7 @@ rest_of_compilation (decl)
shorten_branches (get_insns ());
timevar_pop (TV_SHORTEN_BRANCH);
current_function_nothrow = nothrow_function_p ();
set_nothrow_function_flags ();
if (current_function_nothrow)
/* Now we know that this can't throw; set the flag for the benefit
of other functions later in this translation unit. */