Commit 7b602c4d by Alexandre Oliva Committed by Alexandre Oliva

[IEPM] [PR debug/84620] use constant form for DW_AT_GNU_entry_view

When outputting entry views in symbolic mode, we used to use a lbl_id,
but that outputs the view as an addr, perhaps even in an indirect one,
which is all excessive and undesirable for a small assembler-computed
constant.

Introduce a new value class for symbolic views, so that we can output
the labels as constant data, using as narrow forms as possible, but
wide enough for any symbolic views output in the compilation.  We
don't know exactly where the assembler will reset views, but we count
the symbolic views since known reset points and use that as an upper
bound for view numbers.

Ideally, we'd use uleb128, but then the compiler would have to defer
.debug_info offset computation to the assembler.  I'm not going there
for now, so a symbolic uleb128 assembler constant in an attribute is
not something GCC can deal with ATM.

for  gcc/ChangeLog

	PR debug/84620
	* dwarf2out.h (dw_val_class): Add dw_val_class_symview.
	(dw_val_node): Add val_symbolic_view.
	* dwarf2out.c (dw_line_info_table): Add symviews_since_reset.
	(symview_upper_bound): New.
	(new_line_info_table): Initialize symviews_since_reset.
	(dwarf2out_source_line): Count symviews_since_reset and set
	symview_upper_bound.
	(dw_val_equal_p): Handle symview.
	(add_AT_symview): New.
	(print_dw_val): Handle symview.
	(attr_checksum, attr_checksum_ordered): Likewise.
	(same_dw_val_p, size_of_die): Likewise.
	(value_format, output_die): Likewise.
	(add_high_low_attributes): Use add_AT_symview for entry_view.
	(dwarf2out_finish): Reset symview_upper_bound, clear
	zero_view_p.

