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:
parent
c801c273a6
commit
5e038cad0b
@ -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.
|
||||
|
@ -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
|
||||
|
21
gcc/testsuite/gcc.dg/vect/pr37482.c
Normal file
21
gcc/testsuite/gcc.dg/vect/pr37482.c
Normal 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" } } */
|
||||
|
@ -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));
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user