flow.c (mark_set_1): Recognize multi-register structure return values in CALL insns.
authorDavid S. Miller <davem@pierdol.cobaltmicro.com>
Sat, 12 Sep 1998 01:03:36 +0000 (01:03 +0000)
committerDavid S. Miller <davem@gcc.gnu.org>
Sat, 12 Sep 1998 01:03:36 +0000 (18:03 -0700)
* flow.c (mark_set_1): Recognize multi-register structure return
values in CALL insns.
(mark_used_regs): Likewise.
(count_reg_sets_1): Likewise.
(count_reg_references): Likewise.
* rtlanal.c (note_stores): Likewise.

From-SVN: r22395

gcc/ChangeLog
gcc/flow.c
gcc/rtlanal.c

index 6b2f642deff288e9c1f682c96bae5a3cd7fa2b00..63646a0f67af8dcae70135aa46cd533ba64a515d 100644 (file)
@@ -1,3 +1,12 @@
+Fri Sep 11 23:55:54 1998  David S. Miller  <davem@pierdol.cobaltmicro.com>
+
+       * flow.c (mark_set_1): Recognize multi-register structure return
+       values in CALL insns.
+       (mark_used_regs): Likewise.
+       (count_reg_sets_1): Likewise.
+       (count_reg_references): Likewise.
+       * rtlanal.c (note_stores): Likewise.
+
 Fri Sep 11 22:57:55 1998  Eric Dumazet  <dumazet@cosmosbay.com>
 
        * config/i386/sco5.h (ASM_WEAKEN_LABEL): Defined as in svr4.h.
index af9eb1cde836c9685e7d2884b1e9424ff4e4027e..a7ce4a367e003ada7559de55b5362fbc5bb65bfb 100644 (file)
@@ -2133,6 +2133,19 @@ mark_set_1 (needed, dead, x, insn, significant)
   register int regno;
   register rtx reg = SET_DEST (x);
 
+  /* Some targets place small structures in registers for
+     return values of functions.  We have to detect this
+     case specially here to get correct flow information.  */
+  if (GET_CODE (reg) == PARALLEL
+      && GET_MODE (reg) == BLKmode)
+    {
+      register int i;
+
+      for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
+         mark_set_1 (needed, dead, XVECEXP (reg, 0, i), insn, significant);
+      return;
+    }
+
   /* Modifying just one hardware register of a multi-reg value
      or just a byte field of a register
      does not mean the value from before this insn is now dead.
@@ -2794,15 +2807,17 @@ mark_used_regs (needed, live, x, final, insn)
        /* If this is a store into a register,
           recursively scan the value being stored.  */
 
-       if (GET_CODE (testreg) == REG
-           && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM)
+       if ((GET_CODE (testreg) == PARALLEL
+            && GET_MODE (testreg) == BLKmode)
+           || (GET_CODE (testreg) == REG
+               && (regno = REGNO (testreg), regno != FRAME_POINTER_REGNUM)
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
-           && regno != HARD_FRAME_POINTER_REGNUM
+               && regno != HARD_FRAME_POINTER_REGNUM
 #endif
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-           && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
+               && ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
 #endif
-           )
+               ))
          /* We used to exclude global_regs here, but that seems wrong.
             Storing in them is like storing in mem.  */
          {
@@ -4043,6 +4058,15 @@ count_reg_sets_1 (x)
         || GET_CODE (reg) == STRICT_LOW_PART)
     reg = XEXP (reg, 0);
 
+  if (GET_CODE (reg) == PARALLEL
+      && GET_MODE (reg) == BLKmode)
+    {
+      register int i;
+      for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
+       count_reg_sets_1 (XVECEXP (reg, 0, i));
+      return;
+    }
+
   if (GET_CODE (reg) == REG)
     {
       regno = REGNO (reg);
@@ -4175,7 +4199,9 @@ count_reg_references (x)
        /* If this is a store into a register,
           recursively scan the value being stored.  */
 
-       if (GET_CODE (testreg) == REG)
+       if ((GET_CODE (testreg) == PARALLEL
+            && GET_MODE (testreg) == BLKmode)
+           || GET_CODE (testreg) == REG)
          {
            count_reg_references (SET_SRC (x));
            if (mark_dest)
index fb4176264b35eab76c08008dbdb4289ade92d7f6..41625ee28686ede6d1b133842354040bab477077 100644 (file)
@@ -1086,7 +1086,16 @@ note_stores (x, fun)
             || GET_CODE (dest) == SIGN_EXTRACT
             || GET_CODE (dest) == STRICT_LOW_PART)
        dest = XEXP (dest, 0);
-      (*fun) (dest, x);
+
+      if (GET_CODE (dest) == PARALLEL
+         && GET_MODE (dest) == BLKmode)
+       {
+         register int i;
+         for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+           (*fun) (SET_DEST (XVECEXP (dest, 0, i)), x);
+       }
+      else
+       (*fun) (dest, x);
     }
   else if (GET_CODE (x) == PARALLEL)
     {
@@ -1105,7 +1114,15 @@ note_stores (x, fun)
                     || GET_CODE (dest) == SIGN_EXTRACT
                     || GET_CODE (dest) == STRICT_LOW_PART)
                dest = XEXP (dest, 0);
-             (*fun) (dest, y);
+             if (GET_CODE (dest) == PARALLEL
+                 && GET_MODE (dest) == BLKmode)
+               {
+                 register int i;
+                 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+                   (*fun) (SET_DEST (XVECEXP (dest, 0, i)), y);
+               }
+             else
+               (*fun) (dest, y);
            }
        }
     }