OSDN Git Service

* dwarf2out.c (dw_ranges_by_label_ref): New typedef.
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Jul 2007 08:30:24 +0000 (08:30 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Jul 2007 08:30:24 +0000 (08:30 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126357 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/dwarf2out.c

index fd78478..3ee94b1 100644 (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
index ffcce00..a54e517 100644 (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)