gimple-fold.c (fold_gimple_assign): Do not dispatch to fold () on single RHSs.
authorRichard Biener <rguenther@suse.de>
Fri, 30 Oct 2015 12:18:34 +0000 (12:18 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 30 Oct 2015 12:18:34 +0000 (12:18 +0000)
2015-10-30  Richard Biener  <rguenther@suse.de>

* gimple-fold.c (fold_gimple_assign): Do not dispatch to
fold () on single RHSs.  Allow CONSTRUCTORS with trailing
zeros to be folded to VECTOR_CSTs.
* tree.c (build_vector_from_ctor): Handle VECTOR_CST elements.
* fold-const.c (fold): Use build_vector_from_ctor.

From-SVN: r229574

gcc/ChangeLog
gcc/fold-const.c
gcc/gimple-fold.c
gcc/tree.c

index f1aea782221b64c0beae3e5a2a21ad7aff340c55..4e0d45d9c97af9af4a4c33a3454dd25318ebff6c 100644 (file)
@@ -1,3 +1,11 @@
+2015-10-30  Richard Biener  <rguenther@suse.de>
+
+       * gimple-fold.c (fold_gimple_assign): Do not dispatch to
+       fold () on single RHSs.  Allow CONSTRUCTORS with trailing
+       zeros to be folded to VECTOR_CSTs.
+       * tree.c (build_vector_from_ctor): Handle VECTOR_CST elements.
+       * fold-const.c (fold): Use build_vector_from_ctor.
+
 2015-10-30  Evandro Menezes  <e.menezes@samsung.com>
 
        * config/aarch64/aarch64.md (*movhf_aarch64): Change the type of
index 47ed60923f87568fcbd4e2f17f294452e1ce1e5a..7c5b75a2684e2535aa38ab7e59640409c23b373e 100644 (file)
@@ -11968,26 +11968,13 @@ fold (tree expr)
        if (TREE_CODE (type) != VECTOR_TYPE)
          return t;
 
-       tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
-       unsigned HOST_WIDE_INT idx, pos = 0;
-       tree value;
-
-       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, value)
-         {
-           if (!CONSTANT_CLASS_P (value))
-             return t;
-           if (TREE_CODE (value) == VECTOR_CST)
-             {
-               for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i)
-                 vec[pos++] = VECTOR_CST_ELT (value, i);
-             }
-           else
-             vec[pos++] = value;
-         }
-       for (; pos < TYPE_VECTOR_SUBPARTS (type); ++pos)
-         vec[pos] = build_zero_cst (TREE_TYPE (type));
+       unsigned i;
+       tree val;
+       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
+         if (! CONSTANT_CLASS_P (val))
+           return t;
 
-       return build_vector (type, vec);
+       return build_vector_from_ctor (type, CONSTRUCTOR_ELTS (t));
       }
 
     case CONST_DECL:
index 9760b8a3ad2e59f869d12cbb418a11ca374a4eb6..13a6219bf9d075392aeb94d5c62b1ceaecbf328f 100644 (file)
@@ -354,8 +354,8 @@ fold_gimple_assign (gimple_stmt_iterator *si)
                    return val;
                  }
              }
-
          }
+
        else if (TREE_CODE (rhs) == ADDR_EXPR)
          {
            tree ref = TREE_OPERAND (rhs, 0);
@@ -370,21 +370,29 @@ fold_gimple_assign (gimple_stmt_iterator *si)
            else if (TREE_CODE (ref) == MEM_REF
                     && integer_zerop (TREE_OPERAND (ref, 1)))
              result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0));
+
+           if (result)
+             {
+               /* Strip away useless type conversions.  Both the
+                  NON_LVALUE_EXPR that may have been added by fold, and
+                  "useless" type conversions that might now be apparent
+                  due to propagation.  */
+               STRIP_USELESS_TYPE_CONVERSION (result);
+
+               if (result != rhs && valid_gimple_rhs_p (result))
+                 return result;
+             }
          }
 
        else if (TREE_CODE (rhs) == CONSTRUCTOR
-                && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE
-                && (CONSTRUCTOR_NELTS (rhs)
-                    == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs))))
+                && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE)
          {
            /* Fold a constant vector CONSTRUCTOR to VECTOR_CST.  */
            unsigned i;
            tree val;
 
            FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
-             if (TREE_CODE (val) != INTEGER_CST
-                 && TREE_CODE (val) != REAL_CST
-                 && TREE_CODE (val) != FIXED_CST)
+             if (! CONSTANT_CLASS_P (val))
                return NULL_TREE;
 
            return build_vector_from_ctor (TREE_TYPE (rhs),
@@ -393,21 +401,6 @@ fold_gimple_assign (gimple_stmt_iterator *si)
 
        else if (DECL_P (rhs))
          return get_symbol_constant_value (rhs);
-
-        /* If we couldn't fold the RHS, hand over to the generic
-           fold routines.  */
-        if (result == NULL_TREE)
-          result = fold (rhs);
-
-        /* Strip away useless type conversions.  Both the NON_LVALUE_EXPR
-           that may have been added by fold, and "useless" type
-           conversions that might now be apparent due to propagation.  */
-        STRIP_USELESS_TYPE_CONVERSION (result);
-
-        if (result != rhs && valid_gimple_rhs_p (result))
-         return result;
-
-       return NULL_TREE;
       }
       break;
 
index 3570902855dcbcbdf1b166caf1dcc38a8160fe7c..9228a6abd54b394567da9fff58234d68907c09c5 100644 (file)
@@ -1729,13 +1729,19 @@ tree
 build_vector_from_ctor (tree type, vec<constructor_elt, va_gc> *v)
 {
   tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
-  unsigned HOST_WIDE_INT idx;
+  unsigned HOST_WIDE_INT idx, pos = 0;
   tree value;
 
   FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
-    vec[idx] = value;
+    {
+      if (TREE_CODE (value) == VECTOR_CST)
+       for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i)
+         vec[pos++] = VECTOR_CST_ELT (value, i);
+      else
+       vec[pos++] = value;
+    }
   for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx)
-    vec[idx] = build_zero_cst (TREE_TYPE (type));
+    vec[pos++] = build_zero_cst (TREE_TYPE (type));
 
   return build_vector (type, vec);
 }