gcc/0196-fix-bugs-in-loop-detections-add-filter-to-SSA-statem.patch
2024-06-15 07:34:00 +08:00

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