OSDN Git Service

PR c++/9704
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
index 924ef52..8bd7b25 100644 (file)
@@ -1037,7 +1037,7 @@ regs_set_between_p (x, start, end)
 
 /* Similar to reg_set_between_p, but check all registers in X.  Return 0
    only if none of them are modified between START and END.  Return 1 if
-   X contains a MEM; this routine does not perform any memory aliasing.  */
+   X contains a MEM; this routine does usememory aliasing.  */
 
 int
 modified_between_p (x, start, end)
@@ -1047,6 +1047,10 @@ modified_between_p (x, start, end)
   enum rtx_code code = GET_CODE (x);
   const char *fmt;
   int i, j;
+  rtx insn;
+
+  if (start == end)
+    return 0;
 
   switch (code)
     {
@@ -1063,10 +1067,14 @@ modified_between_p (x, start, end)
       return 1;
 
     case MEM:
-      /* If the memory is not constant, assume it is modified.  If it is
-        constant, we still have to check the address.  */
-      if (! RTX_UNCHANGING_P (x))
+      if (RTX_UNCHANGING_P (x))
+       return 0;
+      if (modified_between_p (XEXP (x, 0), start, end))
        return 1;
+      for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
+       if (memory_modified_in_insn_p (x, insn))
+         return 1;
+      return 0;
       break;
 
     case REG:
@@ -1093,7 +1101,7 @@ modified_between_p (x, start, end)
 
 /* Similar to reg_set_p, but check all registers in X.  Return 0 only if none
    of them are modified in INSN.  Return 1 if X contains a MEM; this routine
-   does not perform any memory aliasing.  */
+   does use memory aliasing.  */
 
 int
 modified_in_p (x, insn)
@@ -1119,10 +1127,13 @@ modified_in_p (x, insn)
       return 1;
 
     case MEM:
-      /* If the memory is not constant, assume it is modified.  If it is
-        constant, we still have to check the address.  */
-      if (! RTX_UNCHANGING_P (x))
+      if (RTX_UNCHANGING_P (x))
+       return 0;
+      if (modified_in_p (XEXP (x, 0), insn))
        return 1;
+      if (memory_modified_in_insn_p (x, insn))
+       return 1;
+      return 0;
       break;
 
     case REG:
@@ -2226,7 +2237,6 @@ volatile_insn_p (x)
     case REG:
     case SCRATCH:
     case CLOBBER:
-    case ASM_INPUT:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
     case CALL:
@@ -2237,6 +2247,7 @@ volatile_insn_p (x)
  /* case TRAP_IF: This isn't clear yet.  */
       return 1;
 
+    case ASM_INPUT:
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
        return 1;
@@ -2293,7 +2304,6 @@ volatile_refs_p (x)
     case REG:
     case SCRATCH:
     case CLOBBER:
-    case ASM_INPUT:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
       return 0;
@@ -2302,6 +2312,7 @@ volatile_refs_p (x)
       return 1;
 
     case MEM:
+    case ASM_INPUT:
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
        return 1;
@@ -2357,7 +2368,6 @@ side_effects_p (x)
     case PC:
     case REG:
     case SCRATCH:
-    case ASM_INPUT:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
       return 0;
@@ -2380,6 +2390,7 @@ side_effects_p (x)
       return 1;
 
     case MEM:
+    case ASM_INPUT:
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
        return 1;
@@ -2506,6 +2517,12 @@ may_trap_p (x)
        return 1;
       break;
 
+    case FIX:
+      /* Conversion of floating point might trap.  */
+      if (flag_trapping_math && HONOR_NANS (GET_MODE (XEXP (x, 0))))
+       return 1;
+      break;
+
     case NEG:
     case ABS:
       /* These operations don't trap even with floating point.  */
@@ -3336,7 +3353,7 @@ find_first_parameter_load (call_insn, boundary)
   return before;
 }
 
-/* Return true if we should avoid inserting code between INSN and preceeding
+/* Return true if we should avoid inserting code between INSN and preceding
    call instruction.  */
 
 bool
@@ -3409,7 +3426,7 @@ hoist_test_store (x, val, live)
   /* Pseudo registers can be allways replaced by another pseudo to avoid
      the side effect, for hard register we must ensure that they are dead.
      Eventually we may want to add code to try turn pseudos to hards, but it
-     is unlikely usefull.  */
+     is unlikely useful.  */
 
   if (REGNO (x) < FIRST_PSEUDO_REGISTER)
     {
@@ -3479,7 +3496,7 @@ can_hoist_insn_p (insn, val, live)
            case USE:
              /* We need to fix callers to really ensure availability
                 of all values inisn uses, but for now it is safe to prohibit
-                hoisting of any insn having such a hiden uses.  */
+                hoisting of any insn having such a hidden uses.  */
              return false;
              break;
            case CLOBBER: