aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-data-ref.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-11-16 11:40:22 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-11-16 11:40:22 +0000
commite9acf80c96d681917d930869b7cbfb7d2fa54d51 (patch)
tree0ccbb5b5dbff8afd58730f89b2eaa07d16f54ac5 /gcc/tree-data-ref.c
parent97602450b04e94aff034381bf6ee4236b95727ed (diff)
downloadgcc-e9acf80c96d681917d930869b7cbfb7d2fa54d51.zip
gcc-e9acf80c96d681917d930869b7cbfb7d2fa54d51.tar.gz
gcc-e9acf80c96d681917d930869b7cbfb7d2fa54d51.tar.bz2
Add flags to dr_with_seg_len_pair_t
This patch adds a bunch of flags to dr_with_seg_len_pair_t, for use by later patches. The update to tree-loop-distribution.c is conservatively correct, but might be tweakable later. 2019-11-16 Richard Sandiford <richard.sandiford@arm.com> gcc/ * tree-data-ref.h (DR_ALIAS_RAW, DR_ALIAS_WAR, DR_ALIAS_WAW) (DR_ALIAS_ARBITRARY, DR_ALIAS_SWAPPED, DR_ALIAS_UNSWAPPED): New flags. (dr_with_seg_len_pair_t::sequencing): New enum. (dr_with_seg_len_pair_t::flags): New member variable. (dr_with_seg_len_pair_t::dr_with_seg_len_pair_t): Take a sequencing parameter and initialize the flags member variable. * tree-loop-distribution.c (compute_alias_check_pairs): Update call accordingly. * tree-vect-data-refs.c (vect_prune_runtime_alias_test_list): Likewise. Ensure the two data references in an alias pair are in statement order, if there is a defined order. * tree-data-ref.c (prune_runtime_alias_test_list): Use DR_ALIAS_SWAPPED and DR_ALIAS_UNSWAPPED to record whether we've swapped the references in a dr_with_seg_len_pair_t. OR together the flags when merging two dr_with_seg_len_pair_ts. After merging, try to restore the original dr_with_seg_len order, updating the flags if that fails. From-SVN: r278350
Diffstat (limited to 'gcc/tree-data-ref.c')
-rw-r--r--gcc/tree-data-ref.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index cf4fb26..21cd2ad 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1502,7 +1502,12 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
if (comp_res == 0)
comp_res = data_ref_compare_tree (DR_INIT (dr_a), DR_INIT (dr_b));
if (comp_res > 0)
- std::swap (alias_pair->first, alias_pair->second);
+ {
+ std::swap (alias_pair->first, alias_pair->second);
+ alias_pair->flags |= DR_ALIAS_SWAPPED;
+ }
+ else
+ alias_pair->flags |= DR_ALIAS_UNSWAPPED;
}
/* Sort the collected data ref pairs so that we can scan them once to
@@ -1514,10 +1519,13 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
for (i = 1; i < alias_pairs->length (); ++i)
{
/* Deal with two ddrs (dr_a1, dr_b1) and (dr_a2, dr_b2). */
- dr_with_seg_len *dr_a1 = &(*alias_pairs)[i-1].first,
- *dr_b1 = &(*alias_pairs)[i-1].second,
- *dr_a2 = &(*alias_pairs)[i].first,
- *dr_b2 = &(*alias_pairs)[i].second;
+ dr_with_seg_len_pair_t *alias_pair1 = &(*alias_pairs)[i - 1];
+ dr_with_seg_len_pair_t *alias_pair2 = &(*alias_pairs)[i];
+
+ dr_with_seg_len *dr_a1 = &alias_pair1->first;
+ dr_with_seg_len *dr_b1 = &alias_pair1->second;
+ dr_with_seg_len *dr_a2 = &alias_pair2->first;
+ dr_with_seg_len *dr_b2 = &alias_pair2->second;
/* Remove duplicate data ref pairs. */
if (*dr_a1 == *dr_a2 && *dr_b1 == *dr_b2)
@@ -1526,6 +1534,7 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
dump_printf (MSG_NOTE, "found equal ranges %T, %T and %T, %T\n",
DR_REF (dr_a1->dr), DR_REF (dr_b1->dr),
DR_REF (dr_a2->dr), DR_REF (dr_b2->dr));
+ alias_pair1->flags |= alias_pair2->flags;
alias_pairs->ordered_remove (i--);
continue;
}
@@ -1631,10 +1640,26 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
dump_printf (MSG_NOTE, "merging ranges for %T, %T and %T, %T\n",
DR_REF (dr_a1->dr), DR_REF (dr_b1->dr),
DR_REF (dr_a2->dr), DR_REF (dr_b2->dr));
+ alias_pair1->flags |= alias_pair2->flags;
alias_pairs->ordered_remove (i);
i--;
}
}
+
+ /* Try to restore the original dr_with_seg_len order within each
+ dr_with_seg_len_pair_t. If we ended up combining swapped and
+ unswapped pairs into the same check, we have to invalidate any
+ RAW, WAR and WAW information for it. */
+ FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair)
+ {
+ unsigned int swap_mask = (DR_ALIAS_SWAPPED | DR_ALIAS_UNSWAPPED);
+ unsigned int swapped = (alias_pair->flags & swap_mask);
+ if (swapped == DR_ALIAS_SWAPPED)
+ std::swap (alias_pair->first, alias_pair->second);
+ else if (swapped != DR_ALIAS_UNSWAPPED)
+ alias_pair->flags |= DR_ALIAS_ARBITRARY;
+ alias_pair->flags &= ~swap_mask;
+ }
}
/* Given LOOP's two data references and segment lengths described by DR_A