]> gcc.gnu.org Git - gcc.git/commitdiff
function.h (struct function): Add flag all_throwers_are_sibcalls.
authorStuart Hastings <stuart@apple.com>
Sun, 25 Aug 2002 05:21:11 +0000 (05:21 +0000)
committerStan Shebs <shebs@gcc.gnu.org>
Sun, 25 Aug 2002 05:21:11 +0000 (05:21 +0000)
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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/except.c
gcc/except.h
gcc/function.h
gcc/toplev.c

index 3cf590b0ebbb90cbe0f353a586e6f5b7f4f36b79..328a765893b98d784ec89403de3d50681a4cf891 100644 (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
index cf692d653ee2bfc35c929c2dfc48269c34da855b..e8f02e62f5f56a1edefa8985188bc10f6e3124c5 100644 (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;
 
index a2818c3408f752587ddcbb4cdbe219d25ef1f2fb..17eeae1bd8053fe53f8eebd8b092a58da2aeec89 100644 (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;
 
-  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;
+         }
+      }
 }
 
 \f
index ce91051d5b1637ab551b14a5627092b91794d171..034ce51c8fe2e3bcab3cd07c7127f5035b000f62 100644 (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.  */
index 0ee31d1ed532bba0a1df83e100c9d252a9476006..ff96b9c2bb2b60628667aface0ba9bd068300db6 100644 (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;
index aec618f178ccce8282dc884bdafdd3e54ba4e95b..24e3f6a518307cf5350c48a954313f439f5c1031 100644 (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.  */
This page took 0.115243 seconds and 5 git commands to generate.