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
This commit is contained in:
parent
ccdc216414
commit
ddb555ed51
@ -1,3 +1,70 @@
|
||||
2011-06-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
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.
|
||||
|
||||
2011-06-22 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi (ARM Options): Document -mtls-dialect option.
|
||||
|
170
gcc/cfgexpand.c
170
gcc/cfgexpand.c
@ -57,6 +57,8 @@ struct ssaexpand SA;
|
||||
of comminucating the profile info to the builtin expanders. */
|
||||
gimple currently_expanding_gimple_stmt;
|
||||
|
||||
static rtx expand_debug_expr (tree);
|
||||
|
||||
/* Return an expression tree corresponding to the RHS of GIMPLE
|
||||
statement STMT. */
|
||||
|
||||
@ -1863,6 +1865,21 @@ expand_call_stmt (gimple stmt)
|
||||
SET_EXPR_LOCATION (exp, gimple_location (stmt));
|
||||
TREE_BLOCK (exp) = gimple_block (stmt);
|
||||
|
||||
/* Ensure RTL is created for debug args. */
|
||||
if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
|
||||
{
|
||||
VEC(tree, gc) **debug_args = decl_debug_args_lookup (decl);
|
||||
unsigned int ix;
|
||||
tree dtemp;
|
||||
|
||||
if (debug_args)
|
||||
for (ix = 1; VEC_iterate (tree, *debug_args, ix, dtemp); ix += 2)
|
||||
{
|
||||
gcc_assert (TREE_CODE (dtemp) == DEBUG_EXPR_DECL);
|
||||
expand_debug_expr (dtemp);
|
||||
}
|
||||
}
|
||||
|
||||
lhs = gimple_call_lhs (stmt);
|
||||
if (lhs)
|
||||
expand_assignment (lhs, exp, false);
|
||||
@ -3297,6 +3314,120 @@ expand_debug_expr (tree exp)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return an RTX equivalent to the source bind value of the tree expression
|
||||
EXP. */
|
||||
|
||||
static rtx
|
||||
expand_debug_source_expr (tree exp)
|
||||
{
|
||||
rtx op0 = NULL_RTX;
|
||||
enum machine_mode mode = VOIDmode, inner_mode;
|
||||
|
||||
switch (TREE_CODE (exp))
|
||||
{
|
||||
case PARM_DECL:
|
||||
{
|
||||
rtx incoming = DECL_INCOMING_RTL (exp);
|
||||
mode = DECL_MODE (exp);
|
||||
if (incoming
|
||||
&& GET_MODE (incoming) != BLKmode
|
||||
&& ((REG_P (incoming) && HARD_REGISTER_P (incoming))
|
||||
|| (MEM_P (incoming)
|
||||
&& REG_P (XEXP (incoming, 0))
|
||||
&& HARD_REGISTER_P (XEXP (incoming, 0)))))
|
||||
{
|
||||
op0 = gen_rtx_ENTRY_VALUE (GET_MODE (incoming));
|
||||
ENTRY_VALUE_EXP (op0) = incoming;
|
||||
break;
|
||||
}
|
||||
if (incoming
|
||||
&& MEM_P (incoming)
|
||||
&& !TREE_ADDRESSABLE (exp)
|
||||
&& GET_MODE (incoming) != BLKmode
|
||||
&& (XEXP (incoming, 0) == virtual_incoming_args_rtx
|
||||
|| (GET_CODE (XEXP (incoming, 0)) == PLUS
|
||||
&& XEXP (XEXP (incoming, 0), 0)
|
||||
== virtual_incoming_args_rtx
|
||||
&& CONST_INT_P (XEXP (XEXP (incoming, 0), 1)))))
|
||||
{
|
||||
op0 = incoming;
|
||||
break;
|
||||
}
|
||||
/* See if this isn't an argument that has been completely
|
||||
optimized out. */
|
||||
if (!DECL_RTL_SET_P (exp)
|
||||
&& incoming == NULL_RTX
|
||||
&& DECL_ABSTRACT_ORIGIN (current_function_decl))
|
||||
{
|
||||
tree aexp = exp;
|
||||
if (DECL_ABSTRACT_ORIGIN (exp))
|
||||
aexp = DECL_ABSTRACT_ORIGIN (exp);
|
||||
if (DECL_CONTEXT (aexp)
|
||||
== DECL_ABSTRACT_ORIGIN (current_function_decl))
|
||||
{
|
||||
VEC(tree, gc) **debug_args;
|
||||
unsigned int ix;
|
||||
tree ddecl;
|
||||
#ifdef ENABLE_CHECKING
|
||||
tree parm;
|
||||
for (parm = DECL_ARGUMENTS (current_function_decl);
|
||||
parm; parm = DECL_CHAIN (parm))
|
||||
gcc_assert (parm != exp
|
||||
&& DECL_ABSTRACT_ORIGIN (parm) != aexp);
|
||||
#endif
|
||||
debug_args = decl_debug_args_lookup (current_function_decl);
|
||||
if (debug_args != NULL)
|
||||
{
|
||||
for (ix = 0; VEC_iterate (tree, *debug_args, ix, ddecl);
|
||||
ix += 2)
|
||||
if (ddecl == aexp)
|
||||
return gen_rtx_DEBUG_PARAMETER_REF (mode, aexp);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (op0 == NULL_RTX)
|
||||
return NULL_RTX;
|
||||
|
||||
inner_mode = GET_MODE (op0);
|
||||
if (mode == inner_mode)
|
||||
return op0;
|
||||
|
||||
if (FLOAT_MODE_P (mode) && FLOAT_MODE_P (inner_mode))
|
||||
{
|
||||
if (GET_MODE_BITSIZE (mode) == GET_MODE_BITSIZE (inner_mode))
|
||||
op0 = simplify_gen_subreg (mode, op0, inner_mode, 0);
|
||||
else if (GET_MODE_BITSIZE (mode) < GET_MODE_BITSIZE (inner_mode))
|
||||
op0 = simplify_gen_unary (FLOAT_TRUNCATE, mode, op0, inner_mode);
|
||||
else
|
||||
op0 = simplify_gen_unary (FLOAT_EXTEND, mode, op0, inner_mode);
|
||||
}
|
||||
else if (FLOAT_MODE_P (mode))
|
||||
gcc_unreachable ();
|
||||
else if (FLOAT_MODE_P (inner_mode))
|
||||
{
|
||||
if (TYPE_UNSIGNED (TREE_TYPE (exp)))
|
||||
op0 = simplify_gen_unary (UNSIGNED_FIX, mode, op0, inner_mode);
|
||||
else
|
||||
op0 = simplify_gen_unary (FIX, mode, op0, inner_mode);
|
||||
}
|
||||
else if (CONSTANT_P (op0)
|
||||
|| GET_MODE_BITSIZE (mode) <= GET_MODE_BITSIZE (inner_mode))
|
||||
op0 = simplify_gen_subreg (mode, op0, inner_mode,
|
||||
subreg_lowpart_offset (mode, inner_mode));
|
||||
else if (TYPE_UNSIGNED (TREE_TYPE (exp)))
|
||||
op0 = simplify_gen_unary (ZERO_EXTEND, mode, op0, inner_mode);
|
||||
else
|
||||
op0 = simplify_gen_unary (SIGN_EXTEND, mode, op0, inner_mode);
|
||||
|
||||
return op0;
|
||||
}
|
||||
|
||||
/* Expand the _LOCs in debug insns. We run this after expanding all
|
||||
regular insns, so that any variables referenced in the function
|
||||
will have their DECL_RTLs set. */
|
||||
@ -3324,7 +3455,11 @@ expand_debug_locations (void)
|
||||
val = NULL_RTX;
|
||||
else
|
||||
{
|
||||
val = expand_debug_expr (value);
|
||||
if (INSN_VAR_LOCATION_STATUS (insn)
|
||||
== VAR_INIT_STATUS_UNINITIALIZED)
|
||||
val = expand_debug_source_expr (value);
|
||||
else
|
||||
val = expand_debug_expr (value);
|
||||
gcc_assert (last == get_last_insn ());
|
||||
}
|
||||
|
||||
@ -3603,6 +3738,39 @@ expand_gimple_basic_block (basic_block bb)
|
||||
break;
|
||||
}
|
||||
|
||||
set_curr_insn_source_location (sloc);
|
||||
set_curr_insn_block (sblock);
|
||||
}
|
||||
else if (gimple_debug_source_bind_p (stmt))
|
||||
{
|
||||
location_t sloc = get_curr_insn_source_location ();
|
||||
tree sblock = get_curr_insn_block ();
|
||||
tree var = gimple_debug_source_bind_get_var (stmt);
|
||||
tree value = gimple_debug_source_bind_get_value (stmt);
|
||||
rtx val;
|
||||
enum machine_mode mode;
|
||||
|
||||
last = get_last_insn ();
|
||||
|
||||
set_curr_insn_source_location (gimple_location (stmt));
|
||||
set_curr_insn_block (gimple_block (stmt));
|
||||
|
||||
mode = DECL_MODE (var);
|
||||
|
||||
val = gen_rtx_VAR_LOCATION (mode, var, (rtx)value,
|
||||
VAR_INIT_STATUS_UNINITIALIZED);
|
||||
|
||||
emit_debug_insn (val);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
/* We can't dump the insn with a TREE where an RTX
|
||||
is expected. */
|
||||
PAT_VAR_LOCATION_LOC (val) = const0_rtx;
|
||||
maybe_dump_rtl_for_gimple_stmt (stmt, last);
|
||||
PAT_VAR_LOCATION_LOC (val) = (rtx)value;
|
||||
}
|
||||
|
||||
set_curr_insn_source_location (sloc);
|
||||
set_curr_insn_block (sblock);
|
||||
}
|
||||
|
@ -812,6 +812,10 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode memmode)
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
case DEBUG_PARAMETER_REF:
|
||||
return DEBUG_PARAMETER_REF_DECL (x)
|
||||
== DEBUG_PARAMETER_REF_DECL (y);
|
||||
|
||||
case ENTRY_VALUE:
|
||||
/* ENTRY_VALUEs are function invariant, it is thus undesirable to
|
||||
use rtx_equal_for_cselib_1 to compare the operands. */
|
||||
@ -963,6 +967,11 @@ cselib_hash_rtx (rtx x, int create, enum machine_mode memmode)
|
||||
+ DECL_UID (DEBUG_IMPLICIT_PTR_DECL (x));
|
||||
return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR;
|
||||
|
||||
case DEBUG_PARAMETER_REF:
|
||||
hash += ((unsigned) DEBUG_PARAMETER_REF << 7)
|
||||
+ DECL_UID (DEBUG_PARAMETER_REF_DECL (x));
|
||||
return hash ? hash : (unsigned int) DEBUG_PARAMETER_REF;
|
||||
|
||||
case ENTRY_VALUE:
|
||||
/* ENTRY_VALUEs are function invariant, thus try to avoid
|
||||
recursing on argument if ENTRY_VALUE is one of the
|
||||
|
@ -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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Pretty formatting of GIMPLE statements and expressions.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com> and
|
||||
Diego Novillo <dnovillo@google.com>
|
||||
|
||||
@ -966,6 +966,17 @@ dump_gimple_debug (pretty_printer *buffer, gimple gs, int spc, int flags)
|
||||
gimple_debug_bind_get_value (gs));
|
||||
break;
|
||||
|
||||
case GIMPLE_DEBUG_SOURCE_BIND:
|
||||
if (flags & TDF_RAW)
|
||||
dump_gimple_fmt (buffer, spc, flags, "%G SRCBIND <%T, %T>", gs,
|
||||
gimple_debug_source_bind_get_var (gs),
|
||||
gimple_debug_source_bind_get_value (gs));
|
||||
else
|
||||
dump_gimple_fmt (buffer, spc, flags, "# DEBUG %T s=> %T",
|
||||
gimple_debug_source_bind_get_var (gs),
|
||||
gimple_debug_source_bind_get_value (gs));
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
26
gcc/gimple.c
26
gcc/gimple.c
@ -1,6 +1,6 @@
|
||||
/* Gimple IR support functions.
|
||||
|
||||
Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -866,6 +866,30 @@ gimple_build_debug_bind_stat (tree var, tree value, gimple stmt MEM_STAT_DECL)
|
||||
}
|
||||
|
||||
|
||||
/* Build a new GIMPLE_DEBUG_SOURCE_BIND statement.
|
||||
|
||||
VAR is bound to VALUE; block and location are taken from STMT. */
|
||||
|
||||
gimple
|
||||
gimple_build_debug_source_bind_stat (tree var, tree value,
|
||||
gimple stmt MEM_STAT_DECL)
|
||||
{
|
||||
gimple p = gimple_build_with_ops_stat (GIMPLE_DEBUG,
|
||||
(unsigned)GIMPLE_DEBUG_SOURCE_BIND, 2
|
||||
PASS_MEM_STAT);
|
||||
|
||||
gimple_debug_source_bind_set_var (p, var);
|
||||
gimple_debug_source_bind_set_value (p, value);
|
||||
if (stmt)
|
||||
{
|
||||
gimple_set_block (p, gimple_block (stmt));
|
||||
gimple_set_location (p, gimple_location (stmt));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Build a GIMPLE_OMP_CRITICAL statement.
|
||||
|
||||
BODY is the sequence of statements for which only one thread can execute.
|
||||
|
74
gcc/gimple.h
74
gcc/gimple.h
@ -1,6 +1,6 @@
|
||||
/* Gimple IR definitions.
|
||||
|
||||
Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -117,12 +117,13 @@ enum gf_mask {
|
||||
GF_PREDICT_TAKEN = 1 << 15
|
||||
};
|
||||
|
||||
/* Currently, there's only one type of gimple debug stmt. Others are
|
||||
/* Currently, there are only two types of gimple debug stmt. Others are
|
||||
envisioned, for example, to enable the generation of is_stmt notes
|
||||
in line number information, to mark sequence points, etc. This
|
||||
subcode is to be used to tell them apart. */
|
||||
enum gimple_debug_subcode {
|
||||
GIMPLE_DEBUG_BIND = 0
|
||||
GIMPLE_DEBUG_BIND = 0,
|
||||
GIMPLE_DEBUG_SOURCE_BIND = 1
|
||||
};
|
||||
|
||||
/* Masks for selecting a pass local flag (PLF) to work on. These
|
||||
@ -823,6 +824,9 @@ gimple gimple_build_assign_with_ops_stat (enum tree_code, tree, tree,
|
||||
gimple gimple_build_debug_bind_stat (tree, tree, gimple MEM_STAT_DECL);
|
||||
#define gimple_build_debug_bind(var,val,stmt) \
|
||||
gimple_build_debug_bind_stat ((var), (val), (stmt) MEM_STAT_INFO)
|
||||
gimple gimple_build_debug_source_bind_stat (tree, tree, gimple MEM_STAT_DECL);
|
||||
#define gimple_build_debug_source_bind(var,val,stmt) \
|
||||
gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO)
|
||||
|
||||
gimple gimple_build_call_vec (tree, VEC(tree, heap) *);
|
||||
gimple gimple_build_call (tree, unsigned, ...);
|
||||
@ -3583,6 +3587,70 @@ gimple_debug_bind_has_value_p (gimple dbg)
|
||||
|
||||
#undef GIMPLE_DEBUG_BIND_NOVALUE
|
||||
|
||||
/* Return true if S is a GIMPLE_DEBUG SOURCE BIND statement. */
|
||||
|
||||
static inline bool
|
||||
gimple_debug_source_bind_p (const_gimple s)
|
||||
{
|
||||
if (is_gimple_debug (s))
|
||||
return s->gsbase.subcode == GIMPLE_DEBUG_SOURCE_BIND;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Return the variable bound in a GIMPLE_DEBUG source bind statement. */
|
||||
|
||||
static inline tree
|
||||
gimple_debug_source_bind_get_var (gimple dbg)
|
||||
{
|
||||
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
|
||||
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
|
||||
return gimple_op (dbg, 0);
|
||||
}
|
||||
|
||||
/* Return the value bound to the variable in a GIMPLE_DEBUG source bind
|
||||
statement. */
|
||||
|
||||
static inline tree
|
||||
gimple_debug_source_bind_get_value (gimple dbg)
|
||||
{
|
||||
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
|
||||
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
|
||||
return gimple_op (dbg, 1);
|
||||
}
|
||||
|
||||
/* Return a pointer to the value bound to the variable in a
|
||||
GIMPLE_DEBUG source bind statement. */
|
||||
|
||||
static inline tree *
|
||||
gimple_debug_source_bind_get_value_ptr (gimple dbg)
|
||||
{
|
||||
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
|
||||
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
|
||||
return gimple_op_ptr (dbg, 1);
|
||||
}
|
||||
|
||||
/* Set the variable bound in a GIMPLE_DEBUG source bind statement. */
|
||||
|
||||
static inline void
|
||||
gimple_debug_source_bind_set_var (gimple dbg, tree var)
|
||||
{
|
||||
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
|
||||
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
|
||||
gimple_set_op (dbg, 0, var);
|
||||
}
|
||||
|
||||
/* Set the value bound to the variable in a GIMPLE_DEBUG source bind
|
||||
statement. */
|
||||
|
||||
static inline void
|
||||
gimple_debug_source_bind_set_value (gimple dbg, tree value)
|
||||
{
|
||||
GIMPLE_CHECK (dbg, GIMPLE_DEBUG);
|
||||
gcc_gimple_checking_assert (gimple_debug_source_bind_p (dbg));
|
||||
gimple_set_op (dbg, 1, value);
|
||||
}
|
||||
|
||||
/* Return the body for the OMP statement GS. */
|
||||
|
||||
static inline gimple_seq
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Interprocedural analyses.
|
||||
Copyright (C) 2005, 2007, 2008, 2009, 2010
|
||||
Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -2393,6 +2393,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||
ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
VEC(tree, heap) *vargs;
|
||||
VEC(tree, gc) **debug_args = NULL;
|
||||
gimple new_stmt;
|
||||
gimple_stmt_iterator gsi;
|
||||
tree callee_decl;
|
||||
@ -2400,6 +2401,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||
|
||||
len = VEC_length (ipa_parm_adjustment_t, adjustments);
|
||||
vargs = VEC_alloc (tree, heap, len);
|
||||
callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
|
||||
|
||||
gsi = gsi_for_stmt (stmt);
|
||||
for (i = 0; i < len; i++)
|
||||
@ -2490,6 +2492,42 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||
NULL, true, GSI_SAME_STMT);
|
||||
VEC_quick_push (tree, vargs, expr);
|
||||
}
|
||||
if (!adj->copy_param && MAY_HAVE_DEBUG_STMTS)
|
||||
{
|
||||
unsigned int ix;
|
||||
tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
|
||||
gimple def_temp;
|
||||
|
||||
arg = gimple_call_arg (stmt, adj->base_index);
|
||||
if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
|
||||
{
|
||||
if (!fold_convertible_p (TREE_TYPE (origin), arg))
|
||||
continue;
|
||||
arg = fold_convert_loc (gimple_location (stmt),
|
||||
TREE_TYPE (origin), arg);
|
||||
}
|
||||
if (debug_args == NULL)
|
||||
debug_args = decl_debug_args_insert (callee_decl);
|
||||
for (ix = 0; VEC_iterate (tree, *debug_args, ix, ddecl); ix += 2)
|
||||
if (ddecl == origin)
|
||||
{
|
||||
ddecl = VEC_index (tree, *debug_args, ix + 1);
|
||||
break;
|
||||
}
|
||||
if (ddecl == NULL)
|
||||
{
|
||||
ddecl = make_node (DEBUG_EXPR_DECL);
|
||||
DECL_ARTIFICIAL (ddecl) = 1;
|
||||
TREE_TYPE (ddecl) = TREE_TYPE (origin);
|
||||
DECL_MODE (ddecl) = DECL_MODE (origin);
|
||||
|
||||
VEC_safe_push (tree, gc, *debug_args, origin);
|
||||
VEC_safe_push (tree, gc, *debug_args, ddecl);
|
||||
}
|
||||
def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg),
|
||||
stmt);
|
||||
gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
|
||||
}
|
||||
}
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
@ -2498,7 +2536,6 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||
print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, 0);
|
||||
}
|
||||
|
||||
callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
|
||||
new_stmt = gimple_build_call_vec (callee_decl, vargs);
|
||||
VEC_free (tree, heap, vargs);
|
||||
if (gimple_call_lhs (stmt))
|
||||
|
@ -552,6 +552,8 @@ print_rtx (const_rtx in_rtx)
|
||||
#ifndef GENERATOR_FILE
|
||||
if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
|
||||
print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
|
||||
else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
|
||||
print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
|
||||
else
|
||||
dump_addr (outfile, " ", XTREE (in_rtx, i));
|
||||
#endif
|
||||
|
@ -413,6 +413,10 @@ rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
case DEBUG_PARAMETER_REF:
|
||||
return DEBUG_PARAMETER_REF_DECL (x)
|
||||
== DEBUG_PARAMETER_REF_DECL (x);
|
||||
|
||||
case ENTRY_VALUE:
|
||||
return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
|
||||
|
||||
@ -548,6 +552,10 @@ rtx_equal_p (const_rtx x, const_rtx y)
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
case DEBUG_PARAMETER_REF:
|
||||
return DEBUG_PARAMETER_REF_DECL (x)
|
||||
== DEBUG_PARAMETER_REF_DECL (y);
|
||||
|
||||
case ENTRY_VALUE:
|
||||
return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
|
||||
|
||||
@ -660,6 +668,7 @@ iterative_hash_rtx (const_rtx x, hashval_t hash)
|
||||
case CONST_DOUBLE:
|
||||
case CONST_FIXED:
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
case DEBUG_PARAMETER_REF:
|
||||
return hash;
|
||||
default:
|
||||
break;
|
||||
|
@ -727,6 +727,10 @@ DEF_RTL_EXPR(DEBUG_IMPLICIT_PTR, "debug_implicit_ptr", "t", RTX_OBJ)
|
||||
parameter. */
|
||||
DEF_RTL_EXPR(ENTRY_VALUE, "entry_value", "0", RTX_OBJ)
|
||||
|
||||
/* Used in VAR_LOCATION for a reference to a parameter that has
|
||||
been optimized away completely. */
|
||||
DEF_RTL_EXPR(DEBUG_PARAMETER_REF, "debug_parameter_ref", "t", RTX_OBJ)
|
||||
|
||||
/* All expressions from this point forward appear only in machine
|
||||
descriptions. */
|
||||
#ifdef GENERATOR_FILE
|
||||
|
@ -941,6 +941,9 @@ extern const char * const reg_note_name[];
|
||||
/* VAR_DECL/PARM_DECL DEBUG_IMPLICIT_PTR takes address of. */
|
||||
#define DEBUG_IMPLICIT_PTR_DECL(RTX) XCTREE (RTX, 0, DEBUG_IMPLICIT_PTR)
|
||||
|
||||
/* PARM_DECL DEBUG_PARAMETER_REF references. */
|
||||
#define DEBUG_PARAMETER_REF_DECL(RTX) XCTREE (RTX, 0, DEBUG_PARAMETER_REF)
|
||||
|
||||
/* Possible initialization status of a variable. When requested
|
||||
by the user, this information is tracked and recorded in the DWARF
|
||||
debug information, along with the variable's location. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Single entry single exit control flow regions.
|
||||
Copyright (C) 2008, 2009, 2010
|
||||
Copyright (C) 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Jan Sjodin <jan.sjodin@amd.com> and
|
||||
Sebastian Pop <sebastian.pop@amd.com>.
|
||||
@ -472,6 +472,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
|
||||
{
|
||||
if (gimple_debug_bind_p (copy))
|
||||
gimple_debug_bind_reset_value (copy);
|
||||
else if (gimple_debug_source_bind_p (copy))
|
||||
return false;
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Tree inlining.
|
||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
@ -188,6 +188,33 @@ remap_ssa_name (tree name, copy_body_data *id)
|
||||
|
||||
if (processing_debug_stmt)
|
||||
{
|
||||
if (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL
|
||||
&& SSA_NAME_IS_DEFAULT_DEF (name)
|
||||
&& id->entry_bb == NULL
|
||||
&& single_succ_p (ENTRY_BLOCK_PTR))
|
||||
{
|
||||
tree vexpr = make_node (DEBUG_EXPR_DECL);
|
||||
gimple def_temp;
|
||||
gimple_stmt_iterator gsi;
|
||||
tree val = SSA_NAME_VAR (name);
|
||||
|
||||
n = (tree *) pointer_map_contains (id->decl_map, val);
|
||||
if (n != NULL)
|
||||
val = *n;
|
||||
if (TREE_CODE (val) != PARM_DECL)
|
||||
{
|
||||
processing_debug_stmt = -1;
|
||||
return name;
|
||||
}
|
||||
def_temp = gimple_build_debug_source_bind (vexpr, val, NULL);
|
||||
DECL_ARTIFICIAL (vexpr) = 1;
|
||||
TREE_TYPE (vexpr) = TREE_TYPE (name);
|
||||
DECL_MODE (vexpr) = DECL_MODE (SSA_NAME_VAR (name));
|
||||
gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
|
||||
gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
|
||||
return vexpr;
|
||||
}
|
||||
|
||||
processing_debug_stmt = -1;
|
||||
return name;
|
||||
}
|
||||
@ -1403,6 +1430,14 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
|
||||
VEC_safe_push (gimple, heap, id->debug_stmts, copy);
|
||||
return copy;
|
||||
}
|
||||
if (gimple_debug_source_bind_p (stmt))
|
||||
{
|
||||
copy = gimple_build_debug_source_bind
|
||||
(gimple_debug_source_bind_get_var (stmt),
|
||||
gimple_debug_source_bind_get_value (stmt), stmt);
|
||||
VEC_safe_push (gimple, heap, id->debug_stmts, copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/* Create a new deep copy of the statement. */
|
||||
copy = gimple_copy (stmt);
|
||||
@ -1478,7 +1513,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
|
||||
|
||||
gimple_set_block (copy, new_block);
|
||||
|
||||
if (gimple_debug_bind_p (copy))
|
||||
if (gimple_debug_bind_p (copy) || gimple_debug_source_bind_p (copy))
|
||||
return copy;
|
||||
|
||||
/* Remap all the operands in COPY. */
|
||||
@ -2151,22 +2186,33 @@ maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
|
||||
{
|
||||
si = ssi;
|
||||
gsi_prev (&ssi);
|
||||
if (!single_pred_p (e->dest))
|
||||
if (!single_pred_p (e->dest) && gimple_debug_bind_p (stmt))
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
gsi_remove (&si, false);
|
||||
gsi_insert_before (&dsi, stmt, GSI_SAME_STMT);
|
||||
continue;
|
||||
}
|
||||
|
||||
var = gimple_debug_bind_get_var (stmt);
|
||||
if (single_pred_p (e->dest))
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
{
|
||||
value = gimple_debug_bind_get_value (stmt);
|
||||
value = unshare_expr (value);
|
||||
var = gimple_debug_bind_get_var (stmt);
|
||||
if (single_pred_p (e->dest))
|
||||
{
|
||||
value = gimple_debug_bind_get_value (stmt);
|
||||
value = unshare_expr (value);
|
||||
}
|
||||
else
|
||||
value = NULL_TREE;
|
||||
new_stmt = gimple_build_debug_bind (var, value, stmt);
|
||||
}
|
||||
else if (gimple_debug_source_bind_p (stmt))
|
||||
{
|
||||
var = gimple_debug_source_bind_get_var (stmt);
|
||||
value = gimple_debug_source_bind_get_value (stmt);
|
||||
new_stmt = gimple_build_debug_source_bind (var, value, stmt);
|
||||
}
|
||||
else
|
||||
value = NULL_TREE;
|
||||
new_stmt = gimple_build_debug_bind (var, value, stmt);
|
||||
gcc_unreachable ();
|
||||
gsi_insert_before (&dsi, new_stmt, GSI_SAME_STMT);
|
||||
VEC_safe_push (gimple, heap, id->debug_stmts, new_stmt);
|
||||
gsi_prev (&ssi);
|
||||
@ -2317,7 +2363,6 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
|
||||
t = id->block;
|
||||
if (gimple_block (stmt))
|
||||
{
|
||||
tree *n;
|
||||
n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt));
|
||||
if (n)
|
||||
t = *n;
|
||||
@ -2330,7 +2375,10 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
|
||||
|
||||
processing_debug_stmt = 1;
|
||||
|
||||
t = gimple_debug_bind_get_var (stmt);
|
||||
if (gimple_debug_source_bind_p (stmt))
|
||||
t = gimple_debug_source_bind_get_var (stmt);
|
||||
else
|
||||
t = gimple_debug_bind_get_var (stmt);
|
||||
|
||||
if (TREE_CODE (t) == PARM_DECL && id->debug_map
|
||||
&& (n = (tree *) pointer_map_contains (id->debug_map, t)))
|
||||
@ -2347,15 +2395,24 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
|
||||
else
|
||||
walk_tree (&t, remap_gimple_op_r, &wi, NULL);
|
||||
|
||||
gimple_debug_bind_set_var (stmt, t);
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
{
|
||||
gimple_debug_bind_set_var (stmt, t);
|
||||
|
||||
if (gimple_debug_bind_has_value_p (stmt))
|
||||
walk_tree (gimple_debug_bind_get_value_ptr (stmt),
|
||||
remap_gimple_op_r, &wi, NULL);
|
||||
if (gimple_debug_bind_has_value_p (stmt))
|
||||
walk_tree (gimple_debug_bind_get_value_ptr (stmt),
|
||||
remap_gimple_op_r, &wi, NULL);
|
||||
|
||||
/* Punt if any decl couldn't be remapped. */
|
||||
if (processing_debug_stmt < 0)
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
/* Punt if any decl couldn't be remapped. */
|
||||
if (processing_debug_stmt < 0)
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
}
|
||||
else if (gimple_debug_source_bind_p (stmt))
|
||||
{
|
||||
gimple_debug_source_bind_set_var (stmt, t);
|
||||
walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
|
||||
remap_gimple_op_r, &wi, NULL);
|
||||
}
|
||||
|
||||
processing_debug_stmt = 0;
|
||||
|
||||
@ -5001,6 +5058,20 @@ tree_function_versioning (tree old_decl, tree new_decl,
|
||||
new_version_node = cgraph_get_node (new_decl);
|
||||
gcc_checking_assert (new_version_node);
|
||||
|
||||
/* Copy over debug args. */
|
||||
if (DECL_HAS_DEBUG_ARGS_P (old_decl))
|
||||
{
|
||||
VEC(tree, gc) **new_debug_args, **old_debug_args;
|
||||
gcc_checking_assert (decl_debug_args_lookup (new_decl) == NULL);
|
||||
DECL_HAS_DEBUG_ARGS_P (new_decl) = 0;
|
||||
old_debug_args = decl_debug_args_lookup (old_decl);
|
||||
if (old_debug_args)
|
||||
{
|
||||
new_debug_args = decl_debug_args_insert (new_decl);
|
||||
*new_debug_args = VEC_copy (tree, gc, *old_debug_args);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output the inlining info for this abstract function, since it has been
|
||||
inlined. If we don't do this now, we can lose the information about the
|
||||
variables in the function when the blocks get blown away as soon as we
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Rewrite a program in Normal form into SSA.
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
@ -745,7 +745,17 @@ mark_def_sites (basic_block bb, gimple stmt, bitmap kills)
|
||||
set_rewrite_uses (stmt, false);
|
||||
|
||||
if (is_gimple_debug (stmt))
|
||||
return;
|
||||
{
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree sym = USE_FROM_PTR (use_p);
|
||||
gcc_assert (DECL_P (sym));
|
||||
set_rewrite_uses (stmt, true);
|
||||
}
|
||||
if (rewrite_uses_p (stmt))
|
||||
SET_BIT (interesting_blocks, bb->index);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If a variable is used before being set, then the variable is live
|
||||
across a block boundary, so mark it live-on-entry to BB. */
|
||||
@ -1279,6 +1289,73 @@ get_reaching_def (tree var)
|
||||
}
|
||||
|
||||
|
||||
/* Helper function for rewrite_stmt. Rewrite uses in a debug stmt. */
|
||||
|
||||
static void
|
||||
rewrite_debug_stmt_uses (gimple stmt)
|
||||
{
|
||||
use_operand_p use_p;
|
||||
ssa_op_iter iter;
|
||||
bool update = false;
|
||||
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree var = USE_FROM_PTR (use_p), def = NULL_TREE;
|
||||
gcc_assert (DECL_P (var));
|
||||
if (var_ann (var) == NULL)
|
||||
{
|
||||
if (TREE_CODE (var) == PARM_DECL && single_succ_p (ENTRY_BLOCK_PTR))
|
||||
{
|
||||
gimple_stmt_iterator gsi
|
||||
= gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
|
||||
int lim;
|
||||
/* Search a few source bind stmts at the start of first bb to
|
||||
see if a DEBUG_EXPR_DECL can't be reused. */
|
||||
for (lim = 32;
|
||||
!gsi_end_p (gsi) && lim > 0;
|
||||
gsi_next (&gsi), lim--)
|
||||
{
|
||||
gimple gstmt = gsi_stmt (gsi);
|
||||
if (!gimple_debug_source_bind_p (gstmt))
|
||||
break;
|
||||
if (gimple_debug_source_bind_get_value (gstmt) == var)
|
||||
{
|
||||
def = gimple_debug_source_bind_get_var (gstmt);
|
||||
if (TREE_CODE (def) == DEBUG_EXPR_DECL)
|
||||
break;
|
||||
else
|
||||
def = NULL_TREE;
|
||||
}
|
||||
}
|
||||
/* If not, add a new source bind stmt. */
|
||||
if (def == NULL_TREE)
|
||||
{
|
||||
gimple def_temp;
|
||||
def = make_node (DEBUG_EXPR_DECL);
|
||||
def_temp = gimple_build_debug_source_bind (def, var, NULL);
|
||||
DECL_ARTIFICIAL (def) = 1;
|
||||
TREE_TYPE (def) = TREE_TYPE (var);
|
||||
DECL_MODE (def) = DECL_MODE (var);
|
||||
gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
|
||||
gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
|
||||
}
|
||||
update = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
def = get_current_def (var);
|
||||
if (def == NULL)
|
||||
{
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
update_stmt (stmt);
|
||||
return;
|
||||
}
|
||||
SET_USE (use_p, def);
|
||||
}
|
||||
if (update)
|
||||
update_stmt (stmt);
|
||||
}
|
||||
|
||||
/* SSA Rewriting Step 2. Rewrite every variable used in each statement in
|
||||
the block with its immediate reaching definitions. Update the current
|
||||
definition of a variable when a new real or virtual definition is found. */
|
||||
@ -1306,12 +1383,17 @@ rewrite_stmt (gimple_stmt_iterator si)
|
||||
|
||||
/* Step 1. Rewrite USES in the statement. */
|
||||
if (rewrite_uses_p (stmt))
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree var = USE_FROM_PTR (use_p);
|
||||
gcc_assert (DECL_P (var));
|
||||
SET_USE (use_p, get_reaching_def (var));
|
||||
}
|
||||
{
|
||||
if (is_gimple_debug (stmt))
|
||||
rewrite_debug_stmt_uses (stmt);
|
||||
else
|
||||
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
|
||||
{
|
||||
tree var = USE_FROM_PTR (use_p);
|
||||
gcc_assert (DECL_P (var));
|
||||
SET_USE (use_p, get_reaching_def (var));
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2. Register the statement's DEF operands. */
|
||||
if (register_defs_p (stmt))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Loop autoparallelization.
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010
|
||||
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <pop@cri.ensmp.fr> and
|
||||
Zdenek Dvorak <dvorakz@suse.cz>.
|
||||
@ -716,8 +716,11 @@ eliminate_local_variables (edge entry, edge exit)
|
||||
FOR_EACH_VEC_ELT (basic_block, body, i, bb)
|
||||
if (bb != entry_bb && bb != exit_bb)
|
||||
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
if (gimple_debug_bind_p (gsi_stmt (gsi)))
|
||||
has_debug_stmt = true;
|
||||
if (is_gimple_debug (gsi_stmt (gsi)))
|
||||
{
|
||||
if (gimple_debug_bind_p (gsi_stmt (gsi)))
|
||||
has_debug_stmt = true;
|
||||
}
|
||||
else
|
||||
eliminate_local_variables_stmt (entry, &gsi, decl_address);
|
||||
|
||||
@ -883,8 +886,8 @@ separate_decls_in_region_stmt (edge entry, edge exit, gimple stmt,
|
||||
replacement decls are stored in DECL_COPIES. */
|
||||
|
||||
static bool
|
||||
separate_decls_in_region_debug_bind (gimple stmt,
|
||||
htab_t name_copies, htab_t decl_copies)
|
||||
separate_decls_in_region_debug (gimple stmt, htab_t name_copies,
|
||||
htab_t decl_copies)
|
||||
{
|
||||
use_operand_p use;
|
||||
ssa_op_iter oi;
|
||||
@ -893,7 +896,12 @@ separate_decls_in_region_debug_bind (gimple stmt,
|
||||
struct name_to_copy_elt elt;
|
||||
void **slot, **dslot;
|
||||
|
||||
var = gimple_debug_bind_get_var (stmt);
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
var = gimple_debug_bind_get_var (stmt);
|
||||
else if (gimple_debug_source_bind_p (stmt))
|
||||
var = gimple_debug_source_bind_get_var (stmt);
|
||||
else
|
||||
return true;
|
||||
if (TREE_CODE (var) == DEBUG_EXPR_DECL)
|
||||
return true;
|
||||
gcc_assert (DECL_P (var) && SSA_VAR_P (var));
|
||||
@ -901,7 +909,10 @@ separate_decls_in_region_debug_bind (gimple stmt,
|
||||
dslot = htab_find_slot_with_hash (decl_copies, &ielt, ielt.uid, NO_INSERT);
|
||||
if (!dslot)
|
||||
return true;
|
||||
gimple_debug_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to);
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
gimple_debug_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to);
|
||||
else if (gimple_debug_source_bind_p (stmt))
|
||||
gimple_debug_source_bind_set_var (stmt, ((struct int_tree_map *) *dslot)->to);
|
||||
|
||||
FOR_EACH_PHI_OR_STMT_USE (use, stmt, oi, SSA_OP_USE)
|
||||
{
|
||||
@ -1295,11 +1306,10 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
|
||||
{
|
||||
gimple stmt = gsi_stmt (gsi);
|
||||
|
||||
if (gimple_debug_bind_p (stmt))
|
||||
if (is_gimple_debug (stmt))
|
||||
{
|
||||
if (separate_decls_in_region_debug_bind (stmt,
|
||||
name_copies,
|
||||
decl_copies))
|
||||
if (separate_decls_in_region_debug (stmt, name_copies,
|
||||
decl_copies))
|
||||
{
|
||||
gsi_remove (&gsi, true);
|
||||
continue;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Scalar Replacement of Aggregates (SRA) converts some structure
|
||||
references into scalar references, exposing them to the scalar
|
||||
optimizers.
|
||||
Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
Contributed by Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
This file is part of GCC.
|
||||
@ -4282,28 +4282,87 @@ static void
|
||||
sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
int i, len;
|
||||
gimple_stmt_iterator *gsip = NULL, gsi;
|
||||
|
||||
if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR))
|
||||
{
|
||||
gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
|
||||
gsip = &gsi;
|
||||
}
|
||||
len = VEC_length (ipa_parm_adjustment_t, adjustments);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
struct ipa_parm_adjustment *adj;
|
||||
imm_use_iterator ui;
|
||||
gimple stmt;
|
||||
tree name;
|
||||
gimple stmt, def_temp;
|
||||
tree name, vexpr, copy = NULL_TREE;
|
||||
use_operand_p use_p;
|
||||
|
||||
adj = VEC_index (ipa_parm_adjustment_t, adjustments, i);
|
||||
if (adj->copy_param || !is_gimple_reg (adj->base))
|
||||
continue;
|
||||
name = gimple_default_def (cfun, adj->base);
|
||||
if (!name)
|
||||
continue;
|
||||
FOR_EACH_IMM_USE_STMT (stmt, ui, name)
|
||||
vexpr = NULL;
|
||||
if (name)
|
||||
FOR_EACH_IMM_USE_STMT (stmt, ui, name)
|
||||
{
|
||||
/* All other users must have been removed by
|
||||
ipa_sra_modify_function_body. */
|
||||
gcc_assert (is_gimple_debug (stmt));
|
||||
if (vexpr == NULL && gsip != NULL)
|
||||
{
|
||||
gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
|
||||
vexpr = make_node (DEBUG_EXPR_DECL);
|
||||
def_temp = gimple_build_debug_source_bind (vexpr, adj->base,
|
||||
NULL);
|
||||
DECL_ARTIFICIAL (vexpr) = 1;
|
||||
TREE_TYPE (vexpr) = TREE_TYPE (name);
|
||||
DECL_MODE (vexpr) = DECL_MODE (adj->base);
|
||||
gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
|
||||
}
|
||||
if (vexpr)
|
||||
{
|
||||
FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
|
||||
SET_USE (use_p, vexpr);
|
||||
}
|
||||
else
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
update_stmt (stmt);
|
||||
}
|
||||
/* Create a VAR_DECL for debug info purposes. */
|
||||
if (!DECL_IGNORED_P (adj->base))
|
||||
{
|
||||
/* All other users must have been removed by
|
||||
ipa_sra_modify_function_body. */
|
||||
gcc_assert (is_gimple_debug (stmt));
|
||||
gimple_debug_bind_reset_value (stmt);
|
||||
update_stmt (stmt);
|
||||
copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
|
||||
VAR_DECL, DECL_NAME (adj->base),
|
||||
TREE_TYPE (adj->base));
|
||||
if (DECL_PT_UID_SET_P (adj->base))
|
||||
SET_DECL_PT_UID (copy, DECL_PT_UID (adj->base));
|
||||
TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (adj->base);
|
||||
TREE_READONLY (copy) = TREE_READONLY (adj->base);
|
||||
TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (adj->base);
|
||||
DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (adj->base);
|
||||
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (adj->base);
|
||||
DECL_IGNORED_P (copy) = DECL_IGNORED_P (adj->base);
|
||||
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (adj->base);
|
||||
DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
|
||||
SET_DECL_RTL (copy, 0);
|
||||
TREE_USED (copy) = 1;
|
||||
DECL_CONTEXT (copy) = current_function_decl;
|
||||
add_referenced_var (copy);
|
||||
add_local_decl (cfun, copy);
|
||||
DECL_CHAIN (copy) =
|
||||
BLOCK_VARS (DECL_INITIAL (current_function_decl));
|
||||
BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
|
||||
}
|
||||
if (gsip != NULL && copy && target_for_debug_bind (adj->base))
|
||||
{
|
||||
gcc_assert (TREE_CODE (adj->base) == PARM_DECL);
|
||||
if (vexpr)
|
||||
def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
|
||||
else
|
||||
def_temp = gimple_build_debug_source_bind (copy, adj->base,
|
||||
NULL);
|
||||
gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Dead code elimination pass for the GNU compiler.
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
Contributed by Ben Elliston <bje@redhat.com>
|
||||
and Andrew MacLeod <amacleod@redhat.com>
|
||||
@ -316,7 +316,8 @@ mark_stmt_if_obviously_necessary (gimple stmt, bool aggressive)
|
||||
easily locate the debug temp bind stmt for a use thereof,
|
||||
would could refrain from marking all debug temps here, and
|
||||
mark them only if they're used. */
|
||||
if (gimple_debug_bind_has_value_p (stmt)
|
||||
if (!gimple_debug_bind_p (stmt)
|
||||
|| gimple_debug_bind_has_value_p (stmt)
|
||||
|| TREE_CODE (gimple_debug_bind_get_var (stmt)) != DEBUG_EXPR_DECL)
|
||||
mark_stmt_necessary (stmt, false);
|
||||
return;
|
||||
|
46
gcc/tree.c
46
gcc/tree.c
@ -203,6 +203,9 @@ static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_ma
|
||||
static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
|
||||
htab_t value_expr_for_decl;
|
||||
|
||||
static GTY ((if_marked ("tree_vec_map_marked_p"), param_is (struct tree_vec_map)))
|
||||
htab_t debug_args_for_decl;
|
||||
|
||||
static GTY ((if_marked ("tree_priority_map_marked_p"),
|
||||
param_is (struct tree_priority_map)))
|
||||
htab_t init_priority_for_decl;
|
||||
@ -6016,6 +6019,49 @@ decl_value_expr_insert (tree from, tree to)
|
||||
*(struct tree_decl_map **) loc = h;
|
||||
}
|
||||
|
||||
/* Lookup a vector of debug arguments for FROM, and return it if we
|
||||
find one. */
|
||||
|
||||
VEC(tree, gc) **
|
||||
decl_debug_args_lookup (tree from)
|
||||
{
|
||||
struct tree_vec_map *h, in;
|
||||
|
||||
if (!DECL_HAS_DEBUG_ARGS_P (from))
|
||||
return NULL;
|
||||
gcc_checking_assert (debug_args_for_decl != NULL);
|
||||
in.base.from = from;
|
||||
h = (struct tree_vec_map *)
|
||||
htab_find_with_hash (debug_args_for_decl, &in, DECL_UID (from));
|
||||
if (h)
|
||||
return &h->to;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Insert a mapping FROM->empty vector of debug arguments in the value
|
||||
expression hashtable. */
|
||||
|
||||
VEC(tree, gc) **
|
||||
decl_debug_args_insert (tree from)
|
||||
{
|
||||
struct tree_vec_map *h;
|
||||
void **loc;
|
||||
|
||||
if (DECL_HAS_DEBUG_ARGS_P (from))
|
||||
return decl_debug_args_lookup (from);
|
||||
if (debug_args_for_decl == NULL)
|
||||
debug_args_for_decl = htab_create_ggc (64, tree_vec_map_hash,
|
||||
tree_vec_map_eq, 0);
|
||||
h = ggc_alloc_tree_vec_map ();
|
||||
h->base.from = from;
|
||||
h->to = NULL;
|
||||
loc = htab_find_slot_with_hash (debug_args_for_decl, h, DECL_UID (from),
|
||||
INSERT);
|
||||
*(struct tree_vec_map **) loc = h;
|
||||
DECL_HAS_DEBUG_ARGS_P (from) = 1;
|
||||
return &h->to;
|
||||
}
|
||||
|
||||
/* Hashing of types so that we don't make duplicates.
|
||||
The entry point is `type_hash_canon'. */
|
||||
|
||||
|
26
gcc/tree.h
26
gcc/tree.h
@ -1,6 +1,6 @@
|
||||
/* Front-end tree definitions for GNU compiler.
|
||||
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
@ -3431,6 +3431,13 @@ struct GTY(())
|
||||
#define DECL_DISREGARD_INLINE_LIMITS(NODE) \
|
||||
(FUNCTION_DECL_CHECK (NODE)->function_decl.disregard_inline_limits)
|
||||
|
||||
extern VEC(tree, gc) **decl_debug_args_lookup (tree);
|
||||
extern VEC(tree, gc) **decl_debug_args_insert (tree);
|
||||
|
||||
/* Nonzero if a FUNCTION_DECL has DEBUG arguments attached to it. */
|
||||
#define DECL_HAS_DEBUG_ARGS_P(NODE) \
|
||||
(FUNCTION_DECL_CHECK (NODE)->function_decl.has_debug_args_flag)
|
||||
|
||||
/* For FUNCTION_DECL, this holds a pointer to a structure ("struct function")
|
||||
that describes the status of this function. */
|
||||
#define DECL_STRUCT_FUNCTION(NODE) \
|
||||
@ -3496,16 +3503,16 @@ struct GTY(()) tree_function_decl {
|
||||
unsigned operator_new_flag : 1;
|
||||
unsigned declared_inline_flag : 1;
|
||||
unsigned regdecl_flag : 1;
|
||||
|
||||
unsigned no_inline_warning_flag : 1;
|
||||
|
||||
unsigned no_instrument_function_entry_exit : 1;
|
||||
unsigned no_limit_stack : 1;
|
||||
unsigned disregard_inline_limits : 1;
|
||||
unsigned pure_flag : 1;
|
||||
unsigned looping_const_or_pure_flag : 1;
|
||||
unsigned has_debug_args_flag : 1;
|
||||
|
||||
|
||||
/* 3 bits left */
|
||||
/* 2 bits left */
|
||||
};
|
||||
|
||||
/* The source language of the translation-unit. */
|
||||
@ -5742,6 +5749,17 @@ struct GTY(()) tree_priority_map {
|
||||
#define tree_priority_map_hash tree_map_base_hash
|
||||
#define tree_priority_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* Map from a decl tree to a tree vector. */
|
||||
|
||||
struct GTY(()) tree_vec_map {
|
||||
struct tree_map_base base;
|
||||
VEC(tree,gc) *to;
|
||||
};
|
||||
|
||||
#define tree_vec_map_eq tree_map_base_eq
|
||||
#define tree_vec_map_hash tree_decl_map_hash
|
||||
#define tree_vec_map_marked_p tree_map_base_marked_p
|
||||
|
||||
/* In tree-ssa.c */
|
||||
|
||||
tree target_for_debug_bind (tree);
|
||||
|
@ -5812,6 +5812,29 @@ prepare_call_arguments (basic_block bb, rtx insn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Add debug arguments. */
|
||||
if (fndecl
|
||||
&& TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& DECL_HAS_DEBUG_ARGS_P (fndecl))
|
||||
{
|
||||
VEC(tree, gc) **debug_args = decl_debug_args_lookup (fndecl);
|
||||
if (debug_args)
|
||||
{
|
||||
unsigned int ix;
|
||||
tree param;
|
||||
for (ix = 0; VEC_iterate (tree, *debug_args, ix, param); ix += 2)
|
||||
{
|
||||
rtx item;
|
||||
tree dtemp = VEC_index (tree, *debug_args, ix + 1);
|
||||
enum machine_mode mode = DECL_MODE (dtemp);
|
||||
item = gen_rtx_DEBUG_PARAMETER_REF (mode, param);
|
||||
item = gen_rtx_CONCAT (mode, item, DECL_RTL (dtemp));
|
||||
call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item,
|
||||
call_arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reverse call_arguments chain. */
|
||||
prev = NULL_RTX;
|
||||
for (cur = call_arguments; cur; cur = next)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-06-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR debug/47858
|
||||
* dwarf2.h (enum dwarf_location_atom): Add DW_OP_GNU_parameter_ref.
|
||||
|
||||
2011-06-13 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* demangle.h (DMGL_RET_POSTFIX): Extend the comment.
|
||||
|
@ -563,6 +563,8 @@ enum dwarf_location_atom
|
||||
DW_OP_GNU_deref_type = 0xf6,
|
||||
DW_OP_GNU_convert = 0xf7,
|
||||
DW_OP_GNU_reinterpret = 0xf9,
|
||||
/* The GNU parameter ref extension. */
|
||||
DW_OP_GNU_parameter_ref = 0xfa,
|
||||
/* HP extensions. */
|
||||
DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
|
||||
DW_OP_HP_is_value = 0xe1,
|
||||
|
Loading…
x
Reference in New Issue
Block a user