summaryrefslogtreecommitdiff
path: root/0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
diff options
context:
space:
mode:
Diffstat (limited to '0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch')
-rw-r--r--0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch420
1 files changed, 420 insertions, 0 deletions
diff --git a/0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch b/0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
new file mode 100644
index 0000000..8f6b3b7
--- /dev/null
+++ b/0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch
@@ -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
+