diff --git a/gcc/Makefile.in b/gcc/Makefile.in index d115879ed9a05683712c85f21e638802efaa77ae..5319fb452c08e69239c582d88977296a0b897ded 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1451,7 +1451,8 @@ OBJS = \ incpath.o \ init-regs.o \ internal-fn.o \ - ipa-cp.o \ + ipa-struct-reorg/ipa-struct-reorg.o \ + ipa-cp.o \ ipa-sra.o \ ipa-devirt.o \ ipa-bbr.o \ diff --git a/gcc/common.opt b/gcc/common.opt index 1cc920c22b18a00ef6dcc493a95f5e6a4057876f..114f055a1ef79e63586f39d4a208731d7a118f5f 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1962,9 +1962,19 @@ fipa-matrix-reorg Common Ignore Does nothing. Preserved for backward compatibility. +fipa-reorder-fields +Common Var(flag_ipa_reorder_fields) Init(0) Optimization +Perform structure fields reorder optimizations. + fipa-struct-reorg -Common Ignore -Does nothing. Preserved for backward compatibility. +Common Var(flag_ipa_struct_reorg) Init(0) Optimization +Perform structure layout optimizations. + +fipa-struct-reorg= +Common RejectNegative Joined UInteger Var(struct_layout_optimize_level) Init(0) IntegerRange(0, 6) +-fipa-struct-reorg=[0,1,2,3,4,5,6] adding none, struct-reorg, reorder-fields, +dfe, safe-pointer-compression, unsafe-pointer-compression, semi-relayout +optimizations. fipa-vrp Common Var(flag_ipa_vrp) Optimization diff --git a/gcc/configure b/gcc/configure index c749ace011dbdbe2632413cc6860a5e8597508e4..98bbf0f857b47e141d58e3a34e6fc936d602b235 100755 --- a/gcc/configure +++ b/gcc/configure @@ -34191,7 +34191,7 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} "depdir":C) $SHELL $ac_aux_dir/mkinstalldirs $DEPDIR ;; "gccdepdir":C) ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR - for lang in $subdirs c-family common analyzer rtl-ssa + for lang in $subdirs c-family common analyzer rtl-ssa ipa-struct-reorg do ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR done ;; diff --git a/gcc/configure.ac b/gcc/configure.ac index 992a50e7b20f7c147a333f9598407ea5920ad777..c74f4b55527d45e222aad15ba66dc203820b66a8 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -1340,7 +1340,7 @@ AC_CHECK_HEADERS(ext/hash_map) ZW_CREATE_DEPDIR AC_CONFIG_COMMANDS([gccdepdir],[ ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs build/$DEPDIR - for lang in $subdirs c-family common analyzer rtl-ssa + for lang in $subdirs c-family common analyzer rtl-ssa ipa-struct-reorg do ${CONFIG_SHELL-/bin/sh} $ac_aux_dir/mkinstalldirs $lang/$DEPDIR done], [subdirs="$subdirs" ac_aux_dir=$ac_aux_dir DEPDIR=$DEPDIR]) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a76a3a3a877c83e3e1ff18924c995688125b7cf5..3ff1f8db7d37418fce56e2f1dc27e2be20d074b1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -526,6 +526,8 @@ Objective-C and Objective-C++ Dialects}. -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol -finline-small-functions -fipa-modref -fipa-cp -fipa-cp-clone @gol -fipa-bit-cp -fipa-vrp -fipa-pta -fipa-profile -fipa-pure-const @gol +-fipa-reorder-fields @gol +-fipa-struct-reorg @gol -fipa-reference -fipa-reference-addressable @gol -fipa-stack-alignment -fipa-icf -fira-algorithm=@var{algorithm} @gol -flive-patching=@var{level} @gol @@ -11912,6 +11914,27 @@ Enabled by default at @option{-O1} and higher. Reduce stack alignment on call sites if possible. Enabled by default. +@item -fipa-reorder-fields +@opindex fipa-reorder-fields +Introduce structure fields reordering optimization, that change fields +ordering of C-like structures in order to better utilize spatial locality. +This transformation is affective for programs containing arrays of structures. +It works only in whole program mode, so it requires @option{-fwhole-program} +to be enabled. + +@item -fipa-struct-reorg +@opindex fipa-struct-reorg +Perform structure reorganization optimization, that change C-like structures +layout in order to better utilize spatial locality. This transformation is +affective for programs containing arrays of structures. Available in two +compilation modes: profile-based (enabled with @option{-fprofile-generate}) +or static (which uses built-in heuristics). It works only in whole program +mode, so it requires @option{-fwhole-program} to be +enabled. Structures considered @samp{cold} by this transformation are not +affected (see @option{--param struct-reorg-cold-struct-ratio=@var{value}}). + +With this flag, the program debug info reflects a new structure layout. + @item -fipa-pta @opindex fipa-pta Perform interprocedural pointer analysis and interprocedural modification @@ -13782,6 +13805,15 @@ In each case, the @var{value} is an integer. The following choices of @var{name} are recognized for all targets: @table @gcctabopt +@item struct-reorg-cold-struct-ratio +The threshold ratio (as a percentage) between a structure frequency +and the frequency of the hottest structure in the program. This parameter +is used by struct-reorg optimization enabled by @option{-fipa-struct-reorg}. +We say that if the ratio of a structure frequency, calculated by profiling, +to the hottest structure frequency in the program is less than this +parameter, then structure reorganization is not applied to this structure. +The default is 10. + @item predictable-branch-outcome When branch is predicted to be taken with probability lower than this threshold (in percent), then it is considered well predictable. diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc index a742156858cdd79589e267cb86920db7779d7f0c..01e5cdece1cff5d3281d1be5c7568d3bd801e179 100644 --- a/gcc/ipa-free-lang-data.cc +++ b/gcc/ipa-free-lang-data.cc @@ -49,6 +49,7 @@ #include "except.h" #include "ipa-utils.h" +extern bool lang_c_p (void); namespace { /* Data used when collecting DECLs and TYPEs for language data removal. */ @@ -102,6 +103,14 @@ 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 + && lang_c_p () + && flag_lto_partition == LTO_PARTITION_ONE) + 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 @@ -109,9 +118,9 @@ fld_simplified_type_name (tree type) this must match fld_ */ if (type != TYPE_MAIN_VARIANT (type) || (!DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (type)) - && (TREE_CODE (type) != RECORD_TYPE - || !TYPE_BINFO (type) - || !BINFO_VTABLE (TYPE_BINFO (type))))) + && (TREE_CODE (type) != RECORD_TYPE + || !TYPE_BINFO (type) + || !BINFO_VTABLE (TYPE_BINFO (type))))) return DECL_NAME (TYPE_NAME (type)); return TYPE_NAME (type); } @@ -340,14 +349,19 @@ 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 + && lang_c_p () + && flag_lto_partition == LTO_PARTITION_ONE) + return t; if (POINTER_TYPE_P (t)) return fld_incomplete_type_of (t, fld); /* FIXME: This triggers verification error, see PR88140. */ -#if 0 - if (TREE_CODE (t) == ARRAY_TYPE) + if (TREE_CODE (t) == ARRAY_TYPE && 0) return fld_process_array_type (t, fld_simplified_type (TREE_TYPE (t), fld), - fld_simplified_types, fld); -#endif + fld_simplified_types, fld); return t; } diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc index 38328c3e8d0aef7715cd6b9357d174b063ed8c2a..f9e956008d88a2b566f2f8bbe44ee028b2e91264 100644 --- a/gcc/ipa-param-manipulation.cc +++ b/gcc/ipa-param-manipulation.cc @@ -55,7 +55,8 @@ static const char *ipa_param_prefixes[IPA_PARAM_PREFIX_COUNT] = {"SYNTH", "ISRA", "simd", - "mask"}; + "mask", + "struct_reorg"}; /* Names of parameters for dumping. Keep in sync with enum ipa_parm_op. */ diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h index a9ad2b216bea4001d48ba06ab09fabbcd0d22478..71f4a0a2f08ec5dcac4c119dfbf91e7a20b6e0f9 100644 --- a/gcc/ipa-param-manipulation.h +++ b/gcc/ipa-param-manipulation.h @@ -126,6 +126,7 @@ enum ipa_param_name_prefix_indices IPA_PARAM_PREFIX_ISRA, IPA_PARAM_PREFIX_SIMD, IPA_PARAM_PREFIX_MASK, + IPA_PARAM_PREFIX_REORG, IPA_PARAM_PREFIX_COUNT }; @@ -189,7 +190,7 @@ struct GTY(()) ipa_adjusted_param /* Index into ipa_param_prefixes specifying a prefix to be used with DECL_NAMEs of newly synthesized parameters. */ - unsigned param_prefix_index : 2; + unsigned param_prefix_index : 3; /* Storage order of the original parameter (for the cases when the new parameter is a component of an original one). */ diff --git a/gcc/opts.cc b/gcc/opts.cc index a97630d1c9ad52c02ef6581b9d72fc0759ddf722..261da08006269e21d6954f38fef4cbe5dc669344 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -2946,6 +2946,22 @@ common_handle_option (struct gcc_options *opts, enable_fdo_optimizations (opts, opts_set, value); SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value); break; + case OPT_fipa_struct_reorg_: + /* No break here - do -fipa-struct-reorg processing. */ + /* FALLTHRU. */ + case OPT_fipa_struct_reorg: + opts->x_flag_ipa_struct_reorg = value; + if (value && !opts->x_struct_layout_optimize_level) + { + /* Using the -fipa-struct-reorg option is equivalent to using + -fipa-struct-reorg=1. */ + opts->x_struct_layout_optimize_level = 1; + } + break; + + case OPT_fipa_reorder_fields: + SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_struct_reorg, value); + break; case OPT_fprofile_generate_: opts->x_profile_data_prefix = xstrdup (arg); diff --git a/gcc/params.opt b/gcc/params.opt index e0ff9e210544bf5c16e60e3caca4963d841d4acc..78c60bc64d3874636aa2ba00863b1b6af15db72d 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -865,6 +865,9 @@ Enum(parloops_schedule_type) String(runtime) Value(PARLOOPS_SCHEDULE_RUNTIME) Common Joined UInteger Var(param_partial_inlining_entry_probability) Init(70) Optimization IntegerRange(0, 100) Param Maximum probability of the entry BB of split region (in percent relative to entry BB of the function) to make partial inlining happen. +-param=struct-reorg-cold-struct-ratio= +Common Joined UInteger Var(param_struct_reorg_cold_struct_ratio) Init(10) IntegerRange(0, 100) Param Optimization+The threshold ratio between current and hottest structure counts. + -param=predictable-branch-outcome= Common Joined UInteger Var(param_predictable_branch_outcome) Init(2) IntegerRange(0, 50) Param Optimization Maximal estimated outcome of branch considered predictable. @@ -1201,4 +1204,12 @@ Enum(vrp_mode) String(vrp) Value(VRP_MODE_VRP) EnumValue Enum(vrp_mode) String(ranger) Value(VRP_MODE_RANGER) +-param=compressed-pointer-size= +Common Joined UInteger Var(param_pointer_compression_size) Init(32) IntegerRange(8, 32) Param Optimization +Target size of compressed pointer, which should be 8, 16 or 32. + +-param=semi-relayout-level= +Common Joined UInteger Var(semi_relayout_level) Init(13) IntegerRange(11, 15) Param Optimization +Set capacity of each bucket to semi-relayout to (1 << semi-relayout-level) / 8 . + ; This comment is to ensure we retain the blank line above. diff --git a/gcc/passes.def b/gcc/passes.def index 8597be472d8e196a386988f613e560a0d1b23988..3e1bd9445800aed6bdbabab766e3dcdc537bea2b 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -179,6 +179,8 @@ along with GCC; see the file COPYING3. If not see compiled unit. */ INSERT_PASSES_AFTER (all_late_ipa_passes) NEXT_PASS (pass_ipa_pta); + /* FIXME: this should a normal IP pass */ + NEXT_PASS (pass_ipa_struct_reorg); NEXT_PASS (pass_omp_simd_clone); TERMINATE_PASS_LIST (all_late_ipa_passes) diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 9a12bb27c342413d5eb24d01651c6b08a3eae8ea..433739944966ac5af01a284eb9eebc8679ab198a 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -2015,6 +2015,8 @@ handle_ssa_name (tree ptr, bool addr, int ostype, } gimple *stmt = SSA_NAME_DEF_STMT (ptr); + if (!stmt) + return false; if (is_gimple_call (stmt)) { /* If STMT is a call to an allocation function get the size diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h index c54d3084cc472dacb54eff8e9a87ade6078e442e..3fe64047c8bae98c1587ccce8927716b77539859 100644 --- a/gcc/symbol-summary.h +++ b/gcc/symbol-summary.h @@ -103,6 +103,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 () @@ -115,7 +121,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/timevar.def b/gcc/timevar.def index 59f03ac947d291cf2b61547718f85a7b234c1d35..6d0ce928e9c9aa2950fb9067adcee429dc400922 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -80,6 +80,7 @@ DEFTIMEVAR (TV_IPA_CONSTANT_PROP , "ipa cp") DEFTIMEVAR (TV_IPA_INLINING , "ipa inlining heuristics") DEFTIMEVAR (TV_IPA_FNSPLIT , "ipa function splitting") DEFTIMEVAR (TV_IPA_COMDATS , "ipa comdats") +DEFTIMEVAR (TV_IPA_STRUCT_REORG , "ipa struct reorg optimization") DEFTIMEVAR (TV_IPA_BBR , "ipa bbr") DEFTIMEVAR (TV_IPA_OPT , "ipa various optimizations") DEFTIMEVAR (TV_IPA_LTO_DECOMPRESS , "lto stream decompression") diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 2eda6e31965fd0a026a2964c83ebd6d420969f7e..9144083974dd8eccec1d2fca377ac43889db103c 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -529,6 +529,7 @@ extern ipa_opt_pass_d *make_pass_ipa_devirt (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_odr (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_reference (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_pure_const (gcc::context *ctxt); +extern simple_ipa_opt_pass *make_pass_ipa_struct_reorg (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_pta (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_tm (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_target_clone (gcc::context *ctxt);