This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Avoid duplicate decls in inlined and versioned functions
- From: Richard Guenther <rguenther at suse dot de>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 28 Feb 2009 20:12:09 +0100 (CET)
- Subject: Re: Avoid duplicate decls in inlined and versioned functions
- References: <20090228191058.GD13301@kam.mff.cuni.cz>
On Sat, 28 Feb 2009, Jan Hubicka wrote:
> Hi,
> Currently inliner merge callee's local_decls into callers duplicating all
> global vars. This can be easilly abused to construct memory bomb using early
> inliner.
>
> Patch adds referenced_var_check_and_insert check into local_decls copying
> code. Now we need to reorder copying before body duplication because we
> add into referenced vars all the variables while copying the VAR_DECLs.
>
> Similar problem exists in function versioning code where declaration of removed
> parameter is added twice: once by copy_arguments_for_versioning, second time by
> setup_one_parameter. We need to reorder copying and argument setup and watch
> for existing decls during copying, otherwise we would miss completely
> elliminated declarations. Those remain in debug info and confuse GDB
> that is not expecting two declarations with same name in same scope
> block.
>
> Bootstrapped/regtested i686-linux, OK?
Ok.
Thanks,
Richard.
> * tree-inline.c (expand_call_inline): Avoid
> Index: tree-inline.c
> ===================================================================
> *** tree-inline.c (revision 144474)
> --- tree-inline.c (working copy)
> *************** expand_call_inline (basic_block bb, gimp
> *** 3305,3330 ****
> DECL_NO_TBAA_P (retvar) = 1;
> }
>
> - /* This is it. Duplicate the callee body. Assume callee is
> - pre-gimplified. Note that we must not alter the caller
> - function in any way before this point, as this CALL_EXPR may be
> - a self-referential call; if we're calling ourselves, we need to
> - duplicate our body before altering anything. */
> - copy_body (id, bb->count, bb->frequency, bb, return_block);
> -
> /* Add local vars in this inlined callee to caller. */
> t_step = id->src_cfun->local_decls;
> for (; t_step; t_step = TREE_CHAIN (t_step))
> {
> var = TREE_VALUE (t_step);
> if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
> ! cfun->local_decls = tree_cons (NULL_TREE, var,
> ! cfun->local_decls);
> else
> ! cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
> ! cfun->local_decls);
> }
>
> /* Clean up. */
> pointer_map_destroy (id->decl_map);
> id->decl_map = st;
> --- 3362,3392 ----
> DECL_NO_TBAA_P (retvar) = 1;
> }
>
> /* Add local vars in this inlined callee to caller. */
> t_step = id->src_cfun->local_decls;
> for (; t_step; t_step = TREE_CHAIN (t_step))
> {
> var = TREE_VALUE (t_step);
> if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
> ! {
> ! if (referenced_var_check_and_insert (var))
> ! cfun->local_decls = tree_cons (NULL_TREE, var,
> ! cfun->local_decls);
> ! }
> else
> ! {
> ! cfun->local_decls = tree_cons (NULL_TREE, remap_decl (var, id),
> ! cfun->local_decls);
> ! }
> }
>
> + /* This is it. Duplicate the callee body. Assume callee is
> + pre-gimplified. Note that we must not alter the caller
> + function in any way before this point, as this CALL_EXPR may be
> + a self-referential call; if we're calling ourselves, we need to
> + duplicate our body before altering anything. */
> + copy_body (id, bb->count, bb->frequency, bb, return_block);
> +
> /* Clean up. */
> pointer_map_destroy (id->decl_map);
> id->decl_map = st;
> *************** copy_arguments_for_versioning (tree orig
> *** 4140,4146 ****
> *parg = new_tree;
> parg = &TREE_CHAIN (new_tree);
> }
> ! else
> {
> /* Make an equivalent VAR_DECL. If the argument was used
> as temporary variable later in function, the uses will be
> --- 4214,4220 ----
> *parg = new_tree;
> parg = &TREE_CHAIN (new_tree);
> }
> ! else if (!pointer_map_contains (id->decl_map, arg))
> {
> /* Make an equivalent VAR_DECL. If the argument was used
> as temporary variable later in function, the uses will be
> *************** tree_function_versioning (tree old_decl,
> *** 4263,4278 ****
> DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl =
> copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl,
> &id);
> - /* Copy the function's arguments. */
> - if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
> - DECL_ARGUMENTS (new_decl) =
> - copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
> - args_to_skip, &vars);
> -
> - DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
> -
> - /* Renumber the lexical scoping (non-code) blocks consecutively. */
> - number_blocks (id.dst_fn);
>
> /* If there's a tree_map, prepare for substitution. */
> if (tree_map)
> --- 4343,4348 ----
> *************** tree_function_versioning (tree old_decl,
> *** 4307,4312 ****
> --- 4377,4392 ----
> VEC_safe_push (gimple, heap, init_stmts, init);
> }
> }
> + /* Copy the function's arguments. */
> + if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
> + DECL_ARGUMENTS (new_decl) =
> + copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
> + args_to_skip, &vars);
> +
> + DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
> +
> + /* Renumber the lexical scoping (non-code) blocks consecutively. */
> + number_blocks (id.dst_fn);
>
> declare_inline_vars (DECL_INITIAL (new_decl), vars);
> if (DECL_STRUCT_FUNCTION (old_decl)->local_decls != NULL_TREE)
>
>
--
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex