Commit f5709183 by Ira Rosen Committed by Ulrich Weigand

tree-vectorizer.h (vect_pattern_recog): Add new argument.

ChangeLog:

	* tree-vectorizer.h (vect_pattern_recog): Add new argument.
	* tree-vect-loop.c (vect_analyze_loop_2): Update call to
	vect_pattern_recog.
	* tree-vect-patterns.c (widened_name_p): Pass basic block
	info to vect_is_simple_use.
	(vect_recog_dot_prod_pattern): Fail for basic blocks.
	(vect_recog_widen_sum_pattern): Likewise.
	(vect_handle_widen_op_by_const): Support basic blocks.
	(vect_operation_fits_smaller_type,
	vect_recog_over_widening_pattern): Likewise.
	(vect_recog_vector_vector_shift_pattern): Support basic blocks.
	Update call to vect_is_simple_use.
	(vect_recog_mixed_size_cond_pattern): Support basic blocks.
	Add printing.
	(check_bool_pattern): Add an argument, update call to
	vect_is_simple_use and the recursive calls.
	(vect_recog_bool_pattern): Update relevant function calls.
	Add printing.
	(vect_mark_pattern_stmts): Update calls to new_stmt_vec_info.
	(vect_pattern_recog_1): Check for reduction only in loops.
	(vect_pattern_recog): Add new argument.  Support basic blocks.
	* tree-vect-stmts.c (vectorizable_conversion): Pass basic block
	info to vect_is_simple_use_1.
	* tree-vect-slp.c (vect_get_and_check_slp_defs): Support basic
	blocks.
	(vect_slp_analyze_bb_1): Call vect_pattern_recog.

testsuite/ChangeLog:

	* gcc.dg/vect/bb-slp-pattern-1.c: New test.
	* gcc.dg/vect/bb-slp-pattern-2.c: New test.

Co-Authored-By: Ulrich Weigand <ulrich.weigand@linaro.org>

