Commit a49de7a4 by Jakub Jelinek Committed by Jakub Jelinek

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
parent ca2c1b32
2015-12-18 Jakub Jelinek <jakub@redhat.com>
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.
2015-12-18 Nathan Sidwell <nathan@acm.org>
* config/nvptx/nvptx.c (nvptx_maybe_convert_symbolic_operand):
......@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "tree-chkp.h"
#include "context.h"
#include "gimplify.h"
/* FIXME: Only for PROP_loops, but cgraph shouldn't have to know about this. */
#include "tree-pass.h"
......@@ -1275,7 +1276,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
if (decl)
e = e->resolve_speculation (decl);
/* If types do not match, speculation was likely wrong.
The direct edge was posisbly redirected to the clone with a different
The direct edge was possibly redirected to the clone with a different
signature. We did not update the call statement yet, so compare it
with the reference that still points to the proper type. */
else if (!gimple_check_call_matching_types (e->call_stmt,
......@@ -1420,6 +1421,70 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
gsi = gsi_for_stmt (e->call_stmt);
/* For optimized away parameters, add on the caller side
before the call
DEBUG D#X => parm_Y(D)
stmts and associate D#X with parm in decl_debug_args_lookup
vector to say for debug info that if parameter parm had been passed,
it would have value parm_Y(D). */
if (e->callee->clone.combined_args_to_skip && MAY_HAVE_DEBUG_STMTS)
{
vec<tree, va_gc> **debug_args
= decl_debug_args_lookup (e->callee->decl);
tree old_decl = gimple_call_fndecl (e->call_stmt);
if (debug_args && old_decl)
{
tree parm;
unsigned i = 0, num;
unsigned len = vec_safe_length (*debug_args);
unsigned nargs = gimple_call_num_args (e->call_stmt);
for (parm = DECL_ARGUMENTS (old_decl), num = 0;
parm && num < nargs;
parm = DECL_CHAIN (parm), num++)
if (bitmap_bit_p (e->callee->clone.combined_args_to_skip, num)
&& is_gimple_reg (parm))
{
unsigned last = i;
while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm))
i += 2;
if (i >= len)
{
i = 0;
while (i < last
&& (**debug_args)[i] != DECL_ORIGIN (parm))
i += 2;
if (i >= last)
continue;
}
tree ddecl = (**debug_args)[i + 1];
tree arg = gimple_call_arg (e->call_stmt, num);
if (!useless_type_conversion_p (TREE_TYPE (ddecl),
TREE_TYPE (arg)))
{
tree rhs1;
if (!fold_convertible_p (TREE_TYPE (ddecl), arg))
continue;
if (TREE_CODE (arg) == SSA_NAME
&& gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg))
&& (rhs1
= gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg)))
&& useless_type_conversion_p (TREE_TYPE (ddecl),
TREE_TYPE (rhs1)))
arg = rhs1;
else
arg = fold_convert (TREE_TYPE (ddecl), arg);
}
gimple *def_temp
= gimple_build_debug_bind (ddecl, unshare_expr (arg),
e->call_stmt);
gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
}
}
}
gsi_replace (&gsi, new_stmt, false);
/* We need to defer cleaning EH info on the new statement to
fixup-cfg. We may not have dominator information at this point
......
......@@ -1209,7 +1209,6 @@ split_function (basic_block return_bb, struct split_point *split_point,
gimple *last_stmt = NULL;
unsigned int i;
tree arg, ddef;
vec<tree, va_gc> **debug_args = NULL;
if (dump_file)
{
......@@ -1432,73 +1431,38 @@ split_function (basic_block return_bb, struct split_point *split_point,
vector to say for debug info that if parameter parm had been passed,
it would have value parm_Y(D). */
if (args_to_skip)
for (parm = DECL_ARGUMENTS (current_function_decl), num = 0;
parm; parm = DECL_CHAIN (parm), num++)
if (bitmap_bit_p (args_to_skip, num)
&& is_gimple_reg (parm))
{
tree ddecl;
gimple *def_temp;
/* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
otherwise if it didn't exist before, we'd end up with
different SSA_NAME_VERSIONs between -g and -g0. */
arg = get_or_create_ssa_default_def (cfun, parm);
if (!MAY_HAVE_DEBUG_STMTS)
continue;
if (debug_args == NULL)
debug_args = decl_debug_args_insert (node->decl);
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);
def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg),
call);
gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
}
/* And 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. */
if (debug_args != NULL)
{
unsigned int i;
tree var, vexpr;
gimple_stmt_iterator cgsi;
gimple *def_temp;
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
var = BLOCK_VARS (DECL_INITIAL (node->decl));
i = vec_safe_length (*debug_args);
cgsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
do
vec<tree, va_gc> **debug_args = NULL;
unsigned i = 0, len = 0;
if (MAY_HAVE_DEBUG_STMTS)
{
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_source_bind (vexpr, parm,
NULL);
gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
def_temp = gimple_build_debug_bind (var, vexpr, NULL);
gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
debug_args = decl_debug_args_lookup (node->decl);
if (debug_args)
len = vec_safe_length (*debug_args);
}
while (i);
pop_cfun ();
for (parm = DECL_ARGUMENTS (current_function_decl), num = 0;
parm; parm = DECL_CHAIN (parm), num++)
if (bitmap_bit_p (args_to_skip, num) && is_gimple_reg (parm))
{
tree ddecl;
gimple *def_temp;
/* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
otherwise if it didn't exist before, we'd end up with
different SSA_NAME_VERSIONs between -g and -g0. */
arg = get_or_create_ssa_default_def (cfun, parm);
if (!MAY_HAVE_DEBUG_STMTS || debug_args == NULL)
continue;
while (i < len && (**debug_args)[i] != DECL_ORIGIN (parm))
i += 2;
if (i >= len)
continue;
ddecl = (**debug_args)[i + 1];
def_temp
= gimple_build_debug_bind (ddecl, unshare_expr (arg), call);
gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
}
}
/* We avoid address being taken on any variable used by split part,
......
2015-12-18 Jakub Jelinek <jakub@redhat.com>
PR debug/68860
* gcc.dg/guality/pr68860-1.c: New test.
* gcc.dg/guality/pr68860-2.c: New test.
2015-12-18 Nathan Sidwell <nathan@acm.org>
* lib/target-supports.exp (check_effective_target_cilkplus): Not nvptx.
......
/* PR debug/68860 */
/* { dg-do run } */
/* { dg-options "-g" } */
#include "../nop.h"
static int __attribute__((noinline))
foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
{
char *x = __builtin_alloca (arg7);
int __attribute__ ((aligned(32))) y;
y = 2;
asm (NOP : "=m" (y) : "m" (y));
x[0] = 25 + arg8;
asm volatile (NOP : "=m" (x[0]) : "m" (x[0]));
return y;
}
/* On s390(x) r2 and r3 are (depending on the optimization level) used
when adjusting the addresses in order to meet the alignment
requirements above. They usually hold the function arguments arg1
and arg2. So it is expected that these values are unavailable in
some of these tests. */
/* { dg-final { gdb-test 14 "arg1" "1" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 14 "arg2" "2" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 14 "arg3" "3" } } */
/* { dg-final { gdb-test 14 "arg4" "4" } } */
/* { dg-final { gdb-test 14 "arg5" "5" } } */
/* { dg-final { gdb-test 14 "arg6" "6" } } */
/* { dg-final { gdb-test 14 "arg7" "30" } } */
/* { dg-final { gdb-test 14 "arg8" "7" } } */
/* { dg-final { gdb-test 14 "y" "2" } } */
/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 16 "arg3" "3" } } */
/* { dg-final { gdb-test 16 "arg4" "4" } } */
/* { dg-final { gdb-test 16 "arg5" "5" } } */
/* { dg-final { gdb-test 16 "arg6" "6" } } */
/* { dg-final { gdb-test 16 "arg7" "30" } } */
/* { dg-final { gdb-test 16 "arg8" "7" } } */
/* { dg-final { gdb-test 16 "*x" "(char) 32" } } */
/* { dg-final { gdb-test 16 "y" "2" } } */
int
main ()
{
int l = 0;
asm volatile ("" : "=r" (l) : "0" (l));
foo (l + 1, l + 2, l + 3, l + 4, l + 5, l + 6, l + 30, 7);
asm volatile ("" :: "r" (l));
return 0;
}
/* PR debug/68860 */
/* { dg-do run } */
/* { dg-options "-g" } */
#include "../nop.h"
int __attribute__((noinline))
foo (int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8)
{
char *x = __builtin_alloca (arg7);
int __attribute__ ((aligned(32))) y;
y = 2;
asm (NOP : "=m" (y) : "m" (y));
x[0] = 25 + arg8;
asm volatile (NOP : "=m" (x[0]) : "m" (x[0]));
return y;
}
/* On s390(x) r2 and r3 are (depending on the optimization level) used
when adjusting the addresses in order to meet the alignment
requirements above. They usually hold the function arguments arg1
and arg2. So it is expected that these values are unavailable in
some of these tests. */
/* { dg-final { gdb-test 14 "arg1" "1" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 14 "arg2" "2" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 14 "arg3" "3" } } */
/* { dg-final { gdb-test 14 "arg4" "4" } } */
/* { dg-final { gdb-test 14 "arg5" "5" } } */
/* { dg-final { gdb-test 14 "arg6" "6" } } */
/* { dg-final { gdb-test 14 "arg7" "30" } } */
/* { dg-final { gdb-test 14 "arg8" "7" } } */
/* { dg-final { gdb-test 14 "y" "2" } } */
/* { dg-final { gdb-test 16 "arg1" "1" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 16 "arg2" "2" { target { ! "s390*-*-*" } } } } */
/* { dg-final { gdb-test 16 "arg3" "3" } } */
/* { dg-final { gdb-test 16 "arg4" "4" } } */
/* { dg-final { gdb-test 16 "arg5" "5" } } */
/* { dg-final { gdb-test 16 "arg6" "6" } } */
/* { dg-final { gdb-test 16 "arg7" "30" } } */
/* { dg-final { gdb-test 16 "arg8" "7" } } */
/* { dg-final { gdb-test 16 "*x" "(char) 32" } } */
/* { dg-final { gdb-test 16 "y" "2" } } */
int
main ()
{
int l = 0;
asm volatile ("" : "=r" (l) : "0" (l));
foo (l + 1, l + 2, l + 3, l + 4, l + 5, l + 6, l + 30, 7);
asm volatile ("" :: "r" (l));
return 0;
}
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment