OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
index 221b3fa..031d103 100644 (file)
@@ -851,6 +851,18 @@ reg_overlap_mentioned_p (x, in)
   else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
           || GET_CODE (x) == CC0)
     return reg_mentioned_p (x, in);
+  else if (GET_CODE (x) == PARALLEL
+          && GET_MODE (x) == BLKmode)
+    {
+      register int i;
+
+      /* If any register in here refers to it
+        we return true.  */
+      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+       if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
+         return 1;
+      return 0;
+    }
   else
     abort ();
 
@@ -1086,7 +1098,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 +1126,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);
            }
        }
     }
@@ -1165,30 +1194,21 @@ dead_or_set_regno_p (insn, test_regno)
   int regno, endregno;
   rtx link;
 
-  /* REG_READ notes are not normally maintained after reload, so we
-     ignore them if the are invalid.  */
-  if (! reload_completed
-#ifdef PRESERVE_DEATH_INFO_REGNO_P
-      || PRESERVE_DEATH_INFO_REGNO_P (test_regno)
-#endif
-      )
+  /* See if there is a death note for something that includes
+     TEST_REGNO.  */
+  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
     {
-      /* See if there is a death note for something that includes
-         TEST_REGNO.  */
-      for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-       {
-         if (REG_NOTE_KIND (link) != REG_DEAD
-             || GET_CODE (XEXP (link, 0)) != REG)
-           continue;
+      if (REG_NOTE_KIND (link) != REG_DEAD
+         || GET_CODE (XEXP (link, 0)) != REG)
+       continue;
 
-         regno = REGNO (XEXP (link, 0));
-         endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
-                     : regno + HARD_REGNO_NREGS (regno,
-                                                 GET_MODE (XEXP (link, 0))));
+      regno = REGNO (XEXP (link, 0));
+      endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
+                 : regno + HARD_REGNO_NREGS (regno,
+                                             GET_MODE (XEXP (link, 0))));
 
-         if (test_regno >= regno && test_regno < endregno)
-           return 1;
-       }
+      if (test_regno >= regno && test_regno < endregno)
+       return 1;
     }
 
   if (GET_CODE (insn) == CALL_INSN
@@ -1202,7 +1222,7 @@ dead_or_set_regno_p (insn, test_regno)
       /* A value is totally replaced if it is the destination or the
         destination is a SUBREG of REGNO that does not change the number of
         words in it.  */
-     if (GET_CODE (dest) == SUBREG
+      if (GET_CODE (dest) == SUBREG
          && (((GET_MODE_SIZE (GET_MODE (dest))
                + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
              == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
@@ -2015,3 +2035,77 @@ computed_jump_p (insn)
     }
   return 0;
 }
+
+/* Traverse X via depth-first search, calling F for each
+   sub-expression (including X itself).  F is also passed the DATA.
+   If F returns -1, do not traverse sub-expressions, but continue
+   traversing the rest of the tree.  If F ever returns any other
+   non-zero value, stop the traversal, and return the value returned
+   by F.  Otherwise, return 0.  This function does not traverse inside
+   tree structure that contains RTX_EXPRs, or into sub-expressions
+   whose format code is `0' since it is not known whether or not those
+   codes are actually RTL.
+
+   This routine is very general, and could (should?) be used to
+   implement many of the other routines in this file.  */
+
+int
+for_each_rtx (x, f, data)
+     rtx* x;
+     rtx_function f;
+     void* data;
+{
+  int result;
+  int length;
+  char* format;
+  int i;
+
+  /* Call F on X.  */
+  result = (*f)(x, data);
+  if (result == -1)
+    /* Do not traverse sub-expressions.  */
+    return 0;
+  else if (result != 0)
+    /* Stop the traversal.  */
+    return result;
+
+  if (*x == NULL_RTX)
+    /* There are no sub-expressions.  */
+    return 0;
+
+  length = GET_RTX_LENGTH (GET_CODE (*x));
+  format = GET_RTX_FORMAT (GET_CODE (*x));
+
+  for (i = 0; i < length; ++i) 
+    {
+      switch (format[i]) 
+       {
+       case 'e':
+         result = for_each_rtx (&XEXP (*x, i), f, data);
+         if (result != 0)
+           return result;
+         break;
+
+       case 'V':
+       case 'E':
+         if (XVEC (*x, i) != 0) 
+           {
+             int j;
+             for (j = 0; j < XVECLEN (*x, i); ++j)
+               {
+                 result = for_each_rtx (&XVECEXP (*x, i, j), f, data);
+                 if (result != 0)
+                   return result;
+               }
+           }
+         break; 
+
+       default:
+         /* Nothing to do.  */
+         break;
+       }
+
+    }
+
+  return 0;
+}