From-SVN: r185436
parent 37b659dd
2012-03-15 Ira Rosen <irar@il.ibm.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
* tree-vectorizer.h (vect_pattern_recog): Add new argument.
* tree-vect-loop.c (vect_analyze_loop_2): Update call to
vect_pattern_recog.
* tree-vect-patterns.c (widened_name_p): Pass basic block
info to vect_is_simple_use.
(vect_recog_dot_prod_pattern): Fail for basic blocks.
(vect_recog_widen_sum_pattern): Likewise.
(vect_handle_widen_op_by_const): Support basic blocks.
(vect_operation_fits_smaller_type,
vect_recog_over_widening_pattern): Likewise.
(vect_recog_vector_vector_shift_pattern): Support basic blocks.
Update call to vect_is_simple_use.
(vect_recog_mixed_size_cond_pattern): Support basic blocks.
Add printing.
(check_bool_pattern): Add an argument, update call to
vect_is_simple_use and the recursive calls.
(vect_recog_bool_pattern): Update relevant function calls.
Add printing.
(vect_mark_pattern_stmts): Update calls to new_stmt_vec_info.
(vect_pattern_recog_1): Check for reduction only in loops.
(vect_pattern_recog): Add new argument. Support basic blocks.
* tree-vect-stmts.c (vectorizable_conversion): Pass basic block
info to vect_is_simple_use_1.
* tree-vect-slp.c (vect_get_and_check_slp_defs): Support basic
blocks.
(vect_slp_analyze_bb_1): Call vect_pattern_recog.
2012-03-15 Jakub Jelinek <jakub@redhat.com> 2012-03-15 Jakub Jelinek <jakub@redhat.com>
Andrew Pinski <apinski@cavium.com> Andrew Pinski <apinski@cavium.com>
......
2012-03-15 Ira Rosen <irar@il.ibm.com>
Ulrich Weigand <ulrich.weigand@linaro.org>
* gcc.dg/vect/bb-slp-pattern-1.c: New test.
* gcc.dg/vect/bb-slp-pattern-2.c: New test.
2012-03-15 Janne Blomqvist <jb@gcc.gnu.org> 2012-03-15 Janne Blomqvist <jb@gcc.gnu.org>
PR libfortran/52434 PR libfortran/52434
......
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include "tree-vect.h"
#define N 8
unsigned short X[N];
unsigned short Y[N];
unsigned int result[N];
/* unsigned short->unsigned int widening-mult. */
__attribute__ ((noinline, noclone)) void
foo (void)
{
result[0] = (unsigned int) (X[0] * Y[0]);
result[1] = (unsigned int) (X[1] * Y[1]);
result[2] = (unsigned int) (X[2] * Y[2]);
result[3] = (unsigned int) (X[3] * Y[3]);
result[4] = (unsigned int) (X[4] * Y[4]);
result[5] = (unsigned int) (X[5] * Y[5]);
result[6] = (unsigned int) (X[6] * Y[6]);
result[7] = (unsigned int) (X[7] * Y[7]);
}
int main (void)
{
int i, tmp;
check_vect ();
for (i = 0; i < N; i++)
{
X[i] = i;
Y[i] = 64-i;
}
foo ();
for (i = 0; i < N; i++)
{
__asm__ volatile ("");
tmp = X[i] * Y[i];
if (result[i] != tmp)
abort ();
}
return 0;
}
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { vect_widen_mult_hi_to_si || vect_unpack } } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_mult_pattern: detected" 8 "slp" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { scan-tree-dump-times "pattern recognized" 8 "slp" { target vect_widen_mult_hi_to_si_pattern } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
/* { dg-require-effective-target vect_condition } */
#include "tree-vect.h"
#define N 128
__attribute__((noinline, noclone)) void
foo (short * __restrict__ a, int * __restrict__ b, int stride)
{
int i;
for (i = 0; i < N/stride; i++, a += stride, b += stride)
{
a[0] = b[0] ? 1 : 7;
a[1] = b[1] ? 2 : 0;
a[2] = b[2] ? 3 : 0;
a[3] = b[3] ? 4 : 0;
a[4] = b[4] ? 5 : 0;
a[5] = b[5] ? 6 : 0;
a[6] = b[6] ? 7 : 0;
a[7] = b[7] ? 8 : 0;
}
}
short a[N];
int b[N];
int main ()
{
int i;
check_vect ();
for (i = 0; i < N; i++)
{
a[i] = i;
b[i] = -i;
}
foo (a, b, 8);
for (i = 1; i < N; i++)
if (a[i] != i%8 + 1)
abort ();
if (a[0] != 7)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "basic block vectorized using SLP" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
...@@ -1514,7 +1514,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo) ...@@ -1514,7 +1514,7 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
vect_analyze_scalar_cycles (loop_vinfo); vect_analyze_scalar_cycles (loop_vinfo);
vect_pattern_recog (loop_vinfo); vect_pattern_recog (loop_vinfo, NULL);
/* Data-flow analysis to detect stmts that do not need to be vectorized. */ /* Data-flow analysis to detect stmts that do not need to be vectorized. */
......
...@@ -105,12 +105,13 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt, ...@@ -105,12 +105,13 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt,
tree oprnd0; tree oprnd0;
enum vect_def_type dt; enum vect_def_type dt;
tree def; tree def;
bb_vec_info bb_vinfo;
stmt_vinfo = vinfo_for_stmt (use_stmt); stmt_vinfo = vinfo_for_stmt (use_stmt);
loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
if (!vect_is_simple_use (name, use_stmt, loop_vinfo, NULL, def_stmt, &def, if (!vect_is_simple_use (name, use_stmt, loop_vinfo, bb_vinfo, def_stmt,
&dt)) &def, &dt))
return false; return false;
if (dt != vect_internal_def if (dt != vect_internal_def
...@@ -135,7 +136,7 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt, ...@@ -135,7 +136,7 @@ widened_name_p (tree name, gimple use_stmt, tree *half_type, gimple *def_stmt,
return false; return false;
if (!vect_is_simple_use (oprnd0, *def_stmt, loop_vinfo, if (!vect_is_simple_use (oprnd0, *def_stmt, loop_vinfo,
NULL, &dummy_gimple, &dummy, &dt)) bb_vinfo, &dummy_gimple, &dummy, &dt))
return false; return false;
return true; return true;
...@@ -211,9 +212,14 @@ vect_recog_dot_prod_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -211,9 +212,14 @@ vect_recog_dot_prod_pattern (VEC (gimple, heap) **stmts, tree *type_in,
gimple pattern_stmt; gimple pattern_stmt;
tree prod_type; tree prod_type;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_info); struct loop *loop;
tree var; tree var;
if (!loop_info)
return NULL;
loop = LOOP_VINFO_LOOP (loop_info);
if (!is_gimple_assign (last_stmt)) if (!is_gimple_assign (last_stmt))
return NULL; return NULL;
...@@ -383,8 +389,16 @@ vect_handle_widen_op_by_const (gimple stmt, enum tree_code code, ...@@ -383,8 +389,16 @@ vect_handle_widen_op_by_const (gimple stmt, enum tree_code code,
{ {
tree new_type, new_oprnd, tmp; tree new_type, new_oprnd, tmp;
gimple new_stmt; gimple new_stmt;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (vinfo_for_stmt (stmt)); loop_vec_info loop_vinfo;
struct loop *loop = LOOP_VINFO_LOOP (loop_info); struct loop *loop = NULL;
bb_vec_info bb_vinfo;
stmt_vec_info stmt_vinfo;
stmt_vinfo = vinfo_for_stmt (stmt);
loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
if (loop_vinfo)
loop = LOOP_VINFO_LOOP (loop_vinfo);
if (code != MULT_EXPR && code != LSHIFT_EXPR) if (code != MULT_EXPR && code != LSHIFT_EXPR)
return false; return false;
...@@ -402,7 +416,9 @@ vect_handle_widen_op_by_const (gimple stmt, enum tree_code code, ...@@ -402,7 +416,9 @@ vect_handle_widen_op_by_const (gimple stmt, enum tree_code code,
if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4) if (TYPE_PRECISION (type) < (TYPE_PRECISION (*half_type) * 4)
|| !gimple_bb (def_stmt) || !gimple_bb (def_stmt)
|| !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) || (loop && !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
|| (!loop && gimple_bb (def_stmt) != BB_VINFO_BB (bb_vinfo)
&& gimple_code (def_stmt) != GIMPLE_PHI)
|| !vinfo_for_stmt (def_stmt)) || !vinfo_for_stmt (def_stmt))
return false; return false;
...@@ -798,9 +814,14 @@ vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -798,9 +814,14 @@ vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in,
tree type, half_type; tree type, half_type;
gimple pattern_stmt; gimple pattern_stmt;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_info); struct loop *loop;
tree var; tree var;
if (!loop_info)
return NULL;
loop = LOOP_VINFO_LOOP (loop_info);
if (!is_gimple_assign (last_stmt)) if (!is_gimple_assign (last_stmt))
return NULL; return NULL;
...@@ -899,7 +920,11 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type, ...@@ -899,7 +920,11 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type,
gimple def_stmt, new_stmt; gimple def_stmt, new_stmt;
bool first = false; bool first = false;
loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (vinfo_for_stmt (stmt)); loop_vec_info loop_info = STMT_VINFO_LOOP_VINFO (vinfo_for_stmt (stmt));
struct loop *loop = LOOP_VINFO_LOOP (loop_info); bb_vec_info bb_info = STMT_VINFO_BB_VINFO (vinfo_for_stmt (stmt));
struct loop *loop = NULL;
if (loop_info)
loop = LOOP_VINFO_LOOP (loop_info);
*op0 = NULL_TREE; *op0 = NULL_TREE;
*op1 = NULL_TREE; *op1 = NULL_TREE;
...@@ -933,7 +958,9 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type, ...@@ -933,7 +958,9 @@ vect_operation_fits_smaller_type (gimple stmt, tree def, tree *new_type,
first = true; first = true;
if (!widened_name_p (oprnd, stmt, &half_type, &def_stmt, false) if (!widened_name_p (oprnd, stmt, &half_type, &def_stmt, false)
|| !gimple_bb (def_stmt) || !gimple_bb (def_stmt)
|| !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) || (loop && !flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
|| (!loop && gimple_bb (def_stmt) != BB_VINFO_BB (bb_info)
&& gimple_code (def_stmt) != GIMPLE_PHI)
|| !vinfo_for_stmt (def_stmt)) || !vinfo_for_stmt (def_stmt))
return false; return false;
} }
...@@ -1107,8 +1134,17 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, ...@@ -1107,8 +1134,17 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts,
int nuses = 0; int nuses = 0;
tree var = NULL_TREE, new_type = NULL_TREE, tmp, new_oprnd; tree var = NULL_TREE, new_type = NULL_TREE, tmp, new_oprnd;
bool first; bool first;
struct loop *loop = (gimple_bb (stmt))->loop_father;
tree type = NULL; tree type = NULL;
loop_vec_info loop_vinfo;
struct loop *loop = NULL;
bb_vec_info bb_vinfo;
stmt_vec_info stmt_vinfo;
stmt_vinfo = vinfo_for_stmt (stmt);
loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
if (loop_vinfo)
loop = LOOP_VINFO_LOOP (loop_vinfo);
first = true; first = true;
while (1) while (1)
...@@ -1141,7 +1177,8 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts, ...@@ -1141,7 +1177,8 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts,
if (nuses != 1 || !is_gimple_assign (use_stmt) if (nuses != 1 || !is_gimple_assign (use_stmt)
|| !gimple_bb (use_stmt) || !gimple_bb (use_stmt)
|| !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) || (loop && !flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
|| (!loop && gimple_bb (use_stmt) != BB_VINFO_BB (bb_vinfo)))
return NULL; return NULL;
/* Create pattern statement for STMT. */ /* Create pattern statement for STMT. */
...@@ -1518,6 +1555,7 @@ vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts, ...@@ -1518,6 +1555,7 @@ vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts,
enum tree_code rhs_code; enum tree_code rhs_code;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
enum vect_def_type dt; enum vect_def_type dt;
tree def; tree def;
...@@ -1551,7 +1589,7 @@ vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts, ...@@ -1551,7 +1589,7 @@ vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts,
!= TYPE_PRECISION (TREE_TYPE (oprnd0))) != TYPE_PRECISION (TREE_TYPE (oprnd0)))
return NULL; return NULL;
if (!vect_is_simple_use (oprnd1, last_stmt, loop_vinfo, NULL, &def_stmt, if (!vect_is_simple_use (oprnd1, last_stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt)) &def, &dt))
return NULL; return NULL;
...@@ -1840,6 +1878,7 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -1840,6 +1878,7 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in,
enum machine_mode cmpmode; enum machine_mode cmpmode;
gimple pattern_stmt, def_stmt; gimple pattern_stmt, def_stmt;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
if (!is_gimple_assign (last_stmt) if (!is_gimple_assign (last_stmt)
|| gimple_assign_rhs_code (last_stmt) != COND_EXPR || gimple_assign_rhs_code (last_stmt) != COND_EXPR
...@@ -1907,12 +1946,15 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -1907,12 +1946,15 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in,
gimple_assign_lhs (def_stmt), NULL_TREE); gimple_assign_lhs (def_stmt), NULL_TREE);
new_pattern_def_seq (stmt_vinfo, def_stmt); new_pattern_def_seq (stmt_vinfo, def_stmt);
def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL); def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, bb_vinfo);
set_vinfo_for_stmt (def_stmt, def_stmt_info); set_vinfo_for_stmt (def_stmt, def_stmt_info);
STMT_VINFO_VECTYPE (def_stmt_info) = vecitype; STMT_VINFO_VECTYPE (def_stmt_info) = vecitype;
*type_in = vecitype; *type_in = vecitype;
*type_out = vectype; *type_out = vectype;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vect_recog_mixed_size_cond_pattern: detected: ");
return pattern_stmt; return pattern_stmt;
} }
...@@ -1921,14 +1963,15 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -1921,14 +1963,15 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in,
true if bool VAR can be optimized that way. */ true if bool VAR can be optimized that way. */
static bool static bool
check_bool_pattern (tree var, loop_vec_info loop_vinfo) check_bool_pattern (tree var, loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{ {
gimple def_stmt; gimple def_stmt;
enum vect_def_type dt; enum vect_def_type dt;
tree def, rhs1; tree def, rhs1;
enum tree_code rhs_code; enum tree_code rhs_code;
if (!vect_is_simple_use (var, NULL, loop_vinfo, NULL, &def_stmt, &def, &dt)) if (!vect_is_simple_use (var, NULL, loop_vinfo, bb_vinfo, &def_stmt, &def,
&dt))
return false; return false;
if (dt != vect_internal_def) if (dt != vect_internal_def)
...@@ -1945,24 +1988,25 @@ check_bool_pattern (tree var, loop_vec_info loop_vinfo) ...@@ -1945,24 +1988,25 @@ check_bool_pattern (tree var, loop_vec_info loop_vinfo)
switch (rhs_code) switch (rhs_code)
{ {
case SSA_NAME: case SSA_NAME:
return check_bool_pattern (rhs1, loop_vinfo); return check_bool_pattern (rhs1, loop_vinfo, bb_vinfo);
CASE_CONVERT: CASE_CONVERT:
if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1 if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
|| !TYPE_UNSIGNED (TREE_TYPE (rhs1))) || !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
&& TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE) && TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
return false; return false;
return check_bool_pattern (rhs1, loop_vinfo); return check_bool_pattern (rhs1, loop_vinfo, bb_vinfo);
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
return check_bool_pattern (rhs1, loop_vinfo); return check_bool_pattern (rhs1, loop_vinfo, bb_vinfo);
case BIT_AND_EXPR: case BIT_AND_EXPR:
case BIT_IOR_EXPR: case BIT_IOR_EXPR:
case BIT_XOR_EXPR: case BIT_XOR_EXPR:
if (!check_bool_pattern (rhs1, loop_vinfo)) if (!check_bool_pattern (rhs1, loop_vinfo, bb_vinfo))
return false; return false;
return check_bool_pattern (gimple_assign_rhs2 (def_stmt), loop_vinfo); return check_bool_pattern (gimple_assign_rhs2 (def_stmt), loop_vinfo,
bb_vinfo);
default: default:
if (TREE_CODE_CLASS (rhs_code) == tcc_comparison) if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
...@@ -2260,6 +2304,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2260,6 +2304,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
tree var, lhs, rhs, vectype; tree var, lhs, rhs, vectype;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (stmt_vinfo);
gimple pattern_stmt; gimple pattern_stmt;
if (!is_gimple_assign (last_stmt)) if (!is_gimple_assign (last_stmt))
...@@ -2283,7 +2328,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2283,7 +2328,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
if (vectype == NULL_TREE) if (vectype == NULL_TREE)
return NULL; return NULL;
if (!check_bool_pattern (var, loop_vinfo)) if (!check_bool_pattern (var, loop_vinfo, bb_vinfo))
return NULL; return NULL;
rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts); rhs = adjust_bool_pattern (var, TREE_TYPE (lhs), NULL_TREE, stmts);
...@@ -2297,6 +2342,9 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2297,6 +2342,9 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
*type_out = vectype; *type_out = vectype;
*type_in = vectype; *type_in = vectype;
VEC_safe_push (gimple, heap, *stmts, last_stmt); VEC_safe_push (gimple, heap, *stmts, last_stmt);
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vect_recog_bool_pattern: detected: ");
return pattern_stmt; return pattern_stmt;
} }
else if (rhs_code == SSA_NAME else if (rhs_code == SSA_NAME
...@@ -2307,7 +2355,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2307,7 +2355,7 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
gcc_assert (vectype != NULL_TREE); gcc_assert (vectype != NULL_TREE);
if (!VECTOR_MODE_P (TYPE_MODE (vectype))) if (!VECTOR_MODE_P (TYPE_MODE (vectype)))
return NULL; return NULL;
if (!check_bool_pattern (var, loop_vinfo)) if (!check_bool_pattern (var, loop_vinfo, bb_vinfo))
return NULL; return NULL;
rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), NULL_TREE, stmts); rhs = adjust_bool_pattern (var, TREE_TYPE (vectype), NULL_TREE, stmts);
...@@ -2322,7 +2370,8 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2322,7 +2370,8 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
} }
pattern_stmt pattern_stmt
= gimple_build_assign_with_ops (SSA_NAME, lhs, rhs, NULL_TREE); = gimple_build_assign_with_ops (SSA_NAME, lhs, rhs, NULL_TREE);
pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL); pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo,
bb_vinfo);
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
STMT_VINFO_DATA_REF (pattern_stmt_info) STMT_VINFO_DATA_REF (pattern_stmt_info)
= STMT_VINFO_DATA_REF (stmt_vinfo); = STMT_VINFO_DATA_REF (stmt_vinfo);
...@@ -2338,6 +2387,8 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in, ...@@ -2338,6 +2387,8 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
*type_out = vectype; *type_out = vectype;
*type_in = vectype; *type_in = vectype;
VEC_safe_push (gimple, heap, *stmts, last_stmt); VEC_safe_push (gimple, heap, *stmts, last_stmt);
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "vect_recog_bool_pattern: detected: ");
return pattern_stmt; return pattern_stmt;
} }
else else
...@@ -2354,12 +2405,14 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, ...@@ -2354,12 +2405,14 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt,
stmt_vec_info pattern_stmt_info, def_stmt_info; stmt_vec_info pattern_stmt_info, def_stmt_info;
stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt); stmt_vec_info orig_stmt_info = vinfo_for_stmt (orig_stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (orig_stmt_info); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (orig_stmt_info);
bb_vec_info bb_vinfo = STMT_VINFO_BB_VINFO (orig_stmt_info);
gimple def_stmt; gimple def_stmt;
pattern_stmt_info = vinfo_for_stmt (pattern_stmt); pattern_stmt_info = vinfo_for_stmt (pattern_stmt);
if (pattern_stmt_info == NULL) if (pattern_stmt_info == NULL)
{ {
pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo, NULL); pattern_stmt_info = new_stmt_vec_info (pattern_stmt, loop_vinfo,
bb_vinfo);
set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info); set_vinfo_for_stmt (pattern_stmt, pattern_stmt_info);
} }
gimple_set_bb (pattern_stmt, gimple_bb (orig_stmt)); gimple_set_bb (pattern_stmt, gimple_bb (orig_stmt));
...@@ -2382,7 +2435,8 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt, ...@@ -2382,7 +2435,8 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt,
def_stmt_info = vinfo_for_stmt (def_stmt); def_stmt_info = vinfo_for_stmt (def_stmt);
if (def_stmt_info == NULL) if (def_stmt_info == NULL)
{ {
def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL); def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo,
bb_vinfo);
set_vinfo_for_stmt (def_stmt, def_stmt_info); set_vinfo_for_stmt (def_stmt, def_stmt_info);
} }
gimple_set_bb (def_stmt, gimple_bb (orig_stmt)); gimple_set_bb (def_stmt, gimple_bb (orig_stmt));
...@@ -2493,6 +2547,7 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func, ...@@ -2493,6 +2547,7 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func,
/* Patterns cannot be vectorized using SLP, because they change the order of /* Patterns cannot be vectorized using SLP, because they change the order of
computation. */ computation. */
if (loop_vinfo)
FOR_EACH_VEC_ELT (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next) FOR_EACH_VEC_ELT (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i, next)
if (next == stmt) if (next == stmt)
VEC_ordered_remove (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i); VEC_ordered_remove (gimple, LOOP_VINFO_REDUCTIONS (loop_vinfo), i);
...@@ -2595,19 +2650,34 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func, ...@@ -2595,19 +2650,34 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func,
be recorded in S3. */ be recorded in S3. */
void void
vect_pattern_recog (loop_vec_info loop_vinfo) vect_pattern_recog (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
{ {
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *loop;
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); basic_block *bbs, bb;
unsigned int nbbs = loop->num_nodes; unsigned int nbbs;
gimple_stmt_iterator si; gimple_stmt_iterator si;
unsigned int i, j; unsigned int i, j;
vect_recog_func_ptr vect_recog_func; vect_recog_func_ptr vect_recog_func;
VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1); VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1);
gimple stmt;
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_pattern_recog ==="); fprintf (vect_dump, "=== vect_pattern_recog ===");
if (loop_vinfo)
{
loop = LOOP_VINFO_LOOP (loop_vinfo);
bbs = LOOP_VINFO_BBS (loop_vinfo);
nbbs = loop->num_nodes;
}
else
{
bb = BB_VINFO_BB (bb_vinfo);
nbbs = 1;
bbs = XNEW (basic_block);
bbs[0] = bb;
}
/* Scan through the loop stmts, applying the pattern recognition /* Scan through the loop stmts, applying the pattern recognition
functions starting at each stmt visited: */ functions starting at each stmt visited: */
for (i = 0; i < nbbs; i++) for (i = 0; i < nbbs; i++)
...@@ -2615,6 +2685,11 @@ vect_pattern_recog (loop_vec_info loop_vinfo) ...@@ -2615,6 +2685,11 @@ vect_pattern_recog (loop_vec_info loop_vinfo)
basic_block bb = bbs[i]; basic_block bb = bbs[i];
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si)) for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{ {
if (bb_vinfo && (stmt = gsi_stmt (si))
&& vinfo_for_stmt (stmt)
&& !STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)))
continue;
/* Scan over all generic vect_recog_xxx_pattern functions. */ /* Scan over all generic vect_recog_xxx_pattern functions. */
for (j = 0; j < NUM_PATTERNS; j++) for (j = 0; j < NUM_PATTERNS; j++)
{ {
...@@ -2626,4 +2701,6 @@ vect_pattern_recog (loop_vec_info loop_vinfo) ...@@ -2626,4 +2701,6 @@ vect_pattern_recog (loop_vec_info loop_vinfo)
} }
VEC_free (gimple, heap, stmts_to_replace); VEC_free (gimple, heap, stmts_to_replace);
if (bb_vinfo)
free (bbs);
} }
...@@ -249,8 +249,10 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo, ...@@ -249,8 +249,10 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
/* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt /* Check if DEF_STMT is a part of a pattern in LOOP and get the def stmt
from the pattern. Check that all the stmts of the node are in the from the pattern. Check that all the stmts of the node are in the
pattern. */ pattern. */
if (loop && def_stmt && gimple_bb (def_stmt) if (def_stmt && gimple_bb (def_stmt)
&& flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)) && ((loop && flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
|| (!loop && gimple_bb (def_stmt) == BB_VINFO_BB (bb_vinfo)
&& gimple_code (def_stmt) != GIMPLE_PHI))
&& vinfo_for_stmt (def_stmt) && vinfo_for_stmt (def_stmt)
&& STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt)) && STMT_VINFO_IN_PATTERN_P (vinfo_for_stmt (def_stmt))
&& !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt)) && !STMT_VINFO_RELEVANT (vinfo_for_stmt (def_stmt))
...@@ -2015,6 +2017,8 @@ vect_slp_analyze_bb_1 (basic_block bb) ...@@ -2015,6 +2017,8 @@ vect_slp_analyze_bb_1 (basic_block bb)
return NULL; return NULL;
} }
vect_pattern_recog (NULL, bb_vinfo);
if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf) if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf)
|| min_vf > max_vf) || min_vf > max_vf)
{ {
......
...@@ -2271,10 +2271,10 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi, ...@@ -2271,10 +2271,10 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
/* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of /* For WIDEN_MULT_EXPR, if OP0 is a constant, use the type of
OP1. */ OP1. */
if (CONSTANT_CLASS_P (op0)) if (CONSTANT_CLASS_P (op0))
ok = vect_is_simple_use_1 (op1, stmt, loop_vinfo, NULL, ok = vect_is_simple_use_1 (op1, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[1], &vectype_in); &def_stmt, &def, &dt[1], &vectype_in);
else else
ok = vect_is_simple_use (op1, stmt, loop_vinfo, NULL, &def_stmt, ok = vect_is_simple_use (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt[1]); &def, &dt[1]);
if (!ok) if (!ok)
......
...@@ -933,7 +933,7 @@ extern void vect_slp_transform_bb (basic_block); ...@@ -933,7 +933,7 @@ extern void vect_slp_transform_bb (basic_block);
in the future. */ in the future. */
typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *); typedef gimple (* vect_recog_func_ptr) (VEC (gimple, heap) **, tree *, tree *);
#define NUM_PATTERNS 10 #define NUM_PATTERNS 10
void vect_pattern_recog (loop_vec_info); void vect_pattern_recog (loop_vec_info, bb_vec_info);
/* In tree-vectorizer.c. */ /* In tree-vectorizer.c. */
unsigned vectorize_loops (void); unsigned vectorize_loops (void);
......
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