]> gcc.gnu.org Git - gcc.git/commitdiff
except.h (struct eh_entry): Add goto_entry_p.
authorMark Mitchell <mark@codesourcery.com>
Thu, 18 Nov 1999 17:50:56 +0000 (17:50 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 18 Nov 1999 17:50:56 +0000 (17:50 +0000)
* except.h (struct eh_entry): Add goto_entry_p.
(eh_region_from_symbol): Remove prototype.
* except.c (find_func_region_from_symbol): New function.
(emit_cleanup_handler): Likewise.
(eh_region_from_symbol): Make it static.
(add_new_handler): Verify the argument.
(find_func_region): Update comment.
(expand_eh_region_end): Expand handlers here, rater than waiting
until expand_leftover_cleanups or start_all_catch.
(expand_leftover_cleanups): Don't expand here.
(expand_start_all_catch): Or here.
(expand_rethrow): Check the return value from find_func_region.
* function.c (expand_function_end): Emit the catch_clauses.

From-SVN: r30576

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

index 829318e1e7733df8473f20f41956b7ea3c4186a7..f8fe6c575cd0e469f1553bb3026462338ab6abd3 100644 (file)
@@ -1,3 +1,19 @@
+1999-11-17  Mark Mitchell  <mark@codesourcery.com>
+
+       * except.h (struct eh_entry): Add goto_entry_p.
+       (eh_region_from_symbol): Remove prototype.
+       * except.c (find_func_region_from_symbol): New function.
+       (emit_cleanup_handler): Likewise.
+       (eh_region_from_symbol): Make it static.
+       (add_new_handler): Verify the argument.
+       (find_func_region): Update comment.
+       (expand_eh_region_end): Expand handlers here, rater than waiting
+       until expand_leftover_cleanups or start_all_catch.
+       (expand_leftover_cleanups): Don't expand here.
+       (expand_start_all_catch): Or here.
+       (expand_rethrow): Check the return value from find_func_region.
+       * function.c (expand_function_end): Emit the catch_clauses.
+       
 1999-11-18  Gavin Romig-Koch  <gavin@cygnus.com>
 
        * integrate.c (expand_inline_function): Add necessary check for NULL.
index 15bd28d8d131959348a6ebfcf9ca4f88b5cb90e6..4b294769f120b1735a92662b0eb2fe07bcf12a2f 100644 (file)
@@ -479,10 +479,14 @@ static void push_entry            PROTO ((struct eh_stack *, struct eh_entry*));
 static void receive_exception_label PROTO ((rtx));
 static int new_eh_region_entry PROTO ((int, rtx));
 static int find_func_region    PROTO ((int));
+static int find_func_region_from_symbol PROTO ((rtx));
 static void clear_function_eh_region PROTO ((void));
 static void process_nestinfo   PROTO ((int, eh_nesting_info *, int *));
 
 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
+static void emit_cleanup_handler PROTO ((struct eh_entry *));
+static int eh_region_from_symbol PROTO((rtx));
+
 \f
 /* Various support routines to manipulate the various data structures
    used by the exception handling code.  */
@@ -590,6 +594,7 @@ push_eh_entry (stack)
   else
     entry->outer_context = create_rethrow_ref (CODE_LABEL_NUMBER (rlab));
   entry->rethrow_label = entry->outer_context;
+  entry->goto_entry_p = 0;
 
   node->entry = entry;
   node->chain = stack->top;
@@ -705,10 +710,8 @@ static int current_func_eh_entry = 0;
 
 #define SIZE_FUNC_EH(X)   (sizeof (struct func_eh_entry) * X)
 
-/* Add a new eh_entry for this function, and base it off of the information
-   in the EH_ENTRY parameter. A NULL parameter is invalid. 
-   OUTER_CONTEXT is a label which is used for rethrowing. The number
-   returned is an number which uniquely identifies this exception range. */
+/* Add a new eh_entry for this function.  The number returned is an
+   number which uniquely identifies this exception range. */
 
 static int 
 new_eh_region_entry (note_eh_region, rethrow) 
@@ -755,6 +758,12 @@ add_new_handler (region, newhandler)
 {
   struct handler_info *last;
 
+  /* If find_func_region returns -1, callers might attempt to pass us
+     this region number.  If that happens, something has gone wrong;
+     -1 is never a valid region.  */
+  if (region == -1)
+    abort ();
+
   newhandler->next = NULL;
   last = function_eh_regions[region].handlers;
   if (last == NULL)
@@ -883,7 +892,7 @@ get_new_handler (handler, typeinfo)
 
 
 /* Find the index in function_eh_regions associated with a NOTE region. If
-   the region cannot be found, a -1 is returned. This should never happen! */
+   the region cannot be found, a -1 is returned.  */
 
 static int 
 find_func_region (insn_region)
@@ -960,7 +969,7 @@ duplicate_eh_handlers (old_note_eh_region, new_note_eh_region, map)
 
 
 /* Given a rethrow symbol, find the EH region number this is for. */
-int 
+static int 
 eh_region_from_symbol (sym)
      rtx sym;
 {
@@ -973,6 +982,14 @@ eh_region_from_symbol (sym)
   return -1;
 }
 
+/* Like find_func_region, but using the rethrow symbol for the region
+   rather than the region number itself.  */
+static int
+find_func_region_from_symbol (sym)
+     rtx sym;
+{
+  return find_func_region (eh_region_from_symbol (sym));
+}
 
 /* When inlining/unrolling, we have to map the symbols passed to
    __rethrow as well. This performs the remap. If a symbol isn't foiund,
@@ -1475,6 +1492,7 @@ expand_eh_region_end (handler)
      tree handler;
 {
   struct eh_entry *entry;
+  struct eh_node *node;
   rtx note;
   int ret, r;
 
@@ -1523,6 +1541,21 @@ expand_eh_region_end (handler)
 
       expand_end_bindings (NULL_TREE, 0, 0);
     }
+
+  /* Go through the goto handlers in the queue, emitting their
+     handlers if we now have enough information to do so.  */
+  for (node = ehqueue.head; node; node = node->chain)
+    if (node->entry->goto_entry_p 
+       && node->entry->outer_context == entry->rethrow_label)
+      emit_cleanup_handler (node->entry);
+
+  /* We can't emit handlers for goto entries until their scopes are
+     complete because we don't know where they need to rethrow to,
+     yet.  */
+  if (entry->finalization != integer_zero_node 
+      && (!entry->goto_entry_p 
+         || find_func_region_from_symbol (entry->outer_context) != -1))
+    emit_cleanup_handler (entry);
 }
 
 /* End the EH region for a goto fixup.  We only need them in the region-based
@@ -1535,6 +1568,8 @@ expand_fixup_region_start ()
     return;
 
   expand_eh_region_start ();
+  /* Mark this entry as the entry for a goto.  */
+  ehstack.top->entry->goto_entry_p = 1;
 }
 
 /* End the EH region for a goto fixup.  CLEANUP is the cleanup we just
@@ -1636,33 +1671,14 @@ expand_leftover_cleanups ()
 {
   struct eh_entry *entry;
 
-  while ((entry = dequeue_eh_entry (&ehqueue)) != 0)
+  for (entry = dequeue_eh_entry (&ehqueue); 
+       entry;
+       entry = dequeue_eh_entry (&ehqueue))
     {
-      rtx prev;
-
-      /* A leftover try block. Shouldn't be one here.  */
+      /* A leftover try bock.  Shouldn't be one here.  */
       if (entry->finalization == integer_zero_node)
        abort ();
 
