OSDN Git Service

* g++.dg/rtti/tinfo1.C: Remove xfails.
[pf3gnuchains/gcc-fork.git] / gcc / loop.c
index 0f62789..08b8529 100644 (file)
@@ -10438,319 +10438,8 @@ update_reg_last_use (rtx x, rtx insn)
     }
 }
 \f
-/* Given an insn INSN and condition COND, return the condition in a
-   canonical form to simplify testing by callers.  Specifically:
-
-   (1) The code will always be a comparison operation (EQ, NE, GT, etc.).
-   (2) Both operands will be machine operands; (cc0) will have been replaced.
-   (3) If an operand is a constant, it will be the second operand.
-   (4) (LE x const) will be replaced with (LT x <const+1>) and similarly
-       for GE, GEU, and LEU.
-
-   If the condition cannot be understood, or is an inequality floating-point
-   comparison which needs to be reversed, 0 will be returned.
-
-   If REVERSE is nonzero, then reverse the condition prior to canonizing it.
-
-   If EARLIEST is nonzero, it is a pointer to a place where the earliest
-   insn used in locating the condition was found.  If a replacement test
-   of the condition is desired, it should be placed in front of that
-   insn and we will be sure that the inputs are still valid.
-
-   If WANT_REG is nonzero, we wish the condition to be relative to that
-   register, if possible.  Therefore, do not canonicalize the condition
-   further.  If ALLOW_CC_MODE is nonzero, allow the condition returned 
-   to be a compare to a CC mode register.
-
-   If VALID_AT_INSN_P, the condition must be valid at both *EARLIEST
-   and at INSN.  */
-
-rtx
-canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
-                       rtx want_reg, int allow_cc_mode, int valid_at_insn_p)
-{
-  enum rtx_code code;
-  rtx prev = insn;
-  rtx set;
-  rtx tem;
-  rtx op0, op1;
-  int reverse_code = 0;
-  enum machine_mode mode;
-
-  code = GET_CODE (cond);
-  mode = GET_MODE (cond);
-  op0 = XEXP (cond, 0);
-  op1 = XEXP (cond, 1);
-
-  if (reverse)
-    code = reversed_comparison_code (cond, insn);
-  if (code == UNKNOWN)
-    return 0;
-
-  if (earliest)
-    *earliest = insn;
-
-  /* If we are comparing a register with zero, see if the register is set
-     in the previous insn to a COMPARE or a comparison operation.  Perform
-     the same tests as a function of STORE_FLAG_VALUE as find_comparison_args
-     in cse.c  */
-
-  while ((GET_RTX_CLASS (code) == RTX_COMPARE
-         || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
-        && op1 == CONST0_RTX (GET_MODE (op0))
-        && op0 != want_reg)
-    {
-      /* Set nonzero when we find something of interest.  */
-      rtx x = 0;
-
-#ifdef HAVE_cc0
-      /* If comparison with cc0, import actual comparison from compare
-        insn.  */
-      if (op0 == cc0_rtx)
-       {
-         if ((prev = prev_nonnote_insn (prev)) == 0
-             || !NONJUMP_INSN_P (prev)
-             || (set = single_set (prev)) == 0
-             || SET_DEST (set) != cc0_rtx)
-           return 0;
-
-         op0 = SET_SRC (set);
-         op1 = CONST0_RTX (GET_MODE (op0));
-         if (earliest)
-           *earliest = prev;
-       }
-#endif
-
-      /* If this is a COMPARE, pick up the two things being compared.  */
-      if (GET_CODE (op0) == COMPARE)
-       {
-         op1 = XEXP (op0, 1);
-         op0 = XEXP (op0, 0);
-         continue;
-       }
-      else if (!REG_P (op0))
-       break;
-
-      /* Go back to the previous insn.  Stop if it is not an INSN.  We also
-        stop if it isn't a single set or if it has a REG_INC note because
-        we don't want to bother dealing with it.  */
-
-      if ((prev = prev_nonnote_insn (prev)) == 0
-         || !NONJUMP_INSN_P (prev)
-         || FIND_REG_INC_NOTE (prev, NULL_RTX))
-       break;
-
-      set = set_of (op0, prev);
-
-      if (set
-         && (GET_CODE (set) != SET
-             || !rtx_equal_p (SET_DEST (set), op0)))
-       break;
-
-      /* If this is setting OP0, get what it sets it to if it looks
-        relevant.  */
-      if (set)
-       {
-         enum machine_mode inner_mode = GET_MODE (SET_DEST (set));
-#ifdef FLOAT_STORE_FLAG_VALUE
-         REAL_VALUE_TYPE fsfv;
-#endif
-
-         /* ??? We may not combine comparisons done in a CCmode with
-            comparisons not done in a CCmode.  This is to aid targets
-            like Alpha that have an IEEE compliant EQ instruction, and
-            a non-IEEE compliant BEQ instruction.  The use of CCmode is
-            actually artificial, simply to prevent the combination, but
-            should not affect other platforms.
-
-            However, we must allow VOIDmode comparisons to match either
-            CCmode or non-CCmode comparison, because some ports have
-            modeless comparisons inside branch patterns.
-
-            ??? This mode check should perhaps look more like the mode check
-            in simplify_comparison in combine.  */
-
-         if ((GET_CODE (SET_SRC (set)) == COMPARE
-              || (((code == NE
-                    || (code == LT
-                        && GET_MODE_CLASS (inner_mode) == MODE_INT
-                        && (GET_MODE_BITSIZE (inner_mode)
-                            <= HOST_BITS_PER_WIDE_INT)
-                        && (STORE_FLAG_VALUE
-                            & ((HOST_WIDE_INT) 1
-                               << (GET_MODE_BITSIZE (inner_mode) - 1))))
-#ifdef FLOAT_STORE_FLAG_VALUE
-                    || (code == LT
-                        && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
-                        && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
-                            REAL_VALUE_NEGATIVE (fsfv)))
-#endif
-                    ))
-                  && COMPARISON_P (SET_SRC (set))))
-             && (((GET_MODE_CLASS (mode) == MODE_CC)
-                  == (GET_MODE_CLASS (inner_mode) == MODE_CC))
-                 || mode == VOIDmode || inner_mode == VOIDmode))
-           x = SET_SRC (set);
-         else if (((code == EQ
-                    || (code == GE
-                        && (GET_MODE_BITSIZE (inner_mode)
-                            <= HOST_BITS_PER_WIDE_INT)
-                        && GET_MODE_CLASS (inner_mode) == MODE_INT
-                        && (STORE_FLAG_VALUE
-                            & ((HOST_WIDE_INT) 1
-                               << (GET_MODE_BITSIZE (inner_mode) - 1))))
-#ifdef FLOAT_STORE_FLAG_VALUE
-                    || (code == GE
-                        && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
-                        && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode),
-                            REAL_VALUE_NEGATIVE (fsfv)))
-#endif
-                    ))
-                  && COMPARISON_P (SET_SRC (set))
-                  && (((GET_MODE_CLASS (mode) == MODE_CC)
-                       == (GET_MODE_CLASS (inner_mode) == MODE_CC))
-                      || mode == VOIDmode || inner_mode == VOIDmode))
-
-           {
-             reverse_code = 1;
-             x = SET_SRC (set);
-           }
-         else
-           break;
-       }
-
-      else if (reg_set_p (op0, prev))
-       /* If this sets OP0, but not directly, we have to give up.  */
-       break;
-
-      if (x)
-       {
-         /* If the caller is expecting the condition to be valid at INSN,
-            make sure X doesn't change before INSN.  */
-         if (valid_at_insn_p)
-           if (modified_in_p (x, prev) || modified_between_p (x, prev, insn))
-             break;
-         if (COMPARISON_P (x))
-           code = GET_CODE (x);
-         if (reverse_code)
-           {
-             code = reversed_comparison_code (x, prev);
-             if (code == UNKNOWN)
-               return 0;
-             reverse_code = 0;
-           }
-
-         op0 = XEXP (x, 0), op1 = XEXP (x, 1);
-         if (earliest)
-           *earliest = prev;
-       }
-    }
-
-  /* If constant is first, put it last.  */
-  if (CONSTANT_P (op0))
-    code = swap_condition (code), tem = op0, op0 = op1, op1 = tem;
-
-  /* If OP0 is the result of a comparison, we weren't able to find what
-     was really being compared, so fail.  */
-  if (!allow_cc_mode
-      && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
-    return 0;
-
-  /* Canonicalize any ordered comparison with integers involving equality
-     if we can do computations in the relevant mode and we do not
-     overflow.  */
-
-  if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
-      && GET_CODE (op1) == CONST_INT
-      && GET_MODE (op0) != VOIDmode
-      && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
-    {
-      HOST_WIDE_INT const_val = INTVAL (op1);
-      unsigned HOST_WIDE_INT uconst_val = const_val;
-      unsigned HOST_WIDE_INT max_val
-       = (unsigned HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (op0));
-
-      switch (code)
-       {
-       case LE:
-         if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1)
-           code = LT, op1 = gen_int_mode (const_val + 1, GET_MODE (op0));
-         break;
-
-       /* When cross-compiling, const_val might be sign-extended from
-          BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */
-       case GE:
-         if ((HOST_WIDE_INT) (const_val & max_val)
-             != (((HOST_WIDE_INT) 1
-                  << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1))))
-           code = GT, op1 = gen_int_mode (const_val - 1, GET_MODE (op0));
-         break;
-
-       case LEU:
-         if (uconst_val < max_val)
-           code = LTU, op1 = gen_int_mode (uconst_val + 1, GET_MODE (op0));
-         break;
-
-       case GEU:
-         if (uconst_val != 0)
-           code = GTU, op1 = gen_int_mode (uconst_val - 1, GET_MODE (op0));
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  /* Never return CC0; return zero instead.  */
-  if (CC0_P (op0))
-    return 0;
-
-  return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
-}
-
-/* Given a jump insn JUMP, return the condition that will cause it to branch
-   to its JUMP_LABEL.  If the condition cannot be understood, or is an
-   inequality floating-point comparison which needs to be reversed, 0 will
-   be returned.
-
-   If EARLIEST is nonzero, it is a pointer to a place where the earliest
-   insn used in locating the condition was found.  If a replacement test
-   of the condition is desired, it should be placed in front of that
-   insn and we will be sure that the inputs are still valid.  If EARLIEST
-   is null, the returned condition will be valid at INSN.
-
-   If ALLOW_CC_MODE is nonzero, allow the condition returned to be a
-   compare CC mode register.
-
-   VALID_AT_INSN_P is the same as for canonicalize_condition.  */
-
-rtx
-get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p)
-{
-  rtx cond;
-  int reverse;
-  rtx set;
-
-  /* If this is not a standard conditional jump, we can't parse it.  */
-  if (!JUMP_P (jump)
-      || ! any_condjump_p (jump))
-    return 0;
-  set = pc_set (jump);
-
-  cond = XEXP (SET_SRC (set), 0);
-
-  /* If this branches to JUMP_LABEL when the condition is false, reverse
-     the condition.  */
-  reverse
-    = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
-      && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
-
-  return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
-                                allow_cc_mode, valid_at_insn_p);
-}
-
-/* Similar to above routine, except that we also put an invariant last
-   unless both operands are invariants.  */
+/* Similar to rtlanal.c:get_condition, except that we also put an
+   invariant last unless both operands are invariants.  */
 
 static rtx
 get_condition_for_loop (const struct loop *loop, rtx x)
@@ -11242,6 +10931,7 @@ load_mems (const struct loop *loop)
          rtx best = mem;
          int j;
          struct elt_loc_list *const_equiv = 0;
+         reg_set_iterator rsi;
 
          if (e)
            {
@@ -11320,17 +11010,17 @@ load_mems (const struct loop *loop)
             data flow, and enables {basic,general}_induction_var to find
             more bivs/givs.  */
          EXECUTE_IF_SET_IN_REG_SET
-           (&load_copies, FIRST_PSEUDO_REGISTER, j,
-            {
-              try_copy_prop (loop, reg, j);
-            });
+           (&load_copies, FIRST_PSEUDO_REGISTER, j, rsi)
+           {
+             try_copy_prop (loop, reg, j);
+           }
          CLEAR_REG_SET (&load_copies);
 
          EXECUTE_IF_SET_IN_REG_SET
-           (&store_copies, FIRST_PSEUDO_REGISTER, j,
-            {
-              try_swap_copy_prop (loop, reg, j);
-            });
+           (&store_copies, FIRST_PSEUDO_REGISTER, j, rsi)
+           {
+             try_swap_copy_prop (loop, reg, j);
+           }
          CLEAR_REG_SET (&store_copies);
        }
     }