aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-04 10:40:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-04 10:40:35 +0000
commit9adee3052156ae36271be28e3ad47dd975c26f42 (patch)
tree6f0ef701d303fb3c40566aa3bcbea2eea6ba1a52 /gcc/tree-vect-data-refs.c
parentdfbddbeb1ca912c9f9f806d8cff55a6ac2887d89 (diff)
downloadgcc-9adee3052156ae36271be28e3ad47dd975c26f42.zip
gcc-9adee3052156ae36271be28e3ad47dd975c26f42.tar.gz
gcc-9adee3052156ae36271be28e3ad47dd975c26f42.tar.bz2
Use base inequality for some vector alias checks
This patch checks whether two data references x and y cannot partially overlap and so are independent whenever &x != &y. We can then use this in the vectoriser to optimise alias checks. gcc/ 2016-08-04 Richard Sandiford <richard.sandiford@linaro.org> * hash-traits.h (pair_hash): New struct. * tree-data-ref.h (data_dependence_relation): Add object_a and object_b fields. (DDR_OBJECT_A, DDR_OBJECT_B): New macros. * tree-data-ref.c (initialize_data_dependence_relation): Initialize DDR_OBJECT_A and DDR_OBJECT_B. * tree-vectorizer.h (vec_object_pair): New type. (_loop_vec_info): Add a check_unequal_addrs field. (LOOP_VINFO_CHECK_UNEQUAL_ADDRS): New macro. (LOOP_REQUIRES_VERSIONING_FOR_ALIAS): Return true if there is an entry in check_unequal_addrs. Check comp_alias_ddrs instead of may_alias_ddrs. * tree-vect-loop.c (destroy_loop_vec_info): Release LOOP_VINFO_CHECK_UNEQUAL_ADDRS. (vect_analyze_loop_2): Likewise, when restarting. (vect_estimate_min_profitable_iters): Estimate the cost of LOOP_VINFO_CHECK_UNEQUAL_ADDRS. * tree-vect-data-refs.c: Include tree-hash-traits.h. (vect_prune_runtime_alias_test_list): Try to handle conflicts using LOOP_VINFO_CHECK_UNEQUAL_ADDRS, if the data dependence allows. Count such tests in the final summary. * tree-vect-loop-manip.c (chain_cond_expr): New function. (vect_create_cond_for_align_checks): Use it. (vect_create_cond_for_unequal_addrs): New function. (vect_loop_versioning): Call it. gcc/testsuite/ * gcc.dg/vect/vect-alias-check-6.c: New test. From-SVN: r250868
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 377cb90..a91e304 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "params.h"
#include "tree-cfg.h"
+#include "tree-hash-traits.h"
/* Return true if load- or store-lanes optab OPTAB is implemented for
COUNT vectors of type VECTYPE. NAME is the name of OPTAB. */
@@ -2986,10 +2987,14 @@ dependence_distance_ge_vf (data_dependence_relation *ddr,
bool
vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
{
- vec<ddr_p> may_alias_ddrs =
- LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
- vec<dr_with_seg_len_pair_t>& comp_alias_ddrs =
- LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
+ typedef pair_hash <tree_operand_hash, tree_operand_hash> tree_pair_hash;
+ hash_set <tree_pair_hash> compared_objects;
+
+ vec<ddr_p> may_alias_ddrs = LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
+ vec<dr_with_seg_len_pair_t> &comp_alias_ddrs
+ = LOOP_VINFO_COMP_ALIAS_DDRS (loop_vinfo);
+ vec<vec_object_pair> &check_unequal_addrs
+ = LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo);
int vect_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
@@ -3024,6 +3029,24 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
if (dependence_distance_ge_vf (ddr, loop_depth, vect_factor))
continue;
+ if (DDR_OBJECT_A (ddr))
+ {
+ vec_object_pair new_pair (DDR_OBJECT_A (ddr), DDR_OBJECT_B (ddr));
+ if (!compared_objects.add (new_pair))
+ {
+ if (dump_enabled_p ())
+ {
+ dump_printf_loc (MSG_NOTE, vect_location, "checking that ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, new_pair.first);
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, new_pair.second);
+ dump_printf (MSG_NOTE, " have different addresses\n");
+ }
+ LOOP_VINFO_CHECK_UNEQUAL_ADDRS (loop_vinfo).safe_push (new_pair);
+ }
+ continue;
+ }
+
dr_a = DDR_A (ddr);
stmt_a = DR_STMT (DDR_A (ddr));
dr_group_first_a = GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt_a));
@@ -3085,11 +3108,13 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
prune_runtime_alias_test_list (&comp_alias_ddrs,
(unsigned HOST_WIDE_INT) vect_factor);
+
+ unsigned int count = (comp_alias_ddrs.length ()
+ + check_unequal_addrs.length ());
dump_printf_loc (MSG_NOTE, vect_location,
"improved number of alias checks from %d to %d\n",
- may_alias_ddrs.length (), comp_alias_ddrs.length ());
- if ((int) comp_alias_ddrs.length () >
- PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
+ may_alias_ddrs.length (), count);
+ if ((int) count > PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,