flow.c (tidy_fallthru_edges): Don't combine complex edges.
authorRichard Henderson <rth@redhat.com>
Wed, 28 Mar 2001 06:22:23 +0000 (22:22 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 28 Mar 2001 06:22:23 +0000 (22:22 -0800)
        * flow.c (tidy_fallthru_edges): Don't combine complex edges.
        (calculate_global_regs_live): Kill call-clobbered registers
        across exception edges.
        * reg-stack.c (convert_regs_1): Kill the entire target stack
        across non-call exception edges.

From-SVN: r40909

gcc/ChangeLog
gcc/flow.c
gcc/reg-stack.c

index 15a9dd295adb59b70b396e10e2bad435f62b1ab8..de13830884d9d16b77b0c1e44ceeeff382ff275e 100644 (file)
        * final.c: Don't check it.
        * except.c: Provide stub definition.
 
+       * flow.c (tidy_fallthru_edges): Don't combine complex edges.
+       (calculate_global_regs_live): Kill call-clobbered registers
+       across exception edges.
+       * reg-stack.c (convert_regs_1): Kill the entire target stack
+       across non-call exception edges.
+
 2001-03-27  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
        * configure.in: Don't check for bcopy.
index bf5043a5e7b757f30ac51f3a66f0f0332a097fb6..e8bf0400262a88448324a17cf2bd8654864de6cb 100644 (file)
@@ -2995,6 +2995,7 @@ tidy_fallthru_edges ()
         merge the flags for the duplicate edges.  So we do not want to
         check that the edge is not a FALLTHRU edge.  */
       if ((s = b->succ) != NULL
+         && ! (s->flags & EDGE_COMPLEX)
          && s->succ_next == NULL
          && s->dest == c
          /* If the jump insn has side effects, we can't tidy the edge.  */
@@ -3542,13 +3543,19 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
      int flags;
 {
   basic_block *queue, *qhead, *qtail, *qend;
-  regset tmp, new_live_at_end;
-  regset_head tmp_head;
+  regset tmp, new_live_at_end, call_used;
+  regset_head tmp_head, call_used_head;
   regset_head new_live_at_end_head;
   int i;
 
   tmp = INITIALIZE_REG_SET (tmp_head);
   new_live_at_end = INITIALIZE_REG_SET (new_live_at_end_head);
+  call_used = INITIALIZE_REG_SET (call_used_head);
+
+  /* Inconveniently, this is only redily available in hard reg set form.  */
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
+    if (call_used_regs[i])
+      SET_REGNO_REG_SET (call_used, i);
 
   /* Create a worklist.  Allocate an extra slot for ENTRY_BLOCK, and one
      because the `head == tail' style test for an empty queue doesn't
@@ -3602,7 +3609,18 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
       for (e = bb->succ; e; e = e->succ_next)
        {
          basic_block sb = e->dest;
-         IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
+
+         /* Call-clobbered registers die across exception and call edges.  */
+         /* ??? Abnormal call edges ignored for the moment, as this gets
+            confused by sibling call edges, which crashes reg-stack.  */
+         if (e->flags & EDGE_EH)
+           {
+             bitmap_operation (tmp, sb->global_live_at_start,
+                               call_used, BITMAP_AND_COMPL);
+             IOR_REG_SET (new_live_at_end, tmp);
+           }
+         else
+           IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
        }
 
       /* The all-important stack pointer must always be live.  */
@@ -3750,6 +3768,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
 
   FREE_REG_SET (tmp);
   FREE_REG_SET (new_live_at_end);
+  FREE_REG_SET (call_used);
 
   if (blocks_out)
     {
index 0e85a5ab922d65f466cdcaf1f68d00c10d61385c..54c3f086a48236a3447cb9104dc3c7516c8a878c 100644 (file)
@@ -2553,10 +2553,15 @@ convert_regs_1 (file, block)
            }
        }
 
-      /* Care for EH edges specially.  The normal return path may return
-        a value in st(0), but the EH path will not, and there's no need
-        to add popping code to the edge.  */
-      if (e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
+      /* Care for non-call EH edges specially.  The normal return path have
+        values in registers.  These will be popped en masse by the unwind
+        library.  */
+      if ((e->flags & (EDGE_EH | EDGE_ABNORMAL_CALL)) == EDGE_EH)
+       target_stack->top = -1;
+
+      /* Other calls may appear to have values live in st(0), but the
+        abnormal return path will not have actually loaded the values.  */
+      else if (e->flags & EDGE_ABNORMAL_CALL)
        {
          /* Assert that the lifetimes are as we expect -- one value
             live at st(0) on the end of the source block, and no