Commit 06066f92 by Ira Rosen Committed by Ira Rosen

tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction with additional argument.


	* tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction
	with additional argument.
	* tree-vectorizer.h (enum vect_def_type): Add 
	vect_double_reduction_def.
	(vect_is_simple_reduction): Add argument.
	* tree-vect-loop.c (vect_determine_vectorization_factor): Fix 
	indentation.
	(vect_analyze_scalar_cycles_1): Detect double reduction. Call
	vect_is_simple_reduction with additional argument.
	(vect_analyze_loop_operations): Handle exit phi nodes in case of
	double reduction.
	(reduction_code_for_scalar_code): Handle additional codes by
	returning ERROR_MARK for them. Fix comment and indentation.
	(vect_is_simple_reduction): Fix comment, add argument to specify
	double reduction. Detect double reduction.
	(get_initial_def_for_induction): Fix indentation.
	(get_initial_def_for_reduction): Fix comment and indentation.
	Handle double reduction. Create initial definitions that do not
	require adjustment if ADJUSTMENT_DEF is NULL. Handle additional cases.
	(vect_create_epilog_for_reduction): Fix comment, add argument to
	handle double reduction. Use PLUS_EXPR in case of MINUS_EXPR in
	epilogue result extraction. Create double reduction phi node and
	replace relevant uses.
	(vectorizable_reduction): Call vect_is_simple_reduction with
	additional argument. Fix indentation. Update epilogue code treatment
	according to the changes in reduction_code_for_scalar_code. Check 
	for double reduction. Call vect_create_epilog_for_reduction with
	additional argument.
	* tree-vect-stmts.c (process_use): Handle double reduction, update
	documentation.
	(vect_mark_stmts_to_be_vectorized): Handle double reduction.
	(vect_get_vec_def_for_operand): Likewise.

