[Sync] Sync patch from openeuler/gcc
This commit is contained in:
parent
3ee8545fc2
commit
a9c5574f8f
420
0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
Normal file
420
0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
Normal file
@ -0,0 +1,420 @@
|
||||
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
|
||||
|
||||
8
gcc.spec
8
gcc.spec
@ -2,7 +2,7 @@
|
||||
%global gcc_major 12
|
||||
# Note, gcc_release must be integer, if you want to add suffixes to
|
||||
# %%{release}, append them after %%{gcc_release} on Release: line.
|
||||
%global gcc_release 21
|
||||
%global gcc_release 22
|
||||
|
||||
%global _unpackaged_files_terminate_build 0
|
||||
%global _performance_build 1
|
||||
@ -192,6 +192,7 @@ Patch51: 0051-Port-fixes-for-IPA-prefetch-to-GCC-12.patch
|
||||
Patch52: 0052-Fix-fails-in-IPA-prefetch-src-openEuler-gcc-I96ID7.patch
|
||||
Patch53: 0053-struct-reorg-Add-Semi-Relayout.patch
|
||||
Patch54: 0054-Struct-Reorg-Bugfix-for-structure-pointer-compressio.patch
|
||||
Patch55: 0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
|
||||
|
||||
# Part 3000 ~ 4999
|
||||
%ifarch loongarch64
|
||||
@ -841,6 +842,7 @@ not stable, so plugins must be rebuilt any time GCC is updated.
|
||||
%patch52 -p1
|
||||
%patch53 -p1
|
||||
%patch54 -p1
|
||||
%patch55 -p1
|
||||
|
||||
%ifarch loongarch64
|
||||
%patch3001 -p1
|
||||
@ -3226,6 +3228,10 @@ end
|
||||
%doc rpm.doc/changelogs/libcc1/ChangeLog*
|
||||
|
||||
%changelog
|
||||
* Fri Apr 12 2024 Zhengchen Hui <zhengchenhui1@huawei.com> - 12.3.1-22
|
||||
- Type: Sync
|
||||
- DESC: Sync patch from openeuler/gcc
|
||||
|
||||
* Thu Apr 11 2024 Zhengchen Hui <zhengchenhui1@huawei.com> - 12.3.1-21
|
||||
- Type: Sync
|
||||
- DESC: Sync patch from openeuler/gcc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user