rtl.def (DEBUG_IMPLICIT_PTR): New rtl code.
* rtl.def (DEBUG_IMPLICIT_PTR): New rtl code. * rtl.h (DEBUG_IMPLICIT_PTR_DECL): Define. * rtl.c (rtx_equal_p_cb, rtx_equal_p): Handle DEBUG_IMPLICIT_PTR. * print-rtl.c (print_rtx): Likewise. * cselib.c (rtx_equal_for_cselib_p, cselib_hash_rtx): Likewise. * cfgexpand.c (expand_debug_expr): Generate DEBUG_IMPLICIT_PTR for ADDR_EXPR with non-addressable object. * dwarf2out.c (enum dw_val_class): Add dw_val_class_decl_ref. (struct dw_val_struct): Add v.val_decl_ref. (dwarf_stack_op_name, output_loc_operands, output_loc_operands_raw): Handle DW_OP_GNU_implicit_pointer. (size_of_loc_descr): Likewise. Fix up DW_OP_call_ref size. (get_ref_die_offset_label): New function. (implicit_ptr_descriptor): New function. (mem_loc_descriptor): Handle DEBUG_IMPLICIT_PTR. (loc_descriptor): Likewise. (gen_variable_die): Put even definitions into decl_die_table. (resolve_addr_in_expr): Resolve still unresolved DW_OP_GNU_implicit_pointer operands, if it can't be resolved return false. (dwarf2out_finish): Call output_location_lists after outputting .debug_info and .debug_abbrev instead of before. * dwarf2.h (DW_OP_GNU_implicit_pointer): New. 2010-09-09 Roland McGrath <roland@redhat.com> * dwarf2out.c (DWARF_REF_SIZE): Define. (size_of_loc_descr): Use it for DW_OP_call_ref. From-SVN: r164050
This commit is contained in:
parent
eed023ccd5
commit
c8a27c4018
|
@ -1,3 +1,33 @@
|
|||
2010-09-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* rtl.def (DEBUG_IMPLICIT_PTR): New rtl code.
|
||||
* rtl.h (DEBUG_IMPLICIT_PTR_DECL): Define.
|
||||
* rtl.c (rtx_equal_p_cb, rtx_equal_p): Handle DEBUG_IMPLICIT_PTR.
|
||||
* print-rtl.c (print_rtx): Likewise.
|
||||
* cselib.c (rtx_equal_for_cselib_p, cselib_hash_rtx): Likewise.
|
||||
* cfgexpand.c (expand_debug_expr): Generate DEBUG_IMPLICIT_PTR
|
||||
for ADDR_EXPR with non-addressable object.
|
||||
* dwarf2out.c (enum dw_val_class): Add dw_val_class_decl_ref.
|
||||
(struct dw_val_struct): Add v.val_decl_ref.
|
||||
(dwarf_stack_op_name, output_loc_operands, output_loc_operands_raw):
|
||||
Handle DW_OP_GNU_implicit_pointer.
|
||||
(size_of_loc_descr): Likewise. Fix up DW_OP_call_ref size.
|
||||
(get_ref_die_offset_label): New function.
|
||||
(implicit_ptr_descriptor): New function.
|
||||
(mem_loc_descriptor): Handle DEBUG_IMPLICIT_PTR.
|
||||
(loc_descriptor): Likewise.
|
||||
(gen_variable_die): Put even definitions into decl_die_table.
|
||||
(resolve_addr_in_expr): Resolve still unresolved
|
||||
DW_OP_GNU_implicit_pointer operands, if it can't be resolved
|
||||
return false.
|
||||
(dwarf2out_finish): Call output_location_lists after outputting
|
||||
.debug_info and .debug_abbrev instead of before.
|
||||
|
||||
2010-09-09 Roland McGrath <roland@redhat.com>
|
||||
|
||||
* dwarf2out.c (DWARF_REF_SIZE): Define.
|
||||
(size_of_loc_descr): Use it for DW_OP_call_ref.
|
||||
|
||||
2010-09-09 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* doc/invoke.text: Reinstate mcmodel=medium.
|
||||
|
|
|
@ -2911,7 +2911,32 @@ expand_debug_expr (tree exp)
|
|||
case ADDR_EXPR:
|
||||
op0 = expand_debug_expr (TREE_OPERAND (exp, 0));
|
||||
if (!op0 || !MEM_P (op0))
|
||||
return NULL;
|
||||
{
|
||||
if ((TREE_CODE (TREE_OPERAND (exp, 0)) == VAR_DECL
|
||||
|| TREE_CODE (TREE_OPERAND (exp, 0)) == PARM_DECL
|
||||
|| TREE_CODE (TREE_OPERAND (exp, 0)) == RESULT_DECL)
|
||||
&& !TREE_ADDRESSABLE (TREE_OPERAND (exp, 0)))
|
||||
return gen_rtx_DEBUG_IMPLICIT_PTR (mode, TREE_OPERAND (exp, 0));
|
||||
|
||||
if (handled_component_p (TREE_OPERAND (exp, 0)))
|
||||
{
|
||||
HOST_WIDE_INT bitoffset, bitsize, maxsize;
|
||||
tree decl
|
||||
= get_ref_base_and_extent (TREE_OPERAND (exp, 0),
|
||||
&bitoffset, &bitsize, &maxsize);
|
||||
if ((TREE_CODE (decl) == VAR_DECL
|
||||
|| TREE_CODE (decl) == PARM_DECL
|
||||
|| TREE_CODE (decl) == RESULT_DECL)
|
||||
&& !TREE_ADDRESSABLE (decl)
|
||||
&& (bitoffset % BITS_PER_UNIT) == 0
|
||||
&& bitsize > 0
|
||||
&& bitsize == maxsize)
|
||||
return plus_constant (gen_rtx_DEBUG_IMPLICIT_PTR (mode, decl),
|
||||
bitoffset / BITS_PER_UNIT);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
op0 = convert_debug_memory_address (mode, XEXP (op0, 0));
|
||||
|
||||
|
|
|
@ -700,6 +700,10 @@ rtx_equal_for_cselib_p (rtx x, rtx y)
|
|||
case DEBUG_EXPR:
|
||||
return 0;
|
||||
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
case LABEL_REF:
|
||||
return XEXP (x, 0) == XEXP (y, 0);
|
||||
|
||||
|
@ -834,6 +838,11 @@ cselib_hash_rtx (rtx x, int create)
|
|||
+ DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x));
|
||||
return hash ? hash : (unsigned int) DEBUG_EXPR;
|
||||
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
hash += ((unsigned) DEBUG_IMPLICIT_PTR << 7)
|
||||
+ DECL_UID (DEBUG_IMPLICIT_PTR_DECL (x));
|
||||
return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR;
|
||||
|
||||
case CONST_INT:
|
||||
hash += ((unsigned) CONST_INT << 7) + INTVAL (x);
|
||||
return hash ? hash : (unsigned int) CONST_INT;
|
||||
|
|
115
gcc/dwarf2out.c
115
gcc/dwarf2out.c
|
@ -4294,6 +4294,7 @@ enum dw_val_class
|
|||
dw_val_class_macptr,
|
||||
dw_val_class_file,
|
||||
dw_val_class_data8,
|
||||
dw_val_class_decl_ref,
|
||||
dw_val_class_vms_delta
|
||||
};
|
||||
|
||||
|
@ -4332,6 +4333,7 @@ typedef struct GTY(()) dw_val_struct {
|
|||
unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag;
|
||||
struct dwarf_file_data * GTY ((tag ("dw_val_class_file"))) val_file;
|
||||
unsigned char GTY ((tag ("dw_val_class_data8"))) val_data8[8];
|
||||
tree GTY ((tag ("dw_val_class_decl_ref"))) val_decl_ref;
|
||||
struct dw_val_vms_delta_union
|
||||
{
|
||||
char * lbl1;
|
||||
|
@ -4695,6 +4697,8 @@ dwarf_stack_op_name (unsigned int op)
|
|||
return "DW_OP_GNU_uninit";
|
||||
case DW_OP_GNU_encoded_addr:
|
||||
return "DW_OP_GNU_encoded_addr";
|
||||
case DW_OP_GNU_implicit_pointer:
|
||||
return "DW_OP_GNU_implicit_pointer";
|
||||
|
||||
default:
|
||||
return "OP_<unknown>";
|
||||
|
@ -4798,6 +4802,9 @@ loc_list_plus_const (dw_loc_list_ref list_head, HOST_WIDE_INT offset)
|
|||
loc_descr_plus_const (&d->expr, offset);
|
||||
}
|
||||
|
||||
#define DWARF_REF_SIZE \
|
||||
(dwarf_version == 2 ? DWARF2_ADDR_SIZE : DWARF_OFFSET_SIZE)
|
||||
|
||||
/* Return the size of a location descriptor. */
|
||||
|
||||
static unsigned long
|
||||
|
@ -4904,12 +4911,15 @@ size_of_loc_descr (dw_loc_descr_ref loc)
|
|||
size += 4;
|
||||
break;
|
||||
case DW_OP_call_ref:
|
||||
size += DWARF2_ADDR_SIZE;
|
||||
size += DWARF_REF_SIZE;
|
||||
break;
|
||||
case DW_OP_implicit_value:
|
||||
size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned)
|
||||
+ loc->dw_loc_oprnd1.v.val_unsigned;
|
||||
break;
|
||||
case DW_OP_GNU_implicit_pointer:
|
||||
size += DWARF_REF_SIZE + size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4946,6 +4956,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);
|
||||
|
||||
/* Output location description stack opcode's operands (if any). */
|
||||
|
||||
|
@ -5165,6 +5176,17 @@ output_loc_operands (dw_loc_descr_ref loc)
|
|||
}
|
||||
break;
|
||||
|
||||
case DW_OP_GNU_implicit_pointer:
|
||||
{
|
||||
char label[MAX_ARTIFICIAL_LABEL_BYTES
|
||||
+ HOST_BITS_PER_WIDE_INT / 2 + 2];
|
||||
gcc_assert (val1->val_class == dw_val_class_die_ref);
|
||||
get_ref_die_offset_label (label, val1->v.val_die_ref.die);
|
||||
dw2_asm_output_offset (DWARF_REF_SIZE, label, debug_info_section, NULL);
|
||||
dw2_asm_output_data_sleb128 (val2->v.val_int, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other codes have no operands. */
|
||||
break;
|
||||
|
@ -5303,6 +5325,10 @@ output_loc_operands_raw (dw_loc_descr_ref loc)
|
|||
dw2_asm_output_data_sleb128_raw (val2->v.val_int);
|
||||
break;
|
||||
|
||||
case DW_OP_GNU_implicit_pointer:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Other codes have no operands. */
|
||||
break;
|
||||
|
@ -6514,6 +6540,15 @@ is_tagged_type (const_tree type)
|
|||
|| code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE);
|
||||
}
|
||||
|
||||
/* Set label to debug_info_section_label + die_offset of a DIE reference. */
|
||||
|
||||
static void
|
||||
get_ref_die_offset_label (char *label, dw_die_ref ref)
|
||||
{
|
||||
sprintf (label, "%s+" HOST_WIDE_INT_PRINT_DEC,
|
||||
debug_info_section_label, ref->die_offset);
|
||||
}
|
||||
|
||||
/* Convert a DIE tag into its string name. */
|
||||
|
||||
static const char *
|
||||
|
@ -13651,6 +13686,7 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
case CONCAT:
|
||||
case CONCATN:
|
||||
case VAR_LOCATION:
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
expansion_failed (NULL_TREE, rtl,
|
||||
"CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
|
||||
return 0;
|
||||
|
@ -14240,6 +14276,35 @@ concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
|
|||
return cc_loc_result;
|
||||
}
|
||||
|
||||
/* Helper function for loc_descriptor. Return DW_OP_GNU_implicit_pointer
|
||||
for DEBUG_IMPLICIT_PTR RTL. */
|
||||
|
||||
static dw_loc_descr_ref
|
||||
implicit_ptr_descriptor (rtx rtl, HOST_WIDE_INT offset)
|
||||
{
|
||||
dw_loc_descr_ref ret;
|
||||
dw_die_ref ref;
|
||||
|
||||
gcc_assert (TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == VAR_DECL
|
||||
|| TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == PARM_DECL
|
||||
|| TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == RESULT_DECL);
|
||||
ref = lookup_decl_die (DEBUG_IMPLICIT_PTR_DECL (rtl));
|
||||
ret = new_loc_descr (DW_OP_GNU_implicit_pointer, 0, offset);
|
||||
ret->dw_loc_oprnd2.val_class = dw_val_class_const;
|
||||
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_IMPLICIT_PTR_DECL (rtl);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Output a proper Dwarf location descriptor for a variable or parameter
|
||||
which is either allocated in a register or in a memory location. For a
|
||||
register, we just generate an OP_REG and the register number. For a
|
||||
|
@ -14457,6 +14522,19 @@ loc_descriptor (rtx rtl, enum machine_mode mode,
|
|||
}
|
||||
break;
|
||||
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
loc_result = implicit_ptr_descriptor (rtl, 0);
|
||||
break;
|
||||
|
||||
case PLUS:
|
||||
if (GET_CODE (XEXP (rtl, 0)) == DEBUG_IMPLICIT_PTR
|
||||
&& CONST_INT_P (XEXP (rtl, 1)))
|
||||
{
|
||||
loc_result
|
||||
= implicit_ptr_descriptor (XEXP (rtl, 0), INTVAL (XEXP (rtl, 1)));
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT && GET_MODE (rtl) == mode
|
||||
&& GET_MODE_SIZE (GET_MODE (rtl)) <= DWARF2_ADDR_SIZE
|
||||
|
@ -19190,7 +19268,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
|
|||
if (declaration)
|
||||
add_AT_flag (var_die, DW_AT_declaration, 1);
|
||||
|
||||
if (decl && (DECL_ABSTRACT (decl) || declaration))
|
||||
if (decl && (DECL_ABSTRACT (decl) || declaration || old_die == NULL))
|
||||
equate_decl_number_to_die (decl, var_die);
|
||||
|
||||
if (! declaration
|
||||
|
@ -22150,6 +22228,17 @@ resolve_addr_in_expr (dw_loc_descr_ref loc)
|
|||
&& loc->dw_loc_oprnd2.val_class == dw_val_class_addr
|
||||
&& resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr, NULL)))
|
||||
return false;
|
||||
else if (loc->dw_loc_opc == DW_OP_GNU_implicit_pointer
|
||||
&& loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
|
||||
{
|
||||
dw_die_ref ref
|
||||
= lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
|
||||
if (ref == NULL)
|
||||
return false;
|
||||
loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
|
||||
loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
|
||||
loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -22429,17 +22518,6 @@ dwarf2out_finish (const char *filename)
|
|||
add_ranges (NULL);
|
||||
}
|
||||
|
||||
/* Output location list section if necessary. */
|
||||
if (have_location_lists)
|
||||
{
|
||||
/* Output the location lists info. */
|
||||
switch_to_section (debug_loc_section);
|
||||
ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
|
||||
DEBUG_LOC_SECTION_LABEL, 0);
|
||||
ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
|
||||
output_location_lists (die);
|
||||
}
|
||||
|
||||
if (debug_info_level >= DINFO_LEVEL_NORMAL)
|
||||
add_AT_lineptr (comp_unit_die, DW_AT_stmt_list,
|
||||
debug_line_section_label);
|
||||
|
@ -22481,6 +22559,17 @@ dwarf2out_finish (const char *filename)
|
|||
switch_to_section (debug_abbrev_section);
|
||||
output_abbrev_section ();
|
||||
|
||||
/* Output location list section if necessary. */
|
||||
if (have_location_lists)
|
||||
{
|
||||
/* Output the location lists info. */
|
||||
switch_to_section (debug_loc_section);
|
||||
ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
|
||||
DEBUG_LOC_SECTION_LABEL, 0);
|
||||
ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
|
||||
output_location_lists (die);
|
||||
}
|
||||
|
||||
/* Output public names table if necessary. */
|
||||
if (!VEC_empty (pubname_entry, pubname_table))
|
||||
{
|
||||
|
|
|
@ -533,7 +533,10 @@ print_rtx (const_rtx in_rtx)
|
|||
|
||||
case 't':
|
||||
#ifndef GENERATOR_FILE
|
||||
dump_addr (outfile, " ", XTREE (in_rtx, i));
|
||||
if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
|
||||
print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
|
||||
else
|
||||
dump_addr (outfile, " ", XTREE (in_rtx, i));
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
|
|
@ -407,6 +407,10 @@ rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
|
|||
case CONST_FIXED:
|
||||
return 0;
|
||||
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -527,6 +531,10 @@ rtx_equal_p (const_rtx x, const_rtx y)
|
|||
case CONST_FIXED:
|
||||
return 0;
|
||||
|
||||
case DEBUG_IMPLICIT_PTR:
|
||||
return DEBUG_IMPLICIT_PTR_DECL (x)
|
||||
== DEBUG_IMPLICIT_PTR_DECL (y);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -711,6 +711,10 @@ DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", RTX_UNARY)
|
|||
initialization status of variables. */
|
||||
DEF_RTL_EXPR(VAR_LOCATION, "var_location", "tei", RTX_EXTRA)
|
||||
|
||||
/* Used in VAR_LOCATION for a pointer to a decl that is no longer
|
||||
addressable. */
|
||||
DEF_RTL_EXPR(DEBUG_IMPLICIT_PTR, "debug_implicit_ptr", "t", RTX_OBJ)
|
||||
|
||||
/* All expressions from this point forward appear only in machine
|
||||
descriptions. */
|
||||
#ifdef GENERATOR_FILE
|
||||
|
|
|
@ -933,6 +933,9 @@ extern const char * const reg_note_name[];
|
|||
/* DEBUG_EXPR_DECL corresponding to a DEBUG_EXPR RTX. */
|
||||
#define DEBUG_EXPR_TREE_DECL(RTX) XCTREE (RTX, 0, DEBUG_EXPR)
|
||||
|
||||
/* VAR_DECL/PARM_DECL DEBUG_IMPLICIT_PTR takes address of. */
|
||||
#define DEBUG_IMPLICIT_PTR_DECL(RTX) XCTREE (RTX, 0, DEBUG_IMPLICIT_PTR)
|
||||
|
||||
/* 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,3 +1,7 @@
|
|||
2010-09-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf2.h (DW_OP_GNU_implicit_pointer): New.
|
||||
|
||||
2010-07-06 Ken Werner <ken.werner@de.ibm.com>
|
||||
|
||||
* floatformat.h (floatformat_ieee_half_big): Add declaration.
|
||||
|
|
|
@ -622,6 +622,7 @@ enum dwarf_location_atom
|
|||
/* The following is for marking variables that are uninitialized. */
|
||||
DW_OP_GNU_uninit = 0xf0,
|
||||
DW_OP_GNU_encoded_addr = 0xf1,
|
||||
DW_OP_GNU_implicit_pointer = 0xf2,
|
||||
/* HP extensions. */
|
||||
DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address. */
|
||||
DW_OP_HP_is_value = 0xe1,
|
||||
|
|
Loading…
Reference in New Issue