From-SVN: r149526
parent b20231fe
2009-07-12 Ira Rosen <irar@il.ibm.com>
* tree-parloops.c (loop_parallel_p): Call vect_is_simple_reduction
with additional argument.
* tree-vectorizer.h (enum vect_def_type): Add
vect_double_reduction_def.
(vect_is_simple_reduction): Add argument.
* tree-vect-loop.c (vect_determine_vectorization_factor): Fix
indentation.
(vect_analyze_scalar_cycles_1): Detect double reduction. Call
vect_is_simple_reduction with additional argument.
(vect_analyze_loop_operations): Handle exit phi nodes in case of
double reduction.
(reduction_code_for_scalar_code): Handle additional codes by
returning ERROR_MARK for them. Fix comment and indentation.
(vect_is_simple_reduction): Fix comment, add argument to specify
double reduction. Detect double reduction.
(get_initial_def_for_induction): Fix indentation.
(get_initial_def_for_reduction): Fix comment and indentation.
Handle double reduction. Create initial definitions that do not
require adjustment if ADJUSTMENT_DEF is NULL. Handle additional cases.
(vect_create_epilog_for_reduction): Fix comment, add argument to
handle double reduction. Use PLUS_EXPR in case of MINUS_EXPR in
epilogue result extraction. Create double reduction phi node and
replace relevant uses.
(vectorizable_reduction): Call vect_is_simple_reduction with
additional argument. Fix indentation. Update epilogue code treatment
according to the changes in reduction_code_for_scalar_code. Check
for double reduction. Call vect_create_epilog_for_reduction with
additional argument.
* tree-vect-stmts.c (process_use): Handle double reduction, update
documentation.
(vect_mark_stmts_to_be_vectorized): Handle double reduction.
(vect_get_vec_def_for_operand): Likewise.
2009-07-12 Danny Smith <dansmister@gmail.com>
* config/i386/winnt.c (i386_pe_determine_dllexport_p): Don't
......
2009-07-12 Ira Rosen <irar@il.ibm.com>
* gcc.dg/vect/no-scevccp-outer-2.c: Expect to vectorize.
* gcc.dg/vect/vect-double-reduc-1.c, gcc.dg/vect/vect-double-reduc-2.c,
gcc.dg/vect/vect-double-reduc-3.c, gcc.dg/vect/vect-double-reduc-4.c,
gcc.dg/vect/vect-double-reduc-5.c, gcc.dg/vect/vect-double-reduc-6.c,
gcc.dg/vect/vect-double-reduc-7.c: New tests.
2009-07-12 Hans-Peter Nilsson <hp@axis.com>
* gfortran.dg/f2003_io_4.f03, gfortran.dg/read_size_noadvance.f90,
......
/* { dg-do compile } */
/* { dg-require-effective-target vect_int } */
#define N 40
int
......@@ -14,5 +16,5 @@ foo (){
return diff;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int_mult } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {642816,660736,678656,696576,714496,732416,750336,768256,786176,804096,822016,839936,857856,875776,893696,911616,929536,947456,965376,983296,1001216,1019136,1037056,1054976,1072896,1090816,1108736,1126656,1144576,1162496,1180416,1198336};
__attribute__ ((noinline)) void
foo ()
{
int sum = 0, i, j, k;
for (k = 0; k < K; k++)
{
sum = 0;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
sum += in[i+k][j] * coeff[i][j];
out[k] = sum;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
coeff[i][j] = i+2;
}
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int_mult } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {357184,339264,321344,303424,285504,267584,249664,231744,213824,195904,177984,160064,142144,124224,106304,88384,70464,52544,34624,16704,-1216,-19136,-37056,-54976,-72896,-90816,-108736,-126656,-144576,-162496,-180416,-198336};
__attribute__ ((noinline)) void
foo ()
{
int res = 0, i, j, k;
for (k = 0; k < K; k++)
{
res = 1000000;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
res -= in[i+k][j] * coeff[i][j];
out[k] = res;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
coeff[i][j] = i+2;
}
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out_max[K], out_min[K];
int check_max[K] = {62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93};
int check_min[K] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
__attribute__ ((noinline)) void
foo (int x, int y)
{
int max, min, i, j, k;
for (k = 0; k < K; k++)
{
max = x;
min = y;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
{
max = max < in[i+k][j] ? in[i+k][j] : max;
min = min > in[i+k][j] ? in[i+k][j] : min;
}
out_max[k] = max;
out_min[k] = min;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
coeff[i][j] = i+2;
}
foo(0, 0);
for (k = 0; k < K; k++)
if (out_max[k] != check_max[k] || out_min[k] != 0)
abort ();
foo(100, 45);
for (k = 0; k < K; k++)
if (out_min[k] != check_min[k] || out_max[k] != 100)
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail vect_no_int_max } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int_mult } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {652816,670736,688656,706576,724496,742416,760336,778256,796176,814096,832016,849936,867856,885776,903696,921616,939536,957456,975376,993296,1011216,1029136,1047056,1064976,1082896,1100816,1118736,1136656,1154576,1172496,1190416,1208336};
__attribute__ ((noinline)) void
foo ()
{
int sum = 0, i, j, k;
for (k = 0; k < K; k++)
{
sum = 10000;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
sum += in[i+k][j] * coeff[i][j];
out[k] = sum;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
coeff[i][j] = i+2;
}
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int_mult } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
signed short in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
signed short coeff[K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {642816,660736,678656,696576,714496,732416,750336,768256,786176,804096,822016,839936,857856,875776,893696,911616,929536,947456,965376,983296,1001216,1019136,1037056,1054976,1072896,1090816,1108736,1126656,1144576,1162496,1180416,1198336};
__attribute__ ((noinline)) void
foo ()
{
int sum = 0, i, j, k;
for (k = 0; k < K; k++)
{
sum = 0;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
sum += in[i+k][j] * coeff[i][j];
out[k] = sum;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
coeff[i][j] = i+2;
}
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* Vectorization of loops with multiple types and double reduction is not
supported yet. */
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int_mult } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 4
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {0,16,256,4096};
__attribute__ ((noinline)) void
foo ()
{
int sum;
int i, j, k;
for (k = 0; k < K; k++)
{
sum = 1;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
sum *= in[i+k][j];
out[k] = sum;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (i = 0; i < 2*K; i++)
for (j = 0; j < K; j++)
in[i][j] = (i+2)/3;
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include <stdio.h>
#include "tree-vect.h"
#define K 32
int in[2*K][K] __attribute__ ((__aligned__(__BIGGEST_ALIGNMENT__)));
int out[K];
int check_result[K] = {63,63,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191,127,127,191,191};
__attribute__ ((noinline)) void
foo ()
{
int res_or, res_and, res_xor, i, j, k;
for (k = 0; k < K; k++)
{
res_or = 0;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
res_or = res_or | in[i+k][j];
res_and = 1;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
res_and = res_and & in[i+k][j];
res_xor = 0;
for (j = 0; j < K; j++)
for (i = 0; i < K; i++)
res_xor = res_xor ^ in[i+k][j];
out[k] = res_or + res_and + res_xor;
}
}
int main ()
{
int i, j, k;
check_vect ();
for (j = 0; j < K; j++)
{
for (i = 0; i < 2*K; i++)
in[i][j] = i+j;
for (i = 0; i < K; i++)
out[i] = i+j;
}
foo();
for (k = 0; k < K; k++)
if (out[k] != check_result[k])
abort ();
return 0;
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 3 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
......@@ -284,13 +284,15 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list,
{
gimple phi = gsi_stmt (gsi);
gimple reduc_stmt = NULL;
bool dummy;
/* ??? TODO: Change this into a generic function that
recognizes reductions. */
if (!is_gimple_reg (PHI_RESULT (phi)))
continue;
if (simple_loop_info)
reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true);
reduc_stmt = vect_is_simple_reduction (simple_loop_info, phi, true,
&dummy);
/* Create a reduction_info struct, initialize it and insert it to
the reduction list. */
......
......@@ -331,7 +331,7 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
...
inner-loop:
d = def_stmt
outer-loop-tail-bb:
outer-loop-tail-bb (or outer-loop-exit-bb in double reduction):
stmt # use (d) */
else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
{
......@@ -341,7 +341,8 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
switch (relevant)
{
case vect_unused_in_scope:
relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) ?
relevant = (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
|| STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_double_reduction_def) ?
vect_used_in_outer_by_reduction : vect_unused_in_scope;
break;
......@@ -393,7 +394,8 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
basic_block bb;
gimple phi;
bool live_p;
enum vect_relevant relevant;
enum vect_relevant relevant, tmp_relevant;
enum vect_def_type def_type;
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
......@@ -465,49 +467,64 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
identify stmts that are used solely by a reduction, and therefore the
order of the results that they produce does not have to be kept. */
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
def_type = STMT_VINFO_DEF_TYPE (stmt_vinfo);
tmp_relevant = relevant;
switch (def_type)
{
enum vect_relevant tmp_relevant = relevant;
switch (tmp_relevant)
{
case vect_unused_in_scope:
gcc_assert (gimple_code (stmt) != GIMPLE_PHI);
relevant = vect_used_by_reduction;
break;
case vect_reduction_def:
switch (tmp_relevant)
{
case vect_unused_in_scope:
relevant = vect_used_by_reduction;
break;
case vect_used_by_reduction:
if (gimple_code (stmt) == GIMPLE_PHI)
break;
/* fall through */
case vect_used_by_reduction:
if (gimple_code (stmt) == GIMPLE_PHI)
break;
/* fall through */
default:
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of reduction.");
VEC_free (gimple, heap, worklist);
return false;
}
default:
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of reduction.");
live_p = false;
}
else if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_nested_cycle)
{
enum vect_relevant tmp_relevant = relevant;
switch (tmp_relevant)
{
case vect_unused_in_scope:
case vect_used_in_outer_by_reduction:
case vect_used_in_outer:
break;
VEC_free (gimple, heap, worklist);
return false;
}
default:
live_p = false;
break;
case vect_nested_cycle:
if (tmp_relevant != vect_unused_in_scope
&& tmp_relevant != vect_used_in_outer_by_reduction
&& tmp_relevant != vect_used_in_outer)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of nested cycle.");
VEC_free (gimple, heap, worklist);
return false;
}
}
live_p = false;
break;
case vect_double_reduction_def:
if (tmp_relevant != vect_unused_in_scope
&& tmp_relevant != vect_used_by_reduction)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "unsupported use of double reduction.");
VEC_free (gimple, heap, worklist);
return false;
}
live_p = false;
break;
live_p = false;
default:
break;
}
FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
......@@ -974,6 +991,7 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
/* Case 4: operand is defined by a loop header phi - reduction */
case vect_reduction_def:
case vect_double_reduction_def:
case vect_nested_cycle:
{
struct loop *loop;
......
......@@ -61,6 +61,7 @@ enum vect_def_type {
vect_internal_def,
vect_induction_def,
vect_reduction_def,
vect_double_reduction_def,
vect_nested_cycle,
vect_unknown_def_type
};
......@@ -822,7 +823,7 @@ extern tree vect_create_addr_base_for_vector_ref (gimple, gimple_seq *,
/* In tree-vect-loop.c. */
/* FORNOW: Used in tree-parloops.c. */
extern void destroy_loop_vec_info (loop_vec_info, bool);
extern gimple vect_is_simple_reduction (loop_vec_info, gimple, bool);
extern gimple vect_is_simple_reduction (loop_vec_info, gimple, bool, bool *);
/* Drive for loop analysis stage. */
extern loop_vec_info vect_analyze_loop (struct loop *);
/* Drive for loop transformation stage. */
......
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