except.h (current_function_eh_stub_label): Declare.
authorBernd Schmidt <crux@pool.informatik.rwth-aachen.de>
Wed, 9 Sep 1998 21:48:42 +0000 (21:48 +0000)
committerJeff Law <law@gcc.gnu.org>
Wed, 9 Sep 1998 21:48:42 +0000 (15:48 -0600)
        * except.h (current_function_eh_stub_label): Declare.
        (current_function_eh_old_stub_label): Declare.
        * function.h (struct function): New members eh_stub_label and
        eh_old_stub_label.
        * except.c (current_function_eh_stub_label): New variable.
        (current_function_eh_old_stub_label): New variable.
        (init_eh_for_function): Clear them.
        (save_eh_status): Save them.
        (restore_eh_status): Restore them.
        (expand_builtin_eh_stub): Set current_function_eh_stub_label.
        (expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label.
        * flow.c (find_basic_blocks_1): When handling a REG_LABEL note, don't
        make an edge from the block that contains it to the block starting
        with the label if this label is one of the eh stub labels.
        If eh stub labels exist, show they are reachable from the last block
        in the function.

From-SVN: r22369

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

index af6291d84233bef29b4586c4810107dc4dd0093c..ccb15b3f1e852213afaf13f6ad9a504cb073e336 100644 (file)
@@ -1,5 +1,22 @@
 Wed Sep  9 21:58:41 1998  Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
 
+       * except.h (current_function_eh_stub_label): Declare.
+       (current_function_eh_old_stub_label): Declare.
+       * function.h (struct function): New members eh_stub_label and
+       eh_old_stub_label.
+       * except.c (current_function_eh_stub_label): New variable.
+       (current_function_eh_old_stub_label): New variable.
+       (init_eh_for_function): Clear them.
+       (save_eh_status): Save them.
+       (restore_eh_status): Restore them.
+       (expand_builtin_eh_stub): Set current_function_eh_stub_label.
+       (expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label.
+       * flow.c (find_basic_blocks_1): When handling a REG_LABEL note, don't
+       make an edge from the block that contains it to the block starting
+       with the label if this label is one of the eh stub labels.
+       If eh stub labels exist, show they are reachable from the last block
+       in the function.
+
        * reload1.c (reload): Break out several subroutines and make some
        variables global.
        (calculate_needs_all_insns): New function, broken out of reload.
index 2d26e9ee9c141640f9bfac91b81b43a15058650a..5f2c61ad38809802a9eebb997e8b8b9f12176a38 100644 (file)
@@ -431,6 +431,12 @@ rtx exception_handler_labels;
 
 rtx current_function_ehc;
 
+/* The labels generated by expand_builtin_eh_stub and
+   expand_builtin_eh_stub_old.  */
+
+rtx current_function_eh_stub_label;
+rtx current_function_eh_old_stub_label;
+
 /* A stack used for keeping track of the currently active exception
    handling region.  As each exception region is started, an entry
    describing the region is pushed onto this stack.  The current
@@ -2148,6 +2154,8 @@ init_eh_for_function ()
   caught_return_label_stack = 0;
   protect_list = NULL_TREE;
   current_function_ehc = NULL_RTX;
+  current_function_eh_stub_label = NULL_RTX;
+  current_function_eh_old_stub_label = NULL_RTX;
 }
 
 /* Save some of the per-function EH info into the save area denoted by
@@ -2170,6 +2178,8 @@ save_eh_status (p)
   p->caught_return_label_stack = caught_return_label_stack;
   p->protect_list = protect_list;
   p->ehc = current_function_ehc;
+  p->eh_stub_label = current_function_eh_stub_label;
+  p->eh_old_stub_label = current_function_eh_old_stub_label;
 
   init_eh_for_function ();
 }
@@ -2193,6 +2203,8 @@ restore_eh_status (p)
   ehstack = p->ehstack;
   catchstack = p->catchstack;
   current_function_ehc = p->ehc;
+  current_function_eh_stub_label = p->eh_stub_label;
+  current_function_eh_old_stub_label = p->eh_old_stub_label;
 }
 \f
 /* This section is for the exception handling specific optimization
@@ -2502,6 +2514,8 @@ expand_builtin_eh_stub_old ()
   rtx after_stub = gen_label_rtx ();
   rtx handler, offset;
 
+  current_function_eh_old_stub_label = stub_start;
+
   emit_jump (after_stub);
   emit_label (stub_start);
 
@@ -2521,6 +2535,8 @@ expand_builtin_eh_stub ()
   rtx handler, offset;
   rtx temp;
 
+  current_function_eh_stub_label = stub_start;
+
   emit_jump (after_stub);
   emit_label (stub_start);
 
index b498a69c7e0117eb85f9212bf78320deccc811d3..d20b6067cb081c13268430d29ec5010d6c036b15 100644 (file)
@@ -24,6 +24,12 @@ typedef struct rtx_def *_except_rtx;
 #define rtx _except_rtx
 #endif
 
+/* The labels generated by expand_builtin_eh_stub and
+   expand_builtin_eh_stub_old.  */
+
+extern rtx current_function_eh_stub_label;
+extern rtx current_function_eh_old_stub_label;
+
 #ifdef TREE_CODE
 
 /* A stack of labels. CHAIN points to the next entry in the stack.  */
@@ -82,7 +88,6 @@ struct eh_queue {
   struct eh_node *tail;
 };
 
-
 /* Start an exception handling region.  All instructions emitted after
    this point are considered to be part of the region until
    expand_eh_region_end () is invoked.  */
index 715555d18046ee7fb44f6557e971f23c8e48c234..af9eb1cde836c9685e7d2884b1e9424ff4e4027e 100644 (file)
@@ -484,7 +484,9 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
        {
          /* Make a list of all labels referred to other than by jumps.  */
          for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
-           if (REG_NOTE_KIND (note) == REG_LABEL)
+           if (REG_NOTE_KIND (note) == REG_LABEL
+               && XEXP (note, 0) != current_function_eh_stub_label
+               && XEXP (note, 0) != current_function_eh_old_stub_label)
              label_value_list = gen_rtx_EXPR_LIST (VOIDmode, XEXP (note, 0),
                                                    label_value_list);
        }
@@ -589,7 +591,6 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
                  {
                    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
                      {
-                       
                        /* References to labels in non-jumping insns have
                           REG_LABEL notes attached to them.
 
@@ -609,12 +610,17 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
                           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.  */
+                          correct, but it is close enough for now.  
+
+                          See below for code that handles the eh_stub labels
+                          specially.  */
                        for (note = REG_NOTES (insn);
                             note;
                             note = XEXP (note, 1))
                          {
-                           if (REG_NOTE_KIND (note) == REG_LABEL)
+                           if (REG_NOTE_KIND (note) == REG_LABEL
+                               && XEXP (note, 0) != current_function_eh_stub_label
+                               && XEXP (note, 0) != current_function_eh_old_stub_label)
                              {
                                x = XEXP (note, 0);
                                block_live[BLOCK_NUM (x)] = 1;
@@ -695,6 +701,22 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
                          }
                      }
                  }
+               /* We know something about the structure of the function
+                  __throw in libgcc2.c.  It is the only function that ever
+                  contains eh_stub labels.  It modifies its return address
+                  so that the last block returns to one of the eh_stub labels
+                  within it.  So we have to make additional edges in the
+                  flow graph.  */
+               if (i + 1 == n_basic_blocks
+                   && current_function_eh_stub_label != 0)
+                 {
+                   mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
+                                                      current_function_eh_stub_label),
+                                   basic_block_end[i], 0);
+                   mark_label_ref (gen_rtx_LABEL_REF (VOIDmode,
+                                                      current_function_eh_old_stub_label),
+                                   basic_block_end[i], 0);
+                 }
              }
        }
 
index 06e90dc88aa34b759d7a097090b52922059e1c6f..786e062a4872d7db2e75af0bf2780c62a21be499 100644 (file)
@@ -142,6 +142,8 @@ struct function
   rtx catch_clauses;
   struct label_node *false_label_stack;
   struct label_node *caught_return_label_stack;
+  rtx eh_stub_label;
+  rtx eh_old_stub_label;
   tree protect_list;
   rtx ehc;