From 4d5b4e6addc17d8ee8a3d62b0d7a1db01c5ca8dc Mon Sep 17 00:00:00 2001 From: aoliva Date: Wed, 22 Dec 2010 03:49:00 +0000 Subject: [PATCH] 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) : Use DECL_VALUE_EXPR. * dbxout.c (dbxout_expand_expr) : Likewise. * var-tracking.c (vt_add_function_parameter): New, split out of... (vt_add_function_parameters): ... this. Handle incoming pointer to hold result. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168160 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 15 ++++ gcc/dbxout.c | 2 +- gcc/dwarf2out.c | 2 +- gcc/function.c | 16 ++++- gcc/tree.h | 6 +- gcc/var-tracking.c | 199 +++++++++++++++++++++++++++++------------------------ 6 files changed, 142 insertions(+), 98 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 630eab1268e..fed571d55e7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-12-22 Alexandre Oliva + + 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) : Use + DECL_VALUE_EXPR. + * dbxout.c (dbxout_expand_expr) : 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 * config/arm/arm.c (output_move_double): Update the comment diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 89ea0f36090..3b0cf342f5e 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -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: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 1fa33001a77..bc218752ddf 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -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; diff --git a/gcc/function.c b/gcc/function.c index 7fa3b0c0aac..0c4d5f82464 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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); } diff --git a/gcc/tree.h b/gcc/tree.h index 8ba20449720..216f3d27ff0 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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) \ diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 44701be12e8..58dce1b654e 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -7999,121 +7999,138 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp) return false; } -/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */ +/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */ static void -vt_add_function_parameters (void) +vt_add_function_parameter (tree parm) { - tree parm; - - for (parm = DECL_ARGUMENTS (current_function_decl); - parm; parm = DECL_CHAIN (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) - continue; + 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 (!DECL_NAME (parm)) - continue; + if (TREE_CODE (parm) != PARM_DECL) + return; - if (!decl_rtl || !incoming) - continue; + if (!decl_rtl || !incoming) + return; - if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode) - continue; + if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode) + return; - if (!vt_get_decl_and_offset (incoming, &decl, &offset)) + if (!vt_get_decl_and_offset (incoming, &decl, &offset)) + { + if (REG_P (incoming) || MEM_P (incoming)) { - 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)); - } + /* This means argument is passed by invisible reference. */ + offset = 0; + decl = parm; + incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming); } - - if (!decl) - continue; - - if (parm != decl) + else { - /* 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 (!vt_get_decl_and_offset (decl_rtl, &decl, &offset)) + return; + offset += byte_lowpart_offset (GET_MODE (incoming), + GET_MODE (decl_rtl)); } + } - if (!track_loc_p (incoming, parm, offset, false, &mode, &offset)) - continue; + 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; + } - out = &VTI (ENTRY_BLOCK_PTR)->out; + if (!track_loc_p (incoming, parm, offset, false, &mode, &offset)) + return; - dv = dv_from_decl (parm); + out = &VTI (ENTRY_BLOCK_PTR)->out; - 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; + dv = dv_from_decl (parm); - /* ??? 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; + 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; - val = cselib_lookup (var_lowpart (mode, incoming), mode, true); + /* ??? 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; - /* ??? 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); - } - } + val = cselib_lookup (var_lowpart (mode, incoming), mode, true); - if (REG_P (incoming)) + /* ??? Float-typed values in memory are not handled by + cselib. */ + if (val) { - 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, + 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 +vt_add_function_parameters (void) +{ + tree parm; + + 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))) + { + tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl)); + + if (TREE_CODE (vexpr) == INDIRECT_REF) + vexpr = TREE_OPERAND (vexpr, 0); + + 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) { cselib_preserve_only_values (); -- 2.11.4.GIT