176 lines
5.3 KiB
Diff
176 lines
5.3 KiB
Diff
From 4369e823f0883c079c0681bef68cead870d02063 Mon Sep 17 00:00:00 2001
|
|
From: Feiyang Liu <liufeiyang6@huawei.com>
|
|
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<class loop *> &sorted_kernels,
|
|
|
|
set<basic_block> end_bb;
|
|
list<basic_block> walked_header_bb; /* Used to record nested loops. */
|
|
+ set<int> walked_non_header_bb_idx;
|
|
|
|
for (unsigned i = 0; i < kernels.size (); ++i)
|
|
{
|
|
@@ -1895,7 +1896,15 @@ filter_and_sort_kernels (vector<class loop *> &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
|
|
|