From 4369e823f0883c079c0681bef68cead870d02063 Mon Sep 17 00:00:00 2001 From: Feiyang Liu Date: Wed, 20 Dec 2023 09:48:02 +0800 Subject: [PATCH] [LLC Allocation][Bugfix] Terminate kernel filtering for same-loop cycle. --- .../gcc.dg/llc-allocate/llc-same-loop-cycle.c | 125 ++++++++++++++++++ gcc/tree-ssa-llc-allocate.c | 11 +- 2 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/llc-allocate/llc-same-loop-cycle.c diff --git a/gcc/testsuite/gcc.dg/llc-allocate/llc-same-loop-cycle.c b/gcc/testsuite/gcc.dg/llc-allocate/llc-same-loop-cycle.c new file mode 100644 index 000000000..ba5b5b0c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/llc-allocate/llc-same-loop-cycle.c @@ -0,0 +1,125 @@ +/* { dg-do compile { target { aarch64*-*-linux* } } } */ +/* { dg-options "-O3 -fwhole-program -flto-partition=one -fllc-allocate -fdump-tree-llc_allocate-details-lineno --param filter-kernels=1 --param=branch-prob-threshold=50 -c -w" } */ + +typedef unsigned long size_t; +typedef long scalar_t__; + +typedef struct TYPE_13__ TYPE_3__ ; +typedef struct TYPE_12__ TYPE_2__ ; +typedef struct TYPE_11__ TYPE_1__ ; + +struct dom_info {int nodes; int* dfs_parent; int* dfs_order; int* key; int* next_bucket; int* bucket; int* dom; int fake_exit_edge; TYPE_3__** dfs_to_bb; } ; +typedef enum cdi_direction { ____Placeholder_cdi_direction } cdi_direction ; +struct TYPE_11__ {scalar_t__ index; } ; +typedef TYPE_1__ edge_iterator ; +typedef TYPE_2__* edge ; +typedef TYPE_3__* basic_block ; +struct TYPE_13__ {size_t index; int preds; int succs; } ; +struct TYPE_12__ {TYPE_3__* src; TYPE_3__* dest; } ; +typedef int TBB ; + +basic_block ENTRY_BLOCK_PTR ; +basic_block EXIT_BLOCK_PTR ; +scalar_t__ bitmap_bit_p (int,size_t) ; +edge ei_edge (edge_iterator) ; +int ei_end_p (edge_iterator) ; +int ei_next (edge_iterator*) ; +edge_iterator ei_start (int) ; +size_t eval (struct dom_info*,int) ; +size_t last_basic_block ; +int link_roots (struct dom_info*,int,int) ; + +__attribute__((used)) static void +calc_idoms (struct dom_info *di, enum cdi_direction reverse) +{ + TBB v, w, k, par; + basic_block en_block; + edge_iterator ei, einext; + + if (reverse) + en_block = EXIT_BLOCK_PTR; + else + en_block = ENTRY_BLOCK_PTR; + + /* Go backwards in DFS order, to first look at the leafs. */ + v = di->nodes; + while (v > 1) + { + basic_block bb = di->dfs_to_bb[v]; + edge e; + + par = di->dfs_parent[v]; + k = v; + + ei = (reverse) ? ei_start (bb->succs) : ei_start (bb->preds); + + if (reverse) + { + /* If this block has a fake edge to exit, process that first. */ + if (bitmap_bit_p (di->fake_exit_edge, bb->index)) + { + einext = ei; + einext.index = 0; + goto do_fake_exit_edge; + } + } + + /* Search all direct predecessors for the smallest node with a path + to them. That way we have the smallest node with also a path to + us only over nodes behind us. In effect we search for our + semidominator. */ + while (!ei_end_p (ei)) + { + basic_block b; + TBB k1; + + e = ei_edge (ei); + b = (reverse) ? e->dest : e->src; + einext = ei; + ei_next (&einext); + + if (b == en_block) + { + do_fake_exit_edge: + k1 = di->dfs_order[last_basic_block]; + } + else + k1 = di->dfs_order[b->index]; + + /* Call eval() only if really needed. If k1 is above V in DFS tree, + then we know, that eval(k1) == k1 and key[k1] == k1. */ + if (k1 > v) + k1 = di->key[eval (di, k1)]; + if (k1 < k) + k = k1; + + ei = einext; + } + + di->key[v] = k; + link_roots (di, par, v); + di->next_bucket[v] = di->bucket[k]; + di->bucket[k] = v; + + /* Transform semidominators into dominators. */ + for (w = di->bucket[par]; w; w = di->next_bucket[w]) + { + k = eval (di, w); + if (di->key[k] < di->key[w]) + di->dom[w] = k; + else + di->dom[w] = par; + } + /* We don't need to cleanup next_bucket[]. */ + di->bucket[par] = 0; + v--; + } + + /* Explicitly define the dominators. */ + di->dom[1] = 0; + for (v = 2; v <= di->nodes; v++) + if (di->dom[v] != di->key[v]) + di->dom[v] = di->dom[di->dom[v]]; +} + +/* { dg-final { scan-tree-dump "Find same-loop cycle." "llc_allocate" } } */ diff --git a/gcc/tree-ssa-llc-allocate.c b/gcc/tree-ssa-llc-allocate.c index fa8979401..62b5f18ad 100644 --- a/gcc/tree-ssa-llc-allocate.c +++ b/gcc/tree-ssa-llc-allocate.c @@ -1863,6 +1863,7 @@ filter_and_sort_kernels (vector &sorted_kernels, set end_bb; list walked_header_bb; /* Used to record nested loops. */ + set walked_non_header_bb_idx; for (unsigned i = 0; i < kernels.size (); ++i) { @@ -1895,7 +1896,15 @@ filter_and_sort_kernels (vector &sorted_kernels, /* bb is not the head of the loop, go to the next. */ if (bb != bb->loop_father->header) { - bb = next_high_probability_bb (bb); + if (walked_non_header_bb_idx.count (bb->index)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Find same-loop cycle. " + "Abort filtering process.\n"); + return false; + } + walked_non_header_bb_idx.insert (bb->index); + bb = next_high_probability_bb (bb); continue; } -- 2.33.0