dwarf2out.c (dw_ranges_by_label_ref): New typedef.

* dwarf2out.c (dw_ranges_by_label_ref): New typedef.
(dw_ranges_struct): Rename block_num to num.  Adjust.
(dw_ranges_by_label_struct): New.
(ranges_by_label, ranges_by_label_allocated,
ranges_by_label_in_use): New variables.
(add_ranges_num): Factored most of the code out of...
(add_ranges): ... this one.  Rewrite in terms of the former.
(add_ranges_by_labels): New.
(output_ranges): Output by-label ranges.
(dwarf2out_finish): Output range for multiple-section
compile_unit.  Output standard DW_AT_low_pc in addition to
unexpected DW_AT_entry_pc.

From-SVN: r126357
This commit is contained in:
Alexandre Oliva 2007-07-05 08:30:24 +00:00 committed by Alexandre Oliva
parent 67de26d755
commit 0435c1d5ef
2 changed files with 150 additions and 13 deletions

View file

@ -1,3 +1,18 @@
2007-07-05 Alexandre Oliva <aoliva@redhat.com>
* dwarf2out.c (dw_ranges_by_label_ref): New typedef.
(dw_ranges_struct): Rename block_num to num. Adjust.
(dw_ranges_by_label_struct): New.
(ranges_by_label, ranges_by_label_allocated,
ranges_by_label_in_use): New variables.
(add_ranges_num): Factored most of the code out of...
(add_ranges): ... this one. Rewrite in terms of the former.
(add_ranges_by_labels): New.
(output_ranges): Output by-label ranges.
(dwarf2out_finish): Output range for multiple-section
compile_unit. Output standard DW_AT_low_pc in addition to
unexpected DW_AT_entry_pc.
2007-07-04 Daniel Berlin <dberlin@dberlin.org>
PR tree-optimization/32604

View file

