except.c (current_function_has_exception_handlers): New.
authorRichard Henderson <rth@redhat.com>
Wed, 20 Mar 2002 00:49:13 +0000 (16:49 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 20 Mar 2002 00:49:13 +0000 (16:49 -0800)
        * except.c (current_function_has_exception_handlers): New.
        * except.h: Declare it.
        * sibcall.c (optimize_sibling_and_tail_recursive_call): Use it.
        Combine tests that disable all sibcalls for the function.

From-SVN: r51054

gcc/ChangeLog
gcc/except.c
gcc/except.h
gcc/sibcall.c

index 1306228a0ac1534f4989cf68c8e6aff669383294..cd732d7c1a2a28d272670cce346cdbe013a15ce1 100644 (file)
@@ -1,3 +1,10 @@
+2002-03-19  Richard Henderson  <rth@redhat.com>
+
+       * except.c (current_function_has_exception_handlers): New.
+       * except.h: Declare it.
+       * sibcall.c (optimize_sibling_and_tail_recursive_call): Use it.
+       Combine tests that disable all sibcalls for the function.
+
 2002-03-19  Olivier Hainque  <hainque@act-europe.fr>
 
        * varasm.c (output_constant_def): Don't call ENCODE_SECTION_INFO
index 939610ffc1f54bbc510d79db32268d5e0d92e215..fa92368ec8d4465805a8e6b91ee47802f46b8fb1 100644 (file)
@@ -1401,6 +1401,23 @@ find_exception_handler_labels ()
   exception_handler_labels = list;
 }
 
+bool
+current_function_has_exception_handlers ()
+{
+  int i;
+
+  for (i = cfun->eh->last_region_number; i > 0; --i)
+    {
+      struct eh_region *region = cfun->eh->region_array[i];
+
+      if (! region || region->region_number != i)
+       continue;
+      if (region->type != ERT_THROW)
+       return true;
+    }
+
+  return false;
+}
 \f
 static struct eh_region *
 duplicate_eh_region_1 (o, map)
index f543c46949f6a04ffce531345dfc7f043ebf9fb8..27dc7143f6c03c7cec31e99b3ad78bafd130d6e5 100644 (file)
@@ -120,6 +120,7 @@ extern void maybe_remove_eh_handler         PARAMS ((rtx));
 extern void convert_from_eh_region_ranges      PARAMS ((void));
 extern void convert_to_eh_region_ranges                PARAMS ((void));
 extern void find_exception_handler_labels      PARAMS ((void));
+extern bool current_function_has_exception_handlers PARAMS ((void));
 extern void output_function_exception_table    PARAMS ((void));
 
 extern void expand_builtin_unwind_init         PARAMS ((void));
index 6c2dc5c09146041d4478a1fb619a0db5dd87e465..5a7997cb0387aaedc12bfadedc1e1fa011b12c89 100644 (file)
@@ -572,7 +572,7 @@ optimize_sibling_and_tail_recursive_calls ()
 {
   rtx insn, insns;
   basic_block alternate_exit = EXIT_BLOCK_PTR;
-  int current_function_uses_addressof;
+  bool no_sibcalls_this_function = false;
   int successful_sibling_call = 0;
   int replaced_call_placeholder = 0;
   edge e;
@@ -595,6 +595,12 @@ optimize_sibling_and_tail_recursive_calls ()
   if (n_basic_blocks == 0)
     return;
 
+  /* If we are using sjlj exceptions, we may need to add a call to 
+     _Unwind_SjLj_Unregister at exit of the function.  Which means
+     that we cannot do any sibcall transformations.  */
+  if (USING_SJLJ_EXCEPTIONS && current_function_has_exception_handlers ())
+    no_sibcalls_this_function = true;
+
   return_value_pseudo = NULL_RTX;
 
   /* Find the exit block.
@@ -655,7 +661,7 @@ optimize_sibling_and_tail_recursive_calls ()
 
   /* If the function uses ADDRESSOF, we can't (easily) determine
      at this point if the value will end up on the stack.  */
-  current_function_uses_addressof = sequence_uses_addressof (insns);
+  no_sibcalls_this_function |= sequence_uses_addressof (insns);
 
   /* Walk the insn chain and find any CALL_PLACEHOLDER insns.  We need to
      select one of the insn sequences attached to each CALL_PLACEHOLDER.
@@ -685,11 +691,10 @@ optimize_sibling_and_tail_recursive_calls ()
 
          /* See if there are any reasons we can't perform either sibling or
             tail call optimizations.  We must be careful with stack slots
-            which are live at potential optimization sites.  ??? The first
-            test is overly conservative and should be replaced.  */
-         if (frame_offset
-             /* Can't take address of local var if used by recursive call.  */
-             || current_function_uses_addressof
+            which are live at potential optimization sites.  */
+         if (no_sibcalls_this_function
+             /* ??? Overly conservative.  */
+             || frame_offset
              /* Any function that calls setjmp might have longjmp called from
                 any called function.  ??? We really should represent this
                 properly in the CFG so that this needn't be special cased.  */