Commit e9d6bd8c by Marc Glisse Committed by Marc Glisse

re PR middle-end/55266 (vector expansion: 24 movs for 4 adds)

2012-11-28  Marc Glisse  <marc.glisse@inria.fr>

	PR middle-end/55266
	* fold-const.c (fold_ternary_loc) [BIT_FIELD_REF]: Handle
	CONSTRUCTOR with vector elements.
	* tree-ssa-propagate.c (valid_gimple_rhs_p): Handle CONSTRUCTOR
	and BIT_FIELD_REF.

From-SVN: r193884
parent 2c3e2ce2
2012-11-28 Marc Glisse <marc.glisse@inria.fr>
PR middle-end/55266
* fold-const.c (fold_ternary_loc) [BIT_FIELD_REF]: Handle
CONSTRUCTOR with vector elements.
* tree-ssa-propagate.c (valid_gimple_rhs_p): Handle CONSTRUCTOR
and BIT_FIELD_REF.
2012-11-28 Richard Biener <rguenther@suse.de> 2012-11-28 Richard Biener <rguenther@suse.de>
PR c/35634 PR c/35634
...@@ -14081,29 +14081,44 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -14081,29 +14081,44 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
{ {
idx = idx / width; idx = idx / width;
n = n / width; n = n / width;
if (TREE_CODE (type) == VECTOR_TYPE)
{
if (TREE_CODE (arg0) == VECTOR_CST) if (TREE_CODE (arg0) == VECTOR_CST)
{ {
if (n == 1)
return VECTOR_CST_ELT (arg0, idx);
tree *vals = XALLOCAVEC (tree, n); tree *vals = XALLOCAVEC (tree, n);
unsigned i; for (unsigned i = 0; i < n; ++i)
for (i = 0; i < n; ++i)
vals[i] = VECTOR_CST_ELT (arg0, idx + i); vals[i] = VECTOR_CST_ELT (arg0, idx + i);
return build_vector (type, vals); return build_vector (type, vals);
} }
else
/* Constructor elements can be subvectors. */
unsigned HOST_WIDE_INT k = 1;
if (CONSTRUCTOR_NELTS (arg0) != 0)
{
tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (arg0, 0)->value);
if (TREE_CODE (cons_elem) == VECTOR_TYPE)
k = TYPE_VECTOR_SUBPARTS (cons_elem);
}
/* We keep an exact subset of the constructor elements. */
if ((idx % k) == 0 && (n % k) == 0)
{ {
vec<constructor_elt, va_gc> *vals;
unsigned i;
if (CONSTRUCTOR_NELTS (arg0) == 0) if (CONSTRUCTOR_NELTS (arg0) == 0)
return build_constructor (type, return build_constructor (type, NULL);
NULL); idx /= k;
if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0, n /= k;
0)->value)) if (n == 1)
!= VECTOR_TYPE)
{ {
if (idx < CONSTRUCTOR_NELTS (arg0))
return CONSTRUCTOR_ELT (arg0, idx)->value;
return build_zero_cst (type);
}
vec<constructor_elt, va_gc> *vals;
vec_alloc (vals, n); vec_alloc (vals, n);
for (i = 0; for (unsigned i = 0;
i < n && idx + i < CONSTRUCTOR_NELTS (arg0); i < n && idx + i < CONSTRUCTOR_NELTS (arg0);
++i) ++i)
CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE, CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
...@@ -14111,22 +14126,17 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type, ...@@ -14111,22 +14126,17 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
(arg0, idx + i)->value); (arg0, idx + i)->value);
return build_constructor (type, vals); return build_constructor (type, vals);
} }
} /* The bitfield references a single constructor element. */
} else if (idx + n <= (idx / k + 1) * k)
else if (n == 1)
{
if (TREE_CODE (arg0) == VECTOR_CST)
return VECTOR_CST_ELT (arg0, idx);
else if (CONSTRUCTOR_NELTS (arg0) == 0)
return build_zero_cst (type);
else if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0,
0)->value))
!= VECTOR_TYPE)
{ {
if (idx < CONSTRUCTOR_NELTS (arg0)) if (CONSTRUCTOR_NELTS (arg0) <= idx / k)
return CONSTRUCTOR_ELT (arg0, idx)->value;
return build_zero_cst (type); return build_zero_cst (type);
} else if (n == k)
return CONSTRUCTOR_ELT (arg0, idx / k)->value;
else
return fold_build3_loc (loc, code, type,
CONSTRUCTOR_ELT (arg0, idx / k)->value, op1,
build_int_cst (TREE_TYPE (op2), (idx % k) * width));
} }
} }
} }
......
...@@ -611,10 +611,24 @@ valid_gimple_rhs_p (tree expr) ...@@ -611,10 +611,24 @@ valid_gimple_rhs_p (tree expr)
return false; return false;
case tcc_exceptional: case tcc_exceptional:
if (code == CONSTRUCTOR)
{
unsigned i;
tree elt;
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)
if (!is_gimple_val (elt))
return false;
return true;
}
if (code != SSA_NAME) if (code != SSA_NAME)
return false; return false;
break; break;
case tcc_reference:
if (code == BIT_FIELD_REF)
return is_gimple_val (TREE_OPERAND (expr, 0));
return false;
default: default:
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment