Patchwork [4/6] dwarf2out: Convert fde_table to a VEC.

login
register
mail settings
Submitter Richard Henderson
Date July 3, 2011, 8:01 p.m.
Message ID <1309723308-26667-5-git-send-email-rth@redhat.com>
Download mbox | patch
Permalink /patch/103032/
State New
Headers show

Comments

Richard Henderson - July 3, 2011, 8:01 p.m.
Prepare for allocating the FDE for the current function earlier
than dwarf2out_begin_prologue.
---
 gcc/dwarf2cfi.c |   16 +++---
 gcc/dwarf2out.c |  172 +++++++++++++++++++++----------------------------------
 gcc/dwarf2out.h |    6 +-
 gcc/function.h  |    6 ++
 4 files changed, 84 insertions(+), 116 deletions(-)

Patch

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index cd22e53..3e63299 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -294,7 +294,7 @@  add_fde_cfi (dw_cfi_ref cfi)
     }
   else
     {
-      dw_fde_ref fde = current_fde ();
+      dw_fde_ref fde = cfun->fde;
       VEC_safe_push (dw_cfi_ref, gc, fde->dw_fde_cfi, cfi);
       dwarf2out_emit_cfi (cfi);
     }
@@ -468,7 +468,7 @@  lookup_cfa (dw_cfa_location *loc)
   FOR_EACH_VEC_ELT (dw_cfi_ref, cie_cfi_vec, ix, cfi)
     lookup_cfa_1 (cfi, loc, &remember);
 
-  fde = current_fde ();
+  fde = cfun->fde;
   if (fde)
     FOR_EACH_VEC_ELT (dw_cfi_ref, fde->dw_fde_cfi, ix, cfi)
       lookup_cfa_1 (cfi, loc, &remember);
@@ -599,8 +599,8 @@  static void
 reg_save (bool for_cie, unsigned int reg, unsigned int sreg,
           HOST_WIDE_INT offset)
 {
+  dw_fde_ref fde = for_cie ? NULL : cfun->fde;
   dw_cfi_ref cfi = new_cfi ();
-  dw_fde_ref fde = current_fde ();
 
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
 
@@ -1652,7 +1652,7 @@  dwarf2out_frame_debug_cfa_window_save (void)
   Rule 16:
   (set sp (and: sp <const_int>))
   constraints: cfa_store.reg == sp
-  effects: current_fde.stack_realign = 1
+  effects: cfun->fde.stack_realign = 1
            cfa_store.offset = 0
 	   fde->drap_reg = cfa.reg if cfa.reg != sp and cfa.reg != fp
 
@@ -1742,7 +1742,7 @@  dwarf2out_frame_debug_expr (rtx expr)
 	src = rsi;
     }
 
