mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-19 15:19:30 +08:00
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:
parent
13d3f0b659
commit
b6128b8c31
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
43
gcc/except.c
43
gcc/except.c
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user