Commit cad984b2 by Richard Sandiford Committed by Richard Sandiford

Dump the list of merged alias pairs

This patch dumps the final (merged) list of alias pairs.  It also adds:

- WAW and RAW versions of vect-alias-check-8.c
- a "well-ordered" version of vect-alias-check-9.c (i.e. all reads
  before any writes)
- a test with mixed steps in the same alias pair

I also tweaked the test value in vect-alias-check-9.c so that the
result was less likely to be accidentally correct if the alias
isn't honoured.

2019-11-16  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* tree-data-ref.c (dump_alias_pair): New function.
	(prune_runtime_alias_test_list): Use it to dump each merged alias pair.

gcc/testsuite/
	* gcc.dg/vect/vect-alias-check-8.c: Test for the RAW flag.
	* gcc.dg/vect/vect-alias-check-9.c: Test for the ARBITRARY flag.
	(TEST_VALUE): Use a higher value for early iterations.
	* gcc.dg/vect/vect-alias-check-14.c: New test.
	* gcc.dg/vect/vect-alias-check-15.c: Likewise.
	* gcc.dg/vect/vect-alias-check-16.c: Likewise.
	* gcc.dg/vect/vect-alias-check-17.c: Likewise.

From-SVN: r278352
parent 52c29905
2019-11-16 Richard Sandiford <richard.sandiford@arm.com> 2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
* tree-data-ref.c (dump_alias_pair): New function.
(prune_runtime_alias_test_list): Use it to dump each merged alias pair.
2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
* tree-data-ref.h (DR_ALIAS_MIXED_STEPS): New flag. * tree-data-ref.h (DR_ALIAS_MIXED_STEPS): New flag.
* tree-data-ref.c (prune_runtime_alias_test_list): Set it when * tree-data-ref.c (prune_runtime_alias_test_list): Set it when
merging data references with different steps. merging data references with different steps.
2019-11-16 Richard Sandiford <richard.sandiford@arm.com> 2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
* gcc.dg/vect/vect-alias-check-8.c: Test for the RAW flag.
* gcc.dg/vect/vect-alias-check-9.c: Test for the ARBITRARY flag.
(TEST_VALUE): Use a higher value for early iterations.
* gcc.dg/vect/vect-alias-check-14.c: New test.
* gcc.dg/vect/vect-alias-check-15.c: Likewise.
* gcc.dg/vect/vect-alias-check-16.c: Likewise.
* gcc.dg/vect/vect-alias-check-17.c: Likewise.
2019-11-16 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/scatter_store_1.c (TEST_LOOP): Start at 0. * gcc.target/aarch64/sve/scatter_store_1.c (TEST_LOOP): Start at 0.
(TEST_ALL): Add tests for 8-bit and 16-bit elements. (TEST_ALL): Add tests for 8-bit and 16-bit elements.
* gcc.target/aarch64/sve/scatter_store_2.c: Update accordingly. * gcc.target/aarch64/sve/scatter_store_2.c: Update accordingly.
......
#define N 200
#define M 4
typedef signed char sc;
typedef unsigned char uc;
typedef signed short ss;
typedef unsigned short us;
typedef int si;
typedef unsigned int ui;
typedef signed long long sll;
typedef unsigned long long ull;
#define FOR_EACH_TYPE(M) \
M (sc) M (uc) \
M (ss) M (us) \
M (si) M (ui) \
M (sll) M (ull) \
M (float) M (double)
#define TEST_VALUE(I) ((I) * 17 / 2)
#define ADD_TEST(TYPE) \
void __attribute__((noinline, noclone)) \
test_##TYPE (TYPE *a, TYPE *b) \
{ \
for (int i = 0; i < N; i += 2) \
{ \
TYPE b0 = b[i + 0]; \
TYPE b1 = b[i + 1]; \
a[i + 0] = b0 + 2; \
a[i + 1] = b1 + 3; \
} \
}
#define DO_TEST(TYPE) \
for (int j = 0; j < M; ++j) \
{ \
TYPE a[N + M]; \
for (int i = 0; i < N + M; ++i) \
a[i] = TEST_VALUE (i); \
test_##TYPE (a + j, a); \
for (int i = 0; i < N; i += 2) \
{ \
TYPE base1 = j == 0 ? TEST_VALUE (i) : a[i]; \
TYPE base2 = j <= 1 ? TEST_VALUE (i + 1) : a[i + 1]; \
if (a[i + j] != (TYPE) (base1 + 2) \
|| a[i + j + 1] != (TYPE) (base2 + 3)) \
__builtin_abort (); \
} \
}
FOR_EACH_TYPE (ADD_TEST)
int
main (void)
{
FOR_EACH_TYPE (DO_TEST)
return 0;
}
/* { dg-final { scan-tree-dump {flags: *WAR\n} "vect" { target vect_int } } } */
/* { dg-final { scan-tree-dump-not {flags: [^\n]*ARBITRARY\n} "vect" } } */
#define N 200
#define DIST 32
typedef signed char sc;
typedef unsigned char uc;
typedef signed short ss;
typedef unsigned short us;
typedef int si;
typedef unsigned int ui;
typedef signed long long sll;
typedef unsigned long long ull;
#define FOR_EACH_TYPE(M) \
M (sc) M (uc) \
M (ss) M (us) \
M (si) M (ui) \
M (sll) M (ull) \
M (float) M (double)
#define ADD_TEST(TYPE) \
void __attribute__((noinline, noclone)) \
test_##TYPE (TYPE *x, TYPE *y) \
{ \
for (int i = 0; i < N; ++i) \
{ \
x[i] = i; \
y[i] = 42 - i * 2; \
} \
}
#define DO_TEST(TYPE) \
for (int i = 0; i < DIST * 2; ++i) \
{ \
TYPE a[N + DIST * 2] = {}; \
test_##TYPE (a + DIST, a + i); \
for (int j = 0; j < N + DIST * 2; ++j) \
{ \
TYPE expected = 0; \
if (i > DIST && j >= i && j < i + N) \
expected = 42 - (j - i) * 2; \
if (j >= DIST && j < DIST + N) \
expected = j - DIST; \
if (i <= DIST && j >= i && j < i + N) \
expected = 42 - (j - i) * 2; \
if (expected != a[j]) \
__builtin_abort (); \
} \
}
FOR_EACH_TYPE (ADD_TEST)
int
main (void)
{
FOR_EACH_TYPE (DO_TEST)
return 0;
}
/* { dg-final { scan-tree-dump {flags: *WAW\n} "vect" { target vect_int } } } */
#define N 200
#define DIST 32
typedef signed char sc;
typedef unsigned char uc;
typedef signed short ss;
typedef unsigned short us;
typedef int si;
typedef unsigned int ui;
typedef signed long long sll;
typedef unsigned long long ull;
#define FOR_EACH_TYPE(M) \
M (sc) M (uc) \
M (ss) M (us) \
M (si) M (ui) \
M (sll) M (ull) \
M (float) M (double)
#define TEST_VALUE(I) ((I) * 13 / 2)
#define ADD_TEST(TYPE) \
TYPE __attribute__((noinline, noclone)) \
test_##TYPE (TYPE *x, TYPE *y) \
{ \
TYPE res = 0; \
for (int i = 0; i < N; ++i) \
{ \
x[i] = i; \
res += y[i]; \
} \
return res; \
}
#define DO_TEST(TYPE) \
for (int i = 0; i < DIST * 2; ++i) \
{ \
TYPE a[N + DIST * 2]; \
for (int j = 0; j < N + DIST * 2; ++j) \
a[j] = TEST_VALUE (j); \
TYPE res = test_##TYPE (a + DIST, a + i); \
for (int j = 0; j < N; ++j) \
if (a[j + DIST] != (TYPE) j) \
__builtin_abort (); \
TYPE expected_res = 0; \
for (int j = i; j < i + N; ++j) \
if (i <= DIST && j >= DIST && j < DIST + N) \
expected_res += j - DIST; \
else \
expected_res += TEST_VALUE (j); \
if (expected_res != res) \
__builtin_abort (); \
}
FOR_EACH_TYPE (ADD_TEST)
int
main (void)
{
FOR_EACH_TYPE (DO_TEST)
return 0;
}
/* { dg-final { scan-tree-dump {flags: *RAW\n} "vect" { target vect_int } } } */
/* { dg-do compile } */
/* { dg-require-effective-target vect_load_lanes } */
struct s { int x[100]; };
void
f (struct s *s1, int a, int b)
{
for (int i = 0; i < 32; ++i)
s1->x[a + i] = s1->x[b + i * 2] + s1->x[b + i * 3];
}
/* { dg-final { scan-tree-dump {flags: *[^\n]*MIXED_STEPS} "vect" } } */
...@@ -58,3 +58,5 @@ main (void) ...@@ -58,3 +58,5 @@ main (void)
FOR_EACH_TYPE (DO_TEST) FOR_EACH_TYPE (DO_TEST)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump {flags: *WAR\n} "vect" { target vect_int } } } */
...@@ -17,7 +17,7 @@ typedef unsigned long long ull; ...@@ -17,7 +17,7 @@ typedef unsigned long long ull;
M (sll) M (ull) \ M (sll) M (ull) \
M (float) M (double) M (float) M (double)
#define TEST_VALUE(I) ((I) * 5 / 2) #define TEST_VALUE(I) ((I) * 17 / 2)
#define ADD_TEST(TYPE) \ #define ADD_TEST(TYPE) \
void __attribute__((noinline, noclone)) \ void __attribute__((noinline, noclone)) \
...@@ -51,3 +51,5 @@ main (void) ...@@ -51,3 +51,5 @@ main (void)
FOR_EACH_TYPE (DO_TEST) FOR_EACH_TYPE (DO_TEST)
return 0; return 0;
} }
/* { dg-final { scan-tree-dump {flags: [^\n]*ARBITRARY\n} "vect" { target vect_int } } } */
...@@ -1452,6 +1452,54 @@ comp_dr_with_seg_len_pair (const void *pa_, const void *pb_) ...@@ -1452,6 +1452,54 @@ comp_dr_with_seg_len_pair (const void *pa_, const void *pb_)
return 0; return 0;
} }
/* Dump information about ALIAS_PAIR, indenting each line by INDENT. */
static void
dump_alias_pair (dr_with_seg_len_pair_t *alias_pair, const char *indent)
{
dump_printf (MSG_NOTE, "%sreference: %T vs. %T\n", indent,
DR_REF (alias_pair->first.dr),
DR_REF (alias_pair->second.dr));
dump_printf (MSG_NOTE, "%ssegment length: %T", indent,
alias_pair->first.seg_len);
if (!operand_equal_p (alias_pair->first.seg_len,
alias_pair->second.seg_len, 0))
dump_printf (MSG_NOTE, " vs. %T", alias_pair->second.seg_len);
dump_printf (MSG_NOTE, "\n%saccess size: ", indent);
dump_dec (MSG_NOTE, alias_pair->first.access_size);
if (maybe_ne (alias_pair->first.access_size, alias_pair->second.access_size))
{
dump_printf (MSG_NOTE, " vs. ");
dump_dec (MSG_NOTE, alias_pair->second.access_size);
}
dump_printf (MSG_NOTE, "\n%salignment: %d", indent,
alias_pair->first.align);
if (alias_pair->first.align != alias_pair->second.align)
dump_printf (MSG_NOTE, " vs. %d", alias_pair->second.align);
dump_printf (MSG_NOTE, "\n%sflags: ", indent);
if (alias_pair->flags & DR_ALIAS_RAW)
dump_printf (MSG_NOTE, " RAW");
if (alias_pair->flags & DR_ALIAS_WAR)
dump_printf (MSG_NOTE, " WAR");
if (alias_pair->flags & DR_ALIAS_WAW)
dump_printf (MSG_NOTE, " WAW");
if (alias_pair->flags & DR_ALIAS_ARBITRARY)
dump_printf (MSG_NOTE, " ARBITRARY");
if (alias_pair->flags & DR_ALIAS_SWAPPED)
dump_printf (MSG_NOTE, " SWAPPED");
if (alias_pair->flags & DR_ALIAS_UNSWAPPED)
dump_printf (MSG_NOTE, " UNSWAPPED");
if (alias_pair->flags & DR_ALIAS_MIXED_STEPS)
dump_printf (MSG_NOTE, " MIXED_STEPS");
if (alias_pair->flags == 0)
dump_printf (MSG_NOTE, " <none>");
dump_printf (MSG_NOTE, "\n");
}
/* Merge alias checks recorded in ALIAS_PAIRS and remove redundant ones. /* Merge alias checks recorded in ALIAS_PAIRS and remove redundant ones.
FACTOR is number of iterations that each data reference is accessed. FACTOR is number of iterations that each data reference is accessed.
...@@ -1655,6 +1703,8 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, ...@@ -1655,6 +1703,8 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
dr_with_seg_len_pair_t. If we ended up combining swapped and dr_with_seg_len_pair_t. If we ended up combining swapped and
unswapped pairs into the same check, we have to invalidate any unswapped pairs into the same check, we have to invalidate any
RAW, WAR and WAW information for it. */ RAW, WAR and WAW information for it. */
if (dump_enabled_p ())
dump_printf (MSG_NOTE, "merged alias checks:\n");
FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair) FOR_EACH_VEC_ELT (*alias_pairs, i, alias_pair)
{ {
unsigned int swap_mask = (DR_ALIAS_SWAPPED | DR_ALIAS_UNSWAPPED); unsigned int swap_mask = (DR_ALIAS_SWAPPED | DR_ALIAS_UNSWAPPED);
...@@ -1664,6 +1714,8 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs, ...@@ -1664,6 +1714,8 @@ prune_runtime_alias_test_list (vec<dr_with_seg_len_pair_t> *alias_pairs,
else if (swapped != DR_ALIAS_UNSWAPPED) else if (swapped != DR_ALIAS_UNSWAPPED)
alias_pair->flags |= DR_ALIAS_ARBITRARY; alias_pair->flags |= DR_ALIAS_ARBITRARY;
alias_pair->flags &= ~swap_mask; alias_pair->flags &= ~swap_mask;
if (dump_enabled_p ())
dump_alias_pair (alias_pair, " ");
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment