./: * libgcc2.c (__throw): Use __builtin_return_addr instead of __eh_pc.
authorJason Merrill <jason@yorick.cygnus.com>
Thu, 4 Dec 1997 09:41:38 +0000 (09:41 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 4 Dec 1997 09:41:38 +0000 (04:41 -0500)
* except.c: Lose outer_context_label_stack.
  (expand_eh_region_end): Rethrow from outer_context here.
(expand_fixup_region_end): Let expand_eh_region_end do the rethrow.
(expand_internal_throw): Take no args.
(expand_internal_throw_indirect): Lose.
(expand_leftover_cleanups, expand_start_all_catch): Use expand_rethrow.
(expand_start_all_catch): Start a rethrow region.
(expand_end_all_catch): End it.
(expand_rethrow): New fn.
* except.h: Reflect above changes.

cp/: * except.c (expand_end_catch_block): Lose rethrow region.
(expand_start_catch_block): Likewise.
(expand_end_catch_block): Don't expand_leftover_cleanups.

From-SVN: r16937

gcc/ChangeLog
gcc/Makefile.in
gcc/cp/ChangeLog
gcc/cp/except.c
gcc/except.c
gcc/except.h
gcc/flow.c
gcc/libgcc2.c

index ec46bc2bd50c2c4b4b321ecfe05806228c8a9b79..c497a759440baedac0bf0e25411a1c0488777d0d 100644 (file)
@@ -1,3 +1,18 @@
+Wed Dec  3 12:01:56 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * libgcc2.c (__throw): Use __builtin_return_addr instead of __eh_pc.
+       * except.c: Lose outer_context_label_stack.
+       (expand_eh_region_end): Rethrow from outer_context here.
+       (expand_fixup_region_end): Let expand_eh_region_end do the rethrow.
+       (expand_internal_throw): Take no args.
+       (expand_internal_throw_indirect): Lose.
+       (expand_leftover_cleanups, expand_start_all_catch): Use expand_rethrow.
+       (expand_start_all_catch): Start a rethrow region.
+       (expand_end_all_catch): End it.
+       (expand_rethrow): New fn.
+       * except.h: Reflect above changes.
+       * flow.c: Revert change of Nov 27.
+
 Thu Dec  4 00:24:09 1997  Jeffrey A Law  (law@cygnus.com)
 
        * i386/t-sol2 (CRTSTUFF_T_CFLAGS): Turn on the optimizer.
index 5f0acfc0198806edbfc57581fc71e6c2671ecd9e..e1fe81241ad5d8c495139c27056ca8b0b627fb0c 100644 (file)
@@ -280,7 +280,7 @@ LIBGCC2 = libgcc2.a
 #
 # -fexceptions is necessary for eh.o now that the exceptions are
 # the default for g++ only.
-LIBGCC2_DEBUG_CFLAGS = -g1
+LIBGCC2_DEBUG_CFLAGS = -g
 LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 -D__GCC_FLOAT_NOT_NEEDED -fexceptions @inhibit_libc@ 
 
 # Additional options to use when compiling libgcc2.a.
index 387c9d7e63ebec043b6c34d04b51840c7b3aa71a..6b9737d6291a46458c032df08ced82209a2bdb35 100644 (file)
@@ -1,3 +1,9 @@
+Wed Dec  3 20:02:39 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * except.c (expand_end_catch_block): Lose rethrow region.
+       (expand_start_catch_block): Likewise.
+       (expand_end_catch_block): Don't expand_leftover_cleanups.
+
 Wed Dec  3 13:24:04 1997  Benjamin Kosnik  <bkoz@rhino.cygnus.com>
 
        * pt.c (tsubst): Remove tree_cons call (places redundant info into
index 6e7c876467f617e05a56d5348ee77963a0c865d1..194c17d5e7f335486ff0f5cebfe4d14dfbe3443e 100644 (file)
@@ -185,10 +185,13 @@ static tree Unwind;
 
    ========================================================================= */
 
+#ifndef DWARF2_UNWIND_INFO
 /* Holds the pc for doing "throw" */
 static tree saved_pc;
 
 extern int throw_used;
+#endif
+
 extern rtx catch_clauses;
 extern tree const_ptr_type_node;
 
@@ -255,12 +258,14 @@ init_exception_processing ()
 
   pop_lang_context ();
 
+#ifndef DWARF2_UNWIND_INFO
   d = build_decl (VAR_DECL, get_identifier ("__eh_pc"), ptr_type_node);
   TREE_PUBLIC (d) = 1;
   DECL_EXTERNAL (d) = 1;
   DECL_ARTIFICIAL (d) = 1;
   cp_finish_decl (d, NULL_TREE, NULL_TREE, 0, 0);
   saved_pc = d;
+#endif
 
   /* If we use setjmp/longjmp EH, arrange for all cleanup actions to
      be protected with __terminate.  */
@@ -520,17 +525,6 @@ expand_start_catch_block (declspecs, declarator)
   if (! doing_eh (1))
     return;
 
-  /* If we are not doing setjmp/longjmp EH, because we are reordered
-     out of line, we arrange to rethrow in the outer context so as to
-     skip through the terminate region we are nested in, should we
-     encounter an exception in the catch handler.  We also need to do
-     this because we are not physically within the try block, if any,
-     that contains this catch block.
-
-     Matches the end in expand_end_catch_block.  */
-  if (! exceptions_via_longjmp)
-    expand_eh_region_start ();
-
   /* Create a binding level for the eh_info and the exception object
      cleanup.  */
   pushlevel (0);
@@ -655,36 +649,11 @@ expand_end_catch_block ()
   expand_end_bindings (getdecls (), kept_level_p (), 0);
   poplevel (kept_level_p (), 1, 0);
 
-  if (! exceptions_via_longjmp)
-    {
-      /* If we are not doing setjmp/longjmp EH, we need an extra
-        region around the whole catch block to skip through the
-        terminate region we are nested in.  */
-
-      tree t = make_node (RTL_EXPR);
-      TREE_TYPE (t) = void_type_node;
-      RTL_EXPR_RTL (t) = const0_rtx;
-      TREE_SIDE_EFFECTS (t) = 1;
-      do_pending_stack_adjust ();
-      start_sequence_for_rtl_expr (t);
-
-      expand_internal_throw (outer_context_label_stack->u.rlabel);
-
-      do_pending_stack_adjust ();
-      RTL_EXPR_SEQUENCE (t) = get_insns ();
-      end_sequence ();
-
-      /* For the rethrow region.  */
-      expand_eh_region_end (t);
-    }
-
   /* Fall to outside the try statement when done executing handler and
      we fall off end of handler.  This is jump Lresume in the
      documentation.  */
   expand_goto (top_label_entry (&caught_return_label_stack));
 
-  expand_leftover_cleanups ();
-
   /* label we emit to jump to if this catch block didn't match.  */
   /* This the closing } in the `if (eq) {' of the documentation.  */
   emit_label (pop_label_entry (&false_label_stack));
@@ -1318,18 +1287,7 @@ expand_throw (exp)
       expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
 
-  if (exceptions_via_longjmp)
-    emit_throw ();
-  else
-    {
-      /* This is the label that represents where in the code we were, when
-        we got an exception.  This needs to be updated when we rethrow an
-        exception, so that the matching routine knows to search out.  */
-      label = gen_label_rtx ();
-      emit_label (label);
-
-      expand_internal_throw (label);
-    }
+  expand_internal_throw ();
 }
 
 /* Build a throw expression.  */
index a493375c8ab35b564a81120a5581d732757029d3..c37f89d9087d4f2add0a6ebf5d8c322800a1f6cc 100644 (file)
@@ -417,7 +417,7 @@ int asynchronous_exceptions = 0;
 /* One to protect cleanup actions with a handler that calls
    __terminate, zero otherwise.  */
 
-int protect_cleanup_actions_with_terminate = 0;
+int protect_cleanup_actions_with_terminate;
 
 /* A list of labels used for exception handlers.  Created by
    find_exception_handler_labels for the optimization passes.  */
@@ -487,21 +487,20 @@ static tree protect_list;
 
 struct label_node *caught_return_label_stack = NULL;
 
-/* Keeps track of the label used as the context of a throw to rethrow an
-   exception to the outer exception region.  */
-
-struct label_node *outer_context_label_stack = NULL;
-
 /* A random data area for the front end's own use.  */
 
 struct label_node *false_label_stack = NULL;
 
+#ifndef DWARF2_UNWIND_INFO
 /* The rtx and the tree for the saved PC value.  */
 
 rtx eh_saved_pc_rtx;
 tree eh_saved_pc;
+#endif
 
 rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx));
+static void expand_rethrow     PROTO((rtx));
+
 \f
 /* Various support routines to manipulate the various data structures
    used by the exception handling code.  */
@@ -1097,7 +1096,9 @@ expand_eh_region_end (handler)
   note = emit_note (NULL_PTR, NOTE_INSN_EH_REGION_END);
   NOTE_BLOCK_NUMBER (note)
     = CODE_LABEL_NUMBER (entry->exception_handler_label);
-  if (exceptions_via_longjmp == 0)
+  if (exceptions_via_longjmp == 0
+      /* We share outer_context between regions; only emit it once.  */
+      && INSN_UID (entry->outer_context) == 0)
     {
       rtx label;
 
@@ -1107,14 +1108,8 @@ expand_eh_region_end (handler)
       /* Emit a label marking the end of this exception region that
         is used for rethrowing into the outer context.  */
       emit_label (entry->outer_context);
+      expand_internal_throw ();
 
-      /* Put in something that takes up space, as otherwise the end
-        address for this EH region could have the exact same address as
-        its outer region. This would cause us to miss the fact that
-        resuming exception handling with this PC value would be inside
-        the outer region.  */
-      emit_insn (gen_nop ());
-      emit_barrier ();
       emit_label (label);
     }
 
@@ -1159,9 +1154,7 @@ void
 expand_fixup_region_end (cleanup)
      tree cleanup;
 {
-  tree t;
   struct eh_node *node;
-  int yes;
 
   if (! doing_eh (0) || exceptions_via_longjmp)
     return;
@@ -1174,20 +1167,10 @@ expand_fixup_region_end (cleanup)
   if (node == 0)
     abort ();
 
-  yes = suspend_momentary ();
-
-  t = build (RTL_EXPR, void_type_node, NULL_RTX, const0_rtx);
-  TREE_SIDE_EFFECTS (t) = 1;
-  do_pending_stack_adjust ();
-  start_sequence_for_rtl_expr (t);
-  expand_internal_throw (node->entry->outer_context);
-  do_pending_stack_adjust ();
-  RTL_EXPR_SEQUENCE (t) = get_insns ();
-  end_sequence ();
+  ehstack.top->entry->outer_context = node->entry->outer_context;
 
-  resume_momentary (yes);
-
-  expand_eh_region_end (t);
+  /* Just rethrow.  size_zero_node is just a NOP.  */
+  expand_eh_region_end (size_zero_node);
 }
 
 /* If we are using the setjmp/longjmp EH codegen method, we emit a
@@ -1225,27 +1208,23 @@ emit_throw ()
   emit_barrier ();
 }
 
-/* An internal throw with an indirect CONTEXT we want to throw from.
-   CONTEXT evaluates to the context of the throw.  */
-
-static void
-expand_internal_throw_indirect (context)
-     rtx context;
-{
-  assemble_external (eh_saved_pc);
-  emit_move_insn (eh_saved_pc_rtx, context);
-  emit_throw ();
-}
-
-/* An internal throw with a direct CONTEXT we want to throw from.
-   CONTEXT must be a label; its address will be used as the context of
-   the throw.  */
+/* Throw the current exception.  If appropriate, this is done by jumping
+   to the next handler.  */
 
 void
-expand_internal_throw (context)
-     rtx context;
+expand_internal_throw ()
 {
-  expand_internal_throw_indirect (gen_rtx (LABEL_REF, Pmode, context));
+#ifndef DWARF2_UNWIND_INFO
+  if (! exceptions_via_longjmp)
+    {
+      rtx label = gen_label_rtx ();
+      emit_label (label);
+      label = gen_rtx (LABEL_REF, Pmode, label);
+      assemble_external (eh_saved_pc);
+      emit_move_insn (eh_saved_pc_rtx, label);
+    }
+#endif
+  emit_throw ();
 }
 
 /* Called from expand_exception_blocks and expand_end_catch_block to
@@ -1284,19 +1263,9 @@ expand_leftover_cleanups ()
 
       prev = get_last_insn ();
       if (prev == NULL || GET_CODE (prev) != BARRIER)
-       {
-         if (exceptions_via_longjmp)
-           emit_throw ();
-         else
-           {
-             /* The below can be optimized away, and we could just
-                fall into the next EH handler, if we are certain they
-                are nested.  */
-             /* Emit code to throw to the outer context if we fall off
-                the end of the handler.  */
-             expand_internal_throw (entry->outer_context);
-           }
-       }
+       /* 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);
@@ -1325,12 +1294,12 @@ expand_start_all_catch ()
 {
   struct eh_entry *entry;
   tree label;
+  rtx outer_context;
 
   if (! doing_eh (1))
     return;
 
-  push_label_entry (&outer_context_label_stack,
-                   ehstack.top->entry->outer_context, NULL_TREE);
+  outer_context = ehstack.top->entry->outer_context;
 
   /* End the try block.  */
   expand_eh_region_end (integer_zero_node);