@ -3715,6 +3715,7 @@ typedef struct dw_line_info_struct *dw_line_info_ref;
typedef struct dw_separate_line_info_struct *dw_separate_line_info_ref;
typedef struct pubname_struct *pubname_ref;
typedef struct dw_ranges_struct *dw_ranges_ref;
typedef struct dw_ranges_by_label_struct *dw_ranges_by_label_ref;
/* Each entry in the line_info_table maintains the file and
line number associated with the label generated for that
@ -3797,7 +3798,15 @@ DEF_VEC_ALLOC_O(pubname_entry, gc);
struct dw_ranges_struct GTY(())
{
int block_num;
/* If this is positive, it's a block number, otherwise it's a
bitwise-negated index into dw_ranges_by_label. */
int num;
};
struct dw_ranges_by_label_struct GTY(())
{
const char *begin;
const char *end;
};
/* The limbo die list structure. */
@ -4004,6 +4013,16 @@ static GTY(()) unsigned ranges_table_allocated;
/* Number of elements in ranges_table currently in use. */
static GTY(()) unsigned ranges_table_in_use;
/* Array of pairs of labels referenced in ranges_table. */
static GTY ((length ("ranges_by_label_allocated")))
dw_ranges_by_label_ref ranges_by_label;
/* Number of elements currently allocated for ranges_by_label. */
static GTY(()) unsigned ranges_by_label_allocated;
/* Number of elements in ranges_by_label currently in use. */
static GTY(()) unsigned ranges_by_label_in_use;
/* Size (in elements) of increments by which we may expand the
ranges_table. */
#define RANGES_TABLE_INCREMENT 64
@ -4160,7 +4179,9 @@ static void add_pubtype (tree, dw_die_ref);
static void output_pubnames (VEC (pubname_entry,gc) *);
static void add_arange (tree, dw_die_ref);
static void output_aranges (void);
static unsigned int add_ranges_num (int);
static unsigned int add_ranges (tree);
static unsigned int add_ranges_by_labels (const char *, const char *);
static void output_ranges (void);
static void output_line_info (void);
static void output_file_names (void);
@ -7570,7 +7591,7 @@ output_aranges (void)
was placed. */
static unsigned int
add_ranges (tree block)
add_ranges_num (int num)
{
unsigned int in_use = ranges_table_in_use;
@ -7584,12 +7605,48 @@ add_ranges (tree block)
RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
}
ranges_table[in_use].block_num = (block ? BLOCK_NUMBER (block) : 0);
ranges_table[in_use].num = num;
ranges_table_in_use = in_use + 1;
return in_use * 2 * DWARF2_ADDR_SIZE;
}
/* Add a new entry to .debug_ranges corresponding to a block, or a
range terminator if BLOCK is NULL. */
static unsigned int
add_ranges (tree block)
{
return add_ranges_num (block ? BLOCK_NUMBER (block) : 0);
}
/* Add a new entry to .debug_ranges corresponding to a pair of
labels. */
static unsigned int
add_ranges_by_labels (const char *begin, const char *end)
{
unsigned int in_use = ranges_by_label_in_use;
if (in_use == ranges_by_label_allocated)
{
ranges_by_label_allocated += RANGES_TABLE_INCREMENT;
ranges_by_label
= ggc_realloc (ranges_by_label,
(ranges_by_label_allocated
* sizeof (struct dw_ranges_by_label_struct)));
memset (ranges_by_label + ranges_by_label_in_use, 0,
RANGES_TABLE_INCREMENT
* sizeof (struct dw_ranges_by_label_struct));
}
ranges_by_label[in_use].begin = begin;
ranges_by_label[in_use].end = end;
ranges_by_label_in_use = in_use + 1;
return add_ranges_num (-(int)in_use - 1);
}
static void
output_ranges (void)
{
@ -7599,9 +7656,9 @@ output_ranges (void)
for (i = 0; i < ranges_table_in_use; i++)
{
int block_num = ranges_table[i].block_num;
int block_num = ranges_table[i].num;
if (block_num)
if (block_num > 0)
{
char blabel[MAX_ARTIFICIAL_LABEL_BYTES];
char elabel[MAX_ARTIFICIAL_LABEL_BYTES];
@ -7621,10 +7678,10 @@ output_ranges (void)
text_section_label, NULL);
}
/* Otherwise, we add a DW_AT_entry_pc attribute to force the
compilation unit base address to zero, which allows us to
use absolute addresses, and not worry about whether the
target supports cross-section arithmetic. */
/* Otherwise, the compilation unit base address is zero,
which allows us to use absolute addresses, and not worry
about whether the target supports cross-section
arithmetic. */
else
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
@ -7634,6 +7691,38 @@ output_ranges (void)
fmt = NULL;
}
/* Negative block_num stands for an index into ranges_by_label. */
else if (block_num < 0)
{
int lab_idx = - block_num - 1;
if (!have_multiple_function_sections)
{
gcc_unreachable ();
#if 0
/* If we ever use add_ranges_by_labels () for a single
function section, all we have to do is to take out
the #if 0 above. */
dw2_asm_output_delta (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].begin,
text_section_label,
fmt, i * 2 * DWARF2_ADDR_SIZE);
dw2_asm_output_delta (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].end,
text_section_label, NULL);
#endif
}
else
{
dw2_asm_output_addr (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].begin,
fmt, i * 2 * DWARF2_ADDR_SIZE);
dw2_asm_output_addr (DWARF2_ADDR_SIZE,
ranges_by_label[lab_idx].end,
NULL);
}
}
else
{
dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL);
@ -14575,10 +14664,43 @@ dwarf2out_finish (const char *filename)
add_AT_lbl_id (comp_unit_die, DW_AT_high_pc, text_end_label);
}
/* If it wasn't, we need to give .debug_loc and .debug_ranges an appropriate
"base address". Use zero so that these addresses become absolute. */
else if (have_location_lists || ranges_table_in_use)
add_AT_addr (comp_unit_die, DW_AT_entry_pc, const0_rtx);
else
{
unsigned fde_idx = 0;
/* We need to give .debug_loc and .debug_ranges an appropriate
"base address". Use zero so that these addresses become
absolute. Historically, we've emitted the unexpected
DW_AT_entry_pc instead of DW_AT_low_pc for this purpose.
Emit both to give time for other tools to adapt. */
add_AT_addr (comp_unit_die, DW_AT_low_pc, const0_rtx);
add_AT_addr (comp_unit_die, DW_AT_entry_pc, const0_rtx);
add_AT_range_list (comp_unit_die, DW_AT_ranges,
add_ranges_by_labels (text_section_label,
text_end_label));
if (flag_reorder_blocks_and_partition)
add_ranges_by_labels (cold_text_section_label,
cold_end_label);
for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
{
dw_fde_ref fde = &fde_table[fde_idx];
if (fde->dw_fde_switched_sections)
{
add_ranges_by_labels (fde->dw_fde_hot_section_label,
fde->dw_fde_hot_section_end_label);
add_ranges_by_labels (fde->dw_fde_unlikely_section_label,
fde->dw_fde_unlikely_section_end_label);
}
else
add_ranges_by_labels (fde->dw_fde_begin,
fde->dw_fde_end);
}
add_ranges (NULL);
}
/* Output location list section if necessary. */
if (have_location_lists)