-      /* Output the label for the start of the exception handler.  */
-
-      receive_exception_label (entry->exception_handler_label);
-
-      /* register a handler for this cleanup region */
-      add_new_handler (
-        find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), 
-        get_new_handler (entry->exception_handler_label, NULL));
-
-      /* And now generate the insns for the handler.  */
-      expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
-
-      prev = get_last_insn ();
-      if (prev == NULL || GET_CODE (prev) != BARRIER)
-       /* Emit code to throw to the outer context if we fall off
-          the end of the handler.  */
-       expand_rethrow (entry->outer_context);
-
-      do_pending_stack_adjust ();
       free (entry);
     }
 }
@@ -1764,6 +1780,56 @@ end_catch_handler ()
   catchstack.top->entry->false_label = NULL_RTX;
 }
 
+/* Emit the handler specified by ENTRY.  */
+
+static void
+emit_cleanup_handler (entry)
+  struct eh_entry *entry;
+{
+  rtx prev;
+  rtx handler_insns;
+
+  /* Put these handler instructions in a sequence.  */
+  do_pending_stack_adjust ();
+  start_sequence ();
+
+  /* Emit the label for the cleanup handler for this region, and
+     expand the code for the handler.
+     
+     Note that a catch region is handled as a side-effect here; for a
+     try block, entry->finalization will contain integer_zero_node, so
+     no code will be generated in the expand_expr call below. But, the
+     label for the handler will still be emitted, so any code emitted
+     after this point will end up being the handler.  */
+      
+  receive_exception_label (entry->exception_handler_label);
+
+  /* register a handler for this cleanup region */
+  add_new_handler (find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), 
+                  get_new_handler (entry->exception_handler_label, NULL));
+
+  /* And now generate the insns for the cleanup handler.  */
+  expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
+
+  prev = get_last_insn ();
+  if (prev == NULL || GET_CODE (prev) != BARRIER)
+    /* Code to throw out to outer context when we fall off end of the
+       handler. We can't do this here for catch blocks, so it's done
+       in expand_end_all_catch instead.  */
+    expand_rethrow (entry->outer_context);
+
+  /* Finish this sequence.  */
+  do_pending_stack_adjust ();
+  handler_insns = get_insns ();
+  end_sequence ();
+
+  /* And add it to the CATCH_CLAUSES.  */
+  push_to_sequence (catch_clauses);
+  emit_insns (handler_insns);
+  catch_clauses = get_insns ();
+  end_sequence ();
+}
+
 /* Generate RTL for the start of a group of catch clauses. 
 
    It is responsible for starting a new instruction sequence for the
@@ -1802,48 +1868,15 @@ expand_start_all_catch ()
      the handlers in this handler-seq.  */
   start_sequence ();
 
