summaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorshebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-25 05:21:11 +0000
committershebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-08-25 05:21:11 +0000
commit043964831d9d0819bda7811ab8acc53408c9ebb7 (patch)
tree3380fca11b3c1b6f649fb9a54c3af4eb23ad8090 /gcc/except.c
parent3e5d979595c5dd72ad98fdffb3deae78547b939b (diff)
downloadgcc-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.c43
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;
+ }
+ }
}