From-SVN: r258411
parent 7ed12599
2018-03-10 Alexandre Oliva <aoliva@redhat.com>
PR debug/84620
* dwarf2out.h (dw_val_class): Add dw_val_class_symview.
(dw_val_node): Add val_symbolic_view.
* dwarf2out.c (dw_line_info_table): Add symviews_since_reset.
(symview_upper_bound): New.
(new_line_info_table): Initialize symviews_since_reset.
(dwarf2out_source_line): Count symviews_since_reset and set
symview_upper_bound.
(dw_val_equal_p): Handle symview.
(add_AT_symview): New.
(print_dw_val): Handle symview.
(attr_checksum, attr_checksum_ordered): Likewise.
(same_dw_val_p, size_of_die): Likewise.
(value_format, output_die): Likewise.
(add_high_low_attributes): Use add_AT_symview for entry_view.
(dwarf2out_finish): Reset symview_upper_bound, clear
zero_view_p.
2018-03-09 Peter Bergner <bergner@vnet.ibm.com> 2018-03-09 Peter Bergner <bergner@vnet.ibm.com>
PR target/83969 PR target/83969
......
...@@ -1434,6 +1434,8 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b) ...@@ -1434,6 +1434,8 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b)
return a->v.val_die_ref.die == b->v.val_die_ref.die; return a->v.val_die_ref.die == b->v.val_die_ref.die;
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
return a->v.val_fde_index == b->v.val_fde_index; return a->v.val_fde_index == b->v.val_fde_index;
case dw_val_class_symview:
return strcmp (a->v.val_symbolic_view, b->v.val_symbolic_view) == 0;
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
...@@ -2951,6 +2953,11 @@ struct GTY(()) dw_line_info_table { ...@@ -2951,6 +2953,11 @@ struct GTY(()) dw_line_info_table {
going to ask the assembler to assign. */ going to ask the assembler to assign. */
var_loc_view view; var_loc_view view;
/* This counts the number of symbolic views emitted in this table
since the latest view reset. Its max value, over all tables,
sets symview_upper_bound. */
var_loc_view symviews_since_reset;
#define FORCE_RESET_NEXT_VIEW(x) ((x) = (var_loc_view)-1) #define FORCE_RESET_NEXT_VIEW(x) ((x) = (var_loc_view)-1)
#define RESET_NEXT_VIEW(x) ((x) = (var_loc_view)0) #define RESET_NEXT_VIEW(x) ((x) = (var_loc_view)0)
#define FORCE_RESETTING_VIEW_P(x) ((x) == (var_loc_view)-1) #define FORCE_RESETTING_VIEW_P(x) ((x) == (var_loc_view)-1)
...@@ -2959,6 +2966,13 @@ struct GTY(()) dw_line_info_table { ...@@ -2959,6 +2966,13 @@ struct GTY(()) dw_line_info_table {
vec<dw_line_info_entry, va_gc> *entries; vec<dw_line_info_entry, va_gc> *entries;
}; };
/* This is an upper bound for view numbers that the assembler may
assign to symbolic views output in this translation. It is used to
decide how big a field to use to represent view numbers in
symview-classed attributes. */
static var_loc_view symview_upper_bound;
/* If we're keep track of location views and their reset points, and /* If we're keep track of location views and their reset points, and
INSN is a reset point (i.e., it necessarily advances the PC), mark INSN is a reset point (i.e., it necessarily advances the PC), mark
the next view in TABLE as reset. */ the next view in TABLE as reset. */
...@@ -3603,6 +3617,7 @@ static addr_table_entry *add_addr_table_entry (void *, enum ate_kind); ...@@ -3603,6 +3617,7 @@ static addr_table_entry *add_addr_table_entry (void *, enum ate_kind);
static void remove_addr_table_entry (addr_table_entry *); static void remove_addr_table_entry (addr_table_entry *);
static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool); static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool);
static inline rtx AT_addr (dw_attr_node *); static inline rtx AT_addr (dw_attr_node *);
static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *); static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
...@@ -5117,6 +5132,21 @@ add_AT_vms_delta (dw_die_ref die, enum dwarf_attribute attr_kind, ...@@ -5117,6 +5132,21 @@ add_AT_vms_delta (dw_die_ref die, enum dwarf_attribute attr_kind,
add_dwarf_attr (die, &attr); add_dwarf_attr (die, &attr);
} }
/* Add a symbolic view identifier attribute value to a DIE. */
static inline void
add_AT_symview (dw_die_ref die, enum dwarf_attribute attr_kind,
const char *view_label)
{
dw_attr_node attr;
attr.dw_attr = attr_kind;
attr.dw_attr_val.val_class = dw_val_class_symview;
attr.dw_attr_val.val_entry = NULL;
attr.dw_attr_val.v.val_symbolic_view = xstrdup (view_label);
add_dwarf_attr (die, &attr);
}
/* Add a label identifier attribute value to a DIE. */ /* Add a label identifier attribute value to a DIE. */
static inline void static inline void
...@@ -6460,6 +6490,9 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile) ...@@ -6460,6 +6490,9 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
fprintf (outfile, "delta: @slotcount(%s-%s)", fprintf (outfile, "delta: @slotcount(%s-%s)",
val->v.val_vms_delta.lbl2, val->v.val_vms_delta.lbl1); val->v.val_vms_delta.lbl2, val->v.val_vms_delta.lbl1);
break; break;
case dw_val_class_symview:
fprintf (outfile, "view: %s", val->v.val_symbolic_view);
break;
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
...@@ -6831,6 +6864,7 @@ attr_checksum (dw_attr_node *at, struct md5_ctx *ctx, int *mark) ...@@ -6831,6 +6864,7 @@ attr_checksum (dw_attr_node *at, struct md5_ctx *ctx, int *mark)
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
case dw_val_class_vms_delta: case dw_val_class_vms_delta:
case dw_val_class_symview:
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
...@@ -7127,6 +7161,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_node *at, ...@@ -7127,6 +7161,7 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_node *at,
break; break;
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
case dw_val_class_symview:
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
case dw_val_class_lineptr: case dw_val_class_lineptr:
case dw_val_class_macptr: case dw_val_class_macptr:
...@@ -7627,6 +7662,9 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) ...@@ -7627,6 +7662,9 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark)
case dw_val_class_die_ref: case dw_val_class_die_ref:
return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark); return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark);
case dw_val_class_symview:
return strcmp (v1->v.val_symbolic_view, v2->v.val_symbolic_view) == 0;
case dw_val_class_fde_ref: case dw_val_class_fde_ref:
case dw_val_class_vms_delta: case dw_val_class_vms_delta:
case dw_val_class_lbl_id: case dw_val_class_lbl_id:
...@@ -9287,6 +9325,16 @@ size_of_die (dw_die_ref die) ...@@ -9287,6 +9325,16 @@ size_of_die (dw_die_ref die)
size += csize; size += csize;
} }
break; break;
case dw_val_class_symview:
if (symview_upper_bound <= 0xff)
size += 1;
else if (symview_upper_bound <= 0xffff)
size += 2;
else if (symview_upper_bound <= 0xffffffff)
size += 4;
else
size += 8;
break;
case dw_val_class_const_implicit: case dw_val_class_const_implicit:
case dw_val_class_unsigned_const_implicit: case dw_val_class_unsigned_const_implicit:
case dw_val_class_file_implicit: case dw_val_class_file_implicit:
...@@ -9735,6 +9783,17 @@ value_format (dw_attr_node *a) ...@@ -9735,6 +9783,17 @@ value_format (dw_attr_node *a)
default: default:
return DW_FORM_block1; return DW_FORM_block1;
} }
case dw_val_class_symview:
/* ??? We might use uleb128, but then we'd have to compute
.debug_info offsets in the assembler. */
if (symview_upper_bound <= 0xff)
return DW_FORM_data1;
else if (symview_upper_bound <= 0xffff)
return DW_FORM_data2;
else if (symview_upper_bound <= 0xffffffff)
return DW_FORM_data4;
else
return DW_FORM_data8;
case dw_val_class_vec: case dw_val_class_vec:
switch (constant_size (a->dw_attr_val.v.val_vec.length switch (constant_size (a->dw_attr_val.v.val_vec.length
* a->dw_attr_val.v.val_vec.elt_size)) * a->dw_attr_val.v.val_vec.elt_size))
...@@ -10500,6 +10559,22 @@ output_die (dw_die_ref die) ...@@ -10500,6 +10559,22 @@ output_die (dw_die_ref die)
} }
break; break;
case dw_val_class_symview:
{
int vsize;
if (symview_upper_bound <= 0xff)
vsize = 1;
else if (symview_upper_bound <= 0xffff)
vsize = 2;
else if (symview_upper_bound <= 0xffffffff)
vsize = 4;
else
vsize = 8;
dw2_asm_output_addr (vsize, a->dw_attr_val.v.val_symbolic_view,
"%s", name);
}
break;
case dw_val_class_const_implicit: case dw_val_class_const_implicit:
if (flag_debug_asm) if (flag_debug_asm)
fprintf (asm_out_file, "\t\t\t%s %s (" fprintf (asm_out_file, "\t\t\t%s %s ("
...@@ -23815,7 +23890,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die) ...@@ -23815,7 +23890,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die)
indirecting them through a table might make things indirecting them through a table might make things
easier, but even that would be more wasteful, easier, but even that would be more wasteful,
space-wise, than what we have now. */ space-wise, than what we have now. */
add_AT_lbl_id (die, DW_AT_GNU_entry_view, label); add_AT_symview (die, DW_AT_GNU_entry_view, label);
} }
} }
...@@ -27412,6 +27487,7 @@ new_line_info_table (void) ...@@ -27412,6 +27487,7 @@ new_line_info_table (void)
table->line_num = 1; table->line_num = 1;
table->is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START; table->is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START;
FORCE_RESET_NEXT_VIEW (table->view); FORCE_RESET_NEXT_VIEW (table->view);
table->symviews_since_reset = 0;
return table; return table;
} }
...@@ -27609,11 +27685,16 @@ dwarf2out_source_line (unsigned int line, unsigned int column, ...@@ -27609,11 +27685,16 @@ dwarf2out_source_line (unsigned int line, unsigned int column,
/* If we're using the assembler to compute view numbers, we /* If we're using the assembler to compute view numbers, we
can't issue a .loc directive for line zero, so we can't can't issue a .loc directive for line zero, so we can't
get a view number at this point. We might attempt to get a view number at this point. We might attempt to
compute it from the previous view, but since we're compute it from the previous view, or equate it to a
omitting the line number entry, we might as well omit the subsequent view (though it might not be there!), but
view number as well. That means pretending it's a view since we're omitting the line number entry, we might as
number zero, which might very well turn out to be well omit the view number as well. That means pretending
correct. */ it's a view number zero, which might very well turn out
to be correct. ??? Extend the assembler so that the
compiler could emit e.g. ".locview .LVU#", to output a
view without changing line number information. We'd then
have to count it in symviews_since_reset; when it's omitted,
it doesn't count. */
if (!zero_view_p) if (!zero_view_p)
zero_view_p = BITMAP_GGC_ALLOC (); zero_view_p = BITMAP_GGC_ALLOC ();
bitmap_set_bit (zero_view_p, table->view); bitmap_set_bit (zero_view_p, table->view);
...@@ -27702,6 +27783,9 @@ dwarf2out_source_line (unsigned int line, unsigned int column, ...@@ -27702,6 +27783,9 @@ dwarf2out_source_line (unsigned int line, unsigned int column,
{ {
if (!RESETTING_VIEW_P (table->view)) if (!RESETTING_VIEW_P (table->view))
{ {
table->symviews_since_reset++;
if (table->symviews_since_reset > symview_upper_bound)
symview_upper_bound = table->symviews_since_reset;
/* When we're using the assembler to compute view /* When we're using the assembler to compute view
numbers, we output symbolic labels after "view" in numbers, we output symbolic labels after "view" in
.loc directives, and the assembler will set them for .loc directives, and the assembler will set them for
...@@ -27720,6 +27804,7 @@ dwarf2out_source_line (unsigned int line, unsigned int column, ...@@ -27720,6 +27804,7 @@ dwarf2out_source_line (unsigned int line, unsigned int column,
} }
else else
{ {
table->symviews_since_reset = 0;
if (FORCE_RESETTING_VIEW_P (table->view)) if (FORCE_RESETTING_VIEW_P (table->view))
fputs (" view -0", asm_out_file); fputs (" view -0", asm_out_file);
else else
...@@ -31295,6 +31380,11 @@ dwarf2out_finish (const char *) ...@@ -31295,6 +31380,11 @@ dwarf2out_finish (const char *)
debug_line_str_hash->traverse<enum dwarf_form, debug_line_str_hash->traverse<enum dwarf_form,
output_indirect_string> (form); output_indirect_string> (form);
} }
/* ??? Move lvugid out of dwarf2out_source_line and reset it too? */
symview_upper_bound = 0;
if (zero_view_p)
bitmap_clear (zero_view_p);
} }
/* Returns a hash value for X (which really is a variable_value_struct). */ /* Returns a hash value for X (which really is a variable_value_struct). */
......
...@@ -161,7 +161,8 @@ enum dw_val_class ...@@ -161,7 +161,8 @@ enum dw_val_class
dw_val_class_const_implicit, dw_val_class_const_implicit,
dw_val_class_unsigned_const_implicit, dw_val_class_unsigned_const_implicit,
dw_val_class_file_implicit, dw_val_class_file_implicit,
dw_val_class_view_list dw_val_class_view_list,
dw_val_class_symview
}; };
/* Describe a floating point constant value, or a vector constant value. */ /* Describe a floating point constant value, or a vector constant value. */
...@@ -233,6 +234,7 @@ struct GTY(()) dw_val_node { ...@@ -233,6 +234,7 @@ struct GTY(()) dw_val_node {
} GTY ((tag ("dw_val_class_vms_delta"))) val_vms_delta; } GTY ((tag ("dw_val_class_vms_delta"))) val_vms_delta;
dw_discr_value GTY ((tag ("dw_val_class_discr_value"))) val_discr_value; dw_discr_value GTY ((tag ("dw_val_class_discr_value"))) val_discr_value;
dw_discr_list_ref GTY ((tag ("dw_val_class_discr_list"))) val_discr_list; dw_discr_list_ref GTY ((tag ("dw_val_class_discr_list"))) val_discr_list;
char * GTY ((tag ("dw_val_class_symview"))) val_symbolic_view;
} }
GTY ((desc ("%1.val_class"))) v; GTY ((desc ("%1.val_class"))) v;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment