代码拉取完成,页面将自动刷新
From 55c547748af36ffc3f2d5ed154a91fb3fcb8431c Mon Sep 17 00:00:00 2001
From: Mingchuan Wu <wumingchuan1992@foxmail.com>
Date: Thu, 11 Apr 2024 15:49:59 +0800
Subject: [PATCH] [Struct Reorg] Port bugfixes to GCC 12.3.1
Migrated from commits in GCC10.3.1:
https://gitee.com/openeuler/gcc/commit/41af6d361a6d85ef4fce8a8438113d765596afdd
https://gitee.com/openeuler/gcc/commit/25d74b98caeaae881e374924886ee664aa1af5bc
https://gitee.com/openeuler/gcc/commit/b5a3bfe92f96cd0d2224d80ac4eaa80dab1bd6bf
https://gitee.com/openeuler/gcc/commit/708ffe6f132ee39441b66b6ab6b98847d35916b7
https://gitee.com/openeuler/gcc/commit/e875e4e7f3716aa268ffbbf55ee199ec82b6aeba
---
gcc/ipa-struct-reorg/ipa-struct-reorg.cc | 97 ++++++++++---------
gcc/testsuite/gcc.dg/struct/dfe_escape.c | 50 ++++++++++
gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c | 69 +++++++++++++
gcc/testsuite/gcc.dg/struct/struct-reorg.exp | 2 +
gcc/testsuite/gcc.dg/struct/struct_reorg-10.c | 29 ++++++
gcc/testsuite/gcc.dg/struct/struct_reorg-11.c | 16 +++
gcc/testsuite/gcc.dg/struct/struct_reorg-12.c | 26 +++++
7 files changed, 243 insertions(+), 46 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_escape.c
create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c
create mode 100644 gcc/testsuite/gcc.dg/struct/struct_reorg-10.c
create mode 100644 gcc/testsuite/gcc.dg/struct/struct_reorg-11.c
create mode 100644 gcc/testsuite/gcc.dg/struct/struct_reorg-12.c
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc
index 6a202b4bd..f03d1d875 100644
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.cc
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.cc
@@ -466,10 +466,19 @@ srtype::has_dead_field (void)
unsigned i;
FOR_EACH_VEC_ELT (fields, i, this_field)
{
- if (!(this_field->field_access & READ_FIELD))
- {
- may_dfe = true;
- break;
+ /* Function pointer members are not processed, because DFE
+ does not currently support accurate analysis of function
+ pointers, and we have not identified specific use cases. */
+ if (!(this_field->field_access & READ_FIELD)
+ && !FUNCTION_POINTER_TYPE_P (this_field->fieldtype))
+ {
+ /* Fields with escape risks should not be processed. */
+ if (this_field->type == NULL
+ || (this_field->type->escapes == does_not_escape))
+ {
+ may_dfe = true;
+ break;
+ }
}
}
return may_dfe;
@@ -1032,8 +1041,13 @@ srtype::create_new_type (void)
{
srfield *f = fields[i];
if (current_layout_opt_level & DEAD_FIELD_ELIMINATION
- && !(f->field_access & READ_FIELD))
- continue;
+ && !(f->field_access & READ_FIELD)
+ && !FUNCTION_POINTER_TYPE_P (f->fieldtype))
+ {
+ /* Fields with escape risks should not be processed. */
+ if (f->type == NULL || (f->type->escapes == does_not_escape))
+ continue;
+ }
f->create_new_fields (newtype, newfields, newlast);
}
@@ -3815,9 +3829,17 @@ ipa_struct_reorg::maybe_mark_or_record_other_side (tree side, tree other,
if (VOID_POINTER_P (TREE_TYPE (side))
&& TREE_CODE (side) == SSA_NAME)
{
- /* The type is other, the declaration is side. */
- current_function->record_decl (type, side, -1,
- isptrptr (TREE_TYPE (other)) ? TREE_TYPE (other) : NULL);
+ tree inner = SSA_NAME_VAR (side);
+ if (inner)
+ {
+ srdecl *in = find_decl (inner);
+ if (in && !in->type->has_escaped ())
+ {
+ /* The type is other, the declaration is side. */
+ current_function->record_decl (type, side, -1,
+ isptrptr (TREE_TYPE (other)) ? TREE_TYPE (other) : NULL);
+ }
+ }
}
else
/* *_1 = &MEM[(void *)&x + 8B]. */
@@ -3910,6 +3932,12 @@ ipa_struct_reorg::maybe_record_assign (cgraph_node *node, gassign *stmt)
maybe_mark_or_record_other_side (rhs, lhs, stmt);
if (TREE_CODE (lhs) == SSA_NAME)
maybe_mark_or_record_other_side (lhs, rhs, stmt);
+
+ /* Handle missing ARRAY_REF cases. */
+ if (TREE_CODE (lhs) == ARRAY_REF)
+ mark_type_as_escape (TREE_TYPE (lhs), escape_array, stmt);
+ if (TREE_CODE (rhs) == ARRAY_REF)
+ mark_type_as_escape (TREE_TYPE (rhs), escape_array, stmt);
}
}
@@ -5272,8 +5300,11 @@ ipa_struct_reorg::record_accesses (void)
record_function (cnode);
else
{
- tree return_type = TREE_TYPE (TREE_TYPE (cnode->decl));
- mark_type_as_escape (return_type, escape_return, NULL);
+ if (cnode->externally_visible)
+ {
+ tree return_type = TREE_TYPE (TREE_TYPE (cnode->decl));
+ mark_type_as_escape (return_type, escape_return, NULL);
+ }
}
}
@@ -5889,6 +5920,7 @@ ipa_struct_reorg::rewrite_expr (tree expr,
bool escape_from_base = false;
tree newbase[max_split];
+ memset (newbase, 0, sizeof (tree[max_split]));
memset (newexpr, 0, sizeof (tree[max_split]));
if (TREE_CODE (expr) == CONSTRUCTOR)
@@ -6912,7 +6944,7 @@ create_bb_for_group_diff_ne_0 (basic_block new_bb, tree &phi, tree ptr,
}
tree
-ipa_struct_reorg::rewrite_pointer_plus_integer (gimple *stmt,
+ipa_struct_reorg::rewrite_pointer_plus_integer (gimple *stmt ATTRIBUTE_UNUSED,
gimple_stmt_iterator *gsi,
tree ptr, tree offset,
srtype *type)
@@ -7889,41 +7921,14 @@ ipa_struct_reorg::rewrite_cond (gcond *stmt,
should be removed. */
bool
-ipa_struct_reorg::rewrite_debug (gimple *stmt, gimple_stmt_iterator *)
+ipa_struct_reorg::rewrite_debug (gimple *, gimple_stmt_iterator *)
{
- if (current_layout_opt_level >= STRUCT_REORDER_FIELDS)
- /* Delete debug gimple now. */
- return true;
- bool remove = false;
- if (gimple_debug_bind_p (stmt))
- {
- tree var = gimple_debug_bind_get_var (stmt);
- tree newvar[max_split];
- if (rewrite_expr (var, newvar, true))
- remove = true;
- if (gimple_debug_bind_has_value_p (stmt))
- {
- var = gimple_debug_bind_get_value (stmt);
- if (TREE_CODE (var) == POINTER_PLUS_EXPR)
- var = TREE_OPERAND (var, 0);
- if (rewrite_expr (var, newvar, true))
- remove = true;
- }
- }
- else if (gimple_debug_source_bind_p (stmt))
- {
- tree var = gimple_debug_source_bind_get_var (stmt);
- tree newvar[max_split];
- if (rewrite_expr (var, newvar, true))
- remove = true;
- var = gimple_debug_source_bind_get_value (stmt);
- if (TREE_CODE (var) == POINTER_PLUS_EXPR)
- var = TREE_OPERAND (var, 0);
- if (rewrite_expr (var, newvar, true))
- remove = true;
- }
-
- return remove;
+ /* In debug statements, there might be some statements that have
+ been optimized out in gimple but left in debug gimple. Sometimes
+ these statements need to be analyzed to escape, but in rewrite
+ stage it shouldn't happen. It needs to care a lot to handle these
+ cases but seems useless. So now we just delete debug gimple. */
+ return true;
}
/* Rewrite PHI nodes, return true if the PHI was replaced. */
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_escape.c b/gcc/testsuite/gcc.dg/struct/dfe_escape.c
new file mode 100644
index 000000000..09efe8027
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/dfe_escape.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct arc arc_t;
+typedef struct arc *arc_p;
+
+typedef struct network
+{
+ int x;
+} network_t;
+
+struct arc
+{
+ int flow;
+ network_t* net_add;
+};
+
+const int MAX = 100;
+
+/* let it escape_array, "Type is used in an array [not handled yet]". */
+network_t* net[2];
+arc_p stop_arcs = NULL;
+
+int
+main ()
+{
+ net[0] = (network_t*) calloc (1, sizeof(network_t));
+ stop_arcs = (arc_p) calloc (MAX, sizeof (arc_t));
+
+ net[0]->x = 100;
+
+ for (unsigned i = 0; i < 3; i++)
+ {
+ net[0]->x = net[0]->x + 2;
+ stop_arcs->flow = net[0]->x / 2;
+ stop_arcs->flow = stop_arcs->flow + 20;
+ stop_arcs->net_add = net[0];
+ stop_arcs++;
+ }
+
+ if( net[1] != 0 && stop_arcs != 0)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */
diff --git a/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c b/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c
new file mode 100644
index 000000000..74ea93bbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c
@@ -0,0 +1,69 @@
+/* { dg-do compile } */
+/* { dg-do run } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef STACK_SIZE
+#if STACK_SIZE > 16000
+#define N 1000
+#else
+#define N (STACK_SIZE/16)
+#endif
+#else
+#define N 1000
+#endif
+
+int num;
+
+int (*foo)(int d);
+int f (int t);
+
+typedef struct str_t str_t1;
+struct str_t
+{
+ int a;
+ float b;
+ int (*foo)(int d);
+};
+
+int main ()
+{
+ int i, r;
+ r = rand ();
+ num = r > N ? N : r;
+ str_t1 * p1 = calloc (num, sizeof (str_t1));
+ if (p1 == NULL)
+ return 0;
+ for (i = 0; i < num; i++)
+ {
+ p1[i].foo = malloc (1 * sizeof (f));
+ p1[i].foo = f;
+ p1[i].foo (i);
+ }
+
+ for (i = 0; i < num; i++)
+ p1[i].a = 1;
+
+ for (i = 0; i < num; i++)
+ p1[i].b = 2;
+
+ for (i = 0; i < num; i++)
+ if (p1[i].a != 1)
+ abort ();
+
+ for (i = 0; i < num; i++)
+ if (abs (p1[i].b - 2) > 0.0001)
+ abort ();
+
+ return 0;
+}
+
+int f (int t)
+{
+ if ( t < 0)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */
diff --git a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
index c5a955b00..687f6609f 100644
--- a/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
+++ b/gcc/testsuite/gcc.dg/struct/struct-reorg.exp
@@ -46,6 +46,8 @@ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/rf_*.c]] \
# -fipa-struct-reorg=3
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/dfe*.c]] \
"" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program"
+gcc-dg-runtest $srcdir/$subdir/struct_reorg-7.c \
+ "" "-fipa-struct-reorg=3 -fdump-ipa-all -flto-partition=one -fwhole-program"
# -fipa-struct-reorg=4
gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/pc*.c]] \
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-10.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-10.c
new file mode 100644
index 000000000..ec422f76f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-10.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */
+
+struct a {
+ int b;
+ char c;
+};
+struct {
+ double d;
+ _Bool e;
+} * f;
+struct g {
+ struct a h;
+} i;
+long j;
+void k();
+void l() { k(i); }
+void k(struct a m) {
+ f->e = 0;
+ for (;;)
+ l();
+}
+int main() {
+ for (; j; f = 0) {
+ struct g *n = 0;
+ char o = n->h.c;
+ }
+ l();
+}
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-11.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-11.c
new file mode 100644
index 000000000..3e42aa84a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-11.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */
+
+struct a {
+ int b;
+ double c;
+};
+struct d {
+ struct a e;
+};
+int f;
+int main() {
+ _Bool g;
+ struct d **h = 0;
+ g = *h += f;
+}
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-12.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-12.c
new file mode 100644
index 000000000..d434f9fe0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-12.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-w -g -O3 -flto-partition=one -fipa-struct-reorg -fwhole-program -S" } */
+
+struct foo {
+ long element1;
+ long element2;
+};
+
+struct goo {
+ struct foo element_foo;
+};
+
+struct goo g1;
+
+void func () {
+ struct foo (*local)[] = 0;
+ long idx;
+ (g1).element_foo = (*local)[idx];
+}
+
+struct foo g2;
+int main () {
+ func ();
+ g2 = g1.element_foo;
+ return 0;
+}
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。