From 591a1ed8489e2c230f19220599b4ce8bb89d6148 Mon Sep 17 00:00:00 2001 From: yzyssdd 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 + +#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 &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 &bb_visited, const std::set &header_bb_idx_set, - std::set > &backedges, + std::set > &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 &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 &bb_visited, std::list &bb_topo_order, const std::set &header_bb_idx_set, - std::set > &backedges, + std::set > &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 &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 &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 &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 &bb_weights, basic_block bb) +update_backedge_path_weight (std::vector &bb_weights, basic_block bb, + const std::set > &unused_edges) { unsigned i; edge e_exit; @@ -2542,6 +2552,11 @@ update_backedge_path_weight (std::vector &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 &bb_weights, std::list &bb_topo_order, const std::set &header_bb_idx_set, - const std::set > &backedges) + const std::set > &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 &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 &sorted_kernel, basic_block bb_start = ENTRY_BLOCK_PTR_FOR_FN (cfun); /* Step 1: Get topological order of bb during traversal. */ - std::set > backedges; + std::set > 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 &sorted_kernel, std::vector bb_weights = std::vector(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 &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