diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-22 10:41:58 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-06-22 10:41:58 +0000 |
commit | 841424ccaf396ea0dfbfc1e27eeabe3ef5889cd0 (patch) | |
tree | 084c46b58471b676de4f37c5db720c691779a0e7 /gcc/cfgexpand.c | |
parent | f41e4452d8ff9a97b75a3b71c581bdc12f27c3c7 (diff) | |
download | gcc-841424ccaf396ea0dfbfc1e27eeabe3ef5889cd0.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@175288 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 170 |
1 files changed, 169 insertions, 1 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index efd3ed93c36..000a790a683 100644 --- a/gcc/cfgexpand.c +++ b/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 ()); } @@ -3606,6 +3741,39 @@ expand_gimple_basic_block (basic_block bb) 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); + } else { if (is_gimple_call (stmt) && gimple_call_tail_p (stmt)) |