> 2019-08-20 Martin Jambor <mjam...@suse.cz> > > * Makefile.in (GTFILES): Added ipa-param-manipulation.h. > * cgraph.h (ipa_replace_map): Removed fields old_tree, replace_p > and ref_p, added fields param_adjustments and performed_splits. > (struct cgraph_clone_info): Remove ags_to_skip and > combined_args_to_skip, new field param_adjustments. > (cgraph_node::create_clone): Changed parameters to use > ipa_param_adjustments. > (cgraph_node::create_virtual_clone): Likewise. > (cgraph_node::create_virtual_clone_with_body): Likewise. > (tree_function_versioning): Likewise. > (cgraph_build_function_type_skip_args): Removed. > * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Convert to > using ipa_param_adjustments. > (clone_of_p): Likewise. > * cgraphclones.c (cgraph_build_function_type_skip_args): Removed. > (build_function_decl_skip_args): Likewise. > (duplicate_thunk_for_node): Adjust parameters using > ipa_param_body_adjustments, copy param_adjustments instead of > args_to_skip. > (cgraph_node::create_clone): Convert to using ipa_param_adjustments. > (cgraph_node::create_virtual_clone): Likewise. > (cgraph_node::create_version_clone_with_body): Likewise. > (cgraph_materialize_clone): Likewise. > (symbol_table::materialize_all_clones): Likewise. > * coretypes.h (cgraph_edge): Declare. > * ipa-cp.c (get_replacement_map): Do not initialize removed fields. > (initialize_node_lattices): Make aware that some parameters might have > already been removed. > (want_remove_some_param_p): New function. > (create_specialized_node): Convert to using ipa_param_adjustments and > deal with possibly pre-existing adjustments. > * ipa-fnsummary.c (ipa_fn_summary_t::duplicate): Simplify > ipa_replace_map check. > * ipa-inline-transform.c (save_inline_function_body): Update to > refelct new tree_function_versioning signature. > * ipa-param-manipulation.c: Rewrite. > * ipa-param-manipulation.h: Likewise. > * ipa-prop.c (adjust_agg_replacement_values): Use a helper from > ipa_param_adjustments to get current parameter indices. > (ipcp_modif_dom_walker::before_dom_children): Likewise. > (ipcp_update_bits): Likewise. > (ipcp_update_vr): Likewise. > * ipa-split.c (split_function): Convert to using > ipa_param_adjustments. > * lto-cgraph.c (output_cgraph_opt_summary_p): Likewise. > (output_node_opt_summary): Do not stream removed fields. Stream > parameter adjustments instead of argumetns to skip. > (input_node_opt_summary): Likewise. > (input_node_opt_summary): Likewise. > * multiple_target.c (create_target_clone): Update to reflet new type > of create_version_clone_with_body. > * omp-simd-clone.c (simd_clone_vector_of_formal_parm_types): Adjust > for the new interface. > (simd_clone_clauses_extract): Likewise, make args an auto_vec. > (simd_clone_compute_base_data_type): Likewise. > (simd_clone_init_simd_arrays): Adjust for the new interface. > (simd_clone_adjust_argument_types): Likewise. > (struct modify_stmt_info): Likewise. > (ipa_simd_modify_stmt_ops): Likewise. > (ipa_simd_modify_function_body): Likewise. > (simd_clone_adjust): Likewise. > * trans-mem.c (ipa_tm_create_version): Update to reflect new type of > tree_function_versioning. > * tree-inline.h (copy_body_data): New fields killed_new_ssa_names and > param_body_adjs. > (copy_decl_to_var): Declare. > * tree-inline.c (update_clone_info): Do not remap old_tree. > (remap_gimple_stmt): Use ipa_param_body_adjustments to modify gimple > statements, walk all extra generated statements and remap their > operands. > (redirect_all_calls): Add killed SSA names to a hash set. > (remap_ssa_name): Do not remap killed SSA names. > (copy_arguments_for_versioning): Renames to copy_arguments_nochange, > half of functionality moved to ipa_param_body_adjustments. > (copy_decl_to_var): Make exported. > (copy_body): Destroy killed_new_ssa_names hash set. > (expand_call_inline): Remap performed splits. > (update_clone_info): Likewise. > (tree_function_versioning): Simplify tree_map processing. Updated to > accept ipa_param_adjustments and use ipa_param_body_adjustments.
OK > +/* Modify actual arguments of a function call in statement STMT, assuming it > + calls CALLEE_DECL. CALLER_ADJ must be the description of parameter > + adjustments of the caller or NULL if there are none. Return the new > + statement that replaced the old one. When invoked, cfun and > + current_function_decl have to be set to the caller. */ > + > +gcall * > +ipa_param_adjustments::modify_call (gcall *stmt, > + vec<ipa_param_performed_split, > + va_gc> *performed_splits, > + tree callee_decl, bool update_references) > +{ > + unsigned len = vec_safe_length (m_adj_params); > + auto_vec<tree, 16> vargs (len); > + tree old_decl = gimple_call_fndecl (stmt); > + unsigned old_nargs = gimple_call_num_args (stmt); > + auto_vec<bool, 16> kept (old_nargs); > + kept.quick_grow_cleared (old_nargs); > + > + auto_vec <unsigned, 16> index_map; > + auto_vec <transitive_split_map> trans_map; > + bool transitive_remapping = false; vertical space here and move the quick_grow_cleared here too I guess. It seems that you omit vertical space after declaration at many places. > diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h > index 71fc4a201aa..b9da00bb5c9 100644 > --- a/gcc/ipa-param-manipulation.h > +++ b/gcc/ipa-param-manipulation.h > @@ -16,101 +16,394 @@ for more details. > > You should have received a copy of the GNU General Public License > along with GCC; see the file COPYING3. If not see > -<http://www.gnu.org/licenses/>. */ > +<http://www.gnu.org/licenses/>. > + > + > + > +This file defines classes and other data structures that are used to > manipulate > +the prototype of a function, especially to create, remove or split its formal > +parameters, but also to remove its return value, and also its call statements > +correspondingly. > + > +The most basic one is a vector of structures ipa_adjusted_param. It is > simply > +a description how the new parameters should look like after the > transformation > +in what way they relate to the previous ones (if in any). Such relation to > an > +old parameter can be an outright copy or an IPA-SRA replacement. If an old > +parameter is not listed or otherwise mentioned, it is removed as unused or at > +least unnecessary. Note that this most basic structure does not work for > +modifying calls of functions with variable number of arguments. > + > +Class ipa_param_adjustments is only a little more than a thin encapsulation > of > +a vector of ipa_param_adjustments. Along with this vector it contains an > index > +of the first potential vararg argument and a boolean flag whether the return > +value should be removed or not. Moreover, the class contains method > +modify_call which can transform a call statement so that it correctly calls a > +modified function. These two data structures were designed to have a small > +memory footprint because they are allocated for each clone of a call graph > node > +that has its prototype changed and live until the end of IPA clone > +materialization and call redirection phase. > + > +On the other hand, class ipa_param_body_adjustments can afford to allocate > more > +data because its life span is much smaller, it is allocated and destroyed in > +the course of materialization of each single clone that needs it or only > when a > +particular pass needs to change a function it is operating on. This class > has > +various methods required to change function declaration and the body of the > +function according to instructions given either by class > ipa_param_adjustments > +or only a vector of ipa_adjusted_params. > + > +When these classes are used in the context of call graph clone > materialization > +and subsequent call statement redirection - which is the point at which we > +modify arguments in call statements - they need to cooperate with each other > in > +order to handle what we refer to as transitive (IPA-SRA) splits. These are > +situations when a formal parameter of one function is split into several > +smaller ones and some of them are then passed on in a call to another > function > +because the formal parameter of this callee has also been split. > + > +Consider a simple example: > + > +struct S {int a, b, c;}; > +struct Z {int x; S s;}; > + > +foo (S s) > +{ > + use (s.b); > +} > + > +bar (Z z) > +{ > + use (z.s.a); > + foo (z.s); > +} > + > +baz () > +{ > + bar (*global); > +} > + > +Both bar and foo would have their parameter split. Foo would receive one > +replacement representing s.b. Function bar would see its parameter split > into > +one replacement representing z.s.a and another representing z.s.b which would > +be passed on to foo. It would be a so called transitive split IPA-SRA > +replacement, one which is passed in a call as an actual argument to another > +IPA-SRA replacement in another function. > + > +Note that the call chain the example can be arbitrarily long and recursive > and > +that any function in it can be cloned by another IPA pass and any number of > +adjacent functions in the call chain can be inlined into each other. Call > +redirection takes place only after bodies of the function have been modified > by > +all of the above. > + > +Call redirection has to be able to find the right decl or SSA_NAME that > +corresponds to the transitive split in the caller. The SSA names are > assigned > +right after clone materialization/ modification and cannot be "added" > +afterwards. Moreover, if the caller has been inlined the SSA_NAMEs in > question > +no longer belong to PARM_DECLs but to VAR_DECLs, indistinguishable from any > +others. > + > +Therefore, when clone materialization finds a call statement which it knows > is > +a part of a transitive split, it will modify it into: > + > + foo (DUMMY_Z_VAR.s, repl_for_a, repl_for_b, <rest of original arguments>); > + > +It will also store {DUMMY_S_VAR, 32} and {DUMMY_S_VAR, 64} representing > offsets > +of z.s.a and z.s.b (assuming a 32-bit int) into foo's cgraph node > +clone->performed_splits vector (which is storing structures of type > +ipa_param_performed_split also defined in this header file). > + > +Call redirection will identify that expression DUMMY_Z_VAR.s is based on a > +variable stored in performed_splits vector and learn that the following > +arguments, already in SSA form, represent offsets 32 and 64 in a split > original > +parameter. It subtracts offset of DUMMY_Z_VAR.s from 32 and 64 and arrives > at > +offsets 0 and 32 within callee's original parameter. At this point it also > +knows from the call graph that only the bit with offset 32 is needed and so > +changes the call statement into final: > + > +bar (repl_for_b, <rest of original arguments>); */ I would probably also include one line comments for public member functions for new classes you introduce so one has most of essential info at one place. Honza