re PR debug/46724 (Wrong debug info: Invalid variable location)

PR debug/46724
* function.c (assign_parms_augmented_arg_list): Name and mark
DECL of result address as NAMELESS rather than IGNORED.
(assign_parms): Set DECL_VALUE_EXPR for indirect result.
* tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
(DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
* dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
DECL_VALUE_EXPR.
* dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
* var-tracking.c (vt_add_function_parameter): New, split out of...
(vt_add_function_parameters): ... this.  Handle incoming
pointer to hold result.

From-SVN: r168160
This commit is contained in:
Alexandre Oliva 2010-12-22 03:49:00 +00:00 committed by Alexandre Oliva
parent 16a9afdc66
commit 8dcfef8f2b
6 changed files with 152 additions and 108 deletions

View File

@ -1,3 +1,18 @@
2010-12-22 Alexandre Oliva <aoliva@redhat.com>
PR debug/46724
* function.c (assign_parms_augmented_arg_list): Name and mark
DECL of result address as NAMELESS rather than IGNORED.
(assign_parms): Set DECL_VALUE_EXPR for indirect result.
* tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
(DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
* dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
DECL_VALUE_EXPR.
* dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
* var-tracking.c (vt_add_function_parameter): New, split out of...
(vt_add_function_parameters): ... this. Handle incoming
pointer to hold result.
2010-12-22 Jie Zhang <jie@codesourcery.com>
* config/arm/arm.c (output_move_double): Update the comment

View File

@ -2396,12 +2396,12 @@ dbxout_expand_expr (tree expr)
/* FALLTHRU */
case PARM_DECL:
case RESULT_DECL:
if (DECL_HAS_VALUE_EXPR_P (expr))
return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
/* FALLTHRU */
case CONST_DECL:
case RESULT_DECL:
return DECL_RTL_IF_SET (expr);
case INTEGER_CST:

View File

@ -15446,12 +15446,12 @@ loc_list_from_tree (tree loc, int want_address)
/* FALLTHRU */
case PARM_DECL:
case RESULT_DECL:
if (DECL_HAS_VALUE_EXPR_P (loc))
return loc_list_from_tree (DECL_VALUE_EXPR (loc),
want_address);
/* FALLTHRU */
case RESULT_DECL:
case FUNCTION_DECL:
{
rtx rtl;

View File

@ -2253,10 +2253,11 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all)
tree decl;
decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
PARM_DECL, NULL_TREE, type);
PARM_DECL, get_identifier (".result_ptr"), type);
DECL_ARG_TYPE (decl) = type;
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_NAMELESS (decl) = 1;
TREE_CONSTANT (decl) = 1;
DECL_CHAIN (decl) = all->orig_fnargs;
all->orig_fnargs = decl;
@ -3418,13 +3419,22 @@ assign_parms (tree fndecl)
rtx x;
if (DECL_BY_REFERENCE (result))
x = addr;
{
SET_DECL_VALUE_EXPR (result, all.function_result_decl);
x = addr;
}
else
{
SET_DECL_VALUE_EXPR (result,
build1 (INDIRECT_REF, TREE_TYPE (result),
all.function_result_decl));
addr = convert_memory_address (Pmode, addr);
x = gen_rtx_MEM (DECL_MODE (result), addr);
set_mem_attributes (x, result, 1);
}
DECL_HAS_VALUE_EXPR_P (result) = 1;
SET_DECL_RTL (result, x);
}

View File

