dwarf2out.c (add_var_loc_to_decl): Add LABEL argument.
* dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop last chain entry if it starts with the still current label. (add_location_or_const_value_attribute): Check that loc_list->first->next is NULL instead of comparing ->first with ->last. (dwarf2out_var_location): Pass last_label resp. last_postcall_label to add_var_loc_to_decl. From-SVN: r158590
This commit is contained in:
parent
8f65940dd1
commit
0f2f44c007
@ -1,5 +1,13 @@
|
||||
2010-04-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* dwarf2out.c (add_var_loc_to_decl): Add LABEL argument. Drop
|
||||
last chain entry if it starts with the still current label.
|
||||
(add_location_or_const_value_attribute): Check that
|
||||
loc_list->first->next is NULL instead of comparing ->first with
|
||||
->last.
|
||||
(dwarf2out_var_location): Pass last_label resp. last_postcall_label
|
||||
to add_var_loc_to_decl.
|
||||
|
||||
* dwarf2out.c (output_call_frame_info): For dw_cie_version
|
||||
>= 4 add also address size and segment size fields into CIE
|
||||
header.
|
||||
|
@ -5748,8 +5748,12 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node {
|
||||
struct GTY (()) var_loc_list_def {
|
||||
struct var_loc_node * GTY (()) first;
|
||||
|
||||
/* Do not mark the last element of the chained list because
|
||||
it is marked through the chain. */
|
||||
/* Pointer to the last but one or last element of the
|
||||
chained list. If the list is empty, both first and
|
||||
last are NULL, if the list contains just one node
|
||||
or the last node certainly is not redundant, it points
|
||||
to the last node, otherwise points to the last but one.
|
||||
Do not mark it for GC because it is marked through the chain. */
|
||||
struct var_loc_node * GTY ((skip ("%h"))) last;
|
||||
|
||||
/* DECL_UID of the variable decl. */
|
||||
@ -5991,7 +5995,7 @@ static hashval_t decl_loc_table_hash (const void *);
|
||||
static int decl_loc_table_eq (const void *, const void *);
|
||||
static var_loc_list *lookup_decl_loc (const_tree);
|
||||
static void equate_decl_number_to_die (tree, dw_die_ref);
|
||||
static struct var_loc_node *add_var_loc_to_decl (tree, rtx);
|
||||
static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *);
|
||||
static void print_spaces (FILE *);
|
||||
static void print_die (dw_die_ref, FILE *);
|
||||
static void print_dwarf_line_table (FILE *);
|
||||
@ -7755,7 +7759,7 @@ equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
|
||||
/* Add a variable location node to the linked list for DECL. */
|
||||
|
||||
static struct var_loc_node *
|
||||
add_var_loc_to_decl (tree decl, rtx loc_note)
|
||||
add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
|
||||
{
|
||||
unsigned int decl_id = DECL_UID (decl);
|
||||
var_loc_list *temp;
|
||||
@ -7774,23 +7778,62 @@ add_var_loc_to_decl (tree decl, rtx loc_note)
|
||||
|
||||
if (temp->last)
|
||||
{
|
||||
struct var_loc_node *last = temp->last, *unused = NULL;
|
||||
if (last->next)
|
||||
{
|
||||
last = last->next;
|
||||
gcc_assert (last->next == NULL);
|
||||
}
|
||||
/* TEMP->LAST here is either pointer to the last but one or
|
||||
last element in the chained list, LAST is pointer to the
|
||||
last element. */
|
||||
/* If the last note doesn't cover any instructions, remove it. */
|
||||
if (label && strcmp (last->label, label) == 0)
|
||||
{
|
||||
if (temp->last != last)
|
||||
{
|
||||
temp->last->next = NULL;
|
||||
unused = last;
|
||||
last = temp->last;
|
||||
gcc_assert (strcmp (last->label, label) != 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (temp->first == temp->last);
|
||||
memset (temp->last, '\0', sizeof (*temp->last));
|
||||
return temp->last;
|
||||
}
|
||||
}
|
||||
/* If the current location is the same as the end of the list,
|
||||
and either both or neither of the locations is uninitialized,
|
||||
we have nothing to do. */
|
||||
if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note),
|
||||
if ((!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last->var_loc_note),
|
||||
NOTE_VAR_LOCATION_LOC (loc_note)))
|
||||
|| ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
|
||||
|| ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
|
||||
!= NOTE_VAR_LOCATION_STATUS (loc_note))
|
||||
&& ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
|
||||
&& ((NOTE_VAR_LOCATION_STATUS (last->var_loc_note)
|
||||
== VAR_INIT_STATUS_UNINITIALIZED)
|
||||
|| (NOTE_VAR_LOCATION_STATUS (loc_note)
|
||||
== VAR_INIT_STATUS_UNINITIALIZED))))
|
||||
{
|
||||
/* Add LOC to the end of list and update LAST. */
|
||||
loc = GGC_CNEW (struct var_loc_node);
|
||||
temp->last->next = loc;
|
||||
temp->last = loc;
|
||||
/* Add LOC to the end of list and update LAST. If the last
|
||||
element of the list has been removed above, reuse its
|
||||
memory for the new node, otherwise allocate a new one. */
|
||||
if (unused)
|
||||
{
|
||||
loc = unused;
|
||||
memset (loc, '\0', sizeof (*loc));
|
||||
}
|
||||
else
|
||||
loc = GGC_CNEW (struct var_loc_node);
|
||||
last->next = loc;
|
||||
/* Ensure TEMP->LAST will point either to the new last but one
|
||||
element of the chain, or to the last element in it. */
|
||||
if (last != temp->last)
|
||||
temp->last = last;
|
||||
}
|
||||
else if (unused)
|
||||
ggc_free (unused);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -15925,7 +15968,7 @@ add_location_or_const_value_attribute (dw_die_ref die, tree decl,
|
||||
loc_list = lookup_decl_loc (decl);
|
||||
if (loc_list
|
||||
&& loc_list->first
|
||||
&& loc_list->first == loc_list->last
|
||||
&& loc_list->first->next == NULL
|
||||
&& NOTE_VAR_LOCATION (loc_list->first->var_loc_note)
|
||||
&& NOTE_VAR_LOCATION_LOC (loc_list->first->var_loc_note))
|
||||
{
|
||||
@ -20384,22 +20427,33 @@ dwarf2out_var_location (rtx loc_note)
|
||||
if (next_real == NULL_RTX)
|
||||
return;
|
||||
|
||||
/* If there were any real insns between note we processed last time
|
||||
and this note (or if it is the first note), clear
|
||||
last_{,postcall_}label so that they are not reused this time. */
|
||||
if (last_var_location_insn == NULL_RTX
|
||||
|| last_var_location_insn != next_real
|
||||
|| last_in_cold_section_p != in_cold_section_p)
|
||||
{
|
||||
last_label = NULL;
|
||||
last_postcall_label = NULL;
|
||||
}
|
||||
|
||||
decl = NOTE_VAR_LOCATION_DECL (loc_note);
|
||||
newloc = add_var_loc_to_decl (decl, loc_note);
|
||||
newloc = add_var_loc_to_decl (decl, loc_note,
|
||||
NOTE_DURING_CALL_P (loc_note)
|
||||
? last_postcall_label : last_label);
|
||||
if (newloc == NULL)
|
||||
return;
|
||||
|
||||
/* If there were no real insns between note we processed last time
|
||||
and this note, use the label we emitted last time. */
|
||||
if (last_var_location_insn == NULL_RTX
|
||||
|| last_var_location_insn != next_real
|
||||
|| last_in_cold_section_p != in_cold_section_p)
|
||||
and this note, use the label we emitted last time. Otherwise
|
||||
create a new label and emit it. */
|
||||
if (last_label == NULL)
|
||||
{
|
||||
ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);
|
||||
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num);
|
||||
loclabel_num++;
|
||||
last_label = ggc_strdup (loclabel);
|
||||
last_postcall_label = NULL;
|
||||
}
|
||||
newloc->var_loc_note = loc_note;
|
||||
newloc->next = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user