This patch makes prune_runtime_alias_test_list take the iteration
factor as a poly_int and tracks polynomial offsets internally
as well.
2017-10-23 Richard Sandiford
Alan Hayward
David Sherwood
gcc/
* tree-data-ref.h (prune_runtime_alias_test_list): Take the
factor as a poly_uint64 rather than an unsigned HOST_WIDE_INT.
* tree-data-ref.c (prune_runtime_alias_test_list): Likewise.
Track polynomial offsets.
Index: gcc/tree-data-ref.h
===
--- gcc/tree-data-ref.h 2017-10-13 10:23:39.775145588 +0100
+++ gcc/tree-data-ref.h 2017-10-23 17:22:25.492282436 +0100
@@ -472,7 +472,7 @@ extern bool dr_equal_offsets_p (struct d
extern bool runtime_alias_check_p (ddr_p, struct loop *, bool);
extern int data_ref_compare_tree (tree, tree);
extern void prune_runtime_alias_test_list (vec *,
- unsigned HOST_WIDE_INT);
+ poly_uint64);
extern void create_runtime_alias_checks (struct loop *,
vec *, tree*);
/* Return true when the base objects of data references A and B are
Index: gcc/tree-data-ref.c
===
--- gcc/tree-data-ref.c 2017-10-23 17:22:18.231825655 +0100
+++ gcc/tree-data-ref.c 2017-10-23 17:22:25.492282436 +0100
@@ -1417,7 +1417,7 @@ comp_dr_with_seg_len_pair (const void *p
void
prune_runtime_alias_test_list (vec *alias_pairs,
- unsigned HOST_WIDE_INT factor)
+ poly_uint64 factor)
{
/* Sort the collected data ref pairs so that we can scan them once to
combine all possible aliasing checks. */
@@ -1462,51 +1462,63 @@ prune_runtime_alias_test_list (vecdr),
DR_BASE_ADDRESS (dr_a2->dr), 0)
|| !operand_equal_p (DR_OFFSET (dr_a1->dr),
DR_OFFSET (dr_a2->dr), 0)
- || !tree_fits_shwi_p (DR_INIT (dr_a1->dr))
- || !tree_fits_shwi_p (DR_INIT (dr_a2->dr)))
+ || !poly_int_tree_p (DR_INIT (dr_a1->dr), _a1)
+ || !poly_int_tree_p (DR_INIT (dr_a2->dr), _a2))
continue;
+ /* Don't combine if we can't tell which one comes first. */
+ if (!ordered_p (init_a1, init_a2))
+ continue;
+
+ /* Make sure dr_a1 starts left of dr_a2. */
+ if (may_gt (init_a1, init_a2))
+ {
+ std::swap (*dr_a1, *dr_a2);
+ std::swap (init_a1, init_a2);
+ }
+
/* Only merge const step data references. */
- if (TREE_CODE (DR_STEP (dr_a1->dr)) != INTEGER_CST
- || TREE_CODE (DR_STEP (dr_a2->dr)) != INTEGER_CST)
+ poly_int64 step_a1, step_a2;
+ if (!poly_int_tree_p (DR_STEP (dr_a1->dr), _a1)
+ || !poly_int_tree_p (DR_STEP (dr_a2->dr), _a2))
continue;
- /* DR_A1 and DR_A2 must goes in the same direction. */
- if (tree_int_cst_compare (DR_STEP (dr_a1->dr), size_zero_node)
- != tree_int_cst_compare (DR_STEP (dr_a2->dr), size_zero_node))
+ bool neg_step = may_lt (step_a1, 0) || may_lt (step_a2, 0);
+
+ /* DR_A1 and DR_A2 must go in the same direction. */
+ if (neg_step && (may_gt (step_a1, 0) || may_gt (step_a2, 0)))
continue;
- bool neg_step
- = (tree_int_cst_compare (DR_STEP (dr_a1->dr), size_zero_node) < 0);
+ poly_uint64 seg_len_a1 = 0, seg_len_a2 = 0;
+ bool const_seg_len_a1 = poly_int_tree_p (dr_a1->seg_len,
+ _len_a1);
+ bool const_seg_len_a2 = poly_int_tree_p (dr_a2->seg_len,
+ _len_a2);
/* We need to compute merged segment length at compilation time for
dr_a1 and dr_a2, which is impossible if either one has non-const
segment length. */
- if ((!tree_fits_uhwi_p (dr_a1->seg_len)
- || !tree_fits_uhwi_p (dr_a2->seg_len))
- && tree_int_cst_compare (DR_STEP (dr_a1->dr),
- DR_STEP (dr_a2->dr)) != 0)
+ if ((!const_seg_len_a1 || !const_seg_len_a2)
+ && may_ne (step_a1, step_a2))
continue;
- /* Make sure dr_a1 starts left of dr_a2. */
- if (tree_int_cst_lt (DR_INIT (dr_a2->dr), DR_INIT (dr_a1->dr)))
- std::swap (*dr_a1, *dr_a2);
-
bool do_remove = false;
- wide_int diff = (wi::to_wide (DR_INIT (dr_a2->dr))
- - wi::to_wide (DR_INIT (dr_a1->dr)));
- wide_int min_seg_len_b;
+ poly_uint64 diff = init_a2 - init_a1;
+ poly_uint64 min_seg_len_b;
tree new_seg_len;
- if