-  fde = current_fde ();
+  fde = cfun->fde;
 
   switch (GET_CODE (dest))
     {
@@ -2268,7 +2268,7 @@  dwarf2out_frame_debug (rtx insn, bool after_p)
 	n = XEXP (note, 0);
 	if (REG_P (n))
 	  {
-	    dw_fde_ref fde = current_fde ();
+	    dw_fde_ref fde = cfun->fde;
 	    if (fde)
 	      {
 		gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
@@ -2387,7 +2387,7 @@  cfi_label_required_p (dw_cfi_ref cfi)
 static void
 add_cfis_to_fde (void)
 {
-  dw_fde_ref fde = current_fde ();
+  dw_fde_ref fde = cfun->fde;
   rtx insn, next;
   /* We always start with a function_begin label.  */
   bool first = false;
@@ -2611,7 +2611,7 @@  dwarf2cfi_function_init (void)
 /* Run once.  */
 
 void
-dwarf2cfi_frame_init (void)
+dwarf2out_frame_init (void)
 {
   dw_cfa_location loc;
 
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index b655a2a..0f93964 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -233,33 +233,12 @@  static GTY(()) section *debug_frame_section;
 #define DWARF_CIE_ID DW_CIE_ID
 #endif
 
-/* A pointer to the base of a table that contains frame description
-   information for each routine.  */
-static GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table;
-
-/* Number of elements currently allocated for fde_table.  */
-static GTY(()) unsigned fde_table_allocated;
-
-/* Number of elements in fde_table currently in use.  */
-static GTY(()) unsigned fde_table_in_use;
-
-/* Size (in elements) of increments by which we may expand the
-   fde_table.  */
-#define FDE_TABLE_INCREMENT 256
-
-/* Get the current fde_table entry we should use.  */
-
-dw_fde_ref
-current_fde (void)
-{
-  return fde_table_in_use ? &fde_table[fde_table_in_use - 1] : NULL;
-}
+DEF_VEC_P (dw_fde_ref);
+DEF_VEC_ALLOC_P (dw_fde_ref, gc);
 
-/* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram
-   attribute that accelerates the lookup of the FDE associated
-   with the subprogram.  This variable holds the table index of the FDE
-   associated with the current function (body) definition.  */
-static unsigned current_funcdef_fde;
+/* A vector for a table that contains frame description
+   information for each routine.  */
+static GTY(()) VEC(dw_fde_ref, gc) *fde_vec;
 
 struct GTY(()) indirect_string_node {
   const char *str;
@@ -1313,7 +1292,7 @@  output_call_frame_info (int for_eh)
   int dw_cie_version;
 
   /* Don't emit a CIE if there won't be any FDEs.  */
-  if (fde_table_in_use == 0)
+  if (fde_vec == NULL)
     return;
 
   /* Nothing to do if the assembler's doing it all.  */
@@ -1330,14 +1309,15 @@  output_call_frame_info (int for_eh)
     {
       bool any_eh_needed = false;
 
-      for (i = 0; i < fde_table_in_use; i++)
-	if (fde_table[i].uses_eh_lsda)
-	  any_eh_needed = any_lsda_needed = true;
-	else if (fde_needed_for_eh_p (&fde_table[i]))
-	  any_eh_needed = true;
-	else if (TARGET_USES_WEAK_UNWIND_INFO)
-	  targetm.asm_out.emit_unwind_label (asm_out_file, fde_table[i].decl,
-					     1, 1);
+      FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, i, fde)
+	{
+	  if (fde->uses_eh_lsda)
+	    any_eh_needed = any_lsda_needed = true;
+	  else if (fde_needed_for_eh_p (fde))
+	    any_eh_needed = true;
+	  else if (TARGET_USES_WEAK_UNWIND_INFO)
+	    targetm.asm_out.emit_unwind_label (asm_out_file, fde->decl, 1, 1);
+	}
 
       if (!any_eh_needed)
 	return;
@@ -1490,10 +1470,9 @@  output_call_frame_info (int for_eh)
   ASM_OUTPUT_LABEL (asm_out_file, l2);
 
   /* Loop through all of the FDE's.  */
-  for (i = 0; i < fde_table_in_use; i++)
+  FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, i, fde)
     {
       unsigned int k;
-      fde = &fde_table[i];
 
       /* Don't emit EH unwind info for leaf functions that don't need it.  */
       if (for_eh && !fde_needed_for_eh_p (fde))
@@ -1564,6 +1543,31 @@  dwarf2out_do_cfi_startproc (bool second)
     }
 }
 
+/* Allocate CURRENT_FDE.  Immediately initialize all we can, noting that
+   this allocation may be done before pass_final.  */
+
+dw_fde_ref
+dwarf2out_alloc_current_fde (void)
+{
+  dw_fde_ref fde;
+
+  fde = ggc_alloc_cleared_dw_fde_node ();
+  fde->decl = current_function_decl;
+  fde->funcdef_number = current_function_funcdef_no;
+  fde->fde_index = VEC_length (dw_fde_ref, fde_vec);
+  fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
+  fde->uses_eh_lsda = crtl->uses_eh_lsda;
+  fde->nothrow = crtl->nothrow;
+  fde->drap_reg = INVALID_REGNUM;
+  fde->vdrap_reg = INVALID_REGNUM;
+
+  /* Record the FDE associated with this function.  */
+  cfun->fde = fde;
+  VEC_safe_push (dw_fde_ref, gc, fde_vec, fde);
+
+  return fde;
+}
+
 /* Output a marker (i.e. a label) for the beginning of a function, before
    the prologue.  */
 
@@ -1601,39 +1605,12 @@  dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   if (!do_frame)
     return;
 
-  /* Expand the fde table if necessary.  */
-  if (fde_table_in_use == fde_table_allocated)
-    {
-      fde_table_allocated += FDE_TABLE_INCREMENT;
-      fde_table = GGC_RESIZEVEC (dw_fde_node, fde_table, fde_table_allocated);
-      memset (fde_table + fde_table_in_use, 0,
-	      FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
-    }
-
-  /* Record the FDE associated with this function.  */
-  current_funcdef_fde = fde_table_in_use;
-
-  /* Add the new FDE at the end of the fde_table.  */
-  fde = &fde_table[fde_table_in_use++];
-  fde->decl = current_function_decl;
+  /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
+  fde = dwarf2out_alloc_current_fde ();
   fde->dw_fde_begin = dup_label;
-  fde->dw_fde_end = NULL;
   fde->dw_fde_current_label = dup_label;
-  fde->dw_fde_second_begin = NULL;
-  fde->dw_fde_second_end = NULL;
-  fde->dw_fde_vms_end_prologue = NULL;
-  fde->dw_fde_vms_begin_epilogue = NULL;
-  fde->dw_fde_cfi = VEC_alloc (dw_cfi_ref, gc, 20);
-  fde->dw_fde_switch_cfi_index = 0;
-  fde->funcdef_number = current_function_funcdef_no;
-  fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
-  fde->uses_eh_lsda = crtl->uses_eh_lsda;
-  fde->nothrow = crtl->nothrow;
-  fde->drap_reg = INVALID_REGNUM;
-  fde->vdrap_reg = INVALID_REGNUM;
   fde->in_std_section = (fnsec == text_section
 			 || (cold_text_section && fnsec == cold_text_section));
-  fde->second_in_std_section = 0;
 
   dwarf2cfi_function_init ();
 
@@ -1669,7 +1646,6 @@  void
 dwarf2out_vms_end_prologue (unsigned int line ATTRIBUTE_UNUSED,
 			const char *file ATTRIBUTE_UNUSED)
 {
-  dw_fde_ref fde;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
   /* Output a label to mark the endpoint of the code generated for this
@@ -1678,8 +1654,7 @@  dwarf2out_vms_end_prologue (unsigned int line ATTRIBUTE_UNUSED,
 			       current_function_funcdef_no);
   ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL,
 			  current_function_funcdef_no);
-  fde = &fde_table[fde_table_in_use - 1];
-  fde->dw_fde_vms_end_prologue = xstrdup (label);
+  cfun->fde->dw_fde_vms_end_prologue = xstrdup (label);
 }
 
 /* Output a marker (i.e. a label) for the beginning of the generated code
@@ -1690,10 +1665,9 @@  void
 dwarf2out_vms_begin_epilogue (unsigned int line ATTRIBUTE_UNUSED,
 			  const char *file ATTRIBUTE_UNUSED)
 {
-  dw_fde_ref fde;
+  dw_fde_ref fde = cfun->fde;
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
 
-  fde = &fde_table[fde_table_in_use - 1];
   if (fde->dw_fde_vms_begin_epilogue)
     return;
 
@@ -1727,24 +1701,13 @@  dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
   ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
 			       current_function_funcdef_no);
   ASM_OUTPUT_LABEL (asm_out_file, label);
-  fde = current_fde ();
+  fde = cfun->fde;
   gcc_assert (fde != NULL);
   if (fde->dw_fde_second_begin == NULL)
     fde->dw_fde_end = xstrdup (label);
 }
 
 void
-dwarf2out_frame_init (void)
-{
-  /* Allocate the initial hunk of the fde_table.  */
-  fde_table = ggc_alloc_cleared_vec_dw_fde_node (FDE_TABLE_INCREMENT);
-  fde_table_allocated = FDE_TABLE_INCREMENT;
-  fde_table_in_use = 0;
-
-  dwarf2cfi_frame_init ();
-}
-
-void
 dwarf2out_frame_finish (void)
 {
   /* Output call frame information.  */
@@ -1776,7 +1739,7 @@  void
 dwarf2out_switch_text_section (void)
 {
   section *sect;
-  dw_fde_ref fde = current_fde ();
+  dw_fde_ref fde = cfun->fde;
 
   gcc_assert (cfun && fde && fde->dw_fde_second_begin == NULL);
 
@@ -8460,12 +8423,11 @@  size_of_aranges (void)
     size += 2 * DWARF2_ADDR_SIZE;
   if (have_multiple_function_sections)
     {
-      unsigned fde_idx = 0;
+      unsigned fde_idx;
+      dw_fde_ref fde;
 
-      for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
+      FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, fde_idx, fde)
 	{
-	  dw_fde_ref fde = &fde_table[fde_idx];
-
 	  if (!fde->in_std_section)
 	    size += 2 * DWARF2_ADDR_SIZE;
 	  if (fde->dw_fde_second_begin && !fde->second_in_std_section)
@@ -9353,12 +9315,11 @@  output_aranges (unsigned long aranges_length)
 
   if (have_multiple_function_sections)
     {
-      unsigned fde_idx = 0;
+      unsigned fde_idx;
+      dw_fde_ref fde;
 
-      for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
+      FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, fde_idx, fde)
 	{
-	  dw_fde_ref fde = &fde_table[fde_idx];
-
 	  if (!fde->in_std_section)
 	    {
 	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
@@ -10924,7 +10885,7 @@  based_loc_descr (rtx reg, HOST_WIDE_INT offset,
 {
   unsigned int regno;
   dw_loc_descr_ref result;
-  dw_fde_ref fde = current_fde ();
+  dw_fde_ref fde = cfun->fde;
 
   /* We only use "frame base" when we're sure we're talking about the
      post-prologue local stack frame.  We do this by *not* running
@@ -13489,7 +13450,7 @@  dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 		&& (node != loc_list->first || loc_list->first->next)
 		&& current_function_decl)
 	      {
-		endname = current_fde ()->dw_fde_end;
+		endname = cfun->fde->dw_fde_end;
 		range_across_switch = true;
 	      }
 	    /* The variable has a location between NODE->LABEL and
@@ -13532,9 +13493,9 @@  dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
 		if (node->next)
 		  endname = node->next->label;
 		else
-		  endname = current_fde ()->dw_fde_second_end;
+		  endname = cfun->fde->dw_fde_second_end;
 		*listp = new_loc_list (descr,
-				       current_fde ()->dw_fde_second_begin,
+				       cfun->fde->dw_fde_second_begin,
 				       endname, secname);
 		listp = &(*listp)->dw_loc_next;
 	      }
@@ -15640,7 +15601,7 @@  convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
   const char *start_label, *last_label, *section;
   dw_cfa_location remember;
 
-  fde = current_fde ();
+  fde = cfun->fde;
   gcc_assert (fde != NULL);
 
   section = secname_for_decl (current_function_decl);
@@ -17660,7 +17621,7 @@  gen_subprogram_die (tree decl, dw_die_ref context_die)
 
       if (!flag_reorder_blocks_and_partition)
 	{
-	  dw_fde_ref fde = &fde_table[current_funcdef_fde];
+	  dw_fde_ref fde = cfun->fde;
 	  if (fde->dw_fde_begin)
 	    {
 	      /* We have already generated the labels.  */
@@ -17706,9 +17667,9 @@  gen_subprogram_die (tree decl, dw_die_ref context_die)
 	  add_pubname (decl, subr_die);
 	}
       else
-	{  /* Generate pubnames entries for the split function code
-	      ranges.  */
-	  dw_fde_ref fde = &fde_table[current_funcdef_fde];
+	{
+	  /* Generate pubnames entries for the split function code ranges.  */
+	  dw_fde_ref fde = cfun->fde;
 
 	  if (fde->dw_fde_second_begin)
 	    {
@@ -17789,7 +17750,7 @@  gen_subprogram_die (tree decl, dw_die_ref context_die)
 
 #ifdef MIPS_DEBUGGING_INFO
       /* Add a reference to the FDE for this routine.  */
-      add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, current_funcdef_fde);
+      add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, cfun->fde->index);
 #endif
 
       cfa_fb_offset = CFA_FRAME_BASE_OFFSET (decl);
@@ -22444,7 +22405,8 @@  dwarf2out_finish (const char *filename)
     }
   else
     {
-      unsigned fde_idx = 0;
+      unsigned fde_idx;
+      dw_fde_ref fde;
       bool range_list_added = false;
 
       if (text_section_used)
@@ -22454,10 +22416,8 @@  dwarf2out_finish (const char *filename)
 	add_ranges_by_labels (comp_unit_die (), cold_text_section_label,
 			      cold_end_label, &range_list_added);
 
-      for (fde_idx = 0; fde_idx < fde_table_in_use; fde_idx++)
+      FOR_EACH_VEC_ELT (dw_fde_ref, fde_vec, fde_idx, fde)
 	{
-	  dw_fde_ref fde = &fde_table[fde_idx];
-
 	  if (!fde->in_std_section)
 	    add_ranges_by_labels (comp_unit_die (), fde->dw_fde_begin,
 				  fde->dw_fde_end, &range_list_added);
diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h
index 2c02b94..abc2208 100644
--- a/gcc/dwarf2out.h
+++ b/gcc/dwarf2out.h
@@ -88,7 +88,10 @@  typedef struct GTY(()) dw_fde_struct {
   cfi_vec dw_fde_cfi;
   int dw_fde_switch_cfi_index; /* Last CFI before switching sections.  */
   HOST_WIDE_INT stack_realignment;
+
   unsigned funcdef_number;
+  unsigned fde_index;
+
   /* Dynamic realign argument pointer register.  */
   unsigned int drap_reg;
   /* Virtual dynamic realign argument pointer register.  */
@@ -215,7 +218,6 @@  dw_loc_descr_node;
 
 
 /* Interface from dwarf2out.c to dwarf2cfi.c.  */
-extern dw_fde_ref current_fde (void);
 extern struct dw_loc_descr_struct *build_cfa_loc
   (dw_cfa_location *, HOST_WIDE_INT);
 extern struct dw_loc_descr_struct *build_cfa_aligned_loc
@@ -224,9 +226,9 @@  extern struct dw_loc_descr_struct *mem_loc_descriptor
   (rtx, enum machine_mode mode, enum machine_mode mem_mode,
    enum var_init_status);
 extern enum machine_mode get_address_mode (rtx mem);
+extern dw_fde_ref dwarf2out_alloc_current_fde (void);
 
 /* Interface from dwarf2cfi.c to dwarf2out.c.  */
-extern void dwarf2cfi_frame_init (void);
 extern void dwarf2cfi_function_init (void);
 extern void lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc,
 			  dw_cfa_location *remember);
diff --git a/gcc/function.h b/gcc/function.h
index 3b572cc..ff193bc 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -169,6 +169,7 @@  struct gimple_df;
 struct temp_slot;
 typedef struct temp_slot *temp_slot_p;
 struct call_site_record_d;
+struct dw_fde_struct;
 
 DEF_VEC_P(temp_slot_p);
 DEF_VEC_ALLOC_P(temp_slot_p,gc);
@@ -542,6 +543,11 @@  struct GTY(()) function {
   /* Used types hash table.  */
   htab_t GTY ((param_is (union tree_node))) used_types_hash;
 
+  /* Dwarf2 Frame Description Entry, containing the Call Frame Instructions
+     used for unwinding.  Only set when either dwarf2 unwinding or dwarf2
+     debugging is enabled.  */
+  struct dw_fde_struct *fde;
+
   /* Last statement uid.  */
   int last_stmt_uid;