From 5e038cad0bb468177c7adad1faebf3465ecda0fd Mon Sep 17 00:00:00 2001 From: Ira Rosen Date: Mon, 22 Sep 2008 07:55:39 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 ++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/vect/pr37482.c | 21 +++++++++++++++++++ gcc/tree-vect-analyze.c | 30 ++++++++++++++++++++++++++++ gcc/tree-vect-transform.c | 21 ++++++++++--------- gcc/tree-vectorizer.h | 31 +++++++++++++++++++++++++++++ 6 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/vect/pr37482.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9f67a4c0e91..0987ef03723 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2008-09-22 Ira Rosen + + 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 * ipa-cp.c (ipcp_estimate_growth): Check recursive calls. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ca0e70872a9..2af0a0e182f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-09-22 Ira Rosen + + PR tree-optimization/37482 + * gcc.dg/vect/pr37482.c: New test. + 2008-09-22 Hans-Peter Nilsson PR middle-end/37170 diff --git a/gcc/testsuite/gcc.dg/vect/pr37482.c b/gcc/testsuite/gcc.dg/vect/pr37482.c new file mode 100644 index 00000000000..0b3bed33afa --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr37482.c @@ -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" } } */ + diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c index 405ac35d9f0..c97b3fa1014 100644 --- a/gcc/tree-vect-analyze.c +++ b/gcc/tree-vect-analyze.c @@ -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)); diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c index 4965da4ad0c..d004aadee7b 100644 --- a/gcc/tree-vect-transform.c +++ b/gcc/tree-vect-transform.c @@ -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)) diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 678dc59da72..84bd8ccd04d 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -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) { -- 2.30.2