aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-12-18 23:16:24 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2015-12-18 23:16:24 +0100
commita49de7a463519e8e3c7e903caef9e78604fd637d (patch)
tree9d8f68bcec113d5a41ce201bffd8fc2d69889feb /gcc/tree-inline.c
parentca2c1b328327f998338cfa4b9e902e439cf57278 (diff)
downloadgcc-a49de7a463519e8e3c7e903caef9e78604fd637d.zip
gcc-a49de7a463519e8e3c7e903caef9e78604fd637d.tar.gz
gcc-a49de7a463519e8e3c7e903caef9e78604fd637d.tar.bz2
re PR debug/68860 (FAIL: gcc.dg/guality/pr36728-1.c -flto -O3 -g line 17 arg1 == 1)
PR debug/68860 * ipa-split.c (split_function): Only perform caller side modifications for decl_debug_args here. * cgraph.c: Include gimplify.h. (cgraph_edge::redirect_call_stmt_to_callee): Add caller side debug stmts for decl_debug_args. Spelling fix in a comment. * tree-inline.c (tree_function_versioning): Populate decl_debug_args for args_to_skip arguments and add callee side debug stmts. Formatting fixes. Avoid shadowing i variable. * gcc.dg/guality/pr68860-1.c: New test. * gcc.dg/guality/pr68860-2.c: New test. From-SVN: r231840
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c129
1 files changed, 113 insertions, 16 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index dea23c7..36c96225 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -5668,6 +5668,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
basic_block old_entry_block, bb;
auto_vec<gimple *, 10> init_stmts;
tree vars = NULL_TREE;
+ bitmap debug_args_to_skip = args_to_skip;
gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL
&& TREE_CODE (new_decl) == FUNCTION_DECL);
@@ -5740,9 +5741,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
/* Copy the function's static chain. */
p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl;
if (p)
- DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl =
- copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl,
- &id);
+ DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl
+ = copy_static_chain (p, &id);
/* If there's a tree_map, prepare for substitution. */
if (tree_map)
@@ -5752,29 +5752,39 @@ tree_function_versioning (tree old_decl, tree new_decl,
replace_info = (*tree_map)[i];
if (replace_info->replace_p)
{
+ int parm_num = -1;
if (!replace_info->old_tree)
{
- int i = replace_info->parm_num;
+ int p = replace_info->parm_num;
tree parm;
- tree req_type;
+ tree req_type, new_type;
- for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
- i --;
+ for (parm = DECL_ARGUMENTS (old_decl); p;
+ parm = DECL_CHAIN (parm))
+ p--;
replace_info->old_tree = parm;
+ parm_num = replace_info->parm_num;
req_type = TREE_TYPE (parm);
- if (!useless_type_conversion_p (req_type, TREE_TYPE (replace_info->new_tree)))
+ new_type = TREE_TYPE (replace_info->new_tree);
+ if (!useless_type_conversion_p (req_type, new_type))
{
if (fold_convertible_p (req_type, replace_info->new_tree))
- replace_info->new_tree = fold_build1 (NOP_EXPR, req_type, replace_info->new_tree);
- else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (replace_info->new_tree)))
- replace_info->new_tree = fold_build1 (VIEW_CONVERT_EXPR, req_type, replace_info->new_tree);
+ replace_info->new_tree
+ = fold_build1 (NOP_EXPR, req_type,
+ replace_info->new_tree);
+ else if (TYPE_SIZE (req_type) == TYPE_SIZE (new_type))
+ replace_info->new_tree
+ = fold_build1 (VIEW_CONVERT_EXPR, req_type,
+ replace_info->new_tree);
else
{
if (dump_file)
{
fprintf (dump_file, " const ");
- print_generic_expr (dump_file, replace_info->new_tree, 0);
- fprintf (dump_file, " can't be converted to param ");
+ print_generic_expr (dump_file,
+ replace_info->new_tree, 0);
+ fprintf (dump_file,
+ " can't be converted to param ");
print_generic_expr (dump_file, parm, 0);
fprintf (dump_file, "\n");
}
@@ -5792,14 +5802,38 @@ tree_function_versioning (tree old_decl, tree new_decl,
&vars);
if (init)
init_stmts.safe_push (init);
+ if (MAY_HAVE_DEBUG_STMTS && args_to_skip)
+ {
+ if (parm_num == -1)
+ {
+ tree parm;
+ int p;
+ for (parm = DECL_ARGUMENTS (old_decl), p = 0; parm;
+ parm = DECL_CHAIN (parm), p++)
+ if (parm == replace_info->old_tree)
+ {
+ parm_num = p;
+ break;
+ }
+ }
+ if (parm_num != -1)
+ {
+ if (debug_args_to_skip == args_to_skip)
+ {
+ debug_args_to_skip = BITMAP_ALLOC (NULL);
+ bitmap_copy (debug_args_to_skip, args_to_skip);
+ }
+ bitmap_clear_bit (debug_args_to_skip, parm_num);
+ }
+ }
}
}
}
/* 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_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);
BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl;
@@ -5914,6 +5948,69 @@ tree_function_versioning (tree old_decl, tree new_decl,
}
}
+ if (debug_args_to_skip && MAY_HAVE_DEBUG_STMTS)
+ {
+ tree parm;
+ vec<tree, va_gc> **debug_args = NULL;
+ unsigned int len = 0;
+ for (parm = DECL_ARGUMENTS (old_decl), i = 0;
+ parm; parm = DECL_CHAIN (parm), i++)
+ if (bitmap_bit_p (debug_args_to_skip, i) && is_gimple_reg (parm))
+ {
+ tree ddecl;
+
+ if (debug_args == NULL)
+ {
+ debug_args = decl_debug_args_insert (new_decl);
+ len = vec_safe_length (*debug_args);
+ }
+ ddecl = make_node (DEBUG_EXPR_DECL);
+ DECL_ARTIFICIAL (ddecl) = 1;
+ TREE_TYPE (ddecl) = TREE_TYPE (parm);
+ DECL_MODE (ddecl) = DECL_MODE (parm);
+ vec_safe_push (*debug_args, DECL_ORIGIN (parm));
+ vec_safe_push (*debug_args, ddecl);
+ }
+ if (debug_args != NULL)
+ {
+ /* On the callee side, add
+ DEBUG D#Y s=> parm
+ DEBUG var => D#Y
+ stmts to the first bb where var is a VAR_DECL created for the
+ optimized away parameter in DECL_INITIAL block. This hints
+ in the debug info that var (whole DECL_ORIGIN is the parm
+ PARM_DECL) is optimized away, but could be looked up at the
+ call site as value of D#X there. */
+ tree var = vars, vexpr;
+ gimple_stmt_iterator cgsi
+ = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
+ gimple *def_temp;
+ var = vars;
+ i = vec_safe_length (*debug_args);
+ do
+ {
+ i -= 2;
+ while (var != NULL_TREE
+ && DECL_ABSTRACT_ORIGIN (var) != (**debug_args)[i])
+ var = TREE_CHAIN (var);
+ if (var == NULL_TREE)
+ break;
+ vexpr = make_node (DEBUG_EXPR_DECL);
+ parm = (**debug_args)[i];
+ DECL_ARTIFICIAL (vexpr) = 1;
+ TREE_TYPE (vexpr) = TREE_TYPE (parm);
+ DECL_MODE (vexpr) = DECL_MODE (parm);
+ def_temp = gimple_build_debug_bind (var, vexpr, NULL);
+ gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT);
+ def_temp = gimple_build_debug_source_bind (vexpr, parm, NULL);
+ gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT);
+ }
+ while (i > len);
+ }
+ }
+
+ if (debug_args_to_skip && debug_args_to_skip != args_to_skip)
+ BITMAP_FREE (debug_args_to_skip);
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);