]> gcc.gnu.org Git - gcc.git/commitdiff
optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all calls within a...
authorAndrew MacLeod <amacleod@cygnus.com>
Tue, 19 Jan 1999 09:39:37 +0000 (09:39 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Tue, 19 Jan 1999 09:39:37 +0000 (09:39 +0000)
* optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all
calls within a libcall block to indicate no throws are possible.
* flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for
libcall blocks. Don't add edges to exception handlers if we see
a REG_EH_REGION note with a value of 0.
(make_edges): Override active_eh_region vector if the call has a note
indicating the call does not throw.

From-SVN: r24757

gcc/ChangeLog
gcc/flow.c
gcc/optabs.c

index 18246de8180aa43700806416cd58e3d5a902cfd4..bc064c4e5b8e4acc41a281da7e25c6678f86ae72 100644 (file)
@@ -1,3 +1,13 @@
+Tue Jan 19 12:30:37 EST 1999  Andrew MacLeod  <amacleod@cygnus.com>
+
+       * optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all
+       calls within a libcall block to indicate no throws are possible.
+       * flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for 
+       libcall blocks. Don't add edges to exception handlers if we see 
+       a REG_EH_REGION note with a value of 0.
+       (make_edges): Override active_eh_region vector if the call has a note
+       indicating the call does not throw.
+
 1999-01-19  Vladimir N. Makarov  <vmakarov@cygnus.com>
 
        * config/rs6000/sysv4.h (CC1_SPEC): Fix correct numbers of {}.
index 244a662e80107618a08e76473a67f976a8bd11a9..aa72c6a966f1ee645f58ee90b158fe35ff6052e5 100644 (file)
@@ -309,7 +309,6 @@ find_basic_blocks (f, nregs, file)
   register rtx insn;
   register int i;
   rtx nonlocal_label_list = nonlocal_label_rtx_list ();
-  int in_libcall_block = 0;
 
   /* Avoid leaking memory if this is called multiple times per compiled
      function.  */
@@ -326,11 +325,6 @@ find_basic_blocks (f, nregs, file)
 
     for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
       {
-       /* Track when we are inside in LIBCALL block.  */
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-           && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-         in_libcall_block = 1;
-
        code = GET_CODE (insn);
 
        /* A basic block starts at label, or after something that can jump.  */
@@ -354,17 +348,23 @@ find_basic_blocks (f, nregs, file)
                emit_insn_after (nop, prev_call);
              }
          }
-       /* We change the code of the CALL_INSN, so that it won't start a
-          new block.  */
-       if (code == CALL_INSN && in_libcall_block)
-         code = INSN;
 
-       /* Record whether this call created an edge.  */
        if (code == CALL_INSN)
-         {
-           prev_call = insn;
-           call_had_abnormal_edge = (nonlocal_label_list != 0 || eh_region);
-         }
+          {
+            rtx note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
+
+            /* We change the code of the CALL_INSN, so that it won't start a
+               new block.  */
+            if (note && XINT (XEXP (note, 0), 0) == 0)
+              code = INSN;
+            else
+              {
+                prev_call = insn;
+                call_had_abnormal_edge = (nonlocal_label_list != 0
+                                          || eh_region);
+              }
+          }
+
        else if (code != NOTE && code != BARRIER)
          prev_call = 0;
 
@@ -374,10 +374,6 @@ find_basic_blocks (f, nregs, file)
          ++eh_region;
        else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
          --eh_region;
-
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-           && find_reg_note (insn, REG_RETVAL, NULL_RTX))
-         in_libcall_block = 0;
       }
   }
 
@@ -447,7 +443,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
   rtx note, eh_note;
   enum rtx_code prev_code, code;
   int depth;
-  int in_libcall_block = 0;
   int call_had_abnormal_edge = 0;
 
   active_eh_region = (int *) alloca ((max_uid_for_flow + 1) * sizeof (int));
@@ -475,12 +470,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
   for (eh_note = NULL_RTX, insn = f, i = -1, prev_code = JUMP_INSN, depth = 1;
        insn; insn = NEXT_INSN (insn))
     {
-
-      /* Track when we are inside in LIBCALL block.  */
-      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-         && find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-       in_libcall_block = 1;
-
       code = GET_CODE (insn);
       if (code == NOTE)
        {
@@ -550,16 +539,19 @@ find_basic_blocks_1 (f, nonlocal_labels)
         for every insn, since most insns can throw.  */
       else if (eh_note
               && (asynchronous_exceptions
-                  || (GET_CODE (insn) == CALL_INSN
-                      && ! in_libcall_block)))
+                  || (GET_CODE (insn) == CALL_INSN)))
        active_eh_region[INSN_UID (insn)] =
                                         NOTE_BLOCK_NUMBER (XEXP (eh_note, 0));
       BLOCK_NUM (insn) = i;
 
       /* We change the code of the CALL_INSN, so that it won't start a
-        new block.  */
-      if (code == CALL_INSN && in_libcall_block)
-       code = INSN;
+        new block if it doesn't throw.  */
+      if (code == CALL_INSN)
+        {
+          rtx rnote = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
+          if (rnote && XINT (XEXP (rnote, 0), 0) == 0)
+            code = INSN;
+        }
 
       /* Record whether this call created an edge.  */
       if (code == CALL_INSN)
@@ -568,9 +560,6 @@ find_basic_blocks_1 (f, nonlocal_labels)
       if (code != NOTE)
        prev_code = code;
 
-      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-         && find_reg_note (insn, REG_RETVAL, NULL_RTX))
-       in_libcall_block = 0;
     }
 
   if (i + 1 != n_basic_blocks)
@@ -839,9 +828,15 @@ make_edges (i)
                   || (GET_CODE (insn) == CALL_INSN
                       && ! find_reg_note (insn, REG_RETVAL, NULL_RTX)))
            {
-             if (active_eh_region[INSN_UID (insn)]) 
+              int region = active_eh_region[INSN_UID (insn)];
+              note = find_reg_note(insn, REG_EH_REGION, NULL_RTX);
+
+              /* Override region if we see a REG_EH_REGION note. */
+              if (note)
+                region = XINT (XEXP (note, 0), 0);
+
+             if (region)
                {
-                 int region;
                  handler_info *ptr;
                  region = active_eh_region[INSN_UID (insn)];
                  for ( ; region; region = nested_eh_region[region])
index 7c53589d77a8a1646848b38fc550201ce1f0a76e..8780f4eb4410891059d0e104b61880197528592b 100644 (file)
@@ -2596,6 +2596,21 @@ emit_libcall_block (insns, target, result, equiv)
 {
   rtx prev, next, first, last, insn;
 
+  /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
+     reg note to indicate that this call cannot throw. (Unless there is
+     already a REG_EH_REGION note.) */
+
+  for (insn = insns; insn; insn = NEXT_INSN (insn))
+    {
+      if (GET_CODE (insn) == CALL_INSN)
+        {
+          rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
+          if (note == NULL_RTX)
+            REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (0),
+                                                  REG_NOTES (insn));
+        }
+    }
+
   /* First emit all insns that set pseudos.  Remove them from the list as
      we go.  Avoid insns that set pseudos which were referenced in previous
      insns.  These can be generated by move_by_pieces, for example,
This page took 0.113477 seconds and 5 git commands to generate.