cse.c (delete_dead_from_cse): If a libcall produces a constant result and that result...
authorJeffrey A Law <law@cygnus.com>
Thu, 12 Feb 1998 14:26:47 +0000 (14:26 +0000)
committerJeff Law <law@gcc.gnu.org>
Thu, 12 Feb 1998 14:26:47 +0000 (07:26 -0700)
        * cse.c (delete_dead_from_cse): If a libcall produces a constant
        result and that result can be substituted into SET_SRC of the
        insn with the REG_RETVAL note, then perform the substitution
        and delete the libcall.

From-SVN: r17871

gcc/ChangeLog
gcc/cse.c

index e8fc0c8773ee4abbee5298c25e3eb24f5f8fe96a..8129ee645b2e4d8b8fff4d89aeab63adbe029cbe 100644 (file)
@@ -1,3 +1,10 @@
+Thu Feb 12 15:26:50 1998  Jeffrey A Law  (law@cygnus.com)
+
+       * cse.c (delete_dead_from_cse): If a libcall produces a constant
+       result and that result can be substituted into SET_SRC of the
+       insn with the REG_RETVAL note, then perform the substitution
+       and delete the libcall.
+
 Thu Feb 12 14:04:09 1998  Gavin Koch  <gavin@cygnus.com>
 
        * mips.md (trucndihi2,truncdiqi2): Change these to support 
index 50b7e146b835c33d04acb9330c98ac52edb49d0d..865451ab684f08969eef662ed8ed04ce69c0524b 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -8754,7 +8754,7 @@ delete_dead_from_cse (insns, nreg)
   rtx insn, prev;
   rtx tem;
   int i;
-  int in_libcall = 0;
+  int in_libcall = 0, dead_libcall = 0;
 
   /* First count the number of times each register is used.  */
   bzero ((char *) counts, sizeof (int) * nreg);
@@ -8767,17 +8767,41 @@ delete_dead_from_cse (insns, nreg)
   for (insn = prev_real_insn (get_last_insn ()); insn; insn = prev)
     {
       int live_insn = 0;
+      rtx note;
 
       prev = prev_real_insn (insn);
 
-      /* Don't delete any insns that are part of a libcall block.
+      /* Don't delete any insns that are part of a libcall block unless
+        we can delete the whole libcall block.
+
         Flow or loop might get confused if we did that.  Remember
         that we are scanning backwards.  */
       if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
-       in_libcall = 1;
+       {
+         in_libcall = 1;
+         live_insn = 1;
+         dead_libcall = 0;
 
-      if (in_libcall)
-       live_insn = 1;
+         /* See if there's a REG_EQUAL note on this insn and try to
+            replace the source with the REG_EQUAL expression.
+       
+            We assume that insns with REG_RETVALs can only be reg->reg
+            copies at this point.  */
+         note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+         if (note)
+           {
+             rtx set = single_set (insn);
+             if (set
+                 && validate_change (insn, &SET_SRC (set), XEXP (note, 0), 0))
+               {
+                 remove_note (insn,
+                              find_reg_note (insn, REG_RETVAL, NULL_RTX));
+                 dead_libcall = 1;
+               }
+           }
+       }
+      else if (in_libcall)
+       live_insn = ! dead_libcall;
       else if (GET_CODE (PATTERN (insn)) == SET)
        {
          if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
@@ -8839,6 +8863,9 @@ delete_dead_from_cse (insns, nreg)
        }
 
       if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
-       in_libcall = 0;
+       {
+         in_libcall = 0;
+         dead_libcall = 0;
+       }
     }
 }