21 Star 27 Fork 151

src-openEuler/gcc

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0135-Backport-SME-mode-switching-Fix-the-mode-passed-to-t.patch 4.76 KB
一键复制 编辑 原始数据 按行查看 历史
huangzifeng 提交于 2024-11-21 11:35 +08:00 . Sync patches from branch openEuler-24.09
From 194700063ed04b56d84912f7ace1b8370af6c696 Mon Sep 17 00:00:00 2001
From: Richard Sandiford <richard.sandiford@arm.com>
Date: Sat, 11 Nov 2023 17:28:56 +0000
Subject: [PATCH 036/157] [Backport][SME] mode-switching: Fix the mode passed
to the emit hook
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=5afd208beaef50bcc43b556d4c41d41656b06436
optimize_mode_switching passes an entity's current mode (if known)
to the emit hook. However, the mode that it passed ignored the
effect of the after hook. Instead, the mode for the first emit
call in a block was taken from the incoming mode, whereas the
mode for each subsequent emit call was taken from the result
of the previous call.
The previous pass through the insns already calculated the
correct mode, so this patch records it in the seginfo structure.
(There was a 32-bit hole on 64-bit hosts, so this doesn't increase
the size of the structure for them.)
gcc/
* mode-switching.cc (seginfo): Add a prev_mode field.
(new_seginfo): Take and initialize the prev_mode.
(optimize_mode_switching): Update calls accordingly.
Use the recorded modes during the emit phase, rather than
computing one on the fly.
---
gcc/mode-switching.cc | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/gcc/mode-switching.cc b/gcc/mode-switching.cc
index 6a13951c9..584cd4f67 100644
--- a/gcc/mode-switching.cc
+++ b/gcc/mode-switching.cc
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3. If not see
NEXT is the next insn in the same basic block. */
struct seginfo
{
+ int prev_mode;
int mode;
rtx_insn *insn_ptr;
struct seginfo *next;
@@ -140,20 +141,22 @@ commit_mode_sets (struct edge_list *edge_list, int e, struct bb_info *info)
return need_commit;
}
-/* Allocate a new BBINFO structure, initialized with the MODE, INSN,
- and REGS_LIVE parameters.
+/* Allocate a new BBINFO structure, initialized with the PREV_MODE, MODE,
+ INSN, and REGS_LIVE parameters.
INSN may not be a NOTE_INSN_BASIC_BLOCK, unless it is an empty
basic block; that allows us later to insert instructions in a FIFO-like
manner. */
static struct seginfo *
-new_seginfo (int mode, rtx_insn *insn, const HARD_REG_SET &regs_live)
+new_seginfo (int prev_mode, int mode, rtx_insn *insn,
+ const HARD_REG_SET &regs_live)
{
struct seginfo *ptr;
gcc_assert (!NOTE_INSN_BASIC_BLOCK_P (insn)
|| insn == BB_END (NOTE_BASIC_BLOCK (insn)));
ptr = XNEW (struct seginfo);
+ ptr->prev_mode = prev_mode;
ptr->mode = mode;
ptr->insn_ptr = insn;
ptr->next = NULL;
@@ -589,7 +592,7 @@ optimize_mode_switching (void)
gcc_assert (NOTE_INSN_BASIC_BLOCK_P (ins_pos));
if (ins_pos != BB_END (bb))
ins_pos = NEXT_INSN (ins_pos);
- ptr = new_seginfo (no_mode, ins_pos, live_now);
+ ptr = new_seginfo (no_mode, no_mode, ins_pos, live_now);
add_seginfo (&tail_ptr, ptr);
for (i = 0; i < no_mode; i++)
clear_mode_bit (transp[bb->index], j, i);
@@ -605,12 +608,12 @@ optimize_mode_switching (void)
if (mode != no_mode && mode != last_mode)
{
- any_set_required = true;
- last_mode = mode;
- ptr = new_seginfo (mode, insn, live_now);
+ ptr = new_seginfo (last_mode, mode, insn, live_now);
add_seginfo (&tail_ptr, ptr);
for (i = 0; i < no_mode; i++)
clear_mode_bit (transp[bb->index], j, i);
+ any_set_required = true;
+ last_mode = mode;
}
if (targetm.mode_switching.after)
@@ -636,7 +639,7 @@ optimize_mode_switching (void)
mark the block as nontransparent. */
if (!any_set_required)
{
- ptr = new_seginfo (no_mode, BB_END (bb), live_now);
+ ptr = new_seginfo (last_mode, no_mode, BB_END (bb), live_now);
add_seginfo (&tail_ptr, ptr);
if (last_mode != no_mode)
for (i = 0; i < no_mode; i++)
@@ -777,9 +780,9 @@ optimize_mode_switching (void)
FOR_EACH_BB_FN (bb, cfun)
{
struct seginfo *ptr, *next;
- int cur_mode = bb_info[j][bb->index].mode_in;
+ struct seginfo *first = bb_info[j][bb->index].seginfo;
- for (ptr = bb_info[j][bb->index].seginfo; ptr; ptr = next)
+ for (ptr = first; ptr; ptr = next)
{
next = ptr->next;
if (ptr->mode != no_mode)
@@ -789,14 +792,15 @@ optimize_mode_switching (void)
rtl_profile_for_bb (bb);
start_sequence ();
+ int cur_mode = (ptr == first && ptr->prev_mode == no_mode
+ ? bb_info[j][bb->index].mode_in
+ : ptr->prev_mode);
+
targetm.mode_switching.emit (entity_map[j], ptr->mode,
cur_mode, ptr->regs_live);
mode_set = get_insns ();
end_sequence ();
- /* modes kill each other inside a basic block. */
- cur_mode = ptr->mode;
-
/* Insert MODE_SET only if it is nonempty. */
if (mode_set != NULL_RTX)
{
--
2.33.0
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/src-openeuler/gcc.git
git@gitee.com:src-openeuler/gcc.git
src-openeuler
gcc
gcc
master

搜索帮助