diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-11-16 11:35:56 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-11-16 11:35:56 +0000 |
commit | 97602450b04e94aff034381bf6ee4236b95727ed (patch) | |
tree | 45dcf86cca2f2d8eab5e7ee415a8178c663c9eea /gcc | |
parent | 1fb2b0f69ee849142b669ba1b82264ce6d0f75f9 (diff) | |
download | gcc-97602450b04e94aff034381bf6ee4236b95727ed.zip gcc-97602450b04e94aff034381bf6ee4236b95727ed.tar.gz gcc-97602450b04e94aff034381bf6ee4236b95727ed.tar.bz2 |
Delay swapping data refs in prune_runtime_alias_test_list
prune_runtime_alias_test_list swapped dr_as between two dr_with_seg_len
pairs before finally deciding whether to merge them. Bailing out later
would therefore leave the pairs in an incorrect state.
IMO a better fix would be to split this out into a subroutine that
produces a temporary dr_with_seg_len on success, rather than changing
an existing one in-place. It would then be easy to merge both the dr_as
and dr_bs if we wanted to, rather than requiring one of them to be equal.
But here I tried to do something that could be backported if necessary.
2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* tree-data-ref.c (prune_runtime_alias_test_list): Delay
swapping the dr_as based on init values until we've decided
whether to merge them.
From-SVN: r278349
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-data-ref.c | 24 |
2 files changed, 21 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f75f3cb..572eaeb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2019-11-16 Richard Sandiford <richard.sandiford@arm.com> + * tree-data-ref.c (prune_runtime_alias_test_list): Delay + swapping the dr_as based on init values until we've decided + whether to merge them. + +2019-11-16 Richard Sandiford <richard.sandiford@arm.com> + * tree-data-ref.c (prune_runtime_alias_test_list): Sort the two accesses in each dr_with_seg_len_pair_t before trying to combine separate dr_with_seg_len_pair_ts. diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index b31ed42..cf4fb26 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -1555,13 +1555,6 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, if (!ordered_p (init_a1, init_a2)) continue; - /* Make sure dr_a1 starts left of dr_a2. */ - if (maybe_gt (init_a1, init_a2)) - { - std::swap (*dr_a1, *dr_a2); - std::swap (init_a1, init_a2); - } - /* Work out what the segment length would be if we did combine DR_A1 and DR_A2: @@ -1578,7 +1571,10 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, The lengths both have sizetype, so the sign is taken from the step instead. */ - if (!operand_equal_p (dr_a1->seg_len, dr_a2->seg_len, 0)) + poly_uint64 new_seg_len = 0; + bool new_seg_len_p = !operand_equal_p (dr_a1->seg_len, + dr_a2->seg_len, 0); + if (new_seg_len_p) { poly_uint64 seg_len_a1, seg_len_a2; if (!poly_int_tree_p (dr_a1->seg_len, &seg_len_a1) @@ -1596,14 +1592,24 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, int sign_a = tree_int_cst_sgn (indicator_a); int sign_b = tree_int_cst_sgn (indicator_b); - poly_uint64 new_seg_len; if (sign_a <= 0 && sign_b <= 0) new_seg_len = lower_bound (seg_len_a1, seg_len_a2); else if (sign_a >= 0 && sign_b >= 0) new_seg_len = upper_bound (seg_len_a1, seg_len_a2); else continue; + } + /* At this point we're committed to merging the refs. */ + /* Make sure dr_a1 starts left of dr_a2. */ + if (maybe_gt (init_a1, init_a2)) + { + std::swap (*dr_a1, *dr_a2); + std::swap (init_a1, init_a2); + } + + if (new_seg_len_p) + { dr_a1->seg_len = build_int_cst (TREE_TYPE (dr_a1->seg_len), new_seg_len); dr_a1->align = MIN (dr_a1->align, known_alignment (new_seg_len)); |