This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [rtlopt] "variable tracking" pass
> > >this is a pass which computes where the variables are located at each
> > >position in code and generated notes which describe the location.
> > >The debug info is not generated from the notes yet (it segfaults when
> > >generating the debug info).
> >
> > This is because it's been ages since it's been updated.
> > If you like, I can redo it so it can generate the debug info again.
>
> That would be nice. Thank you.
>
> I have updated the garbage collector things, but it still segfaults,
> I know where but do not know what to do about it.
>
> I am going to send the debug info generator patch in the next mail.
Here is the patch. Teh place where it segfaults is marked with "FIXME"
word.
Josef
Index: dbxout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dbxout.c,v
retrieving revision 1.124.2.5
diff -u -c -3 -p -r1.124.2.5 dbxout.c
*** dbxout.c 11 Jan 2003 15:34:08 -0000 1.124.2.5
--- dbxout.c 14 Jan 2003 08:41:32 -0000
*************** const struct gcc_debug_hooks dbx_debug_h
*** 349,355 ****
dbxout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx /* label */
};
#endif /* DBX_DEBUGGING_INFO */
--- 349,356 ----
dbxout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx, /* label */
! debug_nothing_rtx /* var location */
};
#endif /* DBX_DEBUGGING_INFO */
Index: debug.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/debug.c,v
retrieving revision 1.10.2.1
diff -u -c -3 -p -r1.10.2.1 debug.c
*** debug.c 8 Dec 2002 14:36:20 -0000 1.10.2.1
--- debug.c 14 Jan 2003 08:41:32 -0000
*************** const struct gcc_debug_hooks do_nothing_
*** 43,49 ****
debug_nothing_tree, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx /* label */
};
/* This file contains implementations of each debug hook that do
--- 43,50 ----
debug_nothing_tree, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx, /* label */
! debug_nothing_rtx /* var location */
};
/* This file contains implementations of each debug hook that do
Index: debug.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/debug.h,v
retrieving revision 1.11.2.1
diff -u -c -3 -p -r1.11.2.1 debug.h
*** debug.h 16 Oct 2002 16:07:13 -0000 1.11.2.1
--- debug.h 14 Jan 2003 08:41:32 -0000
*************** struct gcc_debug_hooks
*** 101,106 ****
--- 101,108 ----
/* Called from final_scan_insn for any CODE_LABEL insn whose
LABEL_NAME is non-null. */
void (* label) PARAMS ((rtx));
+ /* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */
+ void (* var_location) PARAMS ((rtx));
};
extern const struct gcc_debug_hooks *debug_hooks;
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.382.2.4
diff -u -c -3 -p -r1.382.2.4 dwarf2out.c
*** dwarf2out.c 11 Jan 2003 15:34:08 -0000 1.382.2.4
--- dwarf2out.c 14 Jan 2003 08:41:33 -0000
*************** static void dwarf2out_end_block PARAMS
*** 3239,3244 ****
--- 3239,3246 ----
static bool dwarf2out_ignore_block PARAMS ((tree));
static void dwarf2out_global_decl PARAMS ((tree));
static void dwarf2out_abstract_function PARAMS ((tree));
+ static void dwarf2out_var_location PARAMS ((rtx));
+ static void dwarf2out_begin_function PARAMS ((tree));
/* The debug hooks structure. */
*************** const struct gcc_debug_hooks dwarf2_debu
*** 3257,3263 ****
dwarf2out_begin_prologue,
debug_nothing_int_charstar, /* end_prologue */
dwarf2out_end_epilogue,
! debug_nothing_tree, /* begin_function */
debug_nothing_int, /* end_function */
dwarf2out_decl, /* function_decl */
dwarf2out_global_decl,
--- 3259,3265 ----
dwarf2out_begin_prologue,
debug_nothing_int_charstar, /* end_prologue */
dwarf2out_end_epilogue,
! dwarf2out_begin_function,
debug_nothing_int, /* end_function */
dwarf2out_decl, /* function_decl */
dwarf2out_global_decl,
*************** const struct gcc_debug_hooks dwarf2_debu
*** 3266,3272 ****
emitting the abstract description of inline functions until
something tries to reference them. */
dwarf2out_abstract_function, /* outlining_inline_function */
! debug_nothing_rtx /* label */
};
#endif
--- 3268,3275 ----
emitting the abstract description of inline functions until
something tries to reference them. */
dwarf2out_abstract_function, /* outlining_inline_function */
! debug_nothing_rtx, /* label */
! dwarf2out_var_location
};
#endif
*************** static unsigned decl_die_table_in_use;
*** 3481,3486 ****
--- 3484,3506 ----
decl_die_table. */
#define DECL_DIE_TABLE_INCREMENT 256
+ struct var_loc_node GTY ((chain_next ("%h.next")))
+ {
+ rtx GTY (()) var_loc_note;
+ const char * GTY (()) label;
+ struct var_loc_node * GTY (()) next;
+ /* struct var_loc_node *last;*/
+ };
+ /* Unique label counter. */
+ static unsigned int loclabel_num = 0;
+ /* Table of decl location linked lists. */
+ static GTY ((length ("decl_loc_table_allocated"))) struct var_loc_node **decl_loc_table;
+ /* Number of elements in the decl_loc_table that are allocated. */
+ static unsigned decl_loc_table_allocated;
+ /* Number of elements in the decl_loc_table that are in use. */
+ static unsigned decl_loc_table_in_use;
+ #define DECL_LOC_TABLE_INCREMENT 256
+
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
children DIE's, and list of attribute/value pairs. */
*************** lookup_decl_die (decl)
*** 5270,5275 ****
--- 5290,5308 ----
return (decl_id < decl_die_table_in_use ? decl_die_table[decl_id] : NULL);
}
+ static struct var_loc_node * lookup_decl_loc PARAMS ((tree));
+ static void add_var_loc_to_decl PARAMS ((tree, struct var_loc_node *));
+
+ /* Return the var_loc list associated with a given declaration. */
+ static inline struct var_loc_node *
+ lookup_decl_loc (decl)
+ tree decl;
+ {
+ unsigned decl_id = DECL_UID (decl);
+
+ return (decl_id < decl_loc_table_in_use ? decl_loc_table[decl_id] : NULL);
+ }
+
/* Equate a DIE to a particular declaration. */
static void
*************** equate_decl_number_to_die (decl, decl_di
*** 5300,5305 ****
--- 5333,5390 ----
decl_die_table[decl_id] = decl_die;
}
+
+ /* Add a variable location node to the linked list for DECL. */
+ static void
+ add_var_loc_to_decl (decl, loc)
+ tree decl;
+ struct var_loc_node *loc;
+ {
+ unsigned int decl_id = DECL_UID (decl);
+ unsigned int num_allocated;
+ struct var_loc_node *temp;
+ if (decl_id >= decl_loc_table_allocated)
+ {
+ num_allocated
+ = ((decl_id + 1 + DECL_LOC_TABLE_INCREMENT - 1)
+ / DECL_LOC_TABLE_INCREMENT)
+ * DECL_LOC_TABLE_INCREMENT;
+
+ decl_loc_table
+ = (struct var_loc_node **) ggc_realloc (decl_loc_table,
+ sizeof (struct var_loc_node *) * num_allocated);
+
+ memset ((char *) &decl_loc_table[decl_loc_table_allocated], 0,
+ (num_allocated - decl_loc_table_allocated) * sizeof (struct var_loc_node *));
+ decl_loc_table_allocated = num_allocated;
+ }
+
+ if (decl_id >= decl_loc_table_in_use)
+ decl_loc_table_in_use = (decl_id + 1);
+
+ temp = decl_loc_table[decl_id];
+ if (!temp)
+ {
+ decl_loc_table[decl_id] = loc;
+ loc->next = NULL;
+ }
+ else
+ {
+ /* Get to the end of the list */
+ while (temp->next != NULL)
+ temp = temp->next;
+ /* If the current location is the same as the end of the list,
+ just extend the range of the location at the end of the
+ list. */
+ if (rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->var_loc_note), NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
+ temp->label = loc->label;
+ else
+ temp->next = loc;
+ }
+ /*
+ loc->next = decl_loc_table[decl_id];
+ decl_loc_table[decl_id] = loc;*/
+ }
/* Keep track of the number of spaces used to indent the
output of the debugging routines that print the structure of
*************** output_loc_list (list_head)
*** 6679,6691 ****
for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
{
unsigned long size;
!
! dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
! "Location list begin address (%s)",
! list_head->ll_symbol);
! dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section,
! "Location list end address (%s)",
! list_head->ll_symbol);
size = size_of_locs (curr->expr);
/* Output the block length for this list of location operations. */
--- 6764,6787 ----
for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
{
unsigned long size;
! if (separate_line_info_table_in_use == 0)
! {
! dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
! "Location list begin address (%s)",
! list_head->ll_symbol);
! dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section,
! "Location list end address (%s)",
! list_head->ll_symbol);
! }
! else
! {
! dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
! "Location list begin address (%s)",
! list_head->ll_symbol);
! dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->end,
! "Location list end address (%s)",
! list_head->ll_symbol);
! }
size = size_of_locs (curr->expr);
/* Output the block length for this list of location operations. */
*************** mem_loc_descriptor (rtl, mode)
*** 8404,8410 ****
--- 8500,8511 ----
else
return 0;
+ case LO_SUM:
+ return 0;
+
default:
+ fprintf (stderr, "\nInvalid mem_loc_descriptor RTL:\n");
+ print_rtl (stderr, rtl);
abort ();
}
*************** loc_descriptor (rtl)
*** 8452,8457 ****
--- 8553,8561 ----
{
dw_loc_descr_ref loc_result = NULL;
+ if (!rtl)
+ return 0;
+
switch (GET_CODE (rtl))
{
case SUBREG:
*************** loc_descriptor (rtl)
*** 8475,8483 ****
case CONCAT:
loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
break;
!
default:
! abort ();
}
return loc_result;
--- 8579,8613 ----
case CONCAT:
loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
break;
! case VAR_LOCATION:
! /* Single part */
! if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
! {
! loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0));
! }
! /* Multiple parts */
! else
! {
! rtvec par_elems = XVEC (XEXP (rtl, 1), 0);
! int num_elem = GET_NUM_ELEM (par_elems);
! enum machine_mode mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
! int i;
! /* Create the first one, so we have something to add to */
! loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
! add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
! for (i = 1; i < num_elem; i++)
! {
! dw_loc_descr_ref temp = NULL;
! temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
! add_loc_descr (&loc_result, temp);
! mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
! add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
!
! }
! }
! break;
default:
! return 0;
}
return loc_result;
*************** add_location_or_const_value_attribute (d
*** 9489,9500 ****
--- 9619,9676 ----
{
rtx rtl;
dw_loc_descr_ref descr;
+ struct var_loc_node *multiloc;
if (TREE_CODE (decl) == ERROR_MARK)
return;
else if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
abort ();
+ multiloc = lookup_decl_loc (decl);
+ if (multiloc && multiloc->next)
+ {
+ const char * secname;
+ const char *endname;
+ dw_loc_list_ref list;
+
+
+ if (DECL_SECTION_NAME (decl))
+ secname = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+ else if (current_function_decl
+ && DECL_SECTION_NAME (current_function_decl))
+ secname = TREE_STRING_POINTER (DECL_SECTION_NAME (current_function_decl));
+ else
+ secname = TEXT_SECTION_NAME;
+
+ list = new_loc_list (loc_descriptor (NOTE_VAR_LOCATION (multiloc->var_loc_note)),
+ multiloc->label, multiloc->next->label, secname, 1);
+ multiloc = multiloc->next;
+ while (multiloc->next)
+ {
+ add_loc_descr_to_loc_list (&list, loc_descriptor (NOTE_VAR_LOCATION (multiloc->var_loc_note)),
+ multiloc->label, multiloc->next->label, secname);
+ multiloc = multiloc->next;
+ }
+ if (multiloc)
+ {
+ char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
+
+ if (separate_line_info_table_in_use == 0)
+ endname = text_end_label;
+ else
+ { /* FIXME: segfault here because cfun == NULL. */
+ ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
+ current_function_funcdef_no);
+ endname = ggc_strdup (label_id);
+ }
+ add_loc_descr_to_loc_list (&list, loc_descriptor (NOTE_VAR_LOCATION (multiloc->var_loc_note)),
+ multiloc->label, endname, secname);
+ }
+ add_AT_loc_list (die, DW_AT_location, list);
+ return;
+ }
+
+
rtl = rtl_for_decl_location (decl);
if (rtl == NULL_RTX)
return;
*************** init_file_table ()
*** 12345,12351 ****
file_table.in_use = 1;
file_table.last_lookup_index = 0;
}
!
/* Output a label to mark the beginning of a source code line entry
and record information relating to this source line, in
'line_info_table' for later output of the .debug_line section. */
--- 12521,12562 ----
file_table.in_use = 1;
file_table.last_lookup_index = 0;
}
! /* Called by the final INSN scan whenever we see a var location. We
! use it to drop labels in the right places, and throw the location in
! our lookup table. */
! static void
! dwarf2out_var_location (loc_note)
! rtx loc_note;
! {
! char loclabel[MAX_ARTIFICIAL_LABEL_BYTES];
! struct var_loc_node *newloc;
!
! /* printf ("%p %p\n",
! NOTE_VAR_LOCATION_DECL (loc_note),
! NOTE_VAR_LOCATION_LOC (loc_note));*/
! if (!DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
! return;
! newloc = ggc_alloc_cleared (sizeof (struct var_loc_node));
! ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num++);
! ASM_OUTPUT_LABEL (asm_out_file, loclabel);
! newloc->label = ggc_strdup (loclabel);
! newloc->var_loc_note = loc_note;
!
! add_var_loc_to_decl (NOTE_VAR_LOCATION_DECL (loc_note), newloc);
! }
! /* We need to reset the locations at the beginning of each
! function. We can't do this in the end_function hook, because the
! declarations that use the locations won't have been outputted when
! that hook is called. */
!
! static void
! dwarf2out_begin_function (unused)
! tree unused ATTRIBUTE_UNUSED;
! {
! decl_loc_table_in_use = 0;
! memset (decl_loc_table, 0, sizeof (struct var_loc_node *)
! * decl_loc_table_allocated);
! }
/* Output a label to mark the beginning of a source code line entry
and record information relating to this source line, in
'line_info_table' for later output of the .debug_line section. */
*************** dwarf2out_init (main_input_filename)
*** 12536,12541 ****
--- 12747,12758 ----
decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
decl_die_table_in_use = 0;
+ /* Allocate the initial hunk of the decl_loc_table. */
+ decl_loc_table
+ = (struct var_loc_node **) ggc_alloc_cleared (DECL_LOC_TABLE_INCREMENT * sizeof (struct var_loc_node *));
+ decl_loc_table_allocated = DECL_LOC_TABLE_INCREMENT;
+ decl_loc_table_in_use = 0;
+
/* Allocate the initial hunk of the decl_scope_table. */
VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
Index: dwarfout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarfout.c,v
retrieving revision 1.115.2.3
diff -u -c -3 -p -r1.115.2.3 dwarfout.c
*** dwarfout.c 18 Dec 2002 10:35:13 -0000 1.115.2.3
--- dwarfout.c 14 Jan 2003 08:41:33 -0000
*************** const struct gcc_debug_hooks dwarf_debug
*** 1293,1299 ****
dwarfout_global_decl,
dwarfout_deferred_inline_function,
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx /* label */
};
/************************ general utility functions **************************/
--- 1293,1300 ----
dwarfout_global_decl,
dwarfout_deferred_inline_function,
debug_nothing_tree, /* outlining_inline_function */
! debug_nothing_rtx, /* label */
! debug_nothing_rtx /* var location */
};
/************************ general utility functions **************************/
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.266.2.8
diff -u -c -3 -p -r1.266.2.8 final.c
*** final.c 14 Jan 2003 08:14:35 -0000 1.266.2.8
--- final.c 14 Jan 2003 08:41:34 -0000
*************** final_scan_insn (insn, file, optimize, p
*** 1814,1819 ****
--- 1814,1820 ----
break;
case NOTE_INSN_VAR_LOCATION:
+ (*debug_hooks->var_location) (insn);
break;
case 0:
Index: sdbout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sdbout.c,v
retrieving revision 1.71.2.2
diff -u -c -3 -p -r1.71.2.2 sdbout.c
*** sdbout.c 8 Dec 2002 14:36:36 -0000 1.71.2.2
--- sdbout.c 14 Jan 2003 08:41:34 -0000
*************** const struct gcc_debug_hooks sdb_debug_h
*** 333,339 ****
sdbout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! sdbout_label
};
#if 0
--- 333,340 ----
sdbout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
! sdbout_label,
! debug_nothing_rtx /* var location */
};
#if 0
Index: vmsdbgout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/vmsdbgout.c,v
retrieving revision 1.19.2.3
diff -u -c -3 -p -r1.19.2.3 vmsdbgout.c
*** vmsdbgout.c 18 Dec 2002 10:35:29 -0000 1.19.2.3
--- vmsdbgout.c 14 Jan 2003 08:41:34 -0000
*************** const struct gcc_debug_hooks vmsdbg_debu
*** 189,195 ****
vmsdbgout_global_decl,
debug_nothing_tree, /* deferred_inline_function */
vmsdbgout_abstract_function,
! debug_nothing_rtx /* label */
};
/* Definitions of defaults for assembler-dependent names of various
--- 189,196 ----
vmsdbgout_global_decl,
debug_nothing_tree, /* deferred_inline_function */
vmsdbgout_abstract_function,
! debug_nothing_rtx, /* label */
! debug_nothing_rtx /* var location */
};
/* Definitions of defaults for assembler-dependent names of various