]> gcc.gnu.org Git - gcc.git/commitdiff
Flow now removes exception regions when their handlers are all removed.
authorAndrew MacLeod <amacleod@cygnus.com>
Thu, 28 May 1998 07:32:33 +0000 (07:32 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Thu, 28 May 1998 07:32:33 +0000 (07:32 +0000)
From-SVN: r20115

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

index c3069118519571c6e1cdd6b6ca054f81f4f6c0d6..1bb223c463db5c40d774e0907cd4507b6c1f2eed 100644 (file)
@@ -1,3 +1,11 @@
+Thu May 28 10:22:22 EDT 1998  Andrew MacLeod  <amacleod@cygnus.com>
+
+       * except.h (remove_handler): Add new prototype.
+       * except.c (remove_handler): New function to remove handlers
+       from an exception region.
+       * flow.c (find_basic_blocks_1): Remove handlers from regions when
+       handler label is deleted; remove exception regions with no handlers.
+
 Thu May 28 09:36:39 1998  Michael Meissner  <meissner@cygnus.com>
 
        * except.h (rtx): Define rtx type correctly if needed.
index a2cee20dc891232ce604d4f27ea8f3e706109646..5881e223d6477bbe243ef059021a2117400e8fde 100644 (file)
@@ -754,6 +754,34 @@ add_new_handler (region, newhandler)
     }
 }
 
+/* Remove a handler label. The handler label is being deleted, so all
+   regions which reference this handler should have it removed from their
+   list of possible handlers. Any region which has the final handler
+   removed can be deleted. */
+
+void remove_handler (removing_label)
+     rtx removing_label;
+{
+  struct handler_info *handler, *last;
+  int x;
+  for (x = 0 ; x < current_func_eh_entry; ++x)
+    {
+      last = NULL;
+      handler = function_eh_regions[x].handlers;
+      for ( ; handler; last = handler, handler = handler->next)
+        if (handler->handler_label == removing_label)
+          {
+            if (last)
+              {
+                last->next = handler->next;
+                handler = last;
+              }
+            else
+              function_eh_regions[x].handlers = handler->next;
+          }
+    }
+}
+
 /* Create a new handler structure initialized with the handler label and
    typeinfo fields passed in. */
 
index b96399e91164b90e5109929f7457d9d388b44fa2..d2523cb2a81b9fc002ca4b16342bf62c0cbf3f46 100644 (file)
@@ -191,6 +191,13 @@ int new_eh_region_entry                         PROTO((int));
 
 void add_new_handler                       PROTO((int, struct handler_info *));
 
+/* Remove a handler label. The handler label is being deleted, so all
+   regions which reference this handler should have it removed from their
+   list of possible handlers. Any region which has the final handler
+   removed can be deleted. */
+
+void remove_handler                        PROTO((rtx));
+
 /* Create a new handler structure initialized with the handler label and
    typeinfo fields passed in. */
 
index 4ade02ae5c3a58e7f4dea3e6e14e915cf051349f..8021b4e2c89432e637641a08d6bfda7ea592a0a4 100644 (file)
@@ -404,6 +404,7 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
   enum rtx_code prev_code, code;
   int depth, pass;
   int in_libcall_block = 0;
+  int deleted_handler = 0;
 
   pass = 1;
   active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
@@ -770,28 +771,9 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
                            XEXP (x, 1) = NULL_RTX;
                            XEXP (x, 0) = NULL_RTX;
 
-                           /* Now we have to find the EH_BEG and EH_END notes
-                              associated with this label and remove them.  */
-
-#if 0
-/* Handlers and labels no longer needs to have the same values.
-   If there are no references, scan_region will remove any region
-   labels which are of no use. */
-                           for (x = get_insns (); x; x = NEXT_INSN (x))
-                             {
-                               if (GET_CODE (x) == NOTE
-                                   && ((NOTE_LINE_NUMBER (x)
-                                        == NOTE_INSN_EH_REGION_BEG)
-                                       || (NOTE_LINE_NUMBER (x)
-                                           == NOTE_INSN_EH_REGION_END))
-                                   && (NOTE_BLOCK_NUMBER (x)
-                                       == CODE_LABEL_NUMBER (insn)))
-                                 {
-                                   NOTE_LINE_NUMBER (x) = NOTE_INSN_DELETED;
-                                   NOTE_SOURCE_FILE (x) = 0;
-                                 }
-                             }
-#endif
+                            /* Remove the handler from all regions */
+                            remove_handler (insn);
+                            deleted_handler = 1;
                            break;
                          }
                        prev = &XEXP (x, 1);
@@ -861,6 +843,24 @@ find_basic_blocks_1 (f, nonlocal_label_list, live_reachable_p)
                    }
              }
          }
+      /* If we deleted an exception handler, we may have EH region
+         begin/end blocks to remove as well. */
+      if (deleted_handler)
+        for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+          if (GET_CODE (insn) == NOTE)
+            {
+              if ((NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG) ||
+                  (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) 
+                {
+                  int num = CODE_LABEL_NUMBER (insn);
+                  /* A NULL handler indicates a region is no longer needed */
+                  if (get_first_handler (num) == NULL)
+                    {
+                      NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+                      NOTE_SOURCE_FILE (insn) = 0;
+                    }
+                }
+            }
 
       /* There are pathological cases where one function calling hundreds of
         nested inline functions can generate lots and lots of unreachable
This page took 0.08188 seconds and 5 git commands to generate.