1 Star 0 Fork 140

yangxin/gcc

forked from eastb233/src-openeuler_gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
generate-csel-for-arrayref.patch 7.83 KB
一键复制 编辑 原始数据 按行查看 历史
jdkboy 提交于 2020-08-29 09:39 . Add several enhancement patches
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-1.c 2020-05-19 20:12:32.655794652 +0800
@@ -9,4 +9,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-2.c 2020-05-19 20:12:32.667794652 +0800
@@ -11,4 +11,4 @@ unsigned test(unsigned k, unsigned b) {
return a[0]+a[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89430-5.c 2020-05-19 20:12:32.667794652 +0800
@@ -13,4 +13,4 @@ int test(int b, int k) {
return a.data[0] + a.data[1];
}
-/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "Conditional store replacement" "cselim" } } */
diff -uprN a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
--- a/gcc/tree-ssa-phiopt.c 2020-05-26 21:03:43.132721856 +0800
+++ b/gcc/tree-ssa-phiopt.c 2020-05-26 21:02:02.872006469 +0800
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
#include "params.h"
#include "case-cfn-macros.h"
#include "tree-eh.h"
+#include "inchash.h"
static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
@@ -1984,6 +1985,18 @@ struct name_to_bb
basic_block bb;
};
+/* A hash-table of ARRAY_REF with a base of VAR_DECL and an offset of
+ SSA_NAME, and in which basic block it was seen, which would constitute
+ a no-trap region for same accessed. */
+struct array_ref_to_bb
+{
+ unsigned int ssa_name_ver;
+ unsigned int phase;
+ HOST_WIDE_INT size;
+ tree var_decl;
+ basic_block bb;
+};
+
/* Hashtable helpers. */
struct ssa_names_hasher : free_ptr_hash <name_to_bb>
@@ -1992,6 +2005,12 @@ struct ssa_names_hasher : free_ptr_hash
static inline bool equal (const name_to_bb *, const name_to_bb *);
};
+struct array_refs_hasher : free_ptr_hash <array_ref_to_bb>
+{
+ static inline hashval_t hash (const array_ref_to_bb *);
+ static inline bool equal (const array_ref_to_bb *, const array_ref_to_bb *);
+};
+
/* Used for quick clearing of the hash-table when we see calls.
Hash entries with phase < nt_call_phase are invalid. */
static unsigned int nt_call_phase;
@@ -2005,6 +2024,16 @@ ssa_names_hasher::hash (const name_to_bb
^ (n->offset << 6) ^ (n->size << 3);
}
+inline hashval_t
+array_refs_hasher::hash (const array_ref_to_bb *n)
+{
+ inchash::hash hstate (0);
+ hstate.add_int (n->ssa_name_ver);
+ hstate.add_hwi (n->size);
+ hstate.add_ptr (n->var_decl);
+ return hstate.end ();
+}
+
/* The equality function of *P1 and *P2. */
inline bool
@@ -2016,11 +2045,21 @@ ssa_names_hasher::equal (const name_to_b
&& n1->size == n2->size;
}
+inline bool
+array_refs_hasher::equal (const array_ref_to_bb *n1, const array_ref_to_bb *n2)
+{
+ return n1->ssa_name_ver == n2->ssa_name_ver
+ && n1->size == n2->size
+ && n1->var_decl == n2->var_decl;
+}
+
class nontrapping_dom_walker : public dom_walker
{
public:
nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
- : dom_walker (direction), m_nontrapping (ps), m_seen_ssa_names (128) {}
+ : dom_walker (direction), m_nontrapping (ps),
+ m_seen_ssa_names (128), m_seen_array_refs (128)
+ {}
virtual edge before_dom_children (basic_block);
virtual void after_dom_children (basic_block);
@@ -2028,16 +2067,18 @@ public:
private:
/* We see the expression EXP in basic block BB. If it's an interesting
- expression (an MEM_REF through an SSA_NAME) possibly insert the
- expression into the set NONTRAP or the hash table of seen expressions.
- STORE is true if this expression is on the LHS, otherwise it's on
- the RHS. */
+ expression (an MEM_REF through an SSA_NAME or an ARRAY_REF with a base
+ of VAR_DECL and an offset of SSA_NAME) possibly insert the expression
+ into the set NONTRAP or the hash table of seen expressions. STORE
+ is true if this expression is on the LHS, otherwise it's on the RHS. */
void add_or_mark_expr (basic_block, tree, bool);
+ void add_or_mark_array_ref (basic_block, tree);
hash_set<tree> *m_nontrapping;
/* The hash table for remembering what we've seen. */
hash_table<ssa_names_hasher> m_seen_ssa_names;
+ hash_table<array_refs_hasher> m_seen_array_refs;
};
/* Called by walk_dominator_tree, when entering the block BB. */
@@ -2071,7 +2112,9 @@ nontrapping_dom_walker::before_dom_child
else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
{
add_or_mark_expr (bb, gimple_assign_lhs (stmt), true);
+ add_or_mark_array_ref (bb, gimple_assign_lhs (stmt));
add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), false);
+ add_or_mark_array_ref (bb, gimple_assign_rhs1 (stmt));
}
}
return NULL;
@@ -2148,6 +2191,74 @@ nontrapping_dom_walker::add_or_mark_expr
}
}
}
+}
+
+/* We see the expression EXP in basic block BB. If it's an interesting
+ expression (an ARRAY_REF with a base of VAR_DECL and an offset of
+ SSA_NAME) possibly insert the expression into the set NONTRAP or the
+ hash table of seen expressions. */
+void
+nontrapping_dom_walker::add_or_mark_array_ref (basic_block bb, tree exp)
+{
+ if (TREE_CODE (exp) == ARRAY_REF
+ && TREE_CODE (TREE_OPERAND (exp, 1)) == SSA_NAME
+ && int_size_in_bytes (TREE_TYPE (exp)) > 0)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
+ tree base = get_base_address (exp);
+ /* if BASE is a local variable without address-taken, which can't be
+ read-only, a dominating load can constitute a no-trap region for
+ a store as well. */
+ if (TREE_CODE (base) == VAR_DECL
+ && auto_var_p (base) && !TREE_ADDRESSABLE (base))
+ {
+ struct array_ref_to_bb array_map;
+ basic_block found_array_bb = 0;
+
+ /* Try to find the last seen ARRAY_REF with the same base and
+ offset, which can trap. */
+ array_map.ssa_name_ver = SSA_NAME_VERSION (TREE_OPERAND (exp, 1));
+ array_map.phase = 0;
+ array_map.bb = 0;
+ array_map.size = size;
+ array_map.var_decl = base;
+
+ array_ref_to_bb **slot
+ = m_seen_array_refs.find_slot (&array_map, INSERT);
+ struct array_ref_to_bb *a2bb = *slot;
+ if (a2bb != NULL && a2bb->phase >= nt_call_phase)
+ {
+ found_array_bb = a2bb->bb;
+ }
+
+ /* If we've found a trapping MEM_REF, _and_ it dominates EXP
+ (it's in a basic block on the path from us to the dominator root)
+ then we can't trap. */
+ if (found_array_bb && (((size_t)found_array_bb->aux) & 1) == 1)
+ {
+ m_nontrapping->add (exp);
+ }
+ else
+ {
+ /* EXP might trap, so insert it into the hash table. */
+ if (a2bb != NULL)
+ {
+ a2bb->phase = nt_call_phase;
+ a2bb->bb = bb;
+ }
+ else
+ {
+ a2bb = XNEW (struct array_ref_to_bb);
+ a2bb->ssa_name_ver = SSA_NAME_VERSION (TREE_OPERAND (exp, 1));
+ a2bb->phase = nt_call_phase;
+ a2bb->bb = bb;
+ a2bb->size = size;
+ a2bb->var_decl = base;
+ *slot = a2bb;
+ }
+ }
+ }
+ }
}
/* This is the entry point of gathering non trapping memory accesses.
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/anar/gcc.git
git@gitee.com:anar/gcc.git
anar
gcc
gcc
master

搜索帮助