1 Star 0 Fork 128

kkz/gcc

forked from src-openEuler/gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0016-StructReorg-Bugfix-in-certain-scenarios.patch 11.93 KB
一键复制 编辑 原始数据 按行查看 历史
eastb233 提交于 2021-08-19 19:22 . [Sync] Sync patch from openeuler/gcc
From 2194d59a20be1ab627089d2f0c082b5a0a217f52 Mon Sep 17 00:00:00 2001
From: xiezhiheng <xiezhiheng@huawei.com>
Date: Tue, 3 Aug 2021 03:49:52 -0400
Subject: [PATCH 16/22] [StructReorg] Bugfix in certain scenarios
Some bugfix in certain scenarios,
1. disable type simplify in LTO within optimizations
2. only enable optimizations in C language
3. use new to initialize allocated memory in symbol-summary.h
4. cover escape scenarios not considered
diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
index 5a19ea0bb40..1cb544ec3b0 100644
--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
@@ -97,6 +97,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-eh.h"
#include "bitmap.h"
#include "cfgloop.h"
+#include "langhooks.h"
#include "ipa-param-manipulation.h"
#include "tree-ssa-live.h" /* For remove_unused_locals. */
@@ -161,6 +162,44 @@ handled_type (tree type)
return false;
}
+/* Check whether in C language or LTO with only C language. */
+bool
+lang_c_p (void)
+{
+ const char *language_string = lang_hooks.name;
+
+ if (!language_string)
+ {
+ return false;
+ }
+
+ if (strcmp (language_string, "GNU GIMPLE") == 0)
+ {
+ unsigned i = 0;
+ tree t = NULL;
+ const char *unit_string = NULL;
+
+ FOR_EACH_VEC_SAFE_ELT (all_translation_units, i, t)
+ {
+ unit_string = TRANSLATION_UNIT_LANGUAGE (t);
+ if (!unit_string
+ || (strncmp (unit_string, "GNU C", 5) != 0)
+ || (!ISDIGIT (unit_string[5])))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else if (strncmp (language_string, "GNU C", 5) == 0
+ && ISDIGIT (language_string[5]))
+ {
+ return true;
+ }
+
+ return false;
+}
+
enum srmode
{
NORMAL = 0,
@@ -999,7 +1038,6 @@ public:
void analyze_types (void);
void clear_visited (void);
bool create_new_types (void);
- void restore_field_type (void);
void create_new_decls (void);
srdecl *find_decl (tree);
void create_new_functions (void);
@@ -2127,7 +2165,12 @@ ipa_struct_reorg::find_vars (gimple *stmt)
srtype *t = find_type (inner_type (TREE_TYPE (rhs)));
srdecl *d = find_decl (lhs);
if (!d && t)
- current_function->record_decl (t, lhs, -1);
+ {
+ current_function->record_decl (t, lhs, -1);
+ tree var = SSA_NAME_VAR (lhs);
+ if (var && VOID_POINTER_P (TREE_TYPE (var)))
+ current_function->record_decl (t, var, -1);
+ }
}
if (TREE_CODE (rhs) == SSA_NAME
&& VOID_POINTER_P (TREE_TYPE (rhs))
@@ -2136,7 +2179,12 @@ ipa_struct_reorg::find_vars (gimple *stmt)
srtype *t = find_type (inner_type (TREE_TYPE (lhs)));
srdecl *d = find_decl (rhs);
if (!d && t)
- current_function->record_decl (t, rhs, -1);
+ {
+ current_function->record_decl (t, rhs, -1);
+ tree var = SSA_NAME_VAR (rhs);
+ if (var && VOID_POINTER_P (TREE_TYPE (var)))
+ current_function->record_decl (t, var, -1);
+ }
}
}
else
@@ -2816,8 +2864,14 @@ ipa_struct_reorg::maybe_record_call (cgraph_node *node, gcall *stmt)
if (escapes != does_not_escape)
{
for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
- mark_type_as_escape (TREE_TYPE (gimple_call_arg (stmt, i)),
- escapes);
+ {
+ mark_type_as_escape (TREE_TYPE (gimple_call_arg (stmt, i)),
+ escapes);
+ srdecl *d = current_function->find_decl (
+ gimple_call_arg (stmt, i));
+ if (d)
+ d->type->mark_escape (escapes, stmt);
+ }
return;
}
@@ -3753,49 +3807,6 @@ ipa_struct_reorg::analyze_types (void)
}
}
-/* When struct A has a struct B member, B's type info
- is not stored in
- TYPE_FIELDS (TREE_TYPE (TYPE_FIELDS (typeA)))
- Try to restore B's type information. */
-void
-ipa_struct_reorg::restore_field_type (void)
-{
- for (unsigned i = 0; i < types.length (); i++)
- {
- for (unsigned j = 0; j < types[i]->fields.length (); j++)
- {
- srfield *field = types[i]->fields[j];
- if (TREE_CODE (inner_type (field->fieldtype)) == RECORD_TYPE)
- {
- /* If field type has TYPE_FIELDS information,
- we do not need to do this. */
- if (TYPE_FIELDS (field->type->type) != NULL)
- {
- continue;
- }
- for (unsigned k = 0; k < types.length (); k++)
- {
- if (i == k)
- {
- continue;
- }
- const char *type1 = get_type_name (field->type->type);
- const char *type2 = get_type_name (types[k]->type);
- if (type1 == NULL || type2 == NULL)
- {
- continue;
- }
- if (type1 == type2
- && TYPE_FIELDS (types[k]->type))
- {
- field->type = types[k];
- }
- }
- }
- }
- }
-}
-
/* Create all new types we want to create. */
bool
@@ -4652,7 +4663,6 @@ ipa_struct_reorg::rewrite_functions (void)
{
unsigned retval = 0;
- restore_field_type ();
/* Create new types, if we did not create any new types,
then don't rewrite any accesses. */
if (!create_new_types ())
@@ -4887,7 +4897,10 @@ pass_ipa_struct_reorg::gate (function *)
&& flag_ipa_struct_reorg
/* Don't bother doing anything if the program has errors. */
&& !seen_error ()
- && flag_lto_partition == LTO_PARTITION_ONE);
+ && flag_lto_partition == LTO_PARTITION_ONE
+ /* Only enable struct optimizations in C since other
+ languages' grammar forbid. */
+ && lang_c_p ());
}
} // anon namespace
diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index fa1df5c8015..a223b4dadea 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -59,6 +59,12 @@ protected:
/* Allocates new data that are stored within map. */
T* allocate_new ()
{
+ /* In structure optimizatons, we call new to ensure that
+ the allocated memory is initialized to 0. */
+ if (flag_ipa_struct_reorg)
+ return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
+ : new T ();
+
/* Call gcc_internal_because we do not want to call finalizer for
a type T. We call dtor explicitly. */
return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T ()
@@ -71,7 +77,12 @@ protected:
if (is_ggc ())
ggc_delete (item);
else
- m_allocator.remove (item);
+ {
+ if (flag_ipa_struct_reorg)
+ delete item;
+ else
+ m_allocator.remove (item);
+ }
}
/* Unregister all call-graph hooks. */
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-5.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-5.c
new file mode 100644
index 00000000000..273baa9a368
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-5.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-flto -fno-use-linker-plugin" } */
+
+struct D
+{
+ int n;
+ int c [8];
+};
+
+struct A
+{
+ int i;
+ char *p;
+};
+
+struct B
+{
+ struct A *a;
+ struct D *d;
+};
+
+int dtInsert1 (struct B *b)
+{
+ struct A a = { 0, 0 };
+ struct D *d;
+ b->a = &a;
+ d = b->d;
+ &d->c [d->n];
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-6.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-6.c
new file mode 100644
index 00000000000..455f9b501d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-6.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-flto -fno-use-linker-plugin" } */
+
+typedef struct basic_block_def *basic_block;
+typedef struct gimple_seq_node_d *gimple_seq_node;
+typedef struct gimple_seq_d *gimple_seq;
+typedef struct
+{
+ gimple_seq_node ptr;
+ gimple_seq seq;
+ basic_block bb;
+} gimple_stmt_iterator;
+typedef void *gimple;
+extern void exit(int);
+struct gimple_seq_node_d
+{
+ gimple stmt;
+ struct gimple_seq_node_d *next;
+};
+struct gimple_seq_d
+{
+};
+static __inline__ gimple_stmt_iterator
+gsi_start (gimple_seq seq)
+{
+ gimple_stmt_iterator i;
+ i.seq = seq;
+ return i;
+}
+static __inline__ unsigned char
+gsi_end_p (gimple_stmt_iterator i)
+{
+ return i.ptr == ((void *)0);
+}
+static __inline__ void
+gsi_next (gimple_stmt_iterator *i)
+{
+ i->ptr = i->ptr->next;
+}
+static __inline__ gimple
+gsi_stmt (gimple_stmt_iterator i)
+{
+ return i.ptr->stmt;
+}
+void
+c_warn_unused_result (gimple_seq seq)
+{
+ gimple_stmt_iterator i;
+ for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ {
+ gimple g = gsi_stmt (i);
+ if (!g) exit(0);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-7.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-7.c
new file mode 100644
index 00000000000..afc0bd86ca5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-7.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+struct gki_elem {
+ char *key;
+ int idx;
+};
+
+typedef struct {
+ struct gki_elem *table;
+
+ int primelevel;
+ int nhash;
+ int nkeys;
+} GKI;
+
+void *
+sre_malloc(size_t size)
+{
+ void *ptr = malloc (size);
+ return ptr;
+}
+
+__attribute__((noinline)) int
+GKIStoreKey(GKI *hash)
+{
+ hash->table = sre_malloc(sizeof(struct gki_elem));
+}
+
+int
+main ()
+{
+ GKI *hash = malloc (sizeof(GKI));
+ GKIStoreKey(hash);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-8.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-8.c
new file mode 100644
index 00000000000..9bcfaf3681b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-8.c
@@ -0,0 +1,25 @@
+/* { dg-do run } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct {
+ unsigned char blue;
+ unsigned char green;
+} Pixel;
+
+typedef struct {
+ unsigned short colormaplength;
+ Pixel *colormapdata;
+} TargaImage;
+
+TargaImage *img;
+
+int main() {
+ img = (TargaImage *) malloc( sizeof(TargaImage) );
+ if (img->colormaplength > 0) {
+ img->colormapdata = (Pixel *) malloc(sizeof(Pixel) * img->colormaplength);
+ memset(img->colormapdata, 0, (sizeof(Pixel) * img->colormaplength) );
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/struct/struct_reorg-9.c b/gcc/testsuite/gcc.dg/struct/struct_reorg-9.c
new file mode 100644
index 00000000000..052f4e3bdc1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/struct/struct_reorg-9.c
@@ -0,0 +1,54 @@
+/* { dg-do run } */
+
+extern void abort(void);
+
+struct packed_ushort {
+ unsigned short ucs;
+} __attribute__((packed));
+
+struct source {
+ int pos, length;
+};
+
+static int flag;
+
+static void __attribute__((noinline)) fetch(struct source *p)
+{
+ p->length = 128;
+}
+
+static struct packed_ushort __attribute__((noinline)) next(struct source *p)
+{
+ struct packed_ushort rv;
+
+ if (p->pos >= p->length) {
+ if (flag) {
+ flag = 0;
+ fetch(p);
+ return next(p);
+ }
+ flag = 1;
+ rv.ucs = 0xffff;
+ return rv;
+ }
+ rv.ucs = 0;
+ return rv;
+}
+
+int main(void)
+{
+ struct source s;
+ int i;
+
+ s.pos = 0;
+ s.length = 0;
+ flag = 0;
+
+ for (i = 0; i < 16; i++) {
+ struct packed_ushort rv = next(&s);
+ if ((i == 0 && rv.ucs != 0xffff)
+ || (i > 0 && rv.ucs != 0))
+ abort();
+ }
+ return 0;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 3c17694c703..5c1374d6fb1 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5216,6 +5216,12 @@ fld_worklist_push (tree t, class free_lang_data_d *fld)
static tree
fld_simplified_type_name (tree type)
{
+ /* Simplify type will cause that struct A and struct A within
+ struct B are different type pointers, so skip it in structure
+ optimizations. */
+ if (flag_ipa_struct_reorg)
+ return TYPE_NAME (type);
+
if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL)
return TYPE_NAME (type);
/* Drop TYPE_DECLs in TYPE_NAME in favor of the identifier in the
@@ -5454,6 +5460,11 @@ fld_simplified_type (tree t, class free_lang_data_d *fld)
{
if (!t)
return t;
+ /* Simplify type will cause that struct A and struct A within
+ struct B are different type pointers, so skip it in structure
+ optimizations. */
+ if (flag_ipa_struct_reorg)
+ return t;
if (POINTER_TYPE_P (t))
return fld_incomplete_type_of (t, fld);
/* FIXME: This triggers verification error, see PR88140. */
--
2.21.0.windows.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/kkzhs_admin/gcc.git
git@gitee.com:kkzhs_admin/gcc.git
kkzhs_admin
gcc
gcc
master

搜索帮助