Commit 4bbe8262 by Ira Rosen Committed by Ira Rosen

tree-vectorizer.h (vectorizable_condition): Add parameters.


	* tree-vectorizer.h (vectorizable_condition): Add parameters.
	* tree-vect-loop.c (vect_is_simple_reduction): Support COND_EXPR.
	(get_initial_def_for_reduction): Likewise.
	(vectorizable_reduction): Skip the check of first operand in case
	of COND_EXPR. Add check that it is outer loop vectorization if
	nested cycle was detected. Call vectorizable_condition() for 
	COND_EXPR. If reduction epilogue cannot be created do not fail for
	nested cycles (if it is not double reduction). Assert that there
	is only one type in the loop in case of COND_EXPR. Call
	vectorizable_condition() to vectorize COND_EXPR.
	* tree-vect-stmts.c (vectorizable_condition): Update comment.
	Add parameters. Allow nested cycles if called from 
	vectorizable_reduction(). Use reduction vector variable if provided.
	(vect_analyze_stmt): Call vectorizable_reduction() before
	vectorizable_condition().
	(vect_transform_stmt): Update call to vectorizable_condition().

From-SVN: r149806
parent 9e7c935a
2009-07-20 Ira Rosen <irar@il.ibm.com>
* tree-vectorizer.h (vectorizable_condition): Add parameters.
* tree-vect-loop.c (vect_is_simple_reduction): Support COND_EXPR.
(get_initial_def_for_reduction): Likewise.
(vectorizable_reduction): Skip the check of first operand in case
of COND_EXPR. Add check that it is outer loop vectorization if
nested cycle was detected. Call vectorizable_condition() for
COND_EXPR. If reduction epilogue cannot be created do not fail for
nested cycles (if it is not double reduction). Assert that there
is only one type in the loop in case of COND_EXPR. Call
vectorizable_condition() to vectorize COND_EXPR.
* tree-vect-stmts.c (vectorizable_condition): Update comment.
Add parameters. Allow nested cycles if called from
vectorizable_reduction(). Use reduction vector variable if provided.
(vect_analyze_stmt): Call vectorizable_reduction() before
vectorizable_condition().
(vect_transform_stmt): Update call to vectorizable_condition().
2009-07-20 Christian Bruel <christian.bruel@st.com>
* config/sh/sh.opt (-mfmovd): Resurrect and document.
......
2009-07-20 Ira Rosen <irar@il.ibm.com>
* gcc.dg/vect/vect-cond-1.c, gcc.dg/vect/vect-cond-2.c,
gcc.dg/vect/vect-cond-3.c, gcc.dg/vect/vect-cond-4.c,
gcc.dg/vect/vect-cond-5.c, gcc.dg/vect/vect-cond-6.c: New tests.
2009-07-20 Christian Bruel <christian.bruel@st.com>
* gcc.target/sh/mfmovd.c: New test.
......
/* { dg-require-effective-target vect_condition } */
#include <stdlib.h>
#include <stdio.h>
#include "tree-vect.h"
#define M 32
#define N 16
int x_in[M];
int x_out[M];
int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2};
int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024};
int check_result[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48};
__attribute__ ((noinline)) void
foo ()
{
int j, i, x;
int curr_a, next_a;
for (j = 0; j < M; j++)
{
x = x_in[j];
curr_a = a[0];
for (i = 0; i < N; i++)
{
next_a = a[i+1];
curr_a = x > c[i] ? curr_a : next_a;
}
x_out[j] = curr_a;
}
}
int main (void)
{
int i,j;
check_vect ();
for (j = 0; j < M; j++)
x_in[j] = j;
foo ();
for (j = 0; j < M; j++)
if (x_out[j] != check_result[j])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_condition } */
#include <stdlib.h>
#include <stdio.h>
#include "tree-vect.h"
#define N 16
int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2};
int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024};
__attribute__ ((noinline)) void
foo (int *x)
{
int i;
int curr_a, flag, next_a;
curr_a = a[0];
for (i = 0; i < N; i++)
{
flag = *x > c[i];
next_a = a[i+1];
curr_a = flag ? curr_a : next_a;
}
*x = curr_a;
}
int main (void)
{
int x = 7;
check_vect ();
foo (&x);
if (x != 256)
abort ();
return 0;
}
/* The order of computation should not be changed for cond_expr, therefore,
it cannot be vectorized in reduction. */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_condition } */
#include <stdlib.h>
#include <stdio.h>
#include "tree-vect.h"
#define M 32
#define N 16
int x_in[M];
int x_out_a[M], x_out_b[M];
int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2};
int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024};
int b[N+1] = {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
int check_result_a[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48};
int check_result_b[M] = {17,17,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
__attribute__ ((noinline)) void
foo ()
{
int j, i, x;
int curr_a, flag, next_a, curr_b, next_b;
for (j = 0; j < M; j++)
{
x = x_in[j];
curr_a = a[0];
curr_b = b[0];
for (i = 0; i < N; i++)
{
flag = x > c[i];
next_a = a[i+1];
next_b = b[i+1];
curr_a = flag ? curr_a : next_a;
curr_b = flag ? next_b : curr_b;
}
x_out_a[j] = curr_a;
x_out_b[j] = curr_b;
}
}
int main (void)
{
int i,j;
check_vect ();
for (j = 0; j < M; j++)
x_in[j] = j;
foo ();
for (j = 0; j < M; j++)
if (x_out_a[j] != check_result_a[j]
|| x_out_b[j] != check_result_b[j])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_condition } */
#include <stdlib.h>
#include <stdio.h>
#include "tree-vect.h"
#define M 32
#define N 16
int x_in[M];
int x_out_a[M], x_out_b[M];
int c[N] = {3,2,1,10,1,42,3,4,50,9,32,8,11,10,1,2};
int a[N+1] = {0,16,32,48,64,128,256,512,0,16,32,48,64,128,256,512,1024};
int b[N+1] = {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
int check_result_a[M] = {1024,1024,1024,256,256,256,256,256,256,256,256,128,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48};
int check_result_b[M] = {17,17,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
__attribute__ ((noinline)) void
foo (int z)
{
int j, i, x;
int curr_a, flag, next_a, curr_b, next_b;
for (j = 0; j < M; j++)
{
x = x_in[j];
curr_a = a[0];
curr_b = b[0];
for (i = 0; i < N; i++)
{
curr_a = x > c[i] ? curr_a : z;
curr_b = x > c[i] ? next_b : 5;
}
x_out_a[j] = curr_a;
x_out_b[j] = curr_b;
}
}
int main (void)
{
int i,j;
check_vect ();
for (j = 0; j < M; j++)
x_in[j] = j;
foo (125);
for (j = 0; j < M; j++)
if (x_out_a[j] != 125
|| x_out_b[j] != 5)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_condition } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int cond_array[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int a[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
__attribute__ ((noinline)) void
foo (int c)
{
int res, i, j, k, next;
for (k = 0; k < K; k++)
{
res = 0;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
{
next = a[i][j];
res = c > cond_array[i+k][j] ? next : res;
}
out[k] = res;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
cond_array[i][j] = i+j;
for (i = 0; i < K; i++)
a[i][j] = i+2;
}
foo(5);
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* Double reduction with cond_expr is not supported, since eventhough the order
of computation is the same, but vector results should be reduced to scalar
result, which can'be done for cond_expr. */
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_condition } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int cond_array[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int a[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
__attribute__ ((noinline)) void
foo (int c)
{
int res, i, j, k, next;
for (k = 0; k < K; k++)
{
for (j = 0; j < K; j++)
{
res = 0;
for (i = 0; i < K; i++)
{
next = a[i][j];
res = c > cond_array[i+k][j] ? next : res;
}
out[j] = res;
}
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
cond_array[i][j] = i+j;
for (i = 0; i < K; i++)
a[i][j] = i+2;
}
foo(125);
for (k = 0; k < K; k++)
if (out[k] != 33)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -3775,13 +3775,17 @@ vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
Check if STMT is conditional modify expression that can be vectorized.
If VEC_STMT is also passed, vectorize the STMT: create a vectorized
stmt using VEC_COND_EXPR to replace it, put it in VEC_STMT, and insert it
at BSI.
at GSI.
When STMT is vectorized as nested cycle, REDUC_DEF is the vector variable
to be used at REDUC_INDEX (in then clause if REDUC_INDEX is 1, and in
else caluse if it is 2).
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
static bool
bool
vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
gimple *vec_stmt)
gimple *vec_stmt, tree reduc_def, int reduc_index)
{
tree scalar_dest = NULL_TREE;
tree vec_dest = NULL_TREE;
......@@ -3810,7 +3814,9 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def)
if (STMT_VINFO_DEF_TYPE (stmt_info) != vect_internal_def
&& !(STMT_VINFO_DEF_TYPE (stmt_info) == vect_nested_cycle
&& reduc_def))
return false;
/* FORNOW: SLP not supported. */
......@@ -3818,7 +3824,7 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
return false;
/* FORNOW: not yet supported. */
if (STMT_VINFO_LIVE_P (stmt_info))
if (STMT_VINFO_LIVE_P (stmt_info))
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "value used after loop.");
......@@ -3892,8 +3898,14 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL);
vec_cond_rhs =
vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL);
vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL);
vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
if (reduc_index == 1)
vec_then_clause = reduc_def;
else
vec_then_clause = vect_get_vec_def_for_operand (then_clause, stmt, NULL);
if (reduc_index == 2)
vec_else_clause = reduc_def;
else
vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
/* Arguments are ready. Create the new vector stmt. */
vec_compare = build2 (TREE_CODE (cond_expr), vectype,
......@@ -4023,8 +4035,8 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
|| vectorizable_load (stmt, NULL, NULL, NULL, NULL)
|| vectorizable_call (stmt, NULL, NULL)
|| vectorizable_store (stmt, NULL, NULL, NULL)
|| vectorizable_condition (stmt, NULL, NULL)
|| vectorizable_reduction (stmt, NULL, NULL));
|| vectorizable_reduction (stmt, NULL, NULL)
|| vectorizable_condition (stmt, NULL, NULL, NULL, 0));
else
{
if (bb_vinfo)
......@@ -4165,7 +4177,7 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
case condition_vec_info_type:
gcc_assert (!slp_node);
done = vectorizable_condition (stmt, gsi, &vec_stmt);
done = vectorizable_condition (stmt, gsi, &vec_stmt, NULL, 0);
gcc_assert (done);
break;
......
......@@ -786,7 +786,9 @@ extern bool vect_transform_stmt (gimple, gimple_stmt_iterator *,
bool *, slp_tree, slp_instance);
extern void vect_remove_stores (gimple);
extern bool vect_analyze_stmt (gimple, bool *, slp_tree);
extern bool vectorizable_condition (gimple, gimple_stmt_iterator *, gimple *,
tree, int);
/* In tree-vect-data-refs.c. */
extern bool vect_can_force_dr_alignment_p (const_tree, unsigned int);
extern enum dr_alignment_support vect_supportable_dr_alignment
......
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