emit-rtl.c (paradoxical_subreg_p): New function.
authorBernd Schmidt <bernds@codesourcery.com>
Wed, 6 Jul 2011 23:11:51 +0000 (23:11 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Wed, 6 Jul 2011 23:11:51 +0000 (23:11 +0000)
* 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.

From-SVN: r175944

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 c9bcc574ec8cd0b9cc278d56b660f05e217c0688..92683184a13827aa0c479c22445dd2bf421313b8 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 9edfdd18b1cc5e29ef8d4cf0c7b78d4e0953fafc..afc56b1d847388cbd6cd721fa2d1958dcddd5d49 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 c75fd7b81abdfb155941a1bca6ad67bc746b038a..da4b1e1ee4712bb27ba568edbca797d2c213d9c6 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 f010ac6f5abcf0f69e34b0d5783f1404ef7acee8..c641b7e6ca220b543bf6baf6d910871c29a8d6f0 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 567f98d4da858b12c72d7350eedfc061bdcf9047..8349b6fb87e9d3e4d69eefe3473dd0ef12af5552 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 fd431c2001134c5364f43bcfbc03beb80a09aaba..af4c2fb8826ed6bca478d97bd3448822ef0690ce 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 2e9a8910e8b72a97dfd3d378ab1d10f26c390a59..605f23d596269ac2bc91f3e7489a1fb42c2a90f3 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 a9aa01723eee60447efb5fca6de678c290b88dd5..7f84fc81416a033ea9c50b92c306b12fd5ad2d8a 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 2f2aaca7b426d21ac8687d0518eccb20faaaa1f6..ac3c87112c79efb5b5247ba67379d70f03089a8e 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 9ac347ed0fa5b6768e84a592c5bc7fb2917bbf5c..2dfbd8fe11435b2015a92c9ca50e9fe6b19a492e 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,