diff options
author | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-25 05:21:11 +0000 |
---|---|---|
committer | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-08-25 05:21:11 +0000 |
commit | 043964831d9d0819bda7811ab8acc53408c9ebb7 (patch) | |
tree | 3380fca11b3c1b6f649fb9a54c3af4eb23ad8090 /gcc/except.c | |
parent | 3e5d979595c5dd72ad98fdffb3deae78547b939b (diff) | |
download | gcc-043964831d9d0819bda7811ab8acc53408c9ebb7.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@56561 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/gcc/except.c b/gcc/except.c index a2818c3408f..17eeae1bd80 100644 --- a/gcc/except.c +++ b/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; - if (! flag_exceptions) - return true; + /* 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; + 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; + } + } } |