summaryrefslogtreecommitdiff
path: root/0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch
diff options
context:
space:
mode:
Diffstat (limited to '0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch')
-rw-r--r--0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch296
1 files changed, 296 insertions, 0 deletions
diff --git a/0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch b/0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch
new file mode 100644
index 0000000..b5370ff
--- /dev/null
+++ b/0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch
@@ -0,0 +1,296 @@
+From 5392e41dcb7d58a80f2864b3c3f600c538fba799 Mon Sep 17 00:00:00 2001
+From: huangxiaoquan <huangxiaoquan1@huawei.com>
+Date: Wed, 4 Aug 2021 14:21:08 +0800
+Subject: [PATCH 19/22] [StructReorderFields] Fix bugs and improve mechanism
+
+Fix bugs and improve mechanism:
+
+1. Fixed a bug in multi-layer pointer recording.
+2. Use new to initialize allocated memory in symbol-summary.h.
+3. Only enable optimizations in C language.
+
+diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+index 384aa81583c..fe364f742d8 100644
+--- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c
++++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c
+@@ -173,31 +173,30 @@ lang_c_p (void)
+ return false;
+ }
+
+- if (strcmp (language_string, "GNU GIMPLE") == 0)
++ if (lang_GNU_C ())
++ {
++ return true;
++ }
++ else if (strcmp (language_string, "GNU GIMPLE") == 0) // for LTO check
+ {
+ unsigned i = 0;
+- tree t = NULL;
+- const char *unit_string = NULL;
++ tree t = NULL_TREE;
+
+ 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])))
++ language_string = TRANSLATION_UNIT_LANGUAGE (t);
++ if (language_string == NULL
++ || strncmp (language_string, "GNU C", 5)
++ || (language_string[5] != '\0'
++ && !(ISDIGIT (language_string[5]))))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+- else if (strncmp (language_string, "GNU C", 5) == 0
+- && ISDIGIT (language_string[5]))
+- {
+- return true;
+- }
+-
+ return false;
++}
+
+ /* Get the number of pointer layers. */
+
+@@ -1262,7 +1261,7 @@ public:
+ void check_uses (srdecl *decl, vec<srdecl*>&);
+ void check_use (srdecl *decl, gimple *stmt, vec<srdecl*>&);
+ void check_type_and_push (tree newdecl, srdecl *decl,
+- vec<srdecl*> &worklist, gimple *stmt);
++ vec<srdecl*> &worklist, gimple *stmt);
+ void check_other_side (srdecl *decl, tree other, gimple *stmt, vec<srdecl*> &worklist);
+ void check_ptr_layers (tree a_expr, tree b_expr, gimple* stmt);
+
+@@ -3010,11 +3009,9 @@ ipa_struct_reorg::find_var (tree expr, gimple *stmt)
+ {
+ tree r = TREE_OPERAND (expr, 0);
+ tree orig_type = TREE_TYPE (expr);
+- if (handled_component_p (r)
+- || TREE_CODE (r) == MEM_REF)
++ if (handled_component_p (r) || TREE_CODE (r) == MEM_REF)
+ {
+- while (handled_component_p (r)
+- || TREE_CODE (r) == MEM_REF)
++ while (handled_component_p (r) || TREE_CODE (r) == MEM_REF)
+ {
+ if (TREE_CODE (r) == VIEW_CONVERT_EXPR)
+ {
+@@ -3092,10 +3089,12 @@ ipa_struct_reorg::find_vars (gimple *stmt)
+ srdecl *d = find_decl (lhs);
+ if (!d && t)
+ {
+- current_function->record_decl (t, lhs, -1);
++ current_function->record_decl (t, lhs, -1,
++ isptrptr (TREE_TYPE (rhs)) ? TREE_TYPE (rhs) : NULL);
+ tree var = SSA_NAME_VAR (lhs);
+ if (var && VOID_POINTER_P (TREE_TYPE (var)))
+- current_function->record_decl (t, var, -1);
++ current_function->record_decl (t, var, -1,
++ isptrptr (TREE_TYPE (rhs)) ? TREE_TYPE (rhs) : NULL);
+ }
+ }
+ /* void * _1; struct arc * _2;
+@@ -3108,10 +3107,12 @@ ipa_struct_reorg::find_vars (gimple *stmt)
+ srdecl *d = find_decl (rhs);
+ if (!d && t)
+ {
+- current_function->record_decl (t, rhs, -1);
++ current_function->record_decl (t, rhs, -1,
++ isptrptr (TREE_TYPE (lhs)) ? TREE_TYPE (lhs) : NULL);
+ tree var = SSA_NAME_VAR (rhs);
+ if (var && VOID_POINTER_P (TREE_TYPE (var)))
+- current_function->record_decl (t, var, -1);
++ current_function->record_decl (t, var, -1,
++ isptrptr (TREE_TYPE (lhs)) ? TREE_TYPE (lhs) : NULL);
+ }
+ }
+ }
+@@ -3529,7 +3530,7 @@ ipa_struct_reorg::maybe_mark_or_record_other_side (tree side, tree other, gimple
+ {
+ /* The type is other, the declaration is side. */
+ current_function->record_decl (type, side, -1,
+- find_decl (other) ? find_decl (other)->orig_type : NULL);
++ isptrptr (TREE_TYPE (other)) ? TREE_TYPE (other) : NULL);
+ }
+ else
+ {
+@@ -5111,31 +5112,23 @@ ipa_struct_reorg::propagate_escape_via_original (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 (handled_type (field->fieldtype) && field->type)
+- {
+- for (unsigned k = 0; k < types.length (); k++)
+- {
+- 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 && types[k]->has_escaped ())
+- {
+- if (!field->type->has_escaped ())
+- {
+- field->type->mark_escape (
+- escape_via_orig_escape, NULL);
+- }
+- break;
+- }
+- }
+- }
+- }
++ for (unsigned j = 0; j < types.length (); j++)
++ {
++ const char *type1 = get_type_name (types[i]->type);
++ const char *type2 = get_type_name (types[j]->type);
++ if (type1 == NULL || type2 == NULL)
++ {
++ continue;
++ }
++ if (type1 == type2 && types[j]->has_escaped ())
++ {
++ if (!types[i]->has_escaped ())
++ {
++ types[i]->mark_escape (escape_via_orig_escape, NULL);
++ }
++ break;
++ }
++ }
+ }
+ }
+
+@@ -6683,7 +6676,10 @@ pass_ipa_reorder_fields::gate (function *)
+ && flag_ipa_reorder_fields
+ /* 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 a223b4dadea..ddf5e35776e 100644
+--- a/gcc/symbol-summary.h
++++ b/gcc/symbol-summary.h
+@@ -61,10 +61,9 @@ protected:
+ {
+ /* In structure optimizatons, we call new to ensure that
+ the allocated memory is initialized to 0. */
+- if (flag_ipa_struct_reorg)
++ if (flag_ipa_reorder_fields || 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 ()
+@@ -78,7 +77,7 @@ protected:
+ ggc_delete (item);
+ else
+ {
+- if (flag_ipa_struct_reorg)
++ if (flag_ipa_reorder_fields || flag_ipa_struct_reorg)
+ delete item;
+ else
+ m_allocator.remove (item);
+diff --git a/gcc/testsuite/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c b/gcc/testsuite/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c
+new file mode 100644
+index 00000000000..23765fc5615
+--- /dev/null
++++ b/gcc/testsuite/gcc.dg/struct/rf_mul_layer_ptr_record_bug.c
+@@ -0,0 +1,30 @@
++/* { dg-do compile } */
++
++#include <stdio.h>
++#include <stdlib.h>
++
++typedef struct T_HASH_ENTRY
++{
++ unsigned int hash;
++ unsigned int klen;
++ char *key;
++} iHashEntry;
++
++typedef struct T_HASH
++{
++ unsigned int size;
++ unsigned int fill;
++ unsigned int keys;
++
++ iHashEntry **array;
++} uHash;
++
++uHash *retval;
++
++int
++main() {
++ retval->array = (iHashEntry **)calloc(sizeof(iHashEntry *), retval->size);
++ return 0;
++}
++
++/* { dg-final { scan-ipa-dump "Number of structures to transform is 2" "reorder_fields" } } */
+\ No newline at end of file
+diff --git a/gcc/testsuite/gcc.dg/struct/rf_pass_conflict.c b/gcc/testsuite/gcc.dg/struct/rf_pass_conflict.c
+index 8d687c58b30..54e737ee856 100644
+--- a/gcc/testsuite/gcc.dg/struct/rf_pass_conflict.c
++++ b/gcc/testsuite/gcc.dg/struct/rf_pass_conflict.c
+@@ -1,6 +1,6 @@
+-// 针对
++// For testing:
+ /*
+-Compile options: /home/hxq/hcc_gcc9.3.0_org_debug/bin/gcc -O3 -g
++Compile options: gcc -O3 -g
+ -flto -flto-partition=one -fipa-reorder-fields -fipa-struct-reorg
+ -v -save-temps -fdump-ipa-all-details test.c -o test
+
+@@ -94,12 +94,11 @@ switch_arcs(arc_t** deleted_arcs, arc_t* arcnew)
+ copy = *test_arc;
+ count++;
+ *test_arc = arcnew[0];
+- replace_weaker_arc(arcnew, copy.tail, copy.head);
++ replace_weaker_arc(arcnew, NULL, NULL);
+ }
+ return count;
+ }
+
+-
+ int
+ main ()
+ {
+diff --git a/gcc/tree.c b/gcc/tree.c
+index 5c1374d6fb1..89fa469c359 100644
+--- a/gcc/tree.c
++++ b/gcc/tree.c
+@@ -5219,7 +5219,7 @@ 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)
++ if (flag_ipa_reorder_fields || flag_ipa_struct_reorg)
+ return TYPE_NAME (type);
+
+ if (!TYPE_NAME (type) || TREE_CODE (TYPE_NAME (type)) != TYPE_DECL)
+@@ -5463,7 +5463,7 @@ fld_simplified_type (tree t, class free_lang_data_d *fld)
+ /* 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)
++ if (flag_ipa_reorder_fields || flag_ipa_struct_reorg)
+ return t;
+ if (POINTER_TYPE_P (t))
+ return fld_incomplete_type_of (t, fld);
+--
+2.21.0.windows.1
+