flow.c (mark_set_1, [...]): Now case; rework to allow entry to be EXPR_LIST.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Thu, 18 Jan 2001 13:14:34 +0000 (13:14 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Thu, 18 Jan 2001 13:14:34 +0000 (08:14 -0500)
* flow.c (mark_set_1, case PARALLEL): Now case; rework to allow
entry to be EXPR_LIST.
* rtlanal.c (reg_overlap_mentioned_p): Allow PARALLEL in SET to
be an EXPR_LIST (but not null, which other code doesn't allow).
(note_stores): Properly handle PARALLEL in SET.
Recursively call for top-level PARALLEL.
* sched-deps.c (sched_analyze_1): Handle EXPR_LIST in PARALLEL in SET.
* sched-rgn.c (check_live_1, update_live_1): Likewise.

From-SVN: r39118

gcc/ChangeLog
gcc/flow.c
gcc/rtlanal.c
gcc/sched-deps.c
gcc/sched-rgn.c

index 6848e8ec0d59a30d278927abc61139b40ee6a658..51cb1866feb988416a2fdb91d39c965a35b18e7c 100644 (file)
@@ -1,5 +1,14 @@
 Thu Jan 18 06:43:04 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * flow.c (mark_set_1, case PARALLEL): Now case; rework to allow
+       entry to be EXPR_LIST.
+       * rtlanal.c (reg_overlap_mentioned_p): Allow PARALLEL in SET to
+       be an EXPR_LIST (but not null, which other code doesn't allow).
+       (note_stores): Properly handle PARALLEL in SET.
+       Recursively call for top-level PARALLEL.
+       * sched-deps.c (sched_analyze_1): Handle EXPR_LIST in PARALLEL in SET.
+       * sched-rgn.c (check_live_1, update_live_1): Likewise.
+
        * config.gcc (rs6000-ibm-aix*, rs6000-bull-bosx): Add rs6000/aix.h.
 
 2001-01-18  Neil Booth  <neil@daikokuya.demon.co.uk>
index 4d0bdff92ed310fcf5750ca0f42579ed49eb375c..aa37d05de5601fa479c28f907ccc2114a936fdbe 100644 (file)
@@ -4651,23 +4651,30 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
   int not_dead = 0;
   int i;
 
-  /* 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)
-    {
-      for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
-       mark_set_1 (pbi, code, XVECEXP (reg, 0, i), cond, insn, flags);
-      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.  Of course, if it was dead after it's unused now.  */
 
   switch (GET_CODE (reg))
     {
+    case PARALLEL:
+      /* 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.  Note that each element might be either a REG
+        or an EXPR_LIST whose first operand is a REG.  */
+      if (GET_MODE (reg) != BLKmode)
+       abort ();
+
+      for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
+       {
+         rtx elmt = XVECEXP (reg, 0, i);
+
+         mark_set_1 (pbi, code,
+                     GET_CODE (elmt) == EXPR_LIST ? XEXP (elmt, 0) : elmt,
+                     cond, insn, flags);
+       }
+      return;
+
     case ZERO_EXTRACT:
     case SIGN_EXTRACT:
     case STRICT_LOW_PART:
@@ -5964,8 +5971,8 @@ mark_used_regs (pbi, x, cond, insn)
            testreg = XEXP (testreg, 0);
          }
 
-       /* If this is a store into a register, recursively scan the
-          value being stored.  */
+       /* If this is a store into a register or group of registers,
+          recursively scan the value being stored.  */
 
        if ((GET_CODE (testreg) == PARALLEL
             && GET_MODE (testreg) == BLKmode)
index 8bdd23cdfc285b9c795a0d091db6bad62b781104..eec8b6af5016845366255fecde449899b0a641b9 100644 (file)
@@ -1182,20 +1182,21 @@ reg_overlap_mentioned_p (x, in)
 
     case PARALLEL:
       {
-       int i, n;
-
-       /* Check for a NULL entry, used to indicate that the parameter goes
-          both on the stack and in registers.  */
-       if (XEXP (XVECEXP (x, 0, 0), 0))
-         i = 0;
-       else
-         i = 1;
+       int i;
 
        /* If any register in here refers to it we return true.  */
-       for (n = XVECLEN (x, 0); i < n; ++i)
-         if (reg_overlap_mentioned_p (XEXP (XVECEXP (x, 0, i), 0), in))
-           return 1;
-       return 0;
+       for (i = XVECLEN (x, 0); i >= 0; i--)
+         {
+           rtx reg = XVECEXP (x, 0, i);
+
+           if (GET_CODE (reg) == EXPR_LIST)
+             reg = XEXP (reg, 0);
+
+           if (reg_overlap_mentioned_p (reg, in))
+             return 1;
+           return 0;
+         
+         }
       }
 
     default:
@@ -1270,11 +1271,15 @@ note_stores (x, fun, data)
      void (*fun) PARAMS ((rtx, rtx, void *));
      void *data;
 {
+  int i;
+
   if (GET_CODE (x) == COND_EXEC)
     x = COND_EXEC_CODE (x);
+
   if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
     {
       register rtx dest = SET_DEST (x);
+
       while ((GET_CODE (dest) == SUBREG
              && (GET_CODE (SUBREG_REG (dest)) != REG
                  || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
@@ -1283,48 +1288,27 @@ note_stores (x, fun, data)
             || GET_CODE (dest) == STRICT_LOW_PART)
        dest = XEXP (dest, 0);
 
-      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, data);
-       }
+      /* If we have a PARALLEL, SET_DEST is a list of registers or
+        EXPR_LIST expressions, each of whose first operand is a register.
+        We can't know what precisely is being set in these cases, so
+        make up a CLOBBER to pass to the function.  */
+      if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
+       for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+         {
+           rtx reg = XVECEXP (dest, 0, i);
+
+           if (GET_CODE (reg) == EXPR_LIST)
+             reg = XEXP (reg, 0);
+
+           (*fun) (reg, gen_rtx_CLOBBER (VOIDmode, reg), data);
+         }
       else
        (*fun) (dest, x, data);
     }
-  else if (GET_CODE (x) == PARALLEL)
-    {
-      register int i;
-      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
-       {
-         register rtx y = XVECEXP (x, 0, i);
-         if (GET_CODE (y) == COND_EXEC)
-           y = COND_EXEC_CODE (y);
-         if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
-           {
-             register rtx dest = SET_DEST (y);
-             while ((GET_CODE (dest) == SUBREG
-                     && (GET_CODE (SUBREG_REG (dest)) != REG
-                         || (REGNO (SUBREG_REG (dest))
-                             >= FIRST_PSEUDO_REGISTER)))
-                    || GET_CODE (dest) == ZERO_EXTRACT
-                    || GET_CODE (dest) == SIGN_EXTRACT
-                    || GET_CODE (dest) == STRICT_LOW_PART)
-               dest = XEXP (dest, 0);
-             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, data);
-               }
-             else
-               (*fun) (dest, y, data);
-           }
-       }
-    }
+  else if (GET_CODE (x) == PARALLEL)
+    for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+      note_stores (XVECEXP (x, 0, i), fun, data);
 }
 \f
 /* Return nonzero if X's old contents don't survive after INSN.
index 67ea68bedf32c052bb3ae310ec8916d61c749364..9b566a0ec2688f88468c8b58f689f38b1a3db196 100644 (file)
@@ -551,12 +551,20 @@ sched_analyze_1 (deps, x, insn)
   if (dest == 0)
     return;
 
-  if (GET_CODE (dest) == PARALLEL
-      && GET_MODE (dest) == BLKmode)
+  if (GET_CODE (dest) == PARALLEL && GET_MODE (dest) == BLKmode)
     {
       register int i;
+
       for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
-       sched_analyze_1 (deps, XVECEXP (dest, 0, i), insn);
+       {
+         rtx reg = XVECEXP (dest, 0, i);
+
+         if (GET_CODE (reg) == EXPR_LIST)
+           reg = XEXP (reg, 0);
+
+         sched_analyze_1 (deps, reg, insn);
+       }
+
       if (GET_CODE (x) == SET)
        sched_analyze_2 (deps, SET_SRC (x), insn);
       return;
index 46c734cf7da55a405e18d1ca2b57b97073a26e69..71c4018bb1c2621ad14e2e74cb3333b5ccc51f9b 100644 (file)
@@ -1396,13 +1396,21 @@ check_live_1 (src, x)
         || GET_CODE (reg) == STRICT_LOW_PART)
     reg = XEXP (reg, 0);
 
-  if (GET_CODE (reg) == PARALLEL
-      && GET_MODE (reg) == BLKmode)
+  if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
     {
       register int i;
+
       for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
-       if (check_live_1 (src, XVECEXP (reg, 0, i)))
-         return 1;
+       {
+         rtx dest = XVECEXP (reg, 0, i);
+
+         if (GET_CODE (dest) == EXPR_LIST)
+           dest = XEXP (dest, 0);
+
+         if (check_live_1 (src, dest))
+           return 1;
+       }
+
       return 0;
     }
 
@@ -1474,12 +1482,20 @@ update_live_1 (src, x)
         || GET_CODE (reg) == STRICT_LOW_PART)
     reg = XEXP (reg, 0);
 
-  if (GET_CODE (reg) == PARALLEL
-      && GET_MODE (reg) == BLKmode)
+  if (GET_CODE (reg) == PARALLEL && GET_MODE (reg) == BLKmode)
     {
       register int i;
+
       for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
-       update_live_1 (src, XVECEXP (reg, 0, i));
+       {
+         rtx dest = XVECEXP (reg, 0, i);
+
+         if (GET_CODE (dest) == EXPR_LIST)
+           dest = XEXP (dest, 0);
+
+         update_live_1 (src, dest);
+       }
+
       return;
     }
 
@@ -1915,15 +1931,17 @@ haifa_classify_insn (insn)
              if (tmp_class == TRAP_RISKY)
                break;
              /* Test if it is a load.  */
-             tmp_class =
-               WORST_CLASS (tmp_class,
-                            may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
+             tmp_class
+               = WORST_CLASS (tmp_class,
+                              may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
+                                            0));
              break;
            case COND_EXEC:
            case TRAP_IF:
              tmp_class = TRAP_RISKY;
              break;
-           default:;
+           default:
+             ;
            }
          insn_class = WORST_CLASS (insn_class, tmp_class);
          if (insn_class == TRAP_RISKY || insn_class == IRISKY)