* emit-rtl.c (paradoxical_subreg_p): New function.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jul 2011 23:11:51 +0000 (23:11 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Jul 2011 23:11:51 +0000 (23:11 +0000)
* rtl.h (paradoxical_subreg_p): Declare.
* combine.c (set_nonzero_bits_and_sign_copies, get_last_value,
apply_distributive_law, simplify_comparison, simplify_set): Use it.
* cse.c (record_jump_cond, cse_insn): Likewise.
* expr.c (force_operand): Likewise.
* rtlanal.c (num_sign_bit_copies1): Likewise.
* reload1.c (eliminate_regs_1, strip_paradoxical_subreg): Likewise.
* reload.c (push_secondary_reload, find_reloads_toplev): Likewise.
(push_reload): Use precision to check for paradoxical subregs.
* expmed.c (extract_bit_field_1): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175944 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine.c
gcc/cse.c
gcc/emit-rtl.c
gcc/expmed.c
gcc/expr.c
gcc/reload.c
gcc/reload1.c
gcc/rtl.h
gcc/rtlanal.c

index c9bcc57..9268318 100644 (file)
@@ -1,3 +1,17 @@
+2011-07-07  Bernd Schmidt  <bernds@codesourcery.com>
+
+       * emit-rtl.c (paradoxical_subreg_p): New function.
+       * rtl.h (paradoxical_subreg_p): Declare.
+       * combine.c (set_nonzero_bits_and_sign_copies, get_last_value,
+       apply_distributive_law, simplify_comparison, simplify_set): Use it.
+       * cse.c (record_jump_cond, cse_insn): Likewise.
+       * expr.c (force_operand): Likewise.
+       * rtlanal.c (num_sign_bit_copies1): Likewise.
+       * reload1.c (eliminate_regs_1, strip_paradoxical_subreg): Likewise.
+       * reload.c (push_secondary_reload, find_reloads_toplev): Likewise.
+       (push_reload): Use precision to check for paradoxical subregs.
+       * expmed.c (extract_bit_field_1): Likewise.
+
 2011-07-06  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        * config/rs6000/rs6000-protos.h (rs6000_call_indirect_aix): New
index 9edfdd1..afc56b1 100644 (file)
@@ -1610,9 +1610,7 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
         set what we know about X.  */
 
       if (SET_DEST (set) == x
-         || (GET_CODE (SET_DEST (set)) == SUBREG
-             && (GET_MODE_SIZE (GET_MODE (SET_DEST (set)))
-                 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (set)))))
+         || (paradoxical_subreg_p (SET_DEST (set))
              && SUBREG_REG (SET_DEST (set)) == x))
        {
          rtx src = SET_SRC (set);
@@ -6564,8 +6562,7 @@ simplify_set (rtx x)
       && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (src)))
       && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (src))) != UNKNOWN
       && SUBREG_BYTE (src) == 0
-      && (GET_MODE_SIZE (GET_MODE (src))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
+      && paradoxical_subreg_p (src)
       && MEM_P (SUBREG_REG (src)))
     {
       SUBST (SET_SRC (x),
@@ -9260,8 +9257,7 @@ apply_distributive_law (rtx x)
          || ! subreg_lowpart_p (lhs)
          || (GET_MODE_CLASS (GET_MODE (lhs))
              != GET_MODE_CLASS (GET_MODE (SUBREG_REG (lhs))))
-         || (GET_MODE_SIZE (GET_MODE (lhs))
-             > GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))))
+         || paradoxical_subreg_p (lhs)
          || VECTOR_MODE_P (GET_MODE (lhs))
          || GET_MODE_SIZE (GET_MODE (SUBREG_REG (lhs))) > UNITS_PER_WORD
          /* Result might need to be truncated.  Don't change mode if
@@ -11139,9 +11135,8 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
          HOST_WIDE_INT c1 = INTVAL (XEXP (op1, 1));
          int changed = 0;
 
-         if (GET_CODE (inner_op0) == SUBREG && GET_CODE (inner_op1) == SUBREG
-             && (GET_MODE_SIZE (GET_MODE (inner_op0))
-                 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (inner_op0))))
+         if (paradoxical_subreg_p (inner_op0)
+             && GET_CODE (inner_op1) == SUBREG
              && (GET_MODE (SUBREG_REG (inner_op0))
                  == GET_MODE (SUBREG_REG (inner_op1)))
              && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (inner_op0)))
@@ -11984,8 +11979,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
       && (code == NE || code == EQ))
     {
-      if (GET_MODE_SIZE (GET_MODE (op0))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
+      if (paradoxical_subreg_p (op0))
        {
          /* For paradoxical subregs, allow case 1 as above.  Case 3 isn't
             implemented.  */
