re PR debug/43077 (VTA issues caused by SSA expand)
PR debug/43077 * cfgexpand (expand_debug_expr): Expand TERed ssa names in place. (expand_gimple_basic_block): Generate and use debug temps if there are debug uses left after the last real use of TERed ssa names. Unlink debug immediate uses when they are expanded. testsuite/ PR debug/43077 * gcc.dg/guality/pr43077-1.c: New test. From-SVN: r157009
This commit is contained in:
parent
38170f34f3
commit
2a8e30fbf3
@ -1,3 +1,11 @@
|
||||
2010-02-23 Michael Matz <matz@suse.de>
|
||||
|
||||
PR debug/43077
|
||||
* cfgexpand (expand_debug_expr): Expand TERed ssa names in place.
|
||||
(expand_gimple_basic_block): Generate and use debug temps if there
|
||||
are debug uses left after the last real use of TERed ssa names.
|
||||
Unlink debug immediate uses when they are expanded.
|
||||
|
||||
2010-02-23 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 43123
|
||||
|
132
gcc/cfgexpand.c
132
gcc/cfgexpand.c
@ -2338,7 +2338,10 @@ expand_debug_expr (tree exp)
|
||||
|
||||
if (inner_mode == VOIDmode)
|
||||
{
|
||||
inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
|
||||
if (TREE_CODE (exp) == SSA_NAME)
|
||||
inner_mode = TYPE_MODE (TREE_TYPE (exp));
|
||||
else
|
||||
inner_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
|
||||
if (mode == inner_mode)
|
||||
return op0;
|
||||
}
|
||||
@ -2354,6 +2357,7 @@ expand_debug_expr (tree exp)
|
||||
}
|
||||
else if (FLOAT_MODE_P (mode))
|
||||
{
|
||||
gcc_assert (TREE_CODE (exp) != SSA_NAME);
|
||||
if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))))
|
||||
op0 = simplify_gen_unary (UNSIGNED_FLOAT, mode, op0, inner_mode);
|
||||
else
|
||||
@ -2886,14 +2890,24 @@ expand_debug_expr (tree exp)
|
||||
|
||||
case SSA_NAME:
|
||||
{
|
||||
int part = var_to_partition (SA.map, exp);
|
||||
gimple g = get_gimple_for_ssa_name (exp);
|
||||
if (g)
|
||||
{
|
||||
op0 = expand_debug_expr (gimple_assign_rhs_to_tree (g));
|
||||
if (!op0)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
int part = var_to_partition (SA.map, exp);
|
||||
|
||||
if (part == NO_PARTITION)
|
||||
return NULL;
|
||||
if (part == NO_PARTITION)
|
||||
return NULL;
|
||||
|
||||
gcc_assert (part >= 0 && (unsigned)part < SA.map->num_partitions);
|
||||
gcc_assert (part >= 0 && (unsigned)part < SA.map->num_partitions);
|
||||
|
||||
op0 = SA.partition_to_pseudo[part];
|
||||
op0 = SA.partition_to_pseudo[part];
|
||||
}
|
||||
goto adjust_mode;
|
||||
}
|
||||
|
||||
@ -3050,6 +3064,105 @@ expand_gimple_basic_block (basic_block bb)
|
||||
basic_block new_bb;
|
||||
|
||||
stmt = gsi_stmt (gsi);
|
||||
|
||||
/* If this statement is a non-debug one, and we generate debug
|
||||
insns, then this one might be the last real use of a TERed
|
||||
SSA_NAME, but where there are still some debug uses further
|
||||
down. Expanding the current SSA name in such further debug
|
||||
uses by their RHS might lead to wrong debug info, as coalescing
|
||||
might make the operands of such RHS be placed into the same
|
||||
pseudo as something else. Like so:
|
||||
a_1 = a_0 + 1; // Assume a_1 is TERed and a_0 is dead
|
||||
use(a_1);
|
||||
a_2 = ...
|
||||
#DEBUG ... => a_1
|
||||
As a_0 and a_2 don't overlap in lifetime, assume they are coalesced.
|
||||
If we now would expand a_1 by it's RHS (a_0 + 1) in the debug use,
|
||||
the write to a_2 would actually have clobbered the place which
|
||||
formerly held a_0.
|
||||
|
||||
So, instead of that, we recognize the situation, and generate
|
||||
debug temporaries at the last real use of TERed SSA names:
|
||||
a_1 = a_0 + 1;
|
||||
#DEBUG #D1 => a_1
|
||||
use(a_1);
|
||||
a_2 = ...
|
||||
#DEBUG ... => #D1
|
||||
*/
|
||||
if (MAY_HAVE_DEBUG_INSNS
|
||||
&& SA.values
|
||||
&& !is_gimple_debug (stmt))
|
||||
{
|
||||
ssa_op_iter iter;
|
||||
tree op;
|
||||
gimple def;
|
||||
|
||||
location_t sloc = get_curr_insn_source_location ();
|
||||
tree sblock = get_curr_insn_block ();
|
||||
|
||||
/* Look for SSA names that have their last use here (TERed
|
||||
names always have only one real use). */
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
|
||||
if ((def = get_gimple_for_ssa_name (op)))
|
||||
{
|
||||
imm_use_iterator imm_iter;
|
||||
use_operand_p use_p;
|
||||
bool have_debug_uses = false;
|
||||
|
||||
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
|
||||
{
|
||||
if (gimple_debug_bind_p (USE_STMT (use_p)))
|
||||
{
|
||||
have_debug_uses = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_debug_uses)
|
||||
{
|
||||
/* OP is a TERed SSA name, with DEF it's defining
|
||||
statement, and where OP is used in further debug
|
||||
instructions. Generate a debug temporary, and
|
||||
replace all uses of OP in debug insns with that
|
||||
temporary. */
|
||||
gimple debugstmt;
|
||||
tree value = gimple_assign_rhs_to_tree (def);
|
||||
tree vexpr = make_node (DEBUG_EXPR_DECL);
|
||||
rtx val;
|
||||
enum machine_mode mode;
|
||||
|
||||
set_curr_insn_source_location (gimple_location (def));
|
||||
set_curr_insn_block (gimple_block (def));
|
||||
|
||||
DECL_ARTIFICIAL (vexpr) = 1;
|
||||
TREE_TYPE (vexpr) = TREE_TYPE (value);
|
||||
if (DECL_P (value))
|
||||
mode = DECL_MODE (value);
|
||||
else
|
||||
mode = TYPE_MODE (TREE_TYPE (value));
|
||||
DECL_MODE (vexpr) = mode;
|
||||
|
||||
val = gen_rtx_VAR_LOCATION
|
||||
(mode, vexpr, (rtx)value, VAR_INIT_STATUS_INITIALIZED);
|
||||
|
||||
val = emit_debug_insn (val);
|
||||
|
||||
FOR_EACH_IMM_USE_STMT (debugstmt, imm_iter, op)
|
||||
{
|
||||
if (!gimple_debug_bind_p (debugstmt))
|
||||
continue;
|
||||
|
||||
FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
|
||||
SET_USE (use_p, vexpr);
|
||||
|
||||
update_stmt (debugstmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
set_curr_insn_source_location (sloc);
|
||||
set_curr_insn_block (sblock);
|
||||
}
|
||||
|
||||
currently_expanding_gimple_stmt = stmt;
|
||||
|
||||
/* Expand this statement, then evaluate the resulting RTL and
|
||||
@ -3102,6 +3215,13 @@ expand_gimple_basic_block (basic_block bb)
|
||||
INSN_VAR_LOCATION_LOC (val) = (rtx)value;
|
||||
}
|
||||
|
||||
/* In order not to generate too many debug temporaries,
|
||||
we delink all uses of debug statements we already expanded.
|
||||
Therefore debug statements between definition and real
|
||||
use of TERed SSA names will continue to use the SSA name,
|
||||
and not be replaced with debug temps. */
|
||||
delink_stmt_imm_use (stmt);
|
||||
|
||||
gsi = nsi;
|
||||
gsi_next (&nsi);
|
||||
if (gsi_end_p (nsi))
|
||||
|
@ -1,3 +1,8 @@
|
||||
2010-02-23 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/43077
|
||||
* gcc.dg/guality/pr43077-1.c: New test.
|
||||
|
||||
2010-02-23 Manuel López-Ibáñez <manu@gcc.gnu.org>
|
||||
|
||||
PR 43123
|
||||
|
55
gcc/testsuite/gcc.dg/guality/pr43077-1.c
Normal file
55
gcc/testsuite/gcc.dg/guality/pr43077-1.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* PR debug/43077 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-g" } */
|
||||
|
||||
int varb;
|
||||
|
||||
int __attribute__((noinline))
|
||||
fn1 (void)
|
||||
{
|
||||
int vara = (varb == 3); /* { dg-final { gdb-test 11 "vara" "0" } } */
|
||||
asm volatile ("" : : "g" (vara)); /* { dg-final { gdb-test 11 "varb" "2" } } */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
fn2 (void)
|
||||
{
|
||||
int vara = (varb == 3); /* { dg-final { gdb-test 19 "vara" "1" } } */
|
||||
asm volatile ("" : : "g" (vara)); /* { dg-final { gdb-test 19 "varb" "3" } } */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
foo (unsigned long *p, unsigned long *q)
|
||||
{
|
||||
int ret;
|
||||
asm volatile ("" : "=r" (ret), "=r" (*p), "=r" (*q) : "0" (1), "1" (2), "2" (3));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
fn3 (void)
|
||||
{
|
||||
unsigned long a = 0, b = 0, c = 0;
|
||||
a = foo (&b, &c);
|
||||
/* { dg-final { gdb-test 42 "a" "1" } } */
|
||||
/* { dg-final { gdb-test 42 "b" "2" } } */
|
||||
/* { dg-final { gdb-test 42 "c" "3" } } */
|
||||
unsigned long vara = a; /* { dg-final { gdb-test 42 "vara" "1" } } */
|
||||
unsigned long varb = b; /* { dg-final { gdb-test 42 "varb" "2" } } */
|
||||
unsigned long varc = c; /* { dg-final { gdb-test 42 "varc" "3" } } */
|
||||
asm volatile ("" : : "g" (vara), "g" (varb), "g" (varc));
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
asm volatile ("" : "=r" (varb) : "0" (2));
|
||||
fn1 ();
|
||||
asm volatile ("" : "=r" (varb) : "0" (3));
|
||||
fn2 ();
|
||||
fn3 ();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user