@ -2773,7 +2773,8 @@ struct GTY(()) tree_decl_common {
In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
unsigned decl_flag_1 : 1;
/* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P. */
In VAR_DECL, PARM_DECL and RESULT_DECL, this is
DECL_HAS_VALUE_EXPR_P. */
unsigned decl_flag_2 : 1;
/* Logically, these two would go in a theoretical base shared by var and
parm decl. */
@ -2818,7 +2819,8 @@ extern void decl_value_expr_insert (tree, tree);
decl itself. This should only be used for debugging; once this field has
been set, the decl itself may not legitimately appear in the function. */
#define DECL_HAS_VALUE_EXPR_P(NODE) \
(TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
(TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
->decl_common.decl_flag_2)
#define DECL_VALUE_EXPR(NODE) \
(decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
#define SET_DECL_VALUE_EXPR(NODE, VAL) \

View File

@ -7999,6 +7999,113 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
return false;
}
/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */
static void
vt_add_function_parameter (tree parm)
{
rtx decl_rtl = DECL_RTL_IF_SET (parm);
rtx incoming = DECL_INCOMING_RTL (parm);
tree decl;
enum machine_mode mode;
HOST_WIDE_INT offset;
dataflow_set *out;
decl_or_value dv;
if (TREE_CODE (parm) != PARM_DECL)
return;
if (!decl_rtl || !incoming)
return;
if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
return;
if (!vt_get_decl_and_offset (incoming, &decl, &offset))
{
if (REG_P (incoming) || MEM_P (incoming))
{
/* This means argument is passed by invisible reference. */
offset = 0;
decl = parm;
incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
}
else
{
if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
return;
offset += byte_lowpart_offset (GET_MODE (incoming),
GET_MODE (decl_rtl));
}
}
if (!decl)
return;
if (parm != decl)
{
/* Assume that DECL_RTL was a pseudo that got spilled to
memory. The spill slot sharing code will force the
memory to reference spill_slot_decl (%sfp), so we don't
match above. That's ok, the pseudo must have referenced
the entire parameter, so just reset OFFSET. */
gcc_assert (decl == get_spill_slot_decl (false));
offset = 0;
}
if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
return;
out = &VTI (ENTRY_BLOCK_PTR)->out;
dv = dv_from_decl (parm);
if (target_for_debug_bind (parm)
/* We can't deal with these right now, because this kind of
variable is single-part. ??? We could handle parallels
that describe multiple locations for the same single
value, but ATM we don't. */
&& GET_CODE (incoming) != PARALLEL)
{
cselib_val *val;
/* ??? We shouldn't ever hit this, but it may happen because
arguments passed by invisible reference aren't dealt with
above: incoming-rtl will have Pmode rather than the
expected mode for the type. */
if (offset)
return;
val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
/* ??? Float-typed values in memory are not handled by
cselib. */
if (val)
{
preserve_value (val);
set_variable_part (out, val->val_rtx, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
dv = dv_from_value (val->val_rtx);
}
}
if (REG_P (incoming))
{
incoming = var_lowpart (mode, incoming);
gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
incoming);
set_variable_part (out, incoming, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
}
else if (MEM_P (incoming))
{
incoming = var_lowpart (mode, incoming);
set_variable_part (out, incoming, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
}
}
/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
static void
@ -8008,110 +8115,20 @@ vt_add_function_parameters (void)
for (parm = DECL_ARGUMENTS (current_function_decl);
parm; parm = DECL_CHAIN (parm))
vt_add_function_parameter (parm);
if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
{
rtx decl_rtl = DECL_RTL_IF_SET (parm);
rtx incoming = DECL_INCOMING_RTL (parm);
tree decl;
enum machine_mode mode;
HOST_WIDE_INT offset;
dataflow_set *out;
decl_or_value dv;
tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
if (TREE_CODE (parm) != PARM_DECL)
continue;
if (TREE_CODE (vexpr) == INDIRECT_REF)
vexpr = TREE_OPERAND (vexpr, 0);
if (!DECL_NAME (parm))
continue;
if (!decl_rtl || !incoming)
continue;
if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
continue;
if (!vt_get_decl_and_offset (incoming, &decl, &offset))
{
if (REG_P (incoming) || MEM_P (incoming))
{
/* This means argument is passed by invisible reference. */
offset = 0;
decl = parm;
incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
}
else
{
if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
continue;
offset += byte_lowpart_offset (GET_MODE (incoming),
GET_MODE (decl_rtl));
}
}
if (!decl)
continue;
if (parm != decl)
{
/* Assume that DECL_RTL was a pseudo that got spilled to
memory. The spill slot sharing code will force the
memory to reference spill_slot_decl (%sfp), so we don't
match above. That's ok, the pseudo must have referenced
the entire parameter, so just reset OFFSET. */
gcc_assert (decl == get_spill_slot_decl (false));
offset = 0;
}
if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
continue;
out = &VTI (ENTRY_BLOCK_PTR)->out;
dv = dv_from_decl (parm);
if (target_for_debug_bind (parm)
/* We can't deal with these right now, because this kind of
variable is single-part. ??? We could handle parallels
that describe multiple locations for the same single
value, but ATM we don't. */
&& GET_CODE (incoming) != PARALLEL)
{
cselib_val *val;
/* ??? We shouldn't ever hit this, but it may happen because
arguments passed by invisible reference aren't dealt with
above: incoming-rtl will have Pmode rather than the
expected mode for the type. */
if (offset)
continue;
val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
/* ??? Float-typed values in memory are not handled by
cselib. */
if (val)
{
preserve_value (val);
set_variable_part (out, val->val_rtx, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
dv = dv_from_value (val->val_rtx);
}
}
if (REG_P (incoming))
{
incoming = var_lowpart (mode, incoming);
gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
incoming);
set_variable_part (out, incoming, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
}
else if (MEM_P (incoming))
{
incoming = var_lowpart (mode, incoming);
set_variable_part (out, incoming, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
}
if (TREE_CODE (vexpr) == PARM_DECL
&& DECL_ARTIFICIAL (vexpr)
&& !DECL_IGNORED_P (vexpr)
&& DECL_NAMELESS (vexpr))
vt_add_function_parameter (vexpr);
}
if (MAY_HAVE_DEBUG_INSNS)