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
This commit is contained in:
Richard Biener 2015-10-30 12:18:34 +00:00 committed by Richard Biener
parent 04e3481107
commit 7524f419ae
4 changed files with 38 additions and 44 deletions

View 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

View 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;
unsigned i;
tree val;
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
if (! CONSTANT_CLASS_P (val))
return t;
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));
return build_vector (type, vec);
return build_vector_from_ctor (type, CONSTRUCTOR_ELTS (t));
}
case CONST_DECL:

View 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;

View 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);
}