diff options
author | Richard Biener <rguenther@suse.de> | 2015-11-09 12:59:17 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2015-11-09 12:59:17 +0000 |
commit | 64900538f13699c0dc3e314ad35d4b172425d964 (patch) | |
tree | f09f60d6696253def20fa390d7a1c4736c462b37 /gcc | |
parent | cc8ca59eb8522a9530e155f38ac616c15412254b (diff) | |
download | gcc-64900538f13699c0dc3e314ad35d4b172425d964.zip gcc-64900538f13699c0dc3e314ad35d4b172425d964.tar.gz gcc-64900538f13699c0dc3e314ad35d4b172425d964.tar.bz2 |
re PR tree-optimization/56118 (Piecewise vector / complex initialization from constants not combined)
2015-11-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/56118
* tree-vectorizer.h (vect_find_last_scalar_stmt_in_slp): Declare.
* tree-vect-slp.c (vect_find_last_scalar_stmt_in_slp): Export.
* tree-vect-data-refs.c (vect_slp_analyze_node_dependences): New
function.
(vect_slp_analyze_data_ref_dependences): Instead of computing
all dependences of the region DRs just analyze the code motions
SLP vectorization will perform. Remove SLP instances that
cannot have their store/load motions applied.
(vect_analyze_data_refs): Allow DRs without a vectype
in BB vectorization.
* gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c: Adjust.
From-SVN: r230020
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c | 2 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 94 | ||||
-rw-r--r-- | gcc/tree-vect-slp.c | 2 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 1 |
6 files changed, 105 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb6acd5..56c609f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-11-09 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56118 + * tree-vectorizer.h (vect_find_last_scalar_stmt_in_slp): Declare. + * tree-vect-slp.c (vect_find_last_scalar_stmt_in_slp): Export. + * tree-vect-data-refs.c (vect_slp_analyze_node_dependences): New + function. + (vect_slp_analyze_data_ref_dependences): Instead of computing + all dependences of the region DRs just analyze the code motions + SLP vectorization will perform. Remove SLP instances that + cannot have their store/load motions applied. + (vect_analyze_data_refs): Allow DRs without a vectype + in BB vectorization. + 2015-11-09 Julian Brown <julian@codesourcery.com> * final.c (output_asm_insn): Pass VOIDmode to output_address. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cd50cd..3809a72 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-09 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56118 + * gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c: Adjust. + 2015-11-09 Thomas Preud'homme <thomas.preudhomme@arm.com> * gcc.target/arm/thumb2-slow-flash-data.c: Add missing typespec for diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c b/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c index e7328fc..8fe67f4 100644 --- a/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c +++ b/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c @@ -13,4 +13,4 @@ A sum(A a,A b) return a; } -/* { dg-final { scan-tree-dump-times "not vectorized: more than one data ref in stmt" 0 "slp2" } } */ +/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */ diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 11bce79..6e32391 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -559,6 +559,49 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) } +/* Analyze dependences involved in the transform of SLP NODE. */ + +static bool +vect_slp_analyze_node_dependences (slp_instance instance, slp_tree node) +{ + /* This walks over all stmts involved in the SLP load/store done + in NODE verifying we can sink them up to the last stmt in the + group. */ + gimple *last_access = vect_find_last_scalar_stmt_in_slp (node); + for (unsigned k = 0; k < SLP_INSTANCE_GROUP_SIZE (instance); ++k) + { + gimple *access = SLP_TREE_SCALAR_STMTS (node)[k]; + if (access == last_access) + continue; + stmt_vec_info access_stmt_info = vinfo_for_stmt (access); + gimple_stmt_iterator gsi = gsi_for_stmt (access); + gsi_next (&gsi); + for (; gsi_stmt (gsi) != last_access; gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + stmt_vec_info stmt_info = vinfo_for_stmt (stmt); + if (!STMT_VINFO_DATA_REF (stmt_info) + || (DR_IS_READ (STMT_VINFO_DATA_REF (stmt_info)) + && DR_IS_READ (STMT_VINFO_DATA_REF (access_stmt_info)))) + continue; + + ddr_p ddr = initialize_data_dependence_relation + (STMT_VINFO_DATA_REF (access_stmt_info), + STMT_VINFO_DATA_REF (stmt_info), vNULL); + if (vect_slp_analyze_data_ref_dependence (ddr)) + { + /* ??? If the dependence analysis failed we can resort to the + alias oracle which can handle more kinds of stmts. */ + free_dependence_relation (ddr); + return false; + } + free_dependence_relation (ddr); + } + } + return true; +} + + /* Function vect_analyze_data_ref_dependences. Examine all the data references in the basic-block, and make sure there @@ -568,21 +611,45 @@ vect_slp_analyze_data_ref_dependence (struct data_dependence_relation *ddr) bool vect_slp_analyze_data_ref_dependences (bb_vec_info bb_vinfo) { - struct data_dependence_relation *ddr; - unsigned int i; - if (dump_enabled_p ()) dump_printf_loc (MSG_NOTE, vect_location, "=== vect_slp_analyze_data_ref_dependences ===\n"); - if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo), - &BB_VINFO_DDRS (bb_vinfo), - vNULL, true)) - return false; + slp_instance instance; + slp_tree load; + unsigned int i, j; + for (i = 0; BB_VINFO_SLP_INSTANCES (bb_vinfo).iterate (i, &instance); ) + { + bool remove = false; + /* Verify we can sink loads to the vectorized stmt insert location. */ + FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), j, load) + if (! vect_slp_analyze_node_dependences (instance, load)) + { + remove = true; + break; + } + /* Verify we can sink stores to the vectorized stmt insert location. */ + slp_tree store = SLP_INSTANCE_TREE (instance); + if (!remove + && STMT_VINFO_DATA_REF + (vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (store)[0])) + && ! vect_slp_analyze_node_dependences (instance, store)) + remove = true; + if (remove) + { + dump_printf_loc (MSG_NOTE, vect_location, + "removing SLP instance operations starting from: "); + dump_gimple_stmt (MSG_NOTE, TDF_SLIM, + SLP_TREE_SCALAR_STMTS + (SLP_INSTANCE_TREE (instance))[0], 0); + vect_free_slp_instance (instance); + BB_VINFO_SLP_INSTANCES (bb_vinfo).ordered_remove (i); + } + i++; + } - FOR_EACH_VEC_ELT (BB_VINFO_DDRS (bb_vinfo), i, ddr) - if (vect_slp_analyze_data_ref_dependence (ddr)) - return false; + if (!BB_VINFO_SLP_INSTANCES (bb_vinfo).length ()) + return false; return true; } @@ -3674,7 +3741,12 @@ again: } if (is_a <bb_vec_info> (vinfo)) - break; + { + /* No vector type is fine, the ref can still participate + in dependence analysis, we just can't vectorize it. */ + STMT_VINFO_VECTORIZABLE (stmt_info) = false; + continue; + } if (gatherscatter != SG_NONE || simd_lane_access) { diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c index cfdfc29..954b85e 100644 --- a/gcc/tree-vect-slp.c +++ b/gcc/tree-vect-slp.c @@ -1426,7 +1426,7 @@ vect_supported_load_permutation_p (slp_instance slp_instn) /* Find the last store in SLP INSTANCE. */ -static gimple * +gimple * vect_find_last_scalar_stmt_in_slp (slp_tree node) { gimple *last = NULL, *stmt; diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index 9cde091..fed80c8 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -1075,6 +1075,7 @@ extern void vect_detect_hybrid_slp (loop_vec_info); extern void vect_get_slp_defs (vec<tree> , slp_tree, vec<vec<tree> > *, int); extern bool vect_slp_bb (basic_block); +extern gimple *vect_find_last_scalar_stmt_in_slp (slp_tree); /* In tree-vect-patterns.c. */ /* Pattern recognition functions. |