aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-06-22 12:41:58 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2011-06-22 12:41:58 +0200
commitddb555ed5129279c1bbe74574507ad67fff22e5e (patch)
tree084c46b58471b676de4f37c5db720c691779a0e7 /gcc/dwarf2out.c
parentccdc216414a902642b358b80f9aaa14bb7ce192b (diff)
downloadgcc-ddb555ed5129279c1bbe74574507ad67fff22e5e.zip
gcc-ddb555ed5129279c1bbe74574507ad67fff22e5e.tar.gz
gcc-ddb555ed5129279c1bbe74574507ad67fff22e5e.tar.bz2
re PR debug/47858 (IPA-SRA decreases quality of debug info)
PR debug/47858 * gimple.h (enum gimple_debug_subcode): Add GIMPLE_DEBUG_SOURCE_BIND. (gimple_build_debug_source_bind_stat): New prototype. (gimple_build_debug_source_bind): Define. (gimple_debug_source_bind_p, gimple_debug_source_bind_get_var, gimple_debug_source_bind_get_value, gimple_debug_source_bind_get_value_ptr, gimple_debug_source_bind_set_var, gimple_debug_source_bind_set_value): New inlines. * gimple.c (gimple_build_debug_source_bind_stat): New function. * gimple-pretty-print.c (dump_gimple_debug): Handle GIMPLE_DEBUG_SOURCE_BIND. * sese.c (rename_uses): Handle gimple_debug_source_bind_p. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Likewise. * tree-parloops.c (eliminate_local_variables, separate_decls_in_region): Likewise. (separate_decls_in_region_debug): Renamed from separate_decls_in_region_debug_bind. Handle gimple_debug_source_bind_p. * tree.h (decl_debug_args_lookup, decl_debug_args_insert): New prototypes. (DECL_HAS_DEBUG_ARGS_P): Define. (struct tree_function_decl): Add has_debug_args_flag field. * tree.c (debug_args_for_decl): New variable. (decl_debug_args_lookup, decl_debug_args_insert): New functions. * tree-into-ssa.c (mark_def_sites): Handle uses in debug stmts. (rewrite_debug_stmt_uses): New function. (rewrite_stmt): Use it to rewrite debug stmt uses. * rtl.def (DEBUG_PARAMETER_REF): New. * rtl.h (DEBUG_PARAMETER_REF_DECL): Define. * cselib.c (rtx_equal_for_cselib_1, cselib_hash_rtx): Handle DEBUG_PARAMETER_REF. * rtl.c (rtx_equal_p_cb, rtx_equal_p, iterative_hash_rtx): Likewise. * print-rtl.c (print_rtx): Likewise. * tree-sra.c (sra_ipa_reset_debug_stmts): Prefer replacing of SSA_NAMEs with DEBUG_EXPR_DECLs initialized in source bind debug stmts in the first bb. * tree-inline.c (remap_ssa_name): If remapping default def of a PARM_DECL fails, map to a DEBUG_EXPR_DECL set in a source bind debug stmt. (remap_gimple_stmt): Handle gimple_debug_source_bind_p. (maybe_move_debug_stmts_to_successors): Likewise. (copy_debug_stmt): Likewise. Avoid shadowing a variable. (tree_function_versioning): If DECL_HAS_DEBUG_ARGS_P, copy debug args vector from old_decl to new_decl. * ipa-prop.c (ipa_modify_call_arguments): For optimized away or modified parameters, add debug bind stmts before call setting DEBUG_EXPR_DECL which is remembered in debug args vector. * cfgexpand.c (expand_call_stmt): Call expand_debug_expr on DECL_DEBUG_EXPRs from debug args vector. (expand_debug_source_expr): New function. (expand_debug_locations): Use it for source bind insns. (expand_gimple_basic_block): Handle gimple_debug_source_bind_p. * var-tracking.c (prepare_call_arguments): Add debug args to call_arguments if any. * dwarf2out.c (dwarf_stack_op_name, size_of_loc_descr, output_loc_operands, output_loc_operands_raw, resolve_addr_in_expr, compare_loc_operands): Handle DW_OP_GNU_parameter_ref. (get_ref_die_offset, parameter_ref_descriptor): New functions. (mem_loc_descriptor): Handle DEBUG_PARAMETER_REF. (gen_subprogram_die): Handle parameters identified by DEBUG_PARAMETER_REF. * dwarf2.h (enum dwarf_location_atom): Add DW_OP_GNU_parameter_ref. From-SVN: r175288
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c88
1 files changed, 83 insertions, 5 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 480e4e0..6d53620 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4811,6 +4811,8 @@ dwarf_stack_op_name (unsigned int op)
return "DW_OP_GNU_convert";
case DW_OP_GNU_reinterpret:
return "DW_OP_GNU_reinterpret";
+ case DW_OP_GNU_parameter_ref:
+ return "DW_OP_GNU_parameter_ref";
default:
return "OP_<unknown>";
@@ -5085,6 +5087,10 @@ size_of_loc_descr (dw_loc_descr_ref loc)
= get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die);
size += size_of_uleb128 (o);
}
+ break;
+ case DW_OP_GNU_parameter_ref:
+ size += 4;
+ break;
default:
break;
}
@@ -5122,6 +5128,7 @@ size_of_locs (dw_loc_descr_ref loc)
static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
static void get_ref_die_offset_label (char *, dw_die_ref);
+static unsigned long int get_ref_die_offset (dw_die_ref);
static void output_loc_sequence (dw_loc_descr_ref, int);
/* Output location description stack opcode's operands (if any).
@@ -5467,6 +5474,15 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip)
}
break;
+ case DW_OP_GNU_parameter_ref:
+ {
+ unsigned long o;
+ gcc_assert (val1->val_class == dw_val_class_die_ref);
+ o = get_ref_die_offset (val1->v.val_die_ref.die);
+ dw2_asm_output_data (4, o, NULL);
+ }
+ break;
+
default:
/* Other codes have no operands. */
break;
@@ -5649,6 +5665,7 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
case DW_OP_GNU_deref_type:
case DW_OP_GNU_convert:
case DW_OP_GNU_reinterpret:
+ case DW_OP_GNU_parameter_ref:
gcc_unreachable ();
break;
@@ -6965,6 +6982,15 @@ get_base_type_offset (dw_die_ref ref)
return ref->die_offset;
}
+/* Return die_offset of a DIE reference other than base type. */
+
+static unsigned long int
+get_ref_die_offset (dw_die_ref ref)
+{
+ gcc_assert (ref->die_offset);
+ return ref->die_offset;
+}
+
/* Convert a DIE tag into its string name. */
static const char *
@@ -14507,6 +14533,34 @@ rotate_loc_descriptor (rtx rtl, enum machine_mode mode,
return ret;
}
+/* Helper function for mem_loc_descriptor. Return DW_OP_GNU_parameter_ref
+ for DEBUG_PARAMETER_REF RTL. */
+
+static dw_loc_descr_ref
+parameter_ref_descriptor (rtx rtl)
+{
+ dw_loc_descr_ref ret;
+ dw_die_ref ref;
+
+ if (dwarf_strict)
+ return NULL;
+ gcc_assert (TREE_CODE (DEBUG_PARAMETER_REF_DECL (rtl)) == PARM_DECL);
+ ref = lookup_decl_die (DEBUG_PARAMETER_REF_DECL (rtl));
+ ret = new_loc_descr (DW_OP_GNU_parameter_ref, 0, 0);
+ if (ref)
+ {
+ ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
+ ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
+ ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
+ }
+ else
+ {
+ ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
+ ret->dw_loc_oprnd1.v.val_decl_ref = DEBUG_PARAMETER_REF_DECL (rtl);
+ }
+ return ret;
+}
+
/* The following routine converts the RTL for a variable or parameter
(resident in memory) into an equivalent Dwarf representation of a
mechanism for getting the address of that same variable onto the top of a
@@ -14853,7 +14907,11 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
mem_loc_result = new_loc_descr (DW_OP_GNU_entry_value, 0, 0);
mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_loc;
mem_loc_result->dw_loc_oprnd1.v.val_loc = op0;
- return mem_loc_result;
+ break;
+
+ case DEBUG_PARAMETER_REF:
+ mem_loc_result = parameter_ref_descriptor (rtl);
+ break;
case PRE_MODIFY:
/* Extract the PLUS expression nested inside and fall into
@@ -20571,7 +20629,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
{
dw_loc_descr_ref reg, val;
enum machine_mode mode = GET_MODE (XEXP (XEXP (arg, 0), 1));
- dw_die_ref cdie;
+ dw_die_ref cdie, tdie = NULL;
next_arg = XEXP (arg, 1);
if (REG_P (XEXP (XEXP (arg, 0), 0))
@@ -20602,6 +20660,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
tlocc = XEXP (XEXP (arg, 0), 1);
continue;
}
+ reg = NULL;
if (REG_P (XEXP (XEXP (arg, 0), 0)))
reg = reg_loc_descriptor (XEXP (XEXP (arg, 0), 0),
VAR_INIT_STATUS_INITIALIZED);
@@ -20613,9 +20672,20 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
GET_MODE (mem),
VAR_INIT_STATUS_INITIALIZED);
}
+ else if (GET_CODE (XEXP (XEXP (arg, 0), 0))
+ == DEBUG_PARAMETER_REF)
+ {
+ tree tdecl
+ = DEBUG_PARAMETER_REF_DECL (XEXP (XEXP (arg, 0), 0));
+ tdie = lookup_decl_die (tdecl);
+ if (tdie == NULL)
+ continue;
+ }
else
continue;
- if (reg == NULL)
+ if (reg == NULL
+ && GET_CODE (XEXP (XEXP (arg, 0), 0))
+ != DEBUG_PARAMETER_REF)
continue;
val = mem_loc_descriptor (XEXP (XEXP (arg, 0), 1), mode,
VOIDmode,
@@ -20625,8 +20695,11 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
if (die == NULL)
die = gen_call_site_die (decl, subr_die, ca_loc);
cdie = new_die (DW_TAG_GNU_call_site_parameter, die,
- NULL_TREE);
- add_AT_loc (cdie, DW_AT_location, reg);
+ NULL_TREE);
+ if (reg != NULL)
+ add_AT_loc (cdie, DW_AT_location, reg);
+ else if (tdie != NULL)
+ add_AT_die_ref (cdie, DW_AT_abstract_origin, tdie);
add_AT_loc (cdie, DW_AT_GNU_call_site_value, val);
if (next_arg != XEXP (arg, 1))
{
@@ -24208,6 +24281,7 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
return false;
break;
case DW_OP_GNU_implicit_pointer:
+ case DW_OP_GNU_parameter_ref:
if (loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
{
dw_die_ref ref
@@ -24748,6 +24822,10 @@ compare_loc_operands (dw_loc_descr_ref x, dw_loc_descr_ref y)
case DW_OP_GNU_convert:
case DW_OP_GNU_reinterpret:
return valx1->v.val_die_ref.die == valy1->v.val_die_ref.die;
+ case DW_OP_GNU_parameter_ref:
+ return valx1->val_class == dw_val_class_die_ref
+ && valx1->val_class == valy1->val_class
+ && valx1->v.val_die_ref.die == valy1->v.val_die_ref.die;
default:
/* Other codes have no operands. */
return true;