re PR tree-optimization/37482 (definition in block 51 follows the use for SSA_NAME with -maltivec)

PR tree-optimization/37482
	* tree-vectorizer.h (struct _slp_instance): Add new field.
	(SLP_INSTANCE_FIRST_LOAD_STMT): New.
	(get_earlier_stmt): New function.
	* tree-vect-analyze.c (vect_find_first_load_in_slp_instance): New
	function.
	(vect_analyze_slp_instance): Set SLP_INSTANCE_FIRST_LOAD_STMT.
	* tree-vect-transform.c (vect_finish_stmt_generation): Remove the
	asserts that GSI points to the scalar statement being vectorized.
	Set new statement location according to GSI.
	(vect_schedule_slp_instance): Use GSI of
	SLP_INSTANCE_FIRST_LOAD_STMT when vectorizing loads.

From-SVN: r140544
This commit is contained in:
Ira Rosen 2008-09-22 07:55:39 +00:00 committed by Ira Rosen
parent c801c273a6
commit 5e038cad0b
6 changed files with 114 additions and 9 deletions

View File

@ -1,3 +1,18 @@
2008-09-22 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/37482
* tree-vectorizer.h (struct _slp_instance): Add new field.
(SLP_INSTANCE_FIRST_LOAD_STMT): New.
(get_earlier_stmt): New function.
* tree-vect-analyze.c (vect_find_first_load_in_slp_instance): New
function.
(vect_analyze_slp_instance): Set SLP_INSTANCE_FIRST_LOAD_STMT.
* tree-vect-transform.c (vect_finish_stmt_generation): Remove the
asserts that GSI points to the scalar statement being vectorized.
Set new statement location according to GSI.
(vect_schedule_slp_instance): Use GSI of
SLP_INSTANCE_FIRST_LOAD_STMT when vectorizing loads.
2008-09-21 Jan Hubicka <jh@suse.cz>
* ipa-cp.c (ipcp_estimate_growth): Check recursive calls.

View File

@ -1,3 +1,8 @@
2008-09-22 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/37482
* gcc.dg/vect/pr37482.c: New test.
2008-09-22 Hans-Peter Nilsson <hp@axis.com>
PR middle-end/37170

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-require-effective-target vect_int } */
void SexiALI_Convert(void *vdest, void *vsrc, unsigned int frames)
{
unsigned int x;
short *src = vsrc;
unsigned char *dest = vdest;
for(x=0;x<256;x++)
{
int tmp;
tmp = *src;
src++;
tmp += *src;
src++;
*dest++ = tmp;
*dest++ = tmp;
}
}
/* { dg-final { cleanup-tree-dump "vect" } } */

View File

@ -3228,6 +3228,32 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
return false;
}
/* Find the first load in the loop that belongs to INSTANCE.
When loads are in several SLP nodes, there can be a case in which the first
load does not appear in the first SLP node to be transformed, causing
incorrect order of statements. Since we generate all the loads together,
they must be inserted before the first load of the SLP instance and not
before the first load of the first node of the instance. */
static gimple
vect_find_first_load_in_slp_instance (slp_instance instance)
{
int i, j;
slp_tree load_node;
gimple first_load = NULL, load;
for (i = 0;
VEC_iterate (slp_tree, SLP_INSTANCE_LOADS (instance), i, load_node);
i++)
for (j = 0;
VEC_iterate (gimple, SLP_TREE_SCALAR_STMTS (load_node), j, load);
j++)
first_load = get_earlier_stmt (load, first_load);
return first_load;
}
/* Analyze an SLP instance starting from a group of strided stores. Call
vect_build_slp_tree to build a tree of packed stmts if possible.
Return FALSE if it's impossible to SLP any stmt in the loop. */
@ -3312,6 +3338,7 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
SLP_INSTANCE_OUTSIDE_OF_LOOP_COST (new_instance) = outside_cost;
SLP_INSTANCE_INSIDE_OF_LOOP_COST (new_instance) = inside_cost;
SLP_INSTANCE_LOADS (new_instance) = loads;
SLP_INSTANCE_FIRST_LOAD_STMT (new_instance) = NULL;
SLP_INSTANCE_LOAD_PERMUTATION (new_instance) = load_permutation;
if (VEC_length (slp_tree, loads))
{
@ -3328,6 +3355,9 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, gimple stmt)
vect_free_slp_instance (new_instance);
return false;
}
SLP_INSTANCE_FIRST_LOAD_STMT (new_instance)
= vect_find_first_load_in_slp_instance (new_instance);
}
else
VEC_free (int, heap, SLP_INSTANCE_LOAD_PERMUTATION (new_instance));

