This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/4] New parameter manipulation infrastructure


> 2019-08-20  Martin Jambor  <mjambor@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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]