OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
index 79ccf9d..3d90ae7 100644 (file)
@@ -28,6 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "insn-config.h"
 #include "recog.h"
 #include "tm_p.h"
+#include "flags.h"
 
 /* Forward declarations */
 static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
@@ -1621,17 +1622,12 @@ note_stores (x, fun, data)
        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.  We can't know what
-        precisely is being set in these cases, so make up a CLOBBER to pass
-        to the function.  */
+        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),
-                     gen_rtx_CLOBBER (VOIDmode,
-                                      XEXP (XVECEXP (dest, 0, i), 0)),
-                     data);
+             (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
        }
       else
        (*fun) (dest, x, data);
@@ -2010,6 +2006,31 @@ find_regno_fusage (insn, code, regno)
 
   return 0;
 }
+
+/* Return true if INSN is a call to a pure function.  */
+
+int
+pure_call_p (insn)
+     rtx insn;
+{
+  rtx link;
+
+  if (GET_CODE (insn) != CALL_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
+         && GET_CODE (m = XEXP (u, 0)) == MEM && 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.  */
 
@@ -2348,7 +2369,8 @@ may_trap_p (x)
     case UDIV:
     case UMOD:
       if (! CONSTANT_P (XEXP (x, 1))
-         || GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+         || (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+             && flag_trapping_math))
        return 1;
       /* This was const0_rtx, but by not using that,
         we can link this file into other programs.  */
@@ -2367,6 +2389,8 @@ may_trap_p (x)
     case LT:
     case COMPARE:
       /* Some floating point comparisons may trap.  */
+      if (!flag_trapping_math)
+       break;
       /* ??? There is no machine independent way to check for tests that trap
         when COMPARE is used, though many targets do make this distinction.
         For instance, sparc uses CCFPE for compares which generate exceptions
@@ -2387,7 +2411,8 @@ may_trap_p (x)
 
     default:
       /* Any floating arithmetic may trap.  */
-      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
+      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
+         && flag_trapping_math)
        return 1;
     }