91 lines
2.9 KiB
Diff
91 lines
2.9 KiB
Diff
From a2a8b560c1749293d3b6d027e20753a7ea042c80 Mon Sep 17 00:00:00 2001
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
|
Date: Sat, 11 Nov 2023 17:28:55 +0000
|
|
Subject: [PATCH 035/157] [Backport][SME] mode-switching: Avoid quadractic list
|
|
operation
|
|
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=174ee5115a3004d3664165e9d619535b579111d4
|
|
|
|
add_seginfo chained insn information to the end of a list
|
|
by starting at the head of the list. This patch avoids the
|
|
quadraticness by keeping track of the tail pointer.
|
|
|
|
gcc/
|
|
* mode-switching.cc (add_seginfo): Replace head pointer with
|
|
a pointer to the tail pointer.
|
|
(optimize_mode_switching): Update calls accordingly.
|
|
---
|
|
gcc/mode-switching.cc | 24 ++++++++----------------
|
|
1 file changed, 8 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
|
|
index 2a9f98793..6a13951c9 100644
|
|
--- a/gcc/mode-switching.cc
|
|
+++ b/gcc/mode-switching.cc
|
|
@@ -162,23 +162,14 @@ new_seginfo (int mode, rtx_insn *insn, const HARD_REG_SET ®s_live)
|
|
}
|
|
|
|
/* Add a seginfo element to the end of a list.
|
|
- HEAD is a pointer to the list beginning.
|
|
+ TAIL is a pointer to the list's null terminator.
|
|
INFO is the structure to be linked in. */
|
|
|
|
static void
|
|
-add_seginfo (struct bb_info *head, struct seginfo *info)
|
|
+add_seginfo (struct seginfo ***tail_ptr, struct seginfo *info)
|
|
{
|
|
- struct seginfo *ptr;
|
|
-
|
|
- if (head->seginfo == NULL)
|
|
- head->seginfo = info;
|
|
- else
|
|
- {
|
|
- ptr = head->seginfo;
|
|
- while (ptr->next != NULL)
|
|
- ptr = ptr->next;
|
|
- ptr->next = info;
|
|
- }
|
|
+ **tail_ptr = info;
|
|
+ *tail_ptr = &info->next;
|
|
}
|
|
|
|
/* Record in LIVE that register REG died. */
|
|
@@ -573,6 +564,7 @@ optimize_mode_switching (void)
|
|
Also compute the initial transparency settings. */
|
|
FOR_EACH_BB_FN (bb, cfun)
|
|
{
|
|
+ struct seginfo **tail_ptr = &info[bb->index].seginfo;
|
|
struct seginfo *ptr;
|
|
int last_mode = no_mode;
|
|
bool any_set_required = false;
|
|
@@ -598,7 +590,7 @@ optimize_mode_switching (void)
|
|
if (ins_pos != BB_END (bb))
|
|
ins_pos = NEXT_INSN (ins_pos);
|
|
ptr = new_seginfo (no_mode, ins_pos, live_now);
|
|
- add_seginfo (info + bb->index, ptr);
|
|
+ add_seginfo (&tail_ptr, ptr);
|
|
for (i = 0; i < no_mode; i++)
|
|
clear_mode_bit (transp[bb->index], j, i);
|
|
}
|
|
@@ -616,7 +608,7 @@ optimize_mode_switching (void)
|
|
any_set_required = true;
|
|
last_mode = mode;
|
|
ptr = new_seginfo (mode, insn, live_now);
|
|
- add_seginfo (info + bb->index, ptr);
|
|
+ add_seginfo (&tail_ptr, ptr);
|
|
for (i = 0; i < no_mode; i++)
|
|
clear_mode_bit (transp[bb->index], j, i);
|
|
}
|
|
@@ -645,7 +637,7 @@ optimize_mode_switching (void)
|
|
if (!any_set_required)
|
|
{
|
|
ptr = new_seginfo (no_mode, BB_END (bb), live_now);
|
|
- add_seginfo (info + bb->index, ptr);
|
|
+ add_seginfo (&tail_ptr, ptr);
|
|
if (last_mode != no_mode)
|
|
for (i = 0; i < no_mode; i++)
|
|
clear_mode_bit (transp[bb->index], j, i);
|
|
--
|
|
2.33.0
|
|
|