@@ -1342,16 +1311,6 @@ expand_start_all_catch ()
      This is Lresume in the documention.  */
   expand_label (label);
   
-  if (exceptions_via_longjmp == 0)
-    {
-      /* Put in something that takes up space, as otherwise the end
-        address for the EH region could have the exact same address as
-        the outer region, causing us to miss the fact that resuming
-        exception handling with this PC value would be inside the outer
-        region.  */
-      emit_insn (gen_nop ());
-    }
-
   /* Push the label that points to where normal flow is resumed onto
      the top of the label stack.  */
   push_label_entry (&caught_return_label_stack, NULL_RTX, label);
@@ -1402,25 +1361,24 @@ expand_start_all_catch ()
 
       prev = get_last_insn ();
       if (prev == NULL || GET_CODE (prev) != BARRIER)
-       {
-         if (exceptions_via_longjmp)
-           emit_throw ();
-         else
-           {
-             /* 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.
-
-                The below can be optimized away (and we could just fall
-                into the next EH handler) if we are certain they are
-                nested.  */
+       /* 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);
 
-             expand_internal_throw (entry->outer_context);
-           }
-       }
       do_pending_stack_adjust ();
       free (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
+     do this because we are not physically within the region, if any, that
+     logically contains this catch block.  */
+  if (! exceptions_via_longjmp)
+    {
+      expand_eh_region_start ();
+      ehstack.top->entry->outer_context = outer_context;
+    }
 }
 
 /* Finish up the catch block.  At this point all the insns for the
@@ -1432,27 +1390,26 @@ expand_start_all_catch ()
 void
 expand_end_all_catch ()
 {
-  rtx new_catch_clause;
+  rtx new_catch_clause, outer_context;
 
   if (! doing_eh (1))
     return;
 
-  if (exceptions_via_longjmp)
-    emit_throw ();
-  else
-    {
-      /* Code to throw out to outer context, if we fall off end of catch
-        handlers.  This is rethrow (Lresume, same id, same obj) in the
-        documentation. We use Lresume because we know that it will throw
-        to the correct context.
-
-        In other words, if the catch handler doesn't exit or return, we
-        do a "throw" (using the address of Lresume as the point being
-        thrown from) so that the outer EH region can then try to process
-        the exception.  */
+  outer_context = ehstack.top->entry->outer_context;
+  if (! exceptions_via_longjmp)
+    /* Finish the rethrow region.  size_zero_node is just a NOP.  */
+    expand_eh_region_end (size_zero_node);
+  
+  /* Code to throw out to outer context, if we fall off end of catch
+     handlers.  This is rethrow (Lresume, same id, same obj) in the
+     documentation. We use Lresume because we know that it will throw
+     to the correct context.
 
-      expand_internal_throw (outer_context_label_stack->u.rlabel);
-    }
+     In other words, if the catch handler doesn't exit or return, we
+     do a "throw" (using the address of Lresume as the point being
+     thrown from) so that the outer EH region can then try to process
+     the exception.  */
+  expand_rethrow (outer_context);
 
   /* Now we have the complete catch sequence.  */
   new_catch_clause = get_insns ();
@@ -1461,7 +1418,6 @@ expand_end_all_catch ()
   /* This level of catch blocks is done, so set up the successful
      catch jump label for the next layer of catch blocks.  */
   pop_label_entry (&caught_return_label_stack);
-  pop_label_entry (&outer_context_label_stack);
 
   /* Add the new sequence of catches to the main one for this function.  */
   push_to_sequence (catch_clauses);
@@ -1472,6 +1428,18 @@ expand_end_all_catch ()
   /* Here we fall through into the continuation code.  */
 }
 
+/* Rethrow from the outer context LABEL.  */
+
+static void
+expand_rethrow (label)
+     rtx label;
+{
+  if (exceptions_via_longjmp)
+    emit_throw ();
+  else
+    emit_jump (label);
+}
+
 /* End all the pending exception regions on protect_list. The handlers
    will be emitted when expand_leftover_cleanups is invoked.  */
 
@@ -2006,11 +1974,13 @@ init_eh ()
      current context is saved.  */
   tree type = build_pointer_type (make_node (VOID_TYPE));
 
+#ifndef DWARF2_UNWIND_INFO
   eh_saved_pc = build_decl (VAR_DECL, get_identifier ("__eh_pc"), type);
   DECL_EXTERNAL (eh_saved_pc) = 1;
   TREE_PUBLIC (eh_saved_pc) = 1;
   make_decl_rtl (eh_saved_pc, NULL_PTR, 1);
   eh_saved_pc_rtx = DECL_RTL (eh_saved_pc);
