diff options
Diffstat (limited to '0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch')
-rw-r--r-- | 0019-StructReorderFields-Fix-bugs-and-improve-mechanism.patch | 296 |
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 + |