This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]