1 Star 0 Fork 117

yhl123123/gcc

forked from src-openEuler/gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0004-Backport-tree-optimization-Avoid-issueing-loads-in-S.patch 4.84 KB
一键复制 编辑 原始数据 按行查看 历史
eastb233 提交于 2021-07-28 11:42 . [Sync] Sync patch from openeuler/gcc
From bdb0f40cea4aa1a92ead381b645363ae0571c065 Mon Sep 17 00:00:00 2001
From: zhanghaijian <z.zhanghaijian@huawei.com>
Date: Mon, 12 Jul 2021 10:36:15 +0800
Subject: [PATCH 04/13] [Backport]tree-optimization: Avoid issueing loads in SM
when possible
Reference:https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=f9e1ea10e657af9fb02fafecf1a600740fd34409
Currently store-motion emits a load of the value in the loop
preheader even when the original loop does not contain any read
of the reference. This avoids doing this. In the conditional
store-motion case we need to mark the sunk stores with no-warning
since the control dependence is too tricky to figure out for
the uninit warning.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
new file mode 100755
index 00000000000..884f905148f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr39612.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-lim2-details -Wuninitialized" } */
+
+void foo(int *);
+void f2(int dst[3], int R)
+{
+ int i, inter[2];
+
+ for (i = 1; i < R; i++) {
+ if (i & 8)
+ {
+ inter[0] = 1;
+ inter[1] = 1;
+ }
+ }
+
+ foo(inter);
+}
+
+/* { dg-final { scan-tree-dump-times "Executing store motion" 2 "lim2" } } */
+/* { dg-final { scan-tree-dump-not " = inter\\\[\[0-1\]\\\];" "lim2" } } */
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index abd5f702b91..b3fd1647fbd 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -127,6 +127,8 @@ public:
bitmap stored; /* The set of loops in that this memory location
is stored to. */
+ bitmap loaded; /* The set of loops in that this memory location
+ is loaded from. */
vec<mem_ref_loc> accesses_in_loop;
/* The locations of the accesses. Vector
indexed by the loop number. */
@@ -1395,6 +1397,7 @@ mem_ref_alloc (ao_ref *mem, unsigned hash, unsigned id)
ref->ref_decomposed = false;
ref->hash = hash;
ref->stored = NULL;
+ ref->loaded = NULL;
bitmap_initialize (&ref->indep_loop, &lim_bitmap_obstack);
bitmap_initialize (&ref->dep_loop, &lim_bitmap_obstack);
ref->accesses_in_loop.create (1);
@@ -1435,6 +1438,27 @@ mark_ref_stored (im_mem_ref *ref, class loop *loop)
loop = loop_outer (loop);
}
+/* Set the LOOP bit in REF loaded bitmap and allocate that if
+ necessary. Return whether a bit was changed. */
+
+static bool
+set_ref_loaded_in_loop (im_mem_ref *ref, class loop *loop)
+{
+ if (!ref->loaded)
+ ref->loaded = BITMAP_ALLOC (&lim_bitmap_obstack);
+ return bitmap_set_bit (ref->loaded, loop->num);
+}
+
+/* Marks reference REF as loaded in LOOP. */
+
+static void
+mark_ref_loaded (im_mem_ref *ref, class loop *loop)
+{
+ while (loop != current_loops->tree_root
+ && set_ref_loaded_in_loop (ref, loop))
+ loop = loop_outer (loop);
+}
+
/* Gathers memory references in statement STMT in LOOP, storing the
information about them in the memory_accesses structure. Marks
the vops accessed through unrecognized statements there as
@@ -1571,6 +1595,8 @@ gather_mem_refs_stmt (class loop *loop, gimple *stmt)
bitmap_set_bit (&memory_accesses.refs_stored_in_loop[loop->num], ref->id);
mark_ref_stored (ref, loop);
}
+ else
+ mark_ref_loaded (ref, loop);
init_lim_data (stmt)->ref = ref->id;
return;
}
@@ -1968,6 +1994,8 @@ execute_sm_if_changed (edge ex, tree mem, tree tmp_var, tree flag,
gsi = gsi_start_bb (then_bb);
/* Insert actual store. */
stmt = gimple_build_assign (unshare_expr (mem), tmp_var);
+ /* Make sure to not warn about maybe-uninit uses of tmp_var here. */
+ gimple_set_no_warning (stmt, true);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
edge e1 = single_succ_edge (new_bb);
@@ -2115,14 +2143,17 @@ execute_sm (class loop *loop, vec<edge> exits, im_mem_ref *ref)
by move_computations after all dependencies. */
gsi = gsi_for_stmt (first_mem_ref_loc (loop, ref)->stmt);
- /* FIXME/TODO: For the multi-threaded variant, we could avoid this
- load altogether, since the store is predicated by a flag. We
- could, do the load only if it was originally in the loop. */
- load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
- lim_data = init_lim_data (load);
- lim_data->max_loop = loop;
- lim_data->tgt_loop = loop;
- gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+ /* Avoid doing a load if there was no load of the ref in the loop.
+ Esp. when the ref is not always stored we cannot optimize it
+ away later. */
+ if (ref->loaded && bitmap_bit_p (ref->loaded, loop->num))
+ {
+ load = gimple_build_assign (tmp_var, unshare_expr (ref->mem.ref));
+ lim_data = init_lim_data (load);
+ lim_data->max_loop = loop;
+ lim_data->tgt_loop = loop;
+ gsi_insert_before (&gsi, load, GSI_SAME_STMT);
+ }
if (multi_threaded_model_p)
{
--
2.21.0.windows.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/yhl123123/gcc.git
git@gitee.com:yhl123123/gcc.git
yhl123123
gcc
gcc
master

搜索帮助

D67c1975 1850385 1daf7b77 1850385