+#endif
 }
 
 /* Initialize the per-function EH information.  */
index ac46fa4478f7b11fb875e1dae0808ce7949f7204..172bac4d90404421e8655c1be887404c52e849cb 100644 (file)
@@ -192,10 +192,9 @@ extern void add_partial_entry                      PROTO((tree handler));
 
 extern void end_protect_partials               PROTO((void));
 
-/* An internal throw with a direct CONTEXT we want to throw
-   from. CONTEXT must be a label.  */
+/* An internal throw.  */
 
-extern void expand_internal_throw              PROTO((rtx context));
+extern void expand_internal_throw              PROTO((void));
 
 /* Called from expand_exception_blocks and expand_end_catch_block to
    expand and pending handlers.  */
@@ -227,11 +226,6 @@ extern void check_exception_handler_labels PROTO((void));
 
 extern struct label_node *caught_return_label_stack;
 
-/* Keeps track of the label used as the context of a throw to rethrow an
-   exception to the outer exception region.  */
-
-extern struct label_node *outer_context_label_stack;
-
 /* A random area used for purposes elsewhere.  */
 
 extern struct label_node *false_label_stack;
index 8311566e9c82f14222c4d6e2a4d34f16f5a04da7..ed66ce7c4ef5e5a56435be887d347bf862e34299 100644 (file)
@@ -472,15 +472,10 @@ find_basic_blocks (f, nonlocal_label_list)
       /* If we encounter a CALL_INSN, note which exception handler it
         might pass control to.
 
-        Because we do rethrows by loading the address of a label into
-        __eh_pc and throwing, we need to treat labels as potentially
-        jumping to exception handlers.
-
         If doing asynchronous exceptions, record the active EH handler
         for every insn, since most insns can throw.  */
       else if (eh_note
               && (asynchronous_exceptions
-                  || code == CODE_LABEL
                   || (GET_CODE (insn) == CALL_INSN
                       && ! find_reg_note (insn, REG_RETVAL, NULL_RTX))))
        active_eh_handler[INSN_UID (insn)] = XEXP (eh_note, 0);
@@ -574,11 +569,7 @@ find_basic_blocks (f, nonlocal_label_list)
                           associated insns aren't marked dead, so we make
                           the block in question live and create an edge from
                           this insn to the label.  This is not strictly
-                          correct, but it is close enough for now.
-
-                          We also need to mark the CODE_LABEL as reaching
-                          its exception handler for nested exceptions to
-                          to work.  */
+                          correct, but it is close enough for now.  */
                        for (note = REG_NOTES (insn);
                             note;
                             note = XEXP (note, 1))
@@ -590,14 +581,6 @@ find_basic_blocks (f, nonlocal_label_list)
                                mark_label_ref (gen_rtx (LABEL_REF,
                                                         VOIDmode, x),
                                                insn, 0);
-
-                               /* If the CODE_LABEL has an active exception
-                                  handler, then make an edge to the exception
-                                  handler from this insn.  */
-                               if (active_eh_handler[INSN_UID (x)])
-                                 mark_label_ref (gen_rtx (LABEL_REF, VOIDmode,
-                                                          active_eh_handler[INSN_UID (x)]),
-                                                 insn, 0);
                              }
                          }
 
index 53af01b0e31bfa820dc1b6d8f018d0505496a358..faa3c14cf2e455205a04df39999ae44f4babcf73 100644 (file)
@@ -3154,8 +3154,6 @@ __sjpopnthrow ()
 /* This value identifies the place from which an exception is being
    thrown.  */
 
-void *__eh_pc;
-
 #ifdef EH_TABLE_LOOKUP
 
 EH_TABLE_LOOKUP
@@ -3212,6 +3210,8 @@ find_exception_handler (void *pc, exception_table *table)
 /* Support code for exception handling using inline unwinders or
    __unwind_function.  */
 
+void *__eh_pc;
+
 #ifndef EH_TABLE_LOOKUP
 typedef struct exception_table_node {
   exception_table *table;
@@ -3489,7 +3489,7 @@ in_reg_window (int reg, frame_state *udata)
 void
 __throw ()
 {
-  void *pc, *handler, *retaddr;
+  void *pc, *handler, *retaddr, *__eh_pc;
   frame_state ustruct, ustruct2;
   frame_state *udata = &ustruct;
   frame_state *sub_udata = &ustruct2;
@@ -3524,6 +3524,7 @@ label:
   __builtin_unwind_init ();
 
   /* Now reset pc to the right throw point.  */
+  __eh_pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1;
   pc = __eh_pc;
 
   handler = 0;