aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorStuart Hastings <stuart@apple.com>2002-08-25 05:21:11 +0000
committerStan Shebs <shebs@gcc.gnu.org>2002-08-25 05:21:11 +0000
commitb6128b8c319487d4ecb240a211c0af9f6a4c2659 (patch)
tree3380fca11b3c1b6f649fb9a54c3af4eb23ad8090 /gcc
parent13d3f0b659c7db21e006e8d2894c93707a95583d (diff)
downloadgcc-b6128b8c319487d4ecb240a211c0af9f6a4c2659.zip
gcc-b6128b8c319487d4ecb240a211c0af9f6a4c2659.tar.gz
gcc-b6128b8c319487d4ecb240a211c0af9f6a4c2659.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/dwarf2out.c7
-rw-r--r--gcc/except.c43
-rw-r--r--gcc/except.h4
-rw-r--r--gcc/function.h7
-rw-r--r--gcc/toplev.c4
6 files changed, 66 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3cf590b..328a765 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index cf692d6..e8f02e6 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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;
diff --git a/gcc/except.c b/gcc/except.c
index a2818c3..17eeae1 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;
+ }
+ }
}
diff --git a/gcc/except.h b/gcc/except.h
index ce91051..034ce51 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -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. */
diff --git a/gcc/function.h b/gcc/function.h
index 0ee31d1..ff96b9c 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -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;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index aec618f..24e3f6a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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. */