View File

@ -2155,7 +2155,6 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
gcc_assert (stmt == gsi_stmt (*gsi));
gcc_assert (gimple_code (stmt) != GIMPLE_LABEL);
gsi_insert_before (gsi, vec_stmt, GSI_SAME_STMT);
@ -2168,10 +2167,7 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
print_gimple_stmt (vect_dump, vec_stmt, 0, TDF_SLIM);
}
/* Make sure gsi points to the stmt that is being vectorized. */
gcc_assert (stmt == gsi_stmt (*gsi));
gimple_set_location (vec_stmt, gimple_location (stmt));
gimple_set_location (vec_stmt, gimple_location (gsi_stmt (*gsi)));
}
@ -8156,7 +8152,7 @@ vect_remove_stores (gimple first_stmt)
static bool
vect_schedule_slp_instance (slp_tree node, slp_instance instance,
unsigned int vectorization_factor)
unsigned int vectorization_factor)
{
gimple stmt;
bool strided_store, is_store;
@ -8177,6 +8173,7 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
stmt = VEC_index (gimple, SLP_TREE_SCALAR_STMTS (node), 0);
stmt_info = vinfo_for_stmt (stmt);
/* VECTYPE is the type of the destination. */
vectype = get_vectype_for_scalar_type (TREE_TYPE (gimple_assign_lhs (stmt)));
nunits = (unsigned int) TYPE_VECTOR_SUBPARTS (vectype);
@ -8218,7 +8215,14 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
}
si = gsi_for_stmt (stmt);
/* Loads should be inserted before the first load. */
if (SLP_INSTANCE_FIRST_LOAD_STMT (instance)
&& STMT_VINFO_STRIDED_ACCESS (stmt_info)
&& !REFERENCE_CLASS_P (gimple_get_lhs (stmt)))
si = gsi_for_stmt (SLP_INSTANCE_FIRST_LOAD_STMT (instance));
else
si = gsi_for_stmt (stmt);
is_store = vect_transform_stmt (stmt, &si, &strided_store, node, instance);
if (is_store)
{
@ -8252,8 +8256,7 @@ vect_schedule_slp (loop_vec_info loop_vinfo)
{
/* Schedule the tree of INSTANCE. */
is_store = vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance),
instance,
LOOP_VINFO_VECT_FACTOR (loop_vinfo));
instance, LOOP_VINFO_VECT_FACTOR (loop_vinfo));
if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS)
|| vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))

View File

@ -133,6 +133,10 @@ typedef struct _slp_instance {
/* The group of nodes that contain loads of this SLP instance. */
VEC (slp_tree, heap) *loads;
/* The first scalar load of the instance. The created vector loads will be
inserted before this statement. */
gimple first_load;
} *slp_instance;
DEF_VEC_P(slp_instance);
@ -146,6 +150,7 @@ DEF_VEC_ALLOC_P(slp_instance, heap);
#define SLP_INSTANCE_INSIDE_OF_LOOP_COST(S) (S)->cost.inside_of_loop
#define SLP_INSTANCE_LOAD_PERMUTATION(S) (S)->load_permutation
#define SLP_INSTANCE_LOADS(S) (S)->loads
#define SLP_INSTANCE_FIRST_LOAD_STMT(S) (S)->first_load
#define SLP_TREE_LEFT(S) (S)->left
#define SLP_TREE_RIGHT(S) (S)->right
@ -578,6 +583,32 @@ set_vinfo_for_stmt (gimple stmt, stmt_vec_info info)
VEC_replace (vec_void_p, stmt_vec_info_vec, uid - 1, (vec_void_p) info);
}
static inline gimple
get_earlier_stmt (gimple stmt1, gimple stmt2)
{
unsigned int uid1, uid2;
if (stmt1 == NULL)
return stmt2;
if (stmt2 == NULL)
return stmt1;
uid1 = gimple_uid (stmt1);
uid2 = gimple_uid (stmt2);
if (uid1 == 0 || uid2 == 0)
return NULL;
gcc_assert (uid1 <= VEC_length (vec_void_p, stmt_vec_info_vec));
gcc_assert (uid2 <= VEC_length (vec_void_p, stmt_vec_info_vec));
if (uid1 < uid2)
return stmt1;
else
return stmt2;
}
static inline bool
is_pattern_stmt_p (stmt_vec_info stmt_info)
{