aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-10-30 12:18:34 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-10-30 12:18:34 +0000
commit7524f419ae7935594e7ec85daf7cdf736a835b04 (patch)
tree3269624dbefe5c8fadf56f8111a9ab750dc67096
parent04e3481107705d98ecd442657ee0b6b594e53b78 (diff)
downloadgcc-7524f419ae7935594e7ec85daf7cdf736a835b04.zip
gcc-7524f419ae7935594e7ec85daf7cdf736a835b04.tar.gz
gcc-7524f419ae7935594e7ec85daf7cdf736a835b04.tar.bz2
gimple-fold.c (fold_gimple_assign): Do not dispatch to fold () on single RHSs.
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/fold-const.c25
-rw-r--r--gcc/gimple-fold.c37
-rw-r--r--gcc/tree.c12
4 files changed, 38 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f1aea78..4e0d45d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 47ed609..7c5b75a 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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:
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 9760b8a..13a6219 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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;
diff --git a/gcc/tree.c b/gcc/tree.c
index 3570902..9228a6a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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);
}