OSDN Git Service

2008-05-16 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
index 4a4a629..f0dc512 100644 (file)
@@ -1,6 +1,6 @@
 /* Analyze RTL for GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
    Foundation, Inc.
 
 This file is part of GCC.
@@ -1412,49 +1412,41 @@ reg_overlap_mentioned_p (const_rtx x, const_rtx in)
   If the item being stored in or clobbered is a SUBREG of a hard register,
   the SUBREG will be passed.  */
 
-#define NOTE_STORES_BODY(NOTE_STORES_FN) do { \
-  int i; \
-  if (GET_CODE (x) == COND_EXEC) \
-    x = COND_EXEC_CODE (x); \
-  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER) \
-    { \
-      rtx dest = SET_DEST (x); \
-      while ((GET_CODE (dest) == SUBREG \
-             && (!REG_P (SUBREG_REG (dest)) \
-                 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER)) \
-            || GET_CODE (dest) == ZERO_EXTRACT \
-            || GET_CODE (dest) == STRICT_LOW_PART) \
-       dest = XEXP (dest, 0); \
-      /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions, \
-        each of whose first operand is a register.  */ \
-      if (GET_CODE (dest) == PARALLEL) \
-       { \
-         for (i = XVECLEN (dest, 0) - 1; i >= 0; i--) \
-           if (XEXP (XVECEXP (dest, 0, i), 0) != 0) \
-             (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data); \
-       } \
-      else \
-       (*fun) (dest, x, data); \
-    } \
-  else if (GET_CODE (x) == PARALLEL) \
-    for (i = XVECLEN (x, 0) - 1; i >= 0; i--) \
-      NOTE_STORES_FN (XVECEXP (x, 0, i), fun, data); \
-} while (0)
-
 void
 note_stores (const_rtx x, void (*fun) (rtx, const_rtx, void *), void *data)
 {
-  NOTE_STORES_BODY(note_stores);
-}
+  int i;
 
-void
-const_note_stores (const_rtx x, void (*fun) (const_rtx, const_rtx, const void *), const void *data)
-{
-  NOTE_STORES_BODY(const_note_stores);
-}
+  if (GET_CODE (x) == COND_EXEC)
+    x = COND_EXEC_CODE (x);
 
-#undef NOTE_STORES_BODY
+  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
+    {
+      rtx dest = SET_DEST (x);
+
+      while ((GET_CODE (dest) == SUBREG
+             && (!REG_P (SUBREG_REG (dest))
+                 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
+            || GET_CODE (dest) == ZERO_EXTRACT
+            || GET_CODE (dest) == STRICT_LOW_PART)
+       dest = XEXP (dest, 0);
+
+      /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
+        each of whose first operand is a register.  */
+      if (GET_CODE (dest) == PARALLEL)
+       {
+         for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
+           if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
+             (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
+       }
+      else
+       (*fun) (dest, x, 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
 /* Like notes_stores, but call FUN for each expression that is being
    referenced in PBODY, a pointer to the PATTERN of an insn.  We only call
@@ -1854,29 +1846,6 @@ find_regno_fusage (const_rtx insn, enum rtx_code code, unsigned int regno)
   return 0;
 }
 
-/* Return true if INSN is a call to a pure function.  */
-
-int
-pure_call_p (const_rtx insn)
-{
-  const_rtx link;
-
-  if (!CALL_P (insn) || ! CONST_OR_PURE_CALL_P (insn))
-    return 0;
-
-  /* Look for the note that differentiates const and pure functions.  */
-  for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
-    {
-      rtx u, m;
-
-      if (GET_CODE (u = XEXP (link, 0)) == USE
-         && MEM_P (m = XEXP (u, 0)) && GET_MODE (m) == BLKmode
-         && GET_CODE (XEXP (m, 0)) == SCRATCH)
-       return 1;
-    }
-
-  return 0;
-}
 \f
 /* Remove register note NOTE from the REG_NOTES of INSN.  */
 
@@ -2190,7 +2159,7 @@ enum may_trap_p_flags
    cannot trap at its current location, but it might become trapping if moved
    elsewhere.  */
 
-static int
+int
 may_trap_p_1 (const_rtx x, unsigned flags)
 {
   int i;
@@ -2217,8 +2186,11 @@ may_trap_p_1 (const_rtx x, unsigned flags)
     case SCRATCH:
       return 0;
 
-    case ASM_INPUT:
+    case UNSPEC:
     case UNSPEC_VOLATILE:
+      return targetm.unspec_may_trap_p (x, flags);
+
+    case ASM_INPUT:
     case TRAP_IF:
       return 1;
 
@@ -2703,9 +2675,11 @@ computed_jump_p (const_rtx insn)
     {
       rtx pat = PATTERN (insn);
 
-      if (find_reg_note (insn, REG_LABEL, NULL_RTX))
+      /* If we have a JUMP_LABEL set, we're not a computed jump.  */
+      if (JUMP_LABEL (insn) != NULL)
        return 0;
-      else if (GET_CODE (pat) == PARALLEL)
+
+      if (GET_CODE (pat) == PARALLEL)
        {
          int len = XVECLEN (pat, 0);
          int has_use_labelref = 0;
@@ -2992,16 +2966,15 @@ loc_mentioned_in_p (rtx *loc, const_rtx in)
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
-      if (loc == &in->u.fld[i].rt_rtx)
-       return 1;
       if (fmt[i] == 'e')
        {
-         if (loc_mentioned_in_p (loc, XEXP (in, i)))
+         if (loc == &XEXP (in, i) || loc_mentioned_in_p (loc, XEXP (in, i)))
            return 1;
        }
       else if (fmt[i] == 'E')
        for (j = XVECLEN (in, i) - 1; j >= 0; j--)
-         if (loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
+         if (loc == &XVECEXP (in, i, j)
+             || loc_mentioned_in_p (loc, XVECEXP (in, i, j)))
            return 1;
     }
   return 0;
@@ -3269,15 +3242,25 @@ subreg_regno (const_rtx x)
 unsigned int
 subreg_nregs (const_rtx x)
 {
+  return subreg_nregs_with_regno (REGNO (SUBREG_REG (x)), x);
+}
+
+/* Return the number of registers that a subreg REG with REGNO
+   expression refers to.  This is a copy of the rtlanal.c:subreg_nregs
+   changed so that the regno can be passed in. */
+
+unsigned int
+subreg_nregs_with_regno (unsigned int regno, const_rtx x)
+{
   struct subreg_info info;
   rtx subreg = SUBREG_REG (x);
-  int regno = REGNO (subreg);
 
   subreg_get_info (regno, GET_MODE (subreg), SUBREG_BYTE (x), GET_MODE (x),
                   &info);
   return info.nregs;
 }
 
+
 struct parms_set_data
 {
   int nregs;
@@ -3392,7 +3375,10 @@ keep_with_call_p (const_rtx insn)
         if we can break or not.  */
       if (SET_DEST (set) == stack_pointer_rtx)
        {
-         const_rtx i2 = const_next_nonnote_insn (insn);
+         /* This CONST_CAST is okay because next_nonnote_insn just
+            returns it's argument and we assign it to a const_rtx
+            variable.  */
+         const_rtx i2 = next_nonnote_insn (CONST_CAST_RTX(insn));
          if (i2 && keep_with_call_p (i2))
            return true;
        }
@@ -3424,6 +3410,9 @@ label_is_jump_target_p (const_rtx label, const_rtx jump_insn)
          return true;
     }
 
+  if (find_reg_note (jump_insn, REG_LABEL_TARGET, label))
+    return true;
+
   return false;
 }