> 2022-11-11 Martin Jambor <mjam...@suse.cz>
>
> PR ipa/103227
> * ipa-param-manipulation.h (class ipa_param_adjustments): Removed
> member function get_updated_index_or_split.
> (class ipa_param_body_adjustments): New overload of
> register_replacement, new member function append_init_stmts, new
> member m_split_agg_csts_inits.
> * ipa-param-manipulation.cc: Include ipa-prop.h.
> (ipa_param_adjustments::get_updated_index_or_split): Removed.
> (ipa_param_body_adjustments::register_replacement): New overload, use
> it from the older one.
> (ipa_param_body_adjustments::common_initialization): Added the
> capability to create replacements for conflicting IPA-CP discovered
> constants.
> (ipa_param_body_adjustments::ipa_param_body_adjustments): Construct
> the new member.
> (ipa_param_body_adjustments::append_init_stmts): New function.
> * ipa-sra.cc: Include ipa-prop.h.
> (push_param_adjustments_for_index): Require IPA-CP transformation
> summary as a parameter, do not create replacements which are known to
> have constant values.
> (process_isra_node_results): Find and pass to the above function the
> IPA-CP transformation summary.
> * ipa-prop.cc (adjust_agg_replacement_values): Remove the
> functionality replacing IPA-SRA created scalar parameters with
> constants. Simplify, do not require parameter descriptors, do not
> return anything.
> (ipcp_transform_function): Simplify now that
> adjust_agg_replacement_values does not change cfg. Move definition
> and initialization of descriptors lower.
> * tree-inline.cc (tree_function_versioning): Call append_init_stmts of
> param_body_adjs, if there are any.
OK,
Honza
>
> gcc/testsuite/ChangeLog:
>
> 2022-11-11 Martin Jambor <mjam...@suse.cz>
>
> PR ipa/103227
> PR ipa/107640
> * gcc.dg/ipa/pr107640-2.c: New test.
> ---
> gcc/ipa-param-manipulation.cc | 155 ++++++++++++++++----------
> gcc/ipa-param-manipulation.h | 19 ++--
> gcc/ipa-prop.cc | 66 ++++-------
> gcc/ipa-sra.cc | 30 ++++-
> gcc/testsuite/gcc.dg/ipa/pr107640-2.c | 50 +++++++++
> gcc/tree-inline.cc | 2 +
> 6 files changed, 208 insertions(+), 114 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/ipa/pr107640-2.c
>
> diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
> index cee0e23f946..e92cfc0b6d5 100644
> --- a/gcc/ipa-param-manipulation.cc
> +++ b/gcc/ipa-param-manipulation.cc
> @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-phinodes.h"
> #include "cfgexpand.h"
> #include "attribs.h"
> -
> +#include "ipa-prop.h"
>
> /* Actual prefixes of different newly synthetized parameters. Keep in sync
> with IPA_PARAM_PREFIX_* defines. */
> @@ -449,39 +449,6 @@ ipa_param_adjustments::get_updated_indices (vec<int>
> *new_indices)
> }
> }
>
> -/* If a parameter with original INDEX has survived intact, return its new
> - index. Otherwise return -1. In that case, if it has been split and there
> - is a new parameter representing a portion at unit OFFSET for which a value
> - of a TYPE can be substituted, store its new index into SPLIT_INDEX,
> - otherwise store -1 there. */
> -int
> -ipa_param_adjustments::get_updated_index_or_split (int index,
> - unsigned unit_offset,
> - tree type, int *split_index)
> -{
> - unsigned adj_len = vec_safe_length (m_adj_params);
> - for (unsigned i = 0; i < adj_len ; i++)
> - {
> - ipa_adjusted_param *apm = &(*m_adj_params)[i];
> - if (apm->base_index != index)
> - continue;
> - if (apm->op == IPA_PARAM_OP_COPY)
> - return i;
> - if (apm->op == IPA_PARAM_OP_SPLIT
> - && apm->unit_offset == unit_offset)
> - {
> - if (useless_type_conversion_p (apm->type, type))
> - *split_index = i;
> - else
> - *split_index = -1;
> - return -1;
> - }
> - }
> -
> - *split_index = -1;
> - return -1;
> -}
> -
> /* Return the original index for the given new parameter index. Return a
> negative number if not available. */
>
> @@ -1020,6 +987,21 @@ ipa_param_adjustments::debug ()
> dump (stderr);
> }
>
> +/* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
> +
> +void
> +ipa_param_body_adjustments::register_replacement (tree base,
> + unsigned unit_offset,
> + tree replacement)
> +{
> + ipa_param_body_replacement psr;
> + psr.base = base;
> + psr.repl = replacement;
> + psr.dummy = NULL_TREE;
> + psr.unit_offset = unit_offset;
> + m_replacements.safe_push (psr);
> +}
> +
> /* Register that REPLACEMENT should replace parameter described in APM. */
>
> void
> @@ -1029,12 +1011,8 @@ ipa_param_body_adjustments::register_replacement
> (ipa_adjusted_param *apm,
> gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT
> || apm->op == IPA_PARAM_OP_NEW);
> gcc_checking_assert (!apm->prev_clone_adjustment);
> - ipa_param_body_replacement psr;
> - psr.base = m_oparms[apm->prev_clone_index];
> - psr.repl = replacement;
> - psr.dummy = NULL_TREE;
> - psr.unit_offset = apm->unit_offset;
> - m_replacements.safe_push (psr);
> + register_replacement (m_oparms[apm->prev_clone_index], apm->unit_offset,
> + replacement);
> }
>
> /* Copy or not, as appropriate given m_id and decl context, a pre-existing
> @@ -1386,23 +1364,73 @@ ipa_param_body_adjustments::common_initialization
> (tree old_fndecl,
> gcc_unreachable ();
> }
>
> + auto_vec <int, 16> index_mapping;
> + bool need_remap = false;
> + if (m_id)
> + {
> + clone_info *cinfo = clone_info::get (m_id->src_node);
> + if (cinfo && cinfo->param_adjustments)
> + {
> + cinfo->param_adjustments->get_updated_indices (&index_mapping);
> + need_remap = true;
> + }
> +
> + if (ipcp_transformation *ipcp_ts
> + = ipcp_get_transformation_summary (m_id->src_node))
> + {
> + for (const ipa_argagg_value &av : ipcp_ts->m_agg_values)
> + {
> + int parm_num = av.index;
> +
> + if (need_remap)
> + {
> + /* FIXME: We cannot handle the situation when IPA-CP
> + identified that a parameter is a pointer to a global
> + variable and at the same time the variable has some known
> + constant contents (PR 107640). The best place to make
> + sure we don't drop such constants on the floor probably is
> + not here, but we have to make sure that it does not
> + confuse the remapping. */
> + if (parm_num >= (int) index_mapping.length ())
> + continue;
> + parm_num = index_mapping[parm_num];
> + if (parm_num < 0)
> + continue;
> + }
> +
> + if (!kept[parm_num])
> + {
> + /* IPA-CP has detected an aggregate constant in a parameter
> + that will not be kept, which means that IPA-SRA would have
> + split it if there wasn't a constant. Because we are about
> + to remove the original, this is the last chance where we
> + can substitute the uses with a constant (for values passed
> + by reference) or do the split but initialize the
> + replacement with a constant (for split aggregates passed
> + by value). */
> +
> + tree repl;
> + if (av.by_ref)
> + repl = av.value;
> + else
> + {
> + repl = create_tmp_var (TREE_TYPE (av.value),
> + "removed_ipa_cp");
> + gimple *init_stmt = gimple_build_assign (repl, av.value);
> + m_split_agg_csts_inits.safe_push (init_stmt);
> + }
> + register_replacement (m_oparms[parm_num], av.unit_offset,
> + repl);
> + split[parm_num] = true;
> + }
> + }
> + }
> + }
> +
> if (tree_map)
> {
> /* Do not treat parameters which were replaced with a constant as
> completely vanished. */
> - auto_vec <int, 16> index_mapping;
> - bool need_remap = false;
> -
> - if (m_id)
> - {
> - clone_info *cinfo = clone_info::get (m_id->src_node);
> - if (cinfo && cinfo->param_adjustments)
> - {
> - cinfo->param_adjustments->get_updated_indices (&index_mapping);
> - need_remap = true;
> - }
> - }
> -
> for (unsigned i = 0; i < tree_map->length (); i++)
> {
> int parm_num = (*tree_map)[i]->parm_num;
> @@ -1473,8 +1501,9 @@ ipa_param_body_adjustments
> : m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
> m_dead_stmts (), m_dead_ssas (), m_dead_ssa_debug_equiv (),
> m_dead_stmt_debug_equiv (), m_fndecl (fndecl), m_id (NULL), m_oparms (),
> - m_new_decls (), m_new_types (), m_replacements (), m_removed_decls (),
> - m_removed_map (), m_method2func (false)
> + m_new_decls (), m_new_types (), m_replacements (),
> + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
> + m_method2func (false)
> {
> common_initialization (fndecl, NULL, NULL);
> }
> @@ -1491,7 +1520,8 @@ ipa_param_body_adjustments
> m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
> m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
> m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements
> (),
> - m_removed_decls (), m_removed_map (), m_method2func (false)
> + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
> + m_method2func (false)
> {
> common_initialization (fndecl, NULL, NULL);
> }
> @@ -1514,7 +1544,8 @@ ipa_param_body_adjustments
> m_reset_debug_decls (), m_dead_stmts (), m_dead_ssas (),
> m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
> m_id (id), m_oparms (), m_new_decls (), m_new_types (), m_replacements
> (),
> - m_removed_decls (), m_removed_map (), m_method2func (false)
> + m_split_agg_csts_inits (), m_removed_decls (), m_removed_map (),
> + m_method2func (false)
> {
> common_initialization (old_fndecl, vars, tree_map);
> }
> @@ -2383,6 +2414,16 @@
> ipa_param_body_adjustments::perform_cfun_body_modifications ()
> }
>
>
> +/* If there are any initialization statements that need to be emitted into
> + the basic block BB right at ther start of the new function, do so. */
> +void
> +ipa_param_body_adjustments::append_init_stmts (basic_block bb)
> +{
> + gimple_stmt_iterator si = gsi_last_bb (bb);
> + while (!m_split_agg_csts_inits.is_empty ())
> + gsi_insert_after (&si, m_split_agg_csts_inits.pop (), GSI_NEW_STMT);
> +}
> +
> /* Deallocate summaries which otherwise stay alive until the end of
> compilation. */
>
> diff --git a/gcc/ipa-param-manipulation.h b/gcc/ipa-param-manipulation.h
> index e5654f4ff70..e20d34918b3 100644
> --- a/gcc/ipa-param-manipulation.h
> +++ b/gcc/ipa-param-manipulation.h
> @@ -236,13 +236,6 @@ public:
> void get_surviving_params (vec<bool> *surviving_params);
> /* Fill a vector with new indices of surviving original parameters. */
> void get_updated_indices (vec<int> *new_indices);
> - /* If a parameter with original INDEX has survived intact, return its new
> - index. Otherwise return -1. In that case, if it has been split and
> there
> - is a new parameter representing a portion at UNIT_OFFSET for which a
> value
> - of a TYPE can be substituted, store its new index into SPLIT_INDEX,
> - otherwise store -1 there. */
> - int get_updated_index_or_split (int index, unsigned unit_offset, tree type,
> - int *split_index);
> /* Return the original index for the given new parameter index. Return a
> negative number if not available. */
> int get_original_index (int newidx);
> @@ -321,6 +314,8 @@ public:
>
> /* Change the PARM_DECLs. */
> void modify_formal_parameters ();
> + /* Register a REPLACEMENT for accesses to BASE at UNIT_OFFSET. */
> + void register_replacement (tree base, unsigned unit_offset, tree
> replacement);
> /* Register a replacement decl for the transformation done in APM. */
> void register_replacement (ipa_adjusted_param *apm, tree replacement);
> /* Lookup a replacement for a given offset within a given parameter. */
> @@ -340,6 +335,10 @@ public:
> they are mapped to. */
> void remap_with_debug_expressions (tree *t);
>
> + /* If there are any initialization statements that need to be emitted into
> + the basic block BB right at ther start of the new function, do so. */
> + void append_init_stmts (basic_block bb);
> +
> /* Pointers to data structures defining how the function should be
> modified. */
> vec<ipa_adjusted_param, va_gc> *m_adj_params;
> @@ -405,6 +404,12 @@ private:
>
> auto_vec<ipa_param_body_replacement, 16> m_replacements;
>
> + /* List of initialization assignments to be put at the beginning of the
> + cloned function to deal with split aggregates which however have known
> + constant value and so their PARM_DECL disappears. */
> +
> + auto_vec<gimple *, 8> m_split_agg_csts_inits;
> +
> /* Vector for remapping SSA_BASES from old parameter declarations that are
> being removed as a part of the transformation. Before a new VAR_DECL is
> created, it holds the old PARM_DECL, once the variable is built it is
> diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
> index fcadf64ead7..08c7f97efb9 100644
> --- a/gcc/ipa-prop.cc
> +++ b/gcc/ipa-prop.cc
> @@ -5518,29 +5518,21 @@ ipcp_read_transformation_summaries (void)
> }
> }
>
> -/* Adjust the aggregate replacements in TS to reflect parameters skipped in
> - NODE but also if any parameter was IPA-SRAed into a scalar go ahead with
> - substitution of the default_definitions of that new param with the
> - appropriate constant.
> +/* Adjust the aggregate replacements in TS to reflect any parameter removals
> + which might have already taken place. If after adjustments there are no
> + aggregate replacements left, the m_agg_values will be set to NULL. In
> other
> + cases, it may be shrunk. */
>
> - If after adjustments there are no aggregate replacements left, the
> - m_agg_values will be set to NULL. In other cases, it may be shrunk.
> -
> - Return true if any values were already substituted for scalarized
> parameters
> - and update_cfg shuld be run after replace_uses_by. */
> -
> -static bool
> -adjust_agg_replacement_values (cgraph_node *node,
> - ipcp_transformation *ts,
> - const vec<ipa_param_descriptor, va_gc>
> - &descriptors)
> +static void
> +adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
> {
> clone_info *cinfo = clone_info::get (node);
> if (!cinfo || !cinfo->param_adjustments)
> - return false;
> + return;
>
> + auto_vec<int, 16> new_indices;
> + cinfo->param_adjustments->get_updated_indices (&new_indices);
> bool removed_item = false;
> - bool done_replacement = false;
> unsigned dst_index = 0;
> unsigned count = ts->m_agg_values->length ();
> for (unsigned i = 0; i < count; i++)
> @@ -5548,13 +5540,10 @@ adjust_agg_replacement_values (cgraph_node *node,
> ipa_argagg_value *v = &(*ts->m_agg_values)[i];
> gcc_checking_assert (v->index >= 0);
>
> - tree cst_type = TREE_TYPE (v->value);
> - int split_idx;
> - int new_idx
> - = cinfo->param_adjustments->get_updated_index_or_split (v->index,
> - v->unit_offset,
> - cst_type,
> - &split_idx);
> + int new_idx = -1;
> + if ((unsigned) v->index < new_indices.length ())
> + new_idx = new_indices[v->index];
> +
> if (new_idx >= 0)
> {
> v->index = new_idx;
> @@ -5563,19 +5552,7 @@ adjust_agg_replacement_values (cgraph_node *node,
> dst_index++;
> }
> else
> - {
> - removed_item = true;
> - if (split_idx >= 0)
> - {
> - tree parm = ipa_get_param (descriptors, split_idx);
> - tree ddef = ssa_default_def (cfun, parm);
> - if (ddef)
> - {
> - replace_uses_by (ddef, v->value);
> - done_replacement = true;
> - }
> - }
> - }
> + removed_item = true;
> }
>
> if (dst_index == 0)
> @@ -5586,7 +5563,7 @@ adjust_agg_replacement_values (cgraph_node *node,
> else if (removed_item)
> ts->m_agg_values->truncate (dst_index);
>
> - return done_replacement;
> + return;
> }
>
> /* Dominator walker driving the ipcp modification phase. */
> @@ -5955,7 +5932,6 @@ ipcp_update_vr (struct cgraph_node *node)
> unsigned int
> ipcp_transform_function (struct cgraph_node *node)
> {
> - vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
> struct ipa_func_body_info fbi;
> int param_count;
>
> @@ -5974,18 +5950,13 @@ ipcp_transform_function (struct cgraph_node *node)
> param_count = count_formal_params (node->decl);
> if (param_count == 0)
> return 0;
> - vec_safe_grow_cleared (descriptors, param_count, true);
> - ipa_populate_param_decls (node, *descriptors);
>
> - bool cfg_changed = adjust_agg_replacement_values (node, ts, *descriptors);
> + adjust_agg_replacement_values (node, ts);
> if (vec_safe_is_empty (ts->m_agg_values))
> {
> - vec_free (descriptors);
> if (dump_file)
> fprintf (dump_file, " All affected aggregate parameters were either "
> "removed or converted into scalars, phase done.\n");
> - if (cfg_changed)
> - delete_unreachable_blocks_update_callgraph (node, false);
> return 0;
> }
> if (dump_file)
> @@ -6002,12 +5973,15 @@ ipcp_transform_function (struct cgraph_node *node)
> fbi.param_count = param_count;
> fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
>
> + vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
> + vec_safe_grow_cleared (descriptors, param_count, true);
> + ipa_populate_param_decls (node, *descriptors);
> bool modified_mem_access = false;
> calculate_dominance_info (CDI_DOMINATORS);
> ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
> walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
> free_dominance_info (CDI_DOMINATORS);
> - cfg_changed |= walker.cleanup_eh ();
> + bool cfg_changed = walker.cleanup_eh ();
>
> int i;
> struct ipa_bb_info *bi;
> diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
> index 718201d27fa..0f137e810fe 100644
> --- a/gcc/ipa-sra.cc
> +++ b/gcc/ipa-sra.cc
> @@ -84,6 +84,7 @@ along with GCC; see the file COPYING3. If not see
> #include "internal-fn.h"
> #include "symtab-clones.h"
> #include "attribs.h"
> +#include "ipa-prop.h"
>
> static void ipa_sra_summarize_function (cgraph_node *);
>
> @@ -3605,13 +3606,16 @@ retval_used_p (cgraph_node *node, void *)
> /* Push into NEW_PARAMS all required parameter adjustment entries to copy or
> modify parameter which originally had index BASE_INDEX, in the adjustment
> vector of parent clone (if any) had PREV_CLONE_INDEX and was described by
> - PREV_ADJUSTMENT. If the parent clone is the original function,
> - PREV_ADJUSTMENT is NULL and PREV_CLONE_INDEX is equal to BASE_INDEX. */
> + PREV_ADJUSTMENT. If IPA-CP has created a transformation summary for the
> + original node, it needs to be passed in IPCP_TS, otherwise it should be
> + NULL. If the parent clone is the original function, PREV_ADJUSTMENT is
> NULL
> + and PREV_CLONE_INDEX is equal to BASE_INDEX. */
>
> static void
> push_param_adjustments_for_index (isra_func_summary *ifs, unsigned
> base_index,
> unsigned prev_clone_index,
> ipa_adjusted_param *prev_adjustment,
> + ipcp_transformation *ipcp_ts,
> vec<ipa_adjusted_param, va_gc> **new_params)
> {
> isra_param_desc *desc = &(*ifs->m_parameters)[base_index];
> @@ -3652,6 +3656,23 @@ push_param_adjustments_for_index (isra_func_summary
> *ifs, unsigned base_index,
> param_access *pa = (*desc->accesses)[j];
> if (!pa->certain)
> continue;
> +
> + if (ipcp_ts)
> + {
> + ipa_argagg_value_list avl (ipcp_ts);
> + tree value = avl.get_value (base_index, pa->unit_offset);
> + if (value
> + && (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value))) / BITS_PER_UNIT
> + == pa->unit_size))
> + {
> + if (dump_file)
> + fprintf (dump_file, " - omitting component at byte "
> + "offset %u which is known to have a constant value\n ",
> + pa->unit_offset);
> + continue;
> + }
> + }
> +
> if (dump_file)
> fprintf (dump_file, " - component at byte offset %u, "
> "size %u\n", pa->unit_offset, pa->unit_size);
> @@ -3732,6 +3753,7 @@ process_isra_node_results (cgraph_node *node,
> fprintf (dump_file, " Will remove return value.\n");
> }
>
> + ipcp_transformation *ipcp_ts = ipcp_get_transformation_summary (node);
> vec<ipa_adjusted_param, va_gc> *new_params = NULL;
> if (ipa_param_adjustments *old_adjustments
> = cinfo ? cinfo->param_adjustments : NULL)
> @@ -3741,12 +3763,12 @@ process_isra_node_results (cgraph_node *node,
> {
> ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
> push_param_adjustments_for_index (ifs, old_adj->base_index, i,
> - old_adj, &new_params);
> + old_adj, ipcp_ts, &new_params);
> }
> }
> else
> for (unsigned i = 0; i < param_count; i++)
> - push_param_adjustments_for_index (ifs, i, i, NULL, &new_params);
> + push_param_adjustments_for_index (ifs, i, i, NULL, ipcp_ts,
> &new_params);
>
> ipa_param_adjustments *new_adjustments
> = (new (ggc_alloc <ipa_param_adjustments> ())
> diff --git a/gcc/testsuite/gcc.dg/ipa/pr107640-2.c
> b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c
> new file mode 100644
> index 00000000000..94cbe02860d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/pr107640-2.c
> @@ -0,0 +1,50 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-optimized-slim" } */
> +
> +struct S
> +{
> + int a, b, c;
> +};
> +
> +int ellide (int c);
> +volatile short gi;
> +
> +void __attribute__((noipa))
> +consume_s (struct S *p)
> +{
> + gi = p->a;
> +}
> +
> +static void __attribute__((noinline))
> +foo (struct S *p, short *r)
> +{
> + gi = *r;
> + if (!__builtin_constant_p (p->b))
> + ellide (1);
> + consume_s (p);
> +}
> +
> +static void __attribute__((noinline))
> +bar (short *r, struct S *p)
> +{
> + gi = *r;
> + if (!__builtin_constant_p (p->c))
> + ellide (2);
> + consume_s (p);
> +}
> +
> +struct S gs;
> +
> +int main (int argc, char *argv[])
> +{
> + short i = 42;
> + gs.a = 10;
> + gs.b = 20;
> + foo (&gs, &i);
> + gs.b = 30;
> + gs.c = 40;
> + bar (&i, &gs);
> + return 0;
> +}
> +
> +/* { dg-final { scan-tree-dump-not "ellide" "optimized" { xfail *-*-* } } }
> */
> diff --git a/gcc/tree-inline.cc b/gcc/tree-inline.cc
> index 8091ba8f13b..15a1a389493 100644
> --- a/gcc/tree-inline.cc
> +++ b/gcc/tree-inline.cc
> @@ -6377,6 +6377,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
> bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
> while (init_stmts.length ())
> insert_init_stmt (&id, bb, init_stmts.pop ());
> + if (param_body_adjs)
> + param_body_adjs->append_init_stmts (bb);
> update_clone_info (&id);
>
> /* Remap the nonlocal_goto_save_area, if any. */
> --
> 2.38.1
>