passes.c (init_optimization_passes): Move veclower after SSA.

2010-11-04  Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
	Richard Guenther  <rguenther@suse.de>

	* passes.c (init_optimization_passes): Move veclower after SSA.
	* tree-vect-generic.c (uniform_vector_p): New function.
	(expand_vector_operations_1): Handle conversion.
	(pass_lower_vector): Update SSA form.

	testsuite/
	* gcc.dg/vec-scal-opt.c: New testcase.
	* gcc.dg/vec-scal-opt1.c: New testcase.
	* gcc.dg/vec-scal-opt2.c: New testcase.

From-SVN: r166303
This commit is contained in:
Artjoms Sinkarovs 2010-11-04 10:54:33 +00:00 committed by Richard Biener
parent d8ed14ce4e
commit 47853c7300
7 changed files with 169 additions and 17 deletions

View File

@ -1,3 +1,11 @@
2010-11-04 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Richard Guenther <rguenther@suse.de>
* passes.c (init_optimization_passes): Move veclower after SSA.
* tree-vect-generic.c (uniform_vector_p): New function.
(expand_vector_operations_1): Handle conversion.
(pass_lower_vector): Update SSA form.
2010-11-04 Iain Sandoe <iains@gcc.gnu.org>
* gcc/configure.ac: Filter -mdynamic-no-pic from CFLAGS when testing for

View File

@ -736,7 +736,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_refactor_eh);
NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_build_cgraph_edges);
NEXT_PASS (pass_inline_parameters);
@ -755,6 +754,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_referenced_vars);
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_early_warn_uninitialized);
/* Note that it is not strictly necessary to schedule an early
inline pass here. However, some test cases (e.g.,

View File

@ -1,7 +1,14 @@
2010-11-04 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Richard Guenther <rguenther@suse.de>
* gcc.dg/vec-scal-opt.c: New testcase.
* gcc.dg/vec-scal-opt1.c: New testcase.
* gcc.dg/vec-scal-opt2.c: New testcase.
2010-11-04 Iain Sandoe <iains@gcc.gnu.org>
* lib/plugin-support.exp (plugin-test-execute): Filter -mdynamic-no-pic from
plugin build flags on Darwin targets.
* lib/plugin-support.exp (plugin-test-execute): Filter -mdynamic-no-pic
from plugin build flags on Darwin targets.
2010-11-03 H.J. Lu <hongjiu.lu@intel.com>

View File

@ -0,0 +1,22 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-veclower" } */
#define vidx(type, vec, idx) (*((type *) &(vec) + idx))
#define vector(elcount, type) \
__attribute__((vector_size((elcount)*sizeof(type)))) type
short k;
int main (int argc, char *argv[]) {
k = argc;
vector(8, short) v0 = {argc,1,2,3,4,5,6,7};
vector(8, short) v2 = {k, k,k,k,k,k,k,k};
vector(8, short) r1;
r1 = v0 >> v2;
return vidx(short, r1, 0);
}
/* { dg-final { scan-tree-dump-times ">> k.\[0-9_\]*" 1 "veclower" } } */
/* { dg-final { cleanup-tree-dump "veclower" } } */

View File

@ -0,0 +1,20 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-veclower" } */
#define vidx(type, vec, idx) (*((type *) &(vec) + idx))
#define vector(elcount, type) \
__attribute__((vector_size((elcount)*sizeof(type)))) type
short k;
int main (int argc, char *argv[]) {
vector(8, short) v0 = {argc,1,2,3,4,5,6,7};
vector(8, short) r1;
r1 = v0 >> (vector(8, short)){2,2,2,2,2,2,2,2};
return vidx(short, r1, 0);
}
/* { dg-final { scan-tree-dump-times ">> 2" 1 "veclower" } } */
/* { dg-final { cleanup-tree-dump "veclower" } } */

View File

@ -0,0 +1,19 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-veclower" } */
#define vidx(type, vec, idx) (*((type *) &(vec) + idx))
#define vector(elcount, type) \
__attribute__((vector_size((elcount)*sizeof(type)))) type
int main (int argc, char *argv[]) {
vector(8, short) v0 = {argc,1,2,3,4,5,6,7};
vector(8, short) v1 = {2,2,2,2,2,2,2,2};
vector(8, short) r1;
r1 = v0 >> v1;
return vidx(short, r1, 0);
}
/* { dg-final { scan-tree-dump-times ">> 2" 1 "veclower" } } */
/* { dg-final { cleanup-tree-dump "veclower" } } */

