564 lines
25 KiB
Diff
564 lines
25 KiB
Diff
From 591a1ed8489e2c230f19220599b4ce8bb89d6148 Mon Sep 17 00:00:00 2001
|
|
From: yzyssdd <yuzeyang4@huawei.com>
|
|
Date: Thu, 6 Jun 2024 15:42:52 +0800
|
|
Subject: [PATCH 2/2] fix bugs in loop detections, add filter to SSA statement
|
|
and corresponding deja cases. Fix bugs so llc pass can detect it when going
|
|
back into a loop after jumping out of a loop. Return directly from processing
|
|
a non-ssa statement when looking for references in a gimple call.
|
|
|
|
---
|
|
.../gcc.dg/llc-allocate/llc-filter-ssa.c | 30 ++++
|
|
.../gcc.dg/llc-allocate/llc-loop-generate.c | 168 ++++++++++++++++++
|
|
.../aarch64/sve/acle/general-c/prefetch_1.c | 10 +-
|
|
.../acle/general-c/prefetch_gather_index_1.c | 8 +-
|
|
.../acle/general-c/prefetch_gather_index_2.c | 8 +-
|
|
.../acle/general-c/prefetch_gather_offset_1.c | 7 +-
|
|
.../acle/general-c/prefetch_gather_offset_2.c | 7 +-
|
|
.../acle/general-c/prefetch_gather_offset_3.c | 7 +-
|
|
.../acle/general-c/prefetch_gather_offset_4.c | 7 +-
|
|
gcc/tree-ssa-llc-allocate.c | 70 +++++---
|
|
10 files changed, 277 insertions(+), 45 deletions(-)
|
|
create mode 100644 gcc/testsuite/gcc.dg/llc-allocate/llc-filter-ssa.c
|
|
create mode 100644 gcc/testsuite/gcc.dg/llc-allocate/llc-loop-generate.c
|
|
|
|
diff --git a/gcc/testsuite/gcc.dg/llc-allocate/llc-filter-ssa.c b/gcc/testsuite/gcc.dg/llc-allocate/llc-filter-ssa.c
|
|
new file mode 100644
|
|
index 000000000..4478f7531
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/llc-allocate/llc-filter-ssa.c
|
|
@@ -0,0 +1,30 @@
|
|
+/* { dg-do compile } */
|
|
+/* { dg-options "-O2 -ftree-parallelize-loops=2 -fipa-pta -fllc-allocate -S -fdump-tree-llc_allocate-details-lineno" } */
|
|
+
|
|
+int a, b;
|
|
+int *d;
|
|
+void f(void)
|
|
+{
|
|
+ int c;
|
|
+ b %= 1;
|
|
+
|
|
+ if(1 - (b < 1))
|
|
+ {
|
|
+ int *q = 0;
|
|
+
|
|
+ if(a)
|
|
+ {
|
|
+ c = 0;
|
|
+lbl:
|
|
+ for(*d; *d; ++*d)
|
|
+ if(c ? : a ? : (c = 1) ? : 0)
|
|
+ *q &= 1;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ q = (int *)1;
|
|
+ }
|
|
+ goto lbl;
|
|
+}
|
|
+
|
|
+/* { dg-final { scan-tree-dump "Unhandled scenario for non-ssa pointer." "llc-allocate" } } */
|
|
diff --git a/gcc/testsuite/gcc.dg/llc-allocate/llc-loop-generate.c b/gcc/testsuite/gcc.dg/llc-allocate/llc-loop-generate.c
|
|
new file mode 100644
|
|
index 000000000..dc1f0eadc
|
|
--- /dev/null
|
|
+++ b/gcc/testsuite/gcc.dg/llc-allocate/llc-loop-generate.c
|
|
@@ -0,0 +1,168 @@
|
|
+/* { dg-require-effective-target label_values } */
|
|
+/* { dg-require-stack-size "4000" } */
|
|
+/* { dp-option "-O2 -fllc-allocate" } */
|
|
+
|
|
+#include <stdlib.h>
|
|
+
|
|
+#if __INT_MAX__ >= 2147483647
|
|
+typedef unsigned int uint32;
|
|
+typedef signed int sint32;
|
|
+
|
|
+typedef uint32 reg_t;
|
|
+
|
|
+typedef unsigned long int host_addr_t;
|
|
+typedef uint32 target_addr_t;
|
|
+typedef sint32 target_saddr_t;
|
|
+
|
|
+typedef union
|
|
+{
|
|
+ struct
|
|
+ {
|
|
+ signed int offset:18;
|
|
+ unsigned int ignore:4;
|
|
+ unsigned int s1:8;
|
|
+ int :2;
|
|
+ signed int simm:14;
|
|
+ unsigned int s3:8;
|
|
+ unsigned int s2:8;
|
|
+ int pad2:2;
|
|
+ } f1;
|
|
+ long long ll;
|
|
+ double d;
|
|
+} insn_t;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ target_addr_t vaddr_tag;
|
|
+ unsigned long int rigged_paddr;
|
|
+} tlb_entry_t;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ insn_t *pc;
|
|
+ reg_t registers[256];
|
|
+ insn_t *program;
|
|
+ tlb_entry_t tlb_tab[0x100];
|
|
+} environment_t;
|
|
+
|
|
+enum operations
|
|
+{
|
|
+ LOAD32_RR,
|
|
+ METAOP_DONE
|
|
+};
|
|
+
|
|
+host_addr_t
|
|
+f ()
|
|
+{
|
|
+ abort ();
|
|
+}
|
|
+
|
|
+reg_t
|
|
+simulator_kernel (int what, environment_t *env)
|
|
+{
|
|
+ register insn_t *pc = env->pc;
|
|
+ register reg_t *regs = env->registers;
|
|
+ register insn_t insn;
|
|
+ register int s1;
|
|
+ register reg_t r2;
|
|
+ register void *base_addr = &&sim_base_addr;
|
|
+ register tlb_entry_t *tlb = env->tlb_tab;
|
|
+
|
|
+ if (what != 0)
|
|
+ {
|
|
+ int i;
|
|
+ static void *op_map[] =
|
|
+ {
|
|
+ &&L_LOAD32_RR,
|
|
+ &&L_METAOP_DONE,
|
|
+ };
|
|
+ insn_t *program = env->program;
|
|
+ for (i = 0; i < what; i++)
|
|
+ program[i].f1.offset = op_map[program[i].f1.offset] - base_addr;
|
|
+ }
|
|
+
|
|
+ sim_base_addr:;
|
|
+
|
|
+ insn = *pc++;
|
|
+ r2 = (*(reg_t *) (((char *) regs) + (insn.f1.s2 << 2)));
|
|
+ s1 = (insn.f1.s1 << 2);
|
|
+ goto *(base_addr + insn.f1.offset);
|
|
+
|
|
+ L_LOAD32_RR:
|
|
+ {
|
|
+ target_addr_t vaddr_page = r2 / 4096;
|
|
+ unsigned int x = vaddr_page % 0x100;
|
|
+ insn = *pc++;
|
|
+
|
|
+ for (;;)
|
|
+ {
|
|
+ target_addr_t tag = tlb[x].vaddr_tag;
|
|
+ host_addr_t rigged_paddr = tlb[x].rigged_paddr;
|
|
+
|
|
+ if (tag == vaddr_page)
|
|
+ {
|
|
+ *(reg_t *) (((char *) regs) + s1) = *(uint32 *) (rigged_paddr + r2);
|
|
+ r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2));
|
|
+ s1 = insn.f1.s1 << 2;
|
|
+ goto *(base_addr + insn.f1.offset);
|
|
+ }
|
|
+
|
|
+ if (((target_saddr_t) tag < 0))
|
|
+ {
|
|
+ *(reg_t *) (((char *) regs) + s1) = *(uint32 *) f ();
|
|
+ r2 = *(reg_t *) (((char *) regs) + (insn.f1.s2 << 2));
|
|
+ s1 = insn.f1.s1 << 2;
|
|
+ goto *(base_addr + insn.f1.offset);
|
|
+ }
|
|
+
|
|
+ x = (x - 1) % 0x100;
|
|
+ }
|
|
+
|
|
+ L_METAOP_DONE:
|
|
+ return (*(reg_t *) (((char *) regs) + s1));
|
|
+ }
|
|
+}
|
|
+
|
|
+insn_t program[2 + 1];
|
|
+
|
|
+void *malloc ();
|
|
+
|
|
+int
|
|
+main ()
|
|
+{
|
|
+ environment_t env;
|
|
+ insn_t insn;
|
|
+ int i, res;
|
|
+ host_addr_t a_page = (host_addr_t) malloc (2 * 4096);
|
|
+ target_addr_t a_vaddr = 0x123450;
|
|
+ target_addr_t vaddr_page = a_vaddr / 4096;
|
|
+ a_page = (a_page + 4096 - 1) & -4096;
|
|
+
|
|
+ env.tlb_tab[((vaddr_page) % 0x100)].vaddr_tag = vaddr_page;
|
|
+ env.tlb_tab[((vaddr_page) % 0x100)].rigged_paddr = a_page - vaddr_page * 4096;
|
|
+ insn.f1.offset = LOAD32_RR;
|
|
+ env.registers[0] = 0;
|
|
+ env.registers[2] = a_vaddr;
|
|
+ *(sint32 *) (a_page + a_vaddr % 4096) = 88;
|
|
+ insn.f1.s1 = 0;
|
|
+ insn.f1.s2 = 2;
|
|
+
|
|
+ for (i = 0; i < 2; i++)
|
|
+ program[i] = insn;
|
|
+
|
|
+ insn.f1.offset = METAOP_DONE;
|
|
+ insn.f1.s1 = 0;
|
|
+ program[2] = insn;
|
|
+
|
|
+ env.pc = program;
|
|
+ env.program = program;
|
|
+
|
|
+ res = simulator_kernel (2 + 1, &env);
|
|
+
|
|
+ if (res != 88)
|
|
+ abort ();
|
|
+ exit (0);
|
|
+}
|
|
+#else
|
|
+main(){ exit (0); }
|
|
+#endif
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_1.c
|
|
index 316f77fc7..fba3b7447 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_1.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_1.c
|
|
@@ -10,8 +10,12 @@ f1 (svbool_t pg, int32_t *s32_ptr, enum svprfop op)
|
|
svprfb (pg, s32_ptr, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 3 of 'svprfb', which expects a valid 'enum svprfop' value} } */
|
|
svprfb (pg, s32_ptr, (enum svprfop) 0);
|
|
svprfb (pg, s32_ptr, (enum svprfop) 5);
|
|
- svprfb (pg, s32_ptr, (enum svprfop) 6); /* { dg-error {passing 6 to argument 3 of 'svprfb', which expects a valid 'enum svprfop' value} } */
|
|
- svprfb (pg, s32_ptr, (enum svprfop) 7); /* { dg-error {passing 7 to argument 3 of 'svprfb', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb (pg, s32_ptr, (enum svprfop) 6);
|
|
+ svprfb (pg, s32_ptr, (enum svprfop) 7);
|
|
svprfb (pg, s32_ptr, (enum svprfop) 8);
|
|
- svprfb (pg, s32_ptr, (enum svprfop) 14); /* { dg-error {passing 14 to argument 3 of 'svprfb', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb (pg, s32_ptr, (enum svprfop) 14);
|
|
+ svprfb (pg, s32_ptr, (enum svprfop) 15);
|
|
+ svprfb (pg, s32_ptr, (enum svprfop) 16); /* { dg-error {passing 16 to argument 3 of 'svprfb', which expects a valid 'enum svprfop' value} } */
|
|
+
|
|
+
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_1.c
|
|
index c33c95440..cf387bf92 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_1.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_1.c
|
|
@@ -46,8 +46,10 @@ f1 (svbool_t pg, int32_t *s32_ptr, void *void_ptr, void **ptr_ptr,
|
|
svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 4 of 'svprfh_gather_index', which expects a valid 'enum svprfop' value} } */
|
|
svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 0);
|
|
svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 5);
|
|
- svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 4 of 'svprfh_gather_index', which expects a valid 'enum svprfop' value} } */
|
|
- svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 4 of 'svprfh_gather_index', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 6);
|
|
+ svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 7);
|
|
svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 8);
|
|
- svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 4 of 'svprfh_gather_index', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 14);
|
|
+ svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 15);
|
|
+ svprfh_gather_index (pg, s32_ptr, s32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 4 of 'svprfh_gather_index', which expects a valid 'enum svprfop' value} } */
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_2.c
|
|
index 3d7797305..bc99b29d1 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_2.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_index_2.c
|
|
@@ -10,8 +10,10 @@ f1 (svbool_t pg, int32_t *s32_ptr, svint32_t s32, enum svprfop op)
|
|
svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 4 of 'svprfh_gather_s32index', which expects a valid 'enum svprfop' value} } */
|
|
svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 0);
|
|
svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 5);
|
|
- svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 4 of 'svprfh_gather_s32index', which expects a valid 'enum svprfop' value} } */
|
|
- svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 4 of 'svprfh_gather_s32index', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 6);
|
|
+ svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 7);
|
|
svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 8);
|
|
- svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 4 of 'svprfh_gather_s32index', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 14);
|
|
+ svprfh_gather_s32index (pg, s32_ptr, s32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 4 of 'svprfh_gather_s32index', which expects a valid 'enum svprfop' value} } */
|
|
+
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_1.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_1.c
|
|
index cc61901cb..8b304ed89 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_1.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_1.c
|
|
@@ -46,8 +46,9 @@ f1 (svbool_t pg, int32_t *s32_ptr, void *void_ptr, void **ptr_ptr,
|
|
svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 4 of 'svprfb_gather_offset', which expects a valid 'enum svprfop' value} } */
|
|
svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 0);
|
|
svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 5);
|
|
- svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 4 of 'svprfb_gather_offset', which expects a valid 'enum svprfop' value} } */
|
|
- svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 4 of 'svprfb_gather_offset', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 6);
|
|
+ svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 7);
|
|
svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 8);
|
|
- svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 4 of 'svprfb_gather_offset', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 14);
|
|
+ svprfb_gather_offset (pg, s32_ptr, s32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 4 of 'svprfb_gather_offset', which expects a valid 'enum svprfop' value} } */
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_2.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_2.c
|
|
index b74721fad..64e55dd76 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_2.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_2.c
|
|
@@ -30,8 +30,9 @@ f1 (svbool_t pg, svint8_t s8, svuint8_t u8,
|
|
svprfb_gather (pg, u32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 3 of 'svprfb_gather', which expects a valid 'enum svprfop' value} } */
|
|
svprfb_gather (pg, u32, (enum svprfop) 0);
|
|
svprfb_gather (pg, u32, (enum svprfop) 5);
|
|
- svprfb_gather (pg, u32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 3 of 'svprfb_gather', which expects a valid 'enum svprfop' value} } */
|
|
- svprfb_gather (pg, u32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 3 of 'svprfb_gather', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather (pg, u32, (enum svprfop) 6);
|
|
+ svprfb_gather (pg, u32, (enum svprfop) 7);
|
|
svprfb_gather (pg, u32, (enum svprfop) 8);
|
|
- svprfb_gather (pg, u32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 3 of 'svprfb_gather', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather (pg, u32, (enum svprfop) 14);
|
|
+ svprfb_gather (pg, u32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 3 of 'svprfb_gather', which expects a valid 'enum svprfop' value} } */
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_3.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_3.c
|
|
index 24b4aa190..f400e91e8 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_3.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_3.c
|
|
@@ -10,8 +10,9 @@ f1 (svbool_t pg, int32_t *s32_ptr, svint32_t s32, enum svprfop op)
|
|
svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 4 of 'svprfb_gather_s32offset', which expects a valid 'enum svprfop' value} } */
|
|
svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 0);
|
|
svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 5);
|
|
- svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 4 of 'svprfb_gather_s32offset', which expects a valid 'enum svprfop' value} } */
|
|
- svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 4 of 'svprfb_gather_s32offset', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 6);
|
|
+ svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 7);
|
|
svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 8);
|
|
- svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 4 of 'svprfb_gather_s32offset', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 14);
|
|
+ svprfb_gather_s32offset (pg, s32_ptr, s32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 4 of 'svprfb_gather_s32offset', which expects a valid 'enum svprfop' value} } */
|
|
}
|
|
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_4.c b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_4.c
|
|
index 63ccdc5a4..7b91dbd2e 100644
|
|
--- a/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_4.c
|
|
+++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general-c/prefetch_gather_offset_4.c
|
|
@@ -10,8 +10,9 @@ f1 (svbool_t pg, svuint32_t u32, enum svprfop op)
|
|
svprfb_gather_u32base (pg, u32, (enum svprfop) -1); /* { dg-error {passing 4294967295 to argument 3 of 'svprfb_gather_u32base', which expects a valid 'enum svprfop' value} } */
|
|
svprfb_gather_u32base (pg, u32, (enum svprfop) 0);
|
|
svprfb_gather_u32base (pg, u32, (enum svprfop) 5);
|
|
- svprfb_gather_u32base (pg, u32, (enum svprfop) 6); /* { dg-error {passing 6 to argument 3 of 'svprfb_gather_u32base', which expects a valid 'enum svprfop' value} } */
|
|
- svprfb_gather_u32base (pg, u32, (enum svprfop) 7); /* { dg-error {passing 7 to argument 3 of 'svprfb_gather_u32base', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_u32base (pg, u32, (enum svprfop) 6);
|
|
+ svprfb_gather_u32base (pg, u32, (enum svprfop) 7);
|
|
svprfb_gather_u32base (pg, u32, (enum svprfop) 8);
|
|
- svprfb_gather_u32base (pg, u32, (enum svprfop) 14); /* { dg-error {passing 14 to argument 3 of 'svprfb_gather_u32base', which expects a valid 'enum svprfop' value} } */
|
|
+ svprfb_gather_u32base (pg, u32, (enum svprfop) 14);
|
|
+ svprfb_gather_u32base (pg, u32, (enum svprfop) 16); /* { dg-error {passing 16 to argument 3 of 'svprfb_gather_u32base', which expects a valid 'enum svprfop' value} } */
|
|
}
|
|
diff --git a/gcc/tree-ssa-llc-allocate.c b/gcc/tree-ssa-llc-allocate.c
|
|
index 75501f41c..3f6ff3623 100644
|
|
--- a/gcc/tree-ssa-llc-allocate.c
|
|
+++ b/gcc/tree-ssa-llc-allocate.c
|
|
@@ -1020,6 +1020,14 @@ trace_ptr_mem_ref (data_ref &mem_ref, std::set<gimple *> &traced_ref_stmt,
|
|
{
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
fprintf (dump_file, "Unhandled scenario for non-constant offset.\n");
|
|
+
|
|
+ return false;
|
|
+ }
|
|
+ if (TREE_CODE (pointer) != SSA_NAME)
|
|
+ {
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
|
+ fprintf (dump_file, "Unhandled scenario for non-ssa pointer.\n");
|
|
+
|
|
return false;
|
|
}
|
|
|
|
@@ -2330,7 +2338,7 @@ enum bb_traversal_state
|
|
bool
|
|
revisit_bb_abnormal_p (basic_block bb, std::vector<int> &bb_visited,
|
|
const std::set<int> &header_bb_idx_set,
|
|
- std::set<std::pair<int, int> > &backedges,
|
|
+ std::set<std::pair<int, int> > &unused_edges,
|
|
int src_bb_idx)
|
|
{
|
|
/* If the header bb has been already fully traversed, early exit
|
|
@@ -2340,19 +2348,20 @@ revisit_bb_abnormal_p (basic_block bb, std::vector<int> &bb_visited,
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
fprintf (dump_file, "Already visited bb index %d. Abort.\n",
|
|
bb->index);
|
|
+ unused_edges.insert (std::make_pair (src_bb_idx, bb->index));
|
|
return true;
|
|
}
|
|
|
|
/* If we revisit a non-header bb during next-bb traversal, we detect
|
|
an inner-loop cycle and dump warning info. Record this abnormal edge
|
|
- in `backedges` for special treatment in path weight update. */
|
|
+ in `unused_edges` for special treatment in path weight update. */
|
|
if (!header_bb_idx_set.count (bb->index)
|
|
&& bb_visited[bb->index] == UNDER_TRAVERSAL)
|
|
{
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
fprintf (dump_file, "Warning: Find cycle at bb index %d. Abort.\n",
|
|
bb->index);
|
|
- backedges.insert (std::make_pair (src_bb_idx, bb->index));
|
|
+ unused_edges.insert (std::make_pair (src_bb_idx, bb->index));
|
|
return true;
|
|
}
|
|
|
|
@@ -2397,7 +2406,7 @@ void
|
|
get_next_toposort_bb (basic_block bb, std::vector<int> &bb_visited,
|
|
std::list<basic_block> &bb_topo_order,
|
|
const std::set<int> &header_bb_idx_set,
|
|
- std::set<std::pair<int, int> > &backedges,
|
|
+ std::set<std::pair<int, int> > &unused_edges,
|
|
int src_bb_idx)
|
|
{
|
|
/* 1) Before bb returns to the loop header, bb will not go to the outer loop.
|
|
@@ -2412,7 +2421,7 @@ get_next_toposort_bb (basic_block bb, std::vector<int> &bb_visited,
|
|
if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
|
|
return;
|
|
|
|
- if (revisit_bb_abnormal_p (bb, bb_visited, header_bb_idx_set, backedges,
|
|
+ if (revisit_bb_abnormal_p (bb, bb_visited, header_bb_idx_set, unused_edges,
|
|
src_bb_idx))
|
|
return;
|
|
|
|
@@ -2431,7 +2440,7 @@ get_next_toposort_bb (basic_block bb, std::vector<int> &bb_visited,
|
|
FOR_EACH_VEC_ELT (exits, i, e)
|
|
{
|
|
get_next_toposort_bb (e->dest, bb_visited, bb_topo_order,
|
|
- header_bb_idx_set, backedges, bb->index);
|
|
+ header_bb_idx_set, unused_edges, src_bb_idx);
|
|
}
|
|
return;
|
|
}
|
|
@@ -2447,7 +2456,7 @@ get_next_toposort_bb (basic_block bb, std::vector<int> &bb_visited,
|
|
continue;
|
|
|
|
get_next_toposort_bb (e->dest, bb_visited, bb_topo_order,
|
|
- header_bb_idx_set, backedges, bb->index);
|
|
+ header_bb_idx_set, unused_edges, bb->index);
|
|
}
|
|
|
|
/* bb is marked as fully traversed and all its descendents have been
|
|
@@ -2526,7 +2535,8 @@ check_null_info_in_path_update (basic_block bb, edge e)
|
|
to header bb using a backedge. */
|
|
|
|
void
|
|
-update_backedge_path_weight (std::vector<weight> &bb_weights, basic_block bb)
|
|
+update_backedge_path_weight (std::vector<weight> &bb_weights, basic_block bb,
|
|
+ const std::set<std::pair<int, int> > &unused_edges)
|
|
{
|
|
unsigned i;
|
|
edge e_exit;
|
|
@@ -2542,6 +2552,11 @@ update_backedge_path_weight (std::vector<weight> &bb_weights, basic_block bb)
|
|
continue;
|
|
}
|
|
|
|
+ if (unused_edges.count (std::make_pair (bb->index, e_exit->dest->index)))
|
|
+ {
|
|
+ /* Inner-loop-cycle backedge case. */
|
|
+ continue;
|
|
+ }
|
|
update_path_weight (bb_weights, bb->index, e_exit->dest->index,
|
|
e_exit->dest->count.to_gcov_type ());
|
|
}
|
|
@@ -2553,7 +2568,7 @@ void
|
|
update_max_length_of_path (std::vector<weight> &bb_weights,
|
|
std::list<basic_block> &bb_topo_order,
|
|
const std::set<int> &header_bb_idx_set,
|
|
- const std::set<std::pair<int, int> > &backedges)
|
|
+ const std::set<std::pair<int, int> > &unused_edges)
|
|
{
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
fprintf (dump_file, "Start update weight traversal:\n");
|
|
@@ -2573,22 +2588,22 @@ update_max_length_of_path (std::vector<weight> &bb_weights,
|
|
if (check_null_info_in_path_update (bb, e))
|
|
continue;
|
|
|
|
- if (header_bb_idx_set.count (e->dest->index)
|
|
- && bb->loop_father == e->dest->loop_father)
|
|
+ if (unused_edges.count (std::make_pair (bb->index, e->dest->index)))
|
|
{
|
|
- /* Backedge case. */
|
|
- update_backedge_path_weight (bb_weights, bb);
|
|
+ /* Inner-loop-cycle backedge case. */
|
|
+ continue;
|
|
}
|
|
- else if (bb->loop_father->num != 0
|
|
+ else if (bb->loop_father->num != 0
|
|
&& !flow_bb_inside_loop_p (bb->loop_father, e->dest))
|
|
{
|
|
/* Outer-loop edge case. */
|
|
continue;
|
|
}
|
|
- else if (backedges.count (std::make_pair (bb->index, e->dest->index)))
|
|
+ else if (header_bb_idx_set.count (e->dest->index)
|
|
+ && bb->loop_father == e->dest->loop_father)
|
|
{
|
|
- /* Inner-loop-cycle backedge case. */
|
|
- continue;
|
|
+ /* Backedge case. */
|
|
+ update_backedge_path_weight (bb_weights, bb, unused_edges);
|
|
}
|
|
else
|
|
{
|
|
@@ -2676,9 +2691,9 @@ filter_and_sort_kernels_feedback (std::vector<class loop *> &sorted_kernel,
|
|
basic_block bb_start = ENTRY_BLOCK_PTR_FOR_FN (cfun);
|
|
|
|
/* Step 1: Get topological order of bb during traversal. */
|
|
- std::set<std::pair<int, int> > backedges;
|
|
+ std::set<std::pair<int, int> > unused_edges;
|
|
get_next_toposort_bb (bb_start, bb_visited, bb_topo_order, header_bb_idx_set,
|
|
- backedges, -1);
|
|
+ unused_edges, -1);
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
{
|
|
fprintf (dump_file, "\nCheck bbs in topological order:\n");
|
|
@@ -2693,7 +2708,7 @@ filter_and_sort_kernels_feedback (std::vector<class loop *> &sorted_kernel,
|
|
std::vector<weight> bb_weights = std::vector<weight>(bb_num_max, weight_init);
|
|
bb_weights[0].bb_count = 0; /* ENTRY bb has count 0 and prev bb as -1. */
|
|
update_max_length_of_path (bb_weights, bb_topo_order, header_bb_idx_set,
|
|
- backedges);
|
|
+ unused_edges);
|
|
|
|
/* Step 3: Backtrack a path from EXIT bb to ENTRY bb. */
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
@@ -2706,6 +2721,13 @@ filter_and_sort_kernels_feedback (std::vector<class loop *> &sorted_kernel,
|
|
tmp_bb_idx = bb_weights[tmp_bb_idx].prev_bb_idx;
|
|
while (tmp_bb_idx > 0 && tmp_bb_idx < bb_num_max)
|
|
{
|
|
+ if (bb_pathset.count (tmp_bb_idx))
|
|
+ {
|
|
+ if (dump_file && (dump_flags & TDF_DETAILS))
|
|
+ fprintf(dump_file, "ERROR: already seen bb index %d\n",
|
|
+ tmp_bb_idx);
|
|
+ return false;
|
|
+ }
|
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
fprintf (dump_file, "%d: %ld, ", tmp_bb_idx,
|
|
bb_weights[tmp_bb_idx].bb_count);
|
|
@@ -3398,14 +3420,14 @@ issue_builtin_prefetch (data_ref &mem_ref)
|
|
if (param_llc_level == 3)
|
|
{
|
|
/* for simulation.
|
|
- BUILT_IN_PREFETCH (addr, rw, locality). */
|
|
+ BUILT_IN_PREFETCH (addr, rw, locality). */
|
|
call = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH),
|
|
- 3, addr, integer_zero_node, integer_one_node);
|
|
+ 3, addr, integer_zero_node, integer_one_node);
|
|
}
|
|
else if (param_llc_level == 4)
|
|
{
|
|
- tree prfop = build_int_cst (TREE_TYPE (integer_zero_node), 6);
|
|
- call = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH_FULL),
|
|
+ tree prfop = build_int_cst (TREE_TYPE (integer_zero_node), 6);
|
|
+ call = gimple_build_call (builtin_decl_explicit (BUILT_IN_PREFETCH_FULL),
|
|
3, addr, integer_zero_node, prfop);
|
|
}
|
|
else
|
|
--
|
|
2.33.0
|
|
|