diff options
author | CoprDistGit <infra@openeuler.org> | 2025-02-28 10:03:49 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2025-02-28 10:03:49 +0000 |
commit | 73127104a245052cd5cf29cdaaca3e5c32c70348 (patch) | |
tree | 8e28b63e478c43c252f18b49836dff7313affe54 /0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch | |
parent | 49d3feaf4665cdb07576fc1a2382a4d82a612d35 (diff) |
automatic import of gccopeneuler24.03_LTS_SP1
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.patch | 420 |
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 + |