diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-12-18 23:16:24 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-12-18 23:16:24 +0100 |
commit | a49de7a463519e8e3c7e903caef9e78604fd637d (patch) | |
tree | 9d8f68bcec113d5a41ce201bffd8fc2d69889feb /gcc/tree-inline.c | |
parent | ca2c1b328327f998338cfa4b9e902e439cf57278 (diff) | |
download | gcc-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.c | 129 |
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); |