View File

@ -284,6 +284,55 @@ expand_vector_addition (gimple_stmt_iterator *gsi,
a, b, code);
}
/* Check if vector VEC consists of all the equal elements and
that the number of elements corresponds to the type of VEC.
The function returns first element of the vector
or NULL_TREE if the vector is not uniform. */
static tree
uniform_vector_p (tree vec)
{
tree first, t, els;
unsigned i;
if (vec == NULL_TREE)
return NULL_TREE;
if (TREE_CODE (vec) == VECTOR_CST)
{
els = TREE_VECTOR_CST_ELTS (vec);
first = TREE_VALUE (els);
els = TREE_CHAIN (els);
for (t = els; t; t = TREE_CHAIN (t))
if (!operand_equal_p (first, TREE_VALUE (t), 0))
return NULL_TREE;
return first;
}
else if (TREE_CODE (vec) == CONSTRUCTOR)
{
first = error_mark_node;
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (vec), i, t)
{
if (i == 0)
{
first = t;
continue;
}
if (!operand_equal_p (first, t, 0))
return NULL_TREE;
}
if (i != TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec)))
return NULL_TREE;
return first;
}
return NULL_TREE;
}
static tree
expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type,
gimple assign, enum tree_code code)
@ -392,7 +441,7 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
tree lhs, rhs1, rhs2 = NULL, type, compute_type;
enum tree_code code;
enum machine_mode compute_mode;
optab op;
optab op = NULL;
enum gimple_rhs_class rhs_class;
tree new_rhs;
@ -434,18 +483,44 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi)
|| code == LROTATE_EXPR
|| code == RROTATE_EXPR)
{
/* If the 2nd argument is vector, we need a vector/vector shift */
bool vector_scalar_shift;
op = optab_for_tree_code (code, type, optab_scalar);
/* Vector/Scalar shift is supported. */
vector_scalar_shift = (op && (optab_handler (op, TYPE_MODE (type))
!= CODE_FOR_nothing));
/* If the 2nd argument is vector, we need a vector/vector shift.
Except all the elements in the second vector are the same. */
if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs2))))
op = optab_for_tree_code (code, type, optab_vector);
else
{
/* Try for a vector/scalar shift, and if we don't have one, see if we
have a vector/vector shift */
op = optab_for_tree_code (code, type, optab_scalar);
if (!op
|| optab_handler (op, TYPE_MODE (type)) == CODE_FOR_nothing)
op = optab_for_tree_code (code, type, optab_vector);
}
{
tree first;
gimple def_stmt;
/* Check whether we have vector <op> {x,x,x,x} where x
could be a scalar variable or a constant. Transform
vector <op> {x,x,x,x} ==> vector <op> scalar. */
if (vector_scalar_shift
&& ((TREE_CODE (rhs2) == VECTOR_CST
&& (first = uniform_vector_p (rhs2)) != NULL_TREE)
|| (TREE_CODE (rhs2) == SSA_NAME
&& (def_stmt = SSA_NAME_DEF_STMT (rhs2))
&& gimple_assign_single_p (def_stmt)
&& (first = uniform_vector_p
(gimple_assign_rhs1 (def_stmt))) != NULL_TREE)))
{
gimple_assign_set_rhs2 (stmt, first);
update_stmt (stmt);
rhs2 = first;
}
else
op = optab_for_tree_code (code, type, optab_vector);
}
/* Try for a vector/scalar shift, and if we don't have one, see if we
have a vector/vector shift */
else if (!vector_scalar_shift)
op = optab_for_tree_code (code, type, optab_vector);
}
else
op = optab_for_tree_code (code, type, optab_default);
@ -559,8 +634,9 @@ struct gimple_opt_pass pass_lower_vector =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_func | TODO_ggc_collect
| TODO_verify_stmts /* todo_flags_finish */
TODO_dump_func | TODO_update_ssa /* todo_flags_finish */
| TODO_verify_ssa
| TODO_verify_stmts | TODO_verify_flow
}
};