From 64900538f13699c0dc3e314ad35d4b172425d964 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 9 Nov 2015 12:59:17 +0000 Subject: [PATCH] re PR tree-optimization/56118 (Piecewise vector / complex initialization from constants not combined) 2015-11-09 Richard Biener 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 --- gcc/ChangeLog | 14 +++ gcc/testsuite/ChangeLog | 5 + .../gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c | 2 +- gcc/tree-vect-data-refs.c | 94 ++++++++++++++++--- gcc/tree-vect-slp.c | 2 +- gcc/tree-vectorizer.h | 1 + 6 files changed, 105 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb6acd5f6d8..56c609fc9ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-11-09 Richard Biener + + 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 * final.c (output_asm_insn): Pass VOIDmode to output_address. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4cd50cdef13..3809a723828 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-11-09 Richard Biener + + PR tree-optimization/56118 + * gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c: Adjust. + 2015-11-09 Thomas Preud'homme * 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 e7328fcdd21..8fe67f45faa 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 11bce795a5e..6e323911d93 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 (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 cfdfc2936a1..954b85ef8bc 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 9cde091bde9..fed80c81c3f 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 , slp_tree, vec > *, 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. -- 2.30.2