Projects
openEuler:24.03:SP1:Everything
gcc
_service:tar_scm:0055-Struct-Reorg-Port-bugfixe...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0055-Struct-Reorg-Port-bugfixes-to-GCC-12.3.1.patch of Package gcc
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2