GCC Middle and Back End API Reference
ipa-param-manipulation.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ipa_adjusted_param
 
class  ipa_param_adjustments
 
struct  ipa_param_body_replacement
 
class  ipa_param_body_adjustments
 

Macros

#define IPA_PARAM_MAX_INDEX_BITS   16
 

Enumerations

enum  ipa_param_name_prefix_indices {
  IPA_PARAM_PREFIX_SYNTH , IPA_PARAM_PREFIX_ISRA , IPA_PARAM_PREFIX_SIMD , IPA_PARAM_PREFIX_MASK ,
  IPA_PARAM_PREFIX_COUNT
}
 
enum  ipa_parm_op { IPA_PARAM_OP_UNDEFINED , IPA_PARAM_OP_COPY , IPA_PARAM_OP_NEW , IPA_PARAM_OP_SPLIT }
 

Functions

void ipa_dump_adjusted_parameters (FILE *f, vec< ipa_adjusted_param, va_gc > *adj_params)
 
void push_function_arg_decls (vec< tree > *args, tree fndecl)
 
void push_function_arg_types (vec< tree > *types, tree fntype)
 
void ipa_verify_edge_has_no_modifications (cgraph_edge *cs)
 
void ipa_edge_modifications_finalize ()
 
void ipa_release_ssas_in_hash (hash_set< tree > *killed_ssas)
 

Macro Definition Documentation

◆ IPA_PARAM_MAX_INDEX_BITS

#define IPA_PARAM_MAX_INDEX_BITS   16
We do not support manipulating functions with more than
1<<IPA_PARAM_MAX_INDEX_BITS parameters.   

Referenced by can_strub_internally_p(), input_node_opt_summary(), and output_node_opt_summary().

Enumeration Type Documentation

◆ ipa_param_name_prefix_indices

Manipulation of formal and actual parameters of functions and function
   calls.
   Copyright (C) 2017-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
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/>.



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 pass-through (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 pass-through 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" to call
arguments at any later point.  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 simply add as arguments all new "split"
replacements (that have grater or equal offset than the original call
argument):

  foo (repl_for_a, repl_for_b, <rest of original arguments>);

It will also store into ipa_edge_modification_info (which is internal to
ipa-param-modification.c) information about which replacement is which and
where original arguments are.  Call redirection will then invoke
ipa_param_adjustments::modify_call which will access this information and
eliminate all replacements which the callee does not expect (repl_for_a in our
example above).  In between these two steps, however, a call statement might
have extraneous arguments.   
Indices into ipa_param_prefixes to identify a human-readable prefix for newly
synthesized parameters.  Keep in sync with the array.   
Enumerator
IPA_PARAM_PREFIX_SYNTH 
IPA_PARAM_PREFIX_ISRA 
IPA_PARAM_PREFIX_SIMD 
IPA_PARAM_PREFIX_MASK 
IPA_PARAM_PREFIX_COUNT 

◆ ipa_parm_op

Operation to be performed for the parameter in ipa_parm_adjustment
below.   
Enumerator
IPA_PARAM_OP_UNDEFINED 
IPA_PARAM_OP_COPY 
IPA_PARAM_OP_NEW 
IPA_PARAM_OP_SPLIT 

Function Documentation

◆ ipa_dump_adjusted_parameters()

void ipa_dump_adjusted_parameters ( FILE * f,
vec< ipa_adjusted_param, va_gc > * adj_params )
Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
friendly way, assuming they are meant to be applied to FNDECL.   

References ggc_alloc(), i, IPA_PARAM_OP_COPY, ipa_param_op_names, IPA_PARAM_OP_NEW, IPA_PARAM_OP_SPLIT, IPA_PARAM_OP_UNDEFINED, ipa_param_prefixes, print_node_brief(), and vec_safe_length().

Referenced by ipa_param_adjustments::dump().

◆ ipa_edge_modifications_finalize()

void ipa_edge_modifications_finalize ( )
Deallocate summaries which otherwise stay alive until the end of
compilation.   

References ipa_edge_modifications, and NULL.

Referenced by toplev::finalize().

◆ ipa_release_ssas_in_hash()

void ipa_release_ssas_in_hash ( hash_set< tree > * killed_ssas)
Call release_ssa_name on all elements in KILLED_SSAS in a defined order.   

References compare_ssa_versions(), ggc_alloc(), and release_ssa_name().

Referenced by copy_body(), and ipa_param_adjustments::modify_call().

◆ ipa_verify_edge_has_no_modifications()

void ipa_verify_edge_has_no_modifications ( cgraph_edge * cs)
Fail compilation if CS has any summary associated with it in
ipa_edge_modifications.   

References gcc_assert, and ipa_edge_modifications.

Referenced by cgraph_edge::redirect_call_stmt_to_callee().

◆ push_function_arg_decls()

void push_function_arg_decls ( vec< tree > * args,
tree fndecl )
Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
FNDECL.  The function should not be called during LTO WPA phase except for
thunks (or functions with bodies streamed in).  

References count, DECL_ARGUMENTS, DECL_CHAIN, gcc_assert, ggc_alloc(), and gimple_has_body_p().

Referenced by ipa_param_body_adjustments::common_initialization(), ipcp_update_vr(), simd_clone_adjust_argument_types(), and simd_clone_vector_of_formal_parm_types().

◆ push_function_arg_types()

void push_function_arg_types ( vec< tree > * types,
tree fntype )
Fill an empty vector TYPES with trees representing formal parameters of
function type FNTYPE.   

References count, TREE_CHAIN, TREE_VALUE, and TYPE_ARG_TYPES.

Referenced by ipa_param_adjustments::build_new_function_type(), ipa_param_body_adjustments::common_initialization(), and simd_clone_vector_of_formal_parm_types().