OSDN Git Service

Resolve CLooG's value_* macros to their respective mpz_* counterparts.
[pf3gnuchains/gcc-fork.git] / gcc / rtlanal.c
index d15dbe2..f5dc0bb 100644 (file)
@@ -33,7 +33,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 #include "tm_p.h"
 #include "flags.h"
-#include "real.h"
 #include "regs.h"
 #include "function.h"
 #include "df.h"
@@ -293,7 +292,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size,
          decl = SYMBOL_REF_DECL (x);
 
          /* Else check that the access is in bounds.  TODO: restructure
-            expr_size/lhd_expr_size/int_expr_size and just use the latter.  */
+            expr_size/tree_expr_size/int_expr_size and just use the latter.  */
          if (!decl)
            decl_size = -1;
          else if (DECL_P (decl) && DECL_SIZE_UNIT (decl))
@@ -341,7 +340,7 @@ rtx_addr_can_trap_p_1 (const_rtx x, HOST_WIDE_INT offset, HOST_WIDE_INT size,
       /* - or it is an address that can't trap plus a constant integer,
           with the proper remainder modulo the mode size if we are
           considering unaligned memory references.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && !rtx_addr_can_trap_p_1 (XEXP (x, 0), offset + INTVAL (XEXP (x, 1)),
                                     size, mode, unaligned_mems))
        return 0;
@@ -408,7 +407,7 @@ nonzero_address_p (const_rtx x)
       return nonzero_address_p (XEXP (x, 0));
 
     case PLUS:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+      if (CONST_INT_P (XEXP (x, 1)))
         return nonzero_address_p (XEXP (x, 0));
       /* Handle PIC references.  */
       else if (XEXP (x, 0) == pic_offset_table_rtx
@@ -420,7 +419,7 @@ nonzero_address_p (const_rtx x)
       /* Similar to the above; allow positive offsets.  Further, since
         auto-inc is only allowed in memories, the register must be a
         pointer.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) > 0)
        return true;
       return nonzero_address_p (XEXP (x, 0));
@@ -495,10 +494,10 @@ get_integer_term (const_rtx x)
     x = XEXP (x, 0);
 
   if (GET_CODE (x) == MINUS
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (x, 1)))
     return - INTVAL (XEXP (x, 1));
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (x, 1)))
     return INTVAL (XEXP (x, 1));
   return 0;
 }
@@ -514,10 +513,10 @@ get_related_value (const_rtx x)
     return 0;
   x = XEXP (x, 0);
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      && CONST_INT_P (XEXP (x, 1)))
     return XEXP (x, 0);
   else if (GET_CODE (x) == MINUS
-          && GET_CODE (XEXP (x, 1)) == CONST_INT)
+          && CONST_INT_P (XEXP (x, 1)))
     return XEXP (x, 0);
   return 0;
 }
@@ -566,7 +565,7 @@ split_const (rtx x, rtx *base_out, rtx *offset_out)
   if (GET_CODE (x) == CONST)
     {
       x = XEXP (x, 0);
-      if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
+      if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
        {
          *base_out = XEXP (x, 0);
          *offset_out = XEXP (x, 1);
@@ -611,7 +610,7 @@ count_occurrences (const_rtx x, const_rtx find, int count_dest)
       if (XEXP (x, 1))
        count += count_occurrences (XEXP (x, 1), find, count_dest);
       return count;
-       
+
     case MEM:
       if (MEM_P (find) && rtx_equal_p (x, find))
        return 1;
@@ -741,7 +740,7 @@ reg_used_between_p (const_rtx reg, const_rtx from_insn, const_rtx to_insn)
     return 0;
 
   for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
-    if (INSN_P (insn)
+    if (NONDEBUG_INSN_P (insn)
        && (reg_overlap_mentioned_p (reg, PATTERN (insn))
           || (CALL_P (insn) && find_reg_fusage (insn, USE, reg))))
       return 1;
@@ -2148,6 +2147,7 @@ side_effects_p (const_rtx x)
     case SCRATCH:
     case ADDR_VEC:
     case ADDR_DIFF_VEC:
+    case VAR_LOCATION:
       return 0;
 
     case CLOBBER:
@@ -2251,6 +2251,11 @@ may_trap_p_1 (const_rtx x, unsigned flags)
 
       /* Memory ref can trap unless it's a static var or a stack slot.  */
     case MEM:
+      /* Recognize specific pattern of stack checking probes.  */
+      if (flag_stack_check
+         && MEM_VOLATILE_P (x)
+         && XEXP (x, 0) == stack_pointer_rtx)
+       return 1;
       if (/* MEM_NOTRAP_P only relates to the actual position of the memory
             reference; moving it out of context such as when moving code
             when optimizing, might cause its address to become invalid.  */
@@ -2495,7 +2500,7 @@ replace_rtx (rtx x, rtx from, rtx to)
     {
       rtx new_rtx = replace_rtx (SUBREG_REG (x), from, to);
 
-      if (GET_CODE (new_rtx) == CONST_INT)
+      if (CONST_INT_P (new_rtx))
        {
          x = simplify_subreg (GET_MODE (x), new_rtx,
                               GET_MODE (SUBREG_REG (x)),
@@ -2511,7 +2516,7 @@ replace_rtx (rtx x, rtx from, rtx to)
     {
       rtx new_rtx = replace_rtx (XEXP (x, 0), from, to);
 
-      if (GET_CODE (new_rtx) == CONST_INT)
+      if (CONST_INT_P (new_rtx))
        {
          x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
                                        new_rtx, GET_MODE (XEXP (x, 0)));
@@ -2641,9 +2646,7 @@ tablejump_p (const_rtx insn, rtx *labelp, rtx *tablep)
   if (JUMP_P (insn)
       && (label = JUMP_LABEL (insn)) != NULL_RTX
       && (table = next_active_insn (label)) != NULL_RTX
-      && JUMP_P (table)
-      && (GET_CODE (PATTERN (table)) == ADDR_VEC
-         || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
+      && JUMP_TABLE_DATA_P (table))
     {
       if (labelp)
        *labelp = label;
@@ -2774,11 +2777,11 @@ for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
          else if (result != 0)
            /* Stop the traversal.  */
            return result;
-       
+
          if (*x == NULL_RTX)
            /* There are no sub-expressions.  */
            continue;
-       
+
          i = non_rtx_starting_operands[GET_CODE (*x)];
          if (i >= 0)
            {
@@ -2803,11 +2806,11 @@ for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
              else if (result != 0)
                /* Stop the traversal.  */
                return result;
-       
+
              if (*x == NULL_RTX)
                /* There are no sub-expressions.  */
                continue;
-       
+
              i = non_rtx_starting_operands[GET_CODE (*x)];
              if (i >= 0)
                {
@@ -2907,7 +2910,7 @@ int
 commutative_operand_precedence (rtx op)
 {
   enum rtx_code code = GET_CODE (op);
-  
+
   /* Constants always come the second operand.  Prefer "nice" constants.  */
   if (code == CONST_INT)
     return -8;
@@ -2954,7 +2957,7 @@ commutative_operand_precedence (rtx op)
          operand.  In particular,  (plus (minus (reg) (reg)) (neg (reg)))
          is canonical, although it will usually be further simplified.  */
       return 2;
-  
+
     case RTX_UNARY:
       /* Then prefer NEG and NOT.  */
       if (code == NEG || code == NOT)
@@ -3123,10 +3126,10 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
         picking a different register class, or doing it in memory if
         necessary.)  An example of a value with holes is XCmode on 32-bit
         x86 with -m128bit-long-double; it's represented in 6 32-bit registers,
-        3 for each part, but in memory it's two 128-bit parts.  
+        3 for each part, but in memory it's two 128-bit parts.
         Padding is assumed to be at the end (not necessarily the 'high part')
         of each unit.  */
-      if ((offset / GET_MODE_SIZE (xmode_unit) + 1 
+      if ((offset / GET_MODE_SIZE (xmode_unit) + 1
           < GET_MODE_NUNITS (xmode))
          && (offset / GET_MODE_SIZE (xmode_unit)
              != ((offset + GET_MODE_SIZE (ymode) - 1)
@@ -3138,7 +3141,7 @@ subreg_get_info (unsigned int xregno, enum machine_mode xmode,
     }
   else
     nregs_xmode = hard_regno_nregs[xregno][xmode];
-  
+
   nregs_ymode = hard_regno_nregs[xregno][ymode];
 
   /* Paradoxical subregs are otherwise valid.  */
@@ -3470,7 +3473,7 @@ keep_with_call_p (const_rtx insn)
          && general_operand (SET_SRC (set), VOIDmode))
        return true;
       if (REG_P (SET_SRC (set))
-         && FUNCTION_VALUE_REGNO_P (REGNO (SET_SRC (set)))
+         && targetm.calls.function_value_regno_p (REGNO (SET_SRC (set)))
          && REG_P (SET_DEST (set))
          && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
        return true;
@@ -3524,7 +3527,7 @@ label_is_jump_target_p (const_rtx label, const_rtx jump_insn)
 /* Return an estimate of the cost of computing rtx X.
    One use is in cse, to decide which expression to keep in the hash table.
    Another is in rtl generation, to pick the cheapest way to multiply.
-   Other uses like the latter are expected in the future. 
+   Other uses like the latter are expected in the future.
 
    SPEED parameter specify whether costs optimized for speed or size should
    be returned.  */
@@ -3598,19 +3601,19 @@ rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED, bool speed)
 }
 \f
 /* Return cost of address expression X.
-   Expect that X is properly formed address reference.  
+   Expect that X is properly formed address reference.
 
    SPEED parameter specify whether costs optimized for speed or size should
    be returned.  */
 
 int
-address_cost (rtx x, enum machine_mode mode, bool speed)
+address_cost (rtx x, enum machine_mode mode, addr_space_t as, bool speed)
 {
   /* We may be asked for cost of various unusual addresses, such as operands
      of push instruction.  It is not worthwhile to complicate writing
      of the target hook by such cases.  */
 
-  if (!memory_address_p (mode, x))
+  if (!memory_address_addr_space_p (mode, x, as))
     return 1000;
 
   return targetm.address_cost (x, speed);
@@ -3749,7 +3752,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* If pointers extend unsigned and this is a pointer in Pmode, say that
         all the bits above ptr_mode are known to be zero.  */
-      if (POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
          && REG_POINTER (x))
        nonzero &= GET_MODE_MASK (ptr_mode);
 #endif
@@ -3821,8 +3828,8 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       /* If this produces an integer result, we know which bits are set.
         Code here used to clear bits outside the mode of X, but that is
         now done above.  */
-      /* Mind that MODE is the mode the caller wants to look at this 
-        operation in, and not the actual operation mode.  We can wind 
+      /* Mind that MODE is the mode the caller wants to look at this
+        operation in, and not the actual operation mode.  We can wind
         up with (subreg:DI (gt:V4HI x y)), and we don't have anything
         that describes the results of a vector compare.  */
       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
@@ -3986,7 +3993,11 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
        /* If pointers extend unsigned and this is an addition or subtraction
           to a pointer in Pmode, all the bits above ptr_mode are known to be
           zero.  */
-       if (POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
+       /* As we do not know which address space the pointer is refering to,
+          we can do this only if the target does not support different pointer
+          or address modes depending on the address space.  */
+       if (target_default_pointer_address_modes_p ()
+           && POINTERS_EXTEND_UNSIGNED > 0 && GET_MODE (x) == Pmode
            && (code == PLUS || code == MINUS)
            && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
          nonzero &= GET_MODE_MASK (ptr_mode);
@@ -3995,7 +4006,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       break;
 
     case ZERO_EXTRACT:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
        nonzero &= ((HOST_WIDE_INT) 1 << INTVAL (XEXP (x, 1))) - 1;
       break;
@@ -4053,7 +4064,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
         the shift when shifted the appropriate number of bits.  This
         shows that high-order bits are cleared by the right shift and
         low-order bits by left shifts.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) >= 0
          && INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT
          && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (GET_MODE (x)))
@@ -4260,8 +4271,12 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
 #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
       /* If pointers extend signed and this is a pointer in Pmode, say that
         all the bits above ptr_mode are known to be sign bit copies.  */
-      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode && mode == Pmode
-         && REG_POINTER (x))
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+         && mode == Pmode && REG_POINTER (x))
        return GET_MODE_BITSIZE (Pmode) - GET_MODE_BITSIZE (ptr_mode) + 1;
 #endif
 
@@ -4348,7 +4363,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       break;
 
     case SIGN_EXTRACT:
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+      if (CONST_INT_P (XEXP (x, 1)))
        return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
       break;
 
@@ -4372,7 +4387,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       /* If we are rotating left by a number of bits less than the number
         of sign bit copies, we can just subtract that amount from the
         number.  */
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) >= 0
          && INTVAL (XEXP (x, 1)) < (int) bitwidth)
        {
@@ -4418,7 +4433,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       if (code == AND
          && num1 > 1
          && bitwidth <= HOST_BITS_PER_WIDE_INT
-         && GET_CODE (XEXP (x, 1)) == CONST_INT
+         && CONST_INT_P (XEXP (x, 1))
          && !(INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
        return num1;
 
@@ -4426,7 +4441,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       if (code == IOR
          && num1 > 1
          && bitwidth <= HOST_BITS_PER_WIDE_INT
-         && GET_CODE (XEXP (x, 1)) == CONST_INT
+         && CONST_INT_P (XEXP (x, 1))
          && (INTVAL (XEXP (x, 1)) & ((HOST_WIDE_INT) 1 << (bitwidth - 1))))
        return num1;
 
@@ -4457,7 +4472,11 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
       /* If pointers extend signed and this is an addition or subtraction
         to a pointer in Pmode, all the bits above ptr_mode are known to be
         sign bit copies.  */
-      if (! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
+      /* As we do not know which address space the pointer is refering to,
+        we can do this only if the target does not support different pointer
+        or address modes depending on the address space.  */
+      if (target_default_pointer_address_modes_p ()
+         && ! POINTERS_EXTEND_UNSIGNED && GET_MODE (x) == Pmode
          && (code == PLUS || code == MINUS)
          && REG_P (XEXP (x, 0)) && REG_POINTER (XEXP (x, 0)))
        result = MAX ((int) (GET_MODE_BITSIZE (Pmode)
@@ -4502,8 +4521,16 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
                                           known_x, known_mode, known_ret);
 
     case UMOD:
-      /* The result must be <= the second operand.  */
-      return cached_num_sign_bit_copies (XEXP (x, 1), mode,
+      /* The result must be <= the second operand.  If the second operand
+        has (or just might have) the high bit set, we know nothing about
+        the number of sign bit copies.  */
+      if (bitwidth > HOST_BITS_PER_WIDE_INT)
+       return 1;
+      else if ((nonzero_bits (XEXP (x, 1), mode)
+               & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
+       return 1;
+      else
+       return cached_num_sign_bit_copies (XEXP (x, 1), mode,
                                           known_x, known_mode, known_ret);
 
     case DIV:
@@ -4536,7 +4563,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
         sign bit.  */
       num0 = cached_num_sign_bit_copies (XEXP (x, 0), mode,
                                         known_x, known_mode, known_ret);
-      if (GET_CODE (XEXP (x, 1)) == CONST_INT
+      if (CONST_INT_P (XEXP (x, 1))
          && INTVAL (XEXP (x, 1)) > 0
          && INTVAL (XEXP (x, 1)) < GET_MODE_BITSIZE (GET_MODE (x)))
        num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
@@ -4545,7 +4572,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
 
     case ASHIFT:
       /* Left shifts destroy copies.  */
-      if (GET_CODE (XEXP (x, 1)) != CONST_INT
+      if (!CONST_INT_P (XEXP (x, 1))
          || INTVAL (XEXP (x, 1)) < 0
          || INTVAL (XEXP (x, 1)) >= (int) bitwidth
          || INTVAL (XEXP (x, 1)) >= GET_MODE_BITSIZE (GET_MODE (x)))
@@ -4650,7 +4677,7 @@ insn_rtx_cost (rtx pat, bool speed)
 
    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 
+   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
@@ -4727,7 +4754,11 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
         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
+      do
+       prev = prev_nonnote_insn (prev);
+      while (prev && DEBUG_INSN_P (prev));
+
+      if (prev == 0
          || !NONJUMP_INSN_P (prev)
          || FIND_REG_INC_NOTE (prev, NULL_RTX)
          /* In cfglayout mode, there do not have to be labels at the
@@ -4857,7 +4888,7 @@ canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
      overflow.  */
 
   if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
-      && GET_CODE (op1) == CONST_INT
+      && CONST_INT_P (op1)
       && GET_MODE (op0) != VOIDmode
       && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
     {
@@ -5034,3 +5065,20 @@ constant_pool_constant_p (rtx x)
   x = avoid_constant_pool_reference (x);
   return GET_CODE (x) == CONST_DOUBLE;
 }
+\f
+/* If M is a bitmask that selects a field of low-order bits within an item but
+   not the entire word, return the length of the field.  Return -1 otherwise.
+   M is used in machine mode MODE.  */
+
+int
+low_bitmask_len (enum machine_mode mode, unsigned HOST_WIDE_INT m)
+{
+  if (mode != VOIDmode)
+    {
+      if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
+       return -1;
+      m &= GET_MODE_MASK (mode);
+    }
+
+  return exact_log2 (m + 1);
+}