@@ -12721,8 +12715,7 @@ get_last_value (const_rtx x)
      we cannot predict what values the "extra" bits might have.  */
   if (GET_CODE (x) == SUBREG
       && subreg_lowpart_p (x)
-      && (GET_MODE_SIZE (GET_MODE (x))
-         <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+      && !paradoxical_subreg_p (x)
       && (value = get_last_value (SUBREG_REG (x))) != 0)
     return gen_lowpart (GET_MODE (x), value);
 
index c75fd7b..da4b1e1 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -3959,9 +3959,7 @@ record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
      is not worth testing for with no SUBREG).  */
 
   /* Note that GET_MODE (op0) may not equal MODE.  */
-  if (code == EQ && GET_CODE (op0) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (op0))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
+  if (code == EQ && paradoxical_subreg_p (op0))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
       rtx tem = record_jump_cond_subreg (inner_mode, op1);
@@ -3970,9 +3968,7 @@ record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
                          reversed_nonequality);
     }
 
-  if (code == EQ && GET_CODE (op1) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (op1))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
+  if (code == EQ && paradoxical_subreg_p (op1))
     {
       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
       rtx tem = record_jump_cond_subreg (inner_mode, op0);
@@ -4556,9 +4552,7 @@ cse_insn (rtx insn)
         treat it as volatile.  It may do the work of an SI in one context
         where the extra bits are not being used, but cannot replace an SI
         in general.  */
-      if (GET_CODE (src) == SUBREG
-         && (GET_MODE_SIZE (GET_MODE (src))
-             > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
+      if (paradoxical_subreg_p (src))
        sets[i].src_volatile = 1;
 #endif
 
@@ -4836,9 +4830,7 @@ cse_insn (rtx insn)
 
          /* Also skip paradoxical subregs, unless that's what we're
             looking for.  */
-         if (code == SUBREG
-             && (GET_MODE_SIZE (GET_MODE (p->exp))
-                 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (p->exp))))
+         if (paradoxical_subreg_p (p->exp)
              && ! (src != 0
                    && GET_CODE (src) == SUBREG
                    && GET_MODE (src) == GET_MODE (p->exp)
@@ -4947,9 +4939,7 @@ cse_insn (rtx insn)
             size, but later may be adjusted so that the upper bits aren't
             what we want.  So reject it.  */
          if (elt != 0
-             && GET_CODE (elt->exp) == SUBREG
-             && (GET_MODE_SIZE (GET_MODE (elt->exp))
-                 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (elt->exp))))
+             && paradoxical_subreg_p (elt->exp)
              /* It is okay, though, if the rtx we're trying to match
                 will ignore any of the bits we can't predict.  */
              && ! (src != 0
@@ -5710,9 +5700,7 @@ cse_insn (rtx insn)
               some tracking to be wrong.
 
               ??? Think about this more later.  */
-           || (GET_CODE (dest) == SUBREG
-               && (GET_MODE_SIZE (GET_MODE (dest))
-                   > GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
+           || (paradoxical_subreg_p (dest)
                && (GET_CODE (sets[i].src) == SIGN_EXTEND
                    || GET_CODE (sets[i].src) == ZERO_EXTEND)))
          continue;
index f010ac6..c641b7e 100644 (file)
@@ -1334,6 +1334,16 @@ subreg_lowpart_p (const_rtx x)
   return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
          == SUBREG_BYTE (x));
 }
+
+/* Return true if X is a paradoxical subreg, false otherwise.  */
+bool
+paradoxical_subreg_p (const_rtx x)
+{
+  if (GET_CODE (x) != SUBREG)
+    return false;
+  return (GET_MODE_PRECISION (GET_MODE (x))
+         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (x))));
+}
 \f
 /* Return subword OFFSET of operand OP.
    The word number, OFFSET, is interpreted as the word number starting
index 567f98d..8349b6f 100644 (file)
@@ -1476,8 +1476,8 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
              && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (xtarget), ext_mode))
            {
              xtarget = gen_lowpart (ext_mode, xtarget);
-             if (GET_MODE_SIZE (ext_mode)
-                 > GET_MODE_SIZE (GET_MODE (xspec_target)))
+             if (GET_MODE_PRECISION (ext_mode)
+                 > GET_MODE_PRECISION (GET_MODE (xspec_target)))
                xspec_target_subreg = xtarget;
            }
          else
index fd431c2..af4c2fb 100644 (file)
@@ -6497,9 +6497,7 @@ force_operand (rtx value, rtx target)
 #ifdef INSN_SCHEDULING
   /* On machines that have insn scheduling, we want all memory reference to be
      explicit, so we need to deal with such paradoxical SUBREGs.  */
-  if (GET_CODE (value) == SUBREG && MEM_P (SUBREG_REG (value))
-      && (GET_MODE_SIZE (GET_MODE (value))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (value)))))
+  if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
     value
       = simplify_gen_subreg (GET_MODE (value),
                             force_reg (GET_MODE (SUBREG_REG (value)),
index 2e9a891..605f23d 100644 (file)
@@ -347,9 +347,7 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional,
 
   /* If X is a paradoxical SUBREG, use the inner value to determine both the
      mode and object being reloaded.  */
-  if (GET_CODE (x) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (x))
-         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
+  if (paradoxical_subreg_p (x))
     {
       x = SUBREG_REG (x);
       reload_mode = GET_MODE (x);
@@ -1026,20 +1024,20 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          || (((REG_P (SUBREG_REG (in))
                && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (in)))
-             && ((GET_MODE_SIZE (inmode)
-                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+             && ((GET_MODE_PRECISION (inmode)
+                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
 #ifdef LOAD_EXTEND_OP
                  || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
                      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
                          <= UNITS_PER_WORD)
-                     && (GET_MODE_SIZE (inmode)
-                         > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+                     && (GET_MODE_PRECISION (inmode)
+                         > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
                      && INTEGRAL_MODE_P (GET_MODE (SUBREG_REG (in)))
                      && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (in))) != UNKNOWN)
 #endif
 #ifdef WORD_REGISTER_OPERATIONS
-                 || ((GET_MODE_SIZE (inmode)
-                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
+                 || ((GET_MODE_PRECISION (inmode)
+                      < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (in))))
                      && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
                           / UNITS_PER_WORD)))
@@ -1134,11 +1132,11 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          || (((REG_P (SUBREG_REG (out))
                && REGNO (SUBREG_REG (out)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (out)))
-             && ((GET_MODE_SIZE (outmode)
-                  > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+             && ((GET_MODE_PRECISION (outmode)
+                  > GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
 #ifdef WORD_REGISTER_OPERATIONS
-                 || ((GET_MODE_SIZE (outmode)
-                      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
+                 || ((GET_MODE_PRECISION (outmode)
+                      < GET_MODE_PRECISION (GET_MODE (SUBREG_REG (out))))
                      && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
                          ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
                           / UNITS_PER_WORD)))
@@ -4752,16 +4750,15 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
 
       if (regno >= FIRST_PSEUDO_REGISTER
 #ifdef LOAD_EXTEND_OP
-              && (GET_MODE_SIZE (GET_MODE (x))
-                  <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && !paradoxical_subreg_p (x)
 #endif
-              && (reg_equiv_address (regno) != 0
-                  || (reg_equiv_mem (regno) != 0
-                      && (! strict_memory_address_addr_space_p
-                              (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
-                               MEM_ADDR_SPACE (reg_equiv_mem (regno)))
-                          || ! offsettable_memref_p (reg_equiv_mem (regno))
-                          || num_not_at_initial_offset))))
+         && (reg_equiv_address (regno) != 0
+             || (reg_equiv_mem (regno) != 0
+                 && (! strict_memory_address_addr_space_p
+                     (GET_MODE (x), XEXP (reg_equiv_mem (regno), 0),
+                      MEM_ADDR_SPACE (reg_equiv_mem (regno)))
+                     || ! offsettable_memref_p (reg_equiv_mem (regno))
+                     || num_not_at_initial_offset))))
        x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
                                           insn, address_reloaded);
     }
index a9aa017..7f84fc8 100644 (file)
@@ -2840,8 +2840,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
         eliminated version of the memory location because push_reload
         may do the replacement in certain circumstances.  */
       if (REG_P (SUBREG_REG (x))
-         && (GET_MODE_SIZE (GET_MODE (x))
-             <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+         && !paradoxical_subreg_p (x)
          && reg_equivs
          && reg_equiv_memory_loc (REGNO (SUBREG_REG (x))) != 0)
        {
@@ -4495,12 +4494,9 @@ strip_paradoxical_subreg (rtx *op_ptr, rtx *other_ptr)
   rtx op, inner, other, tem;
 
   op = *op_ptr;
-  if (GET_CODE (op) != SUBREG)
+  if (!paradoxical_subreg_p (op))
     return false;
-
   inner = SUBREG_REG (op);
-  if (GET_MODE_SIZE (GET_MODE (op)) <= GET_MODE_SIZE (GET_MODE (inner)))
-    return false;
 
   other = *other_ptr;
   tem = gen_lowpart_common (GET_MODE (inner), other);
index 2f2aaca..ac3c871 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1633,6 +1633,7 @@ extern rtx operand_subword (rtx, unsigned int, int, enum machine_mode);
 
 /* In emit-rtl.c */
 extern rtx operand_subword_force (rtx, unsigned int, enum machine_mode);
+extern bool paradoxical_subreg_p (const_rtx);
 extern int subreg_lowpart_p (const_rtx);
 extern unsigned int subreg_lowpart_offset (enum machine_mode,
                                           enum machine_mode);
index 9ac347e..2dfbd8f 100644 (file)
@@ -4483,8 +4483,7 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
         then we lose all sign bit copies that existed before the store
         to the stack.  */
 
-      if ((GET_MODE_SIZE (GET_MODE (x))
-          > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
+      if (paradoxical_subreg_p (x)
          && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
          && MEM_P (SUBREG_REG (x)))
        return cached_num_sign_bit_copies (SUBREG_REG (x), mode,