-  entry = dequeue_eh_entry (&ehqueue);
-  for ( ; entry->finalization != integer_zero_node;
-                                 entry = dequeue_eh_entry (&ehqueue))
-    {
-      rtx prev;
-
-      /* Emit the label for the cleanup handler for this region, and
-        expand the code for the handler. 
-
-        Note that a catch region is handled as a side-effect here;
-        for a try block, entry->finalization will contain
-        integer_zero_node, so no code will be generated in the
-        expand_expr call below. But, the label for the handler will
-        still be emitted, so any code emitted after this point will
-        end up being the handler.  */
-      
-      receive_exception_label (entry->exception_handler_label);
-
-      /* register a handler for this cleanup region */
-      add_new_handler (
-        find_func_region (CODE_LABEL_NUMBER (entry->exception_handler_label)), 
-        get_new_handler (entry->exception_handler_label, NULL));
-
-      /* And now generate the insns for the cleanup handler.  */
-      expand_expr (entry->finalization, const0_rtx, VOIDmode, 0);
-
-      prev = get_last_insn ();
-      if (prev == NULL || GET_CODE (prev) != BARRIER)
-       /* Code to throw out to outer context when we fall off end
-          of the handler. We can't do this here for catch blocks,
-          so it's done in expand_end_all_catch instead.  */
-       expand_rethrow (entry->outer_context);
-
-      do_pending_stack_adjust ();
-      free (entry);
-    }
+  for (entry = dequeue_eh_entry (&ehqueue); 
+       entry->finalization != integer_zero_node;
+       entry = dequeue_eh_entry (&ehqueue))
+    free (entry);
 
   /* At this point, all the cleanups are done, and the ehqueue now has
      the current exception region at its head. We dequeue it, and put it
      on the catch stack. */
-
-    push_entry (&catchstack, entry);
+  push_entry (&catchstack, entry);
 
   /* If we are not doing setjmp/longjmp EH, because we are reordered
      out of line, we arrange to rethrow in the outer context.  We need to
@@ -1935,6 +1968,10 @@ expand_rethrow (label)
          label = last_rethrow_symbol;
        emit_library_call (rethrow_libfunc, 0, VOIDmode, 1, label, Pmode);
        region = find_func_region (eh_region_from_symbol (label));
+       /* If the region is -1, it doesn't exist yet.  We should be
+          trying to rethrow there yet.  */
+       if (region == -1)
+         abort ();
        function_eh_regions[region].rethrow_ref = 1;
 
        /* Search backwards for the actual call insn.  */
index 07d4359a239f74df4ad0316535cb6104b8c92e08..eafeaa942cdb96af27ed62768e58c18ea9e7ae59 100644 (file)
@@ -62,6 +62,9 @@ struct eh_entry {
   int label_used;
   rtx false_label;
   rtx rethrow_label;
+  /* If non-zero, this entry is for a handler created when we left an
+     exception-region via goto.  */
+  unsigned goto_entry_p : 1;
 };
 #else
 struct label_node;
@@ -108,16 +111,10 @@ struct eh_status
   /* This stack is used to represent what the current eh region is
      for the catch blocks beings processed */
   struct eh_stack x_catchstack;
-  /* A queue used for tracking which exception regions have closed but
-     whose handlers have not yet been expanded. Regions are emitted in
-     groups in an attempt to improve paging performance.
-
+  /* A queue used for tracking which exception regions have closed.
      As we exit a region, we enqueue a new entry. The entries are then
-     dequeued during expand_leftover_cleanups and expand_start_all_catch,
-
-     We should redo things so that we either take RTL for the handler,
-     or we expand the handler expressed as a tree immediately at region
-     end time.  */
+     dequeued during expand_leftover_cleanups and
+     expand_start_all_catch.  */
   struct eh_queue x_ehqueue;
   /* Insns for all of the exception handlers for the current function.
      They are currently emitted by the frontend code.  */
@@ -271,10 +268,6 @@ int rethrow_used                                PROTO((int));
 
 void update_rethrow_references                 PROTO((void));
 
-/* Return the region number a this is the rethrow label for. */
-
-int eh_region_from_symbol                       PROTO((rtx));
-
 /* Get a pointer to the first handler in an exception region's list. */
 
 struct handler_info *get_first_handler          PROTO((int));
index 7c491df9158e755544c355c3e1047d871f5241d2..7014a8b1b6c9d43126aa5af31a4c711a65f34ed7 100644 (file)
@@ -6436,6 +6436,9 @@ expand_function_end (filename, line, end_bindings)
 
     expand_leftover_cleanups ();
 
+    /* If there are any catch_clauses remaining, output them now.  */
+    emit_insns (catch_clauses);
+    catch_clauses = NULL_RTX;
     /* If the above emitted any code, may sure we jump around it.  */
     if (last != get_last_insn ())
       {
This page took 0.075257 seconds and 5 git commands to generate.