This patch is for the google/gcc-4_7 branch.

Backport pending upstream patch to output DW_AT_high_pc as a constant
instead of a relocated address.  This significantly reduces the number
of entries used in the .debug_addr table with -gfission.

Tested: Ran regression tests and validate-failures.py.


2012-04-27  Mark Wielaard  <m...@redhat.com>

        * dwarf2out.h (enum dw_val_class): Add dw_val_class_high_pc.
        * dwarf2out.c (dw_val_equal_p): Handle dw_val_class_high_pc.
        (add_AT_low_high_pc): New function.
        (AT_lbl): Handle dw_val_class_high_pc.
        (print_die): Likewise.
        (attr_checksum): Likewise.
        (attr_checksum_ordered): Likewise.
        (same_dw_val_p): Likewise.
        (size_of_die): Likewise.
        (value_format): Likewise.
        (output_die): Likewise.
        (gen_subprogram_die): Use add_AT_low_high_pc.
        (add_high_low_attributes): Likewise.
        (dwarf2out_finish): Likewise.


Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c     (revision 189857)
+++ gcc/dwarf2out.c     (working copy)
@@ -1666,6 +1666,7 @@ dw_val_equal_p (dw_val_node *a, dw_val_n
     case dw_val_class_fde_ref:
       return a->v.val_fde_index == b->v.val_fde_index;
     case dw_val_class_lbl_id:
+    case dw_val_class_high_pc:
       return strcmp (a->v.val_lbl_id, b->v.val_lbl_id) == 0;
     case dw_val_class_str:
       return a->v.val_str == b->v.val_str;
@@ -4549,6 +4550,35 @@ add_AT_data8 (dw_die_ref die, enum dwarf
   add_dwarf_attr (die, &attr);
 }
 
+/* Add DW_AT_low_pc and DW_AT_high_pc to a DIE.  */
+static inline void
+add_AT_low_high_pc (dw_die_ref die, const char *lbl_low, const char *lbl_high,
+                   bool force_direct)
+{
+  dw_attr_node attr;
+
+  attr.dw_attr = DW_AT_low_pc;
+  attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  attr.dw_attr_val.val_index = -1U;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_low);
+  add_dwarf_attr (die, &attr);
+  if (dwarf_split_debug_info && !force_direct)
+    set_AT_index (get_AT (die, DW_AT_low_pc), add_addr_table_entry (&attr));
+
+  attr.dw_attr = DW_AT_high_pc;
+  if (dwarf_version < 4)
+    attr.dw_attr_val.val_class = dw_val_class_lbl_id;
+  else
+    attr.dw_attr_val.val_class = dw_val_class_high_pc;
+  attr.dw_attr_val.val_index = -1U;
+  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_high);
+  add_dwarf_attr (die, &attr);
+  if (attr.dw_attr_val.val_class == dw_val_class_lbl_id
+      && dwarf_split_debug_info && !force_direct)
+    set_AT_index (get_AT (die, DW_AT_high_pc), add_addr_table_entry (&attr));
+
+}
+
 /* Hash and equality functions for debug_str_hash.  */
 
 static hashval_t
@@ -5005,7 +5035,8 @@ AT_lbl (dw_attr_ref a)
 {
   gcc_assert (a && (AT_class (a) == dw_val_class_lbl_id
                    || AT_class (a) == dw_val_class_lineptr
-                   || AT_class (a) == dw_val_class_macptr));
+                   || AT_class (a) == dw_val_class_macptr
+                   || AT_class (a) == dw_val_class_high_pc));
   return a->dw_attr_val.v.val_lbl_id;
 }
 
@@ -5884,6 +5915,7 @@ print_die (dw_die_ref die, FILE *outfile
        case dw_val_class_lbl_id:
        case dw_val_class_lineptr:
        case dw_val_class_macptr:
+       case dw_val_class_high_pc:
          fprintf (outfile, "label: %s", AT_lbl (a));
          break;
        case dw_val_class_str:
@@ -6040,6 +6072,7 @@ attr_checksum (dw_attr_ref at, struct md
     case dw_val_class_lbl_id:
     case dw_val_class_lineptr:
     case dw_val_class_macptr:
+    case dw_val_class_high_pc:
       break;
 
     case dw_val_class_file:
@@ -6312,6 +6345,7 @@ attr_checksum_ordered (enum dwarf_tag ta
     case dw_val_class_lbl_id:
     case dw_val_class_lineptr:
     case dw_val_class_macptr:
+    case dw_val_class_high_pc:
       break;
 
     case dw_val_class_file:
@@ -6771,6 +6805,7 @@ same_dw_val_p (const dw_val_node *v1, co
     case dw_val_class_lbl_id:
     case dw_val_class_lineptr:
     case dw_val_class_macptr:
+    case dw_val_class_high_pc:
       return 1;
 
     case dw_val_class_file:
@@ -8093,6 +8128,9 @@ size_of_die (dw_die_ref die)
        case dw_val_class_vms_delta:
          size += DWARF_OFFSET_SIZE;
          break;
+       case dw_val_class_high_pc:
+         size += DWARF2_ADDR_SIZE;
+         break;
        default:
          gcc_unreachable ();
        }
@@ -8412,6 +8450,17 @@ value_format (dw_attr_ref a)
     case dw_val_class_data8:
       return DW_FORM_data8;
 
+    case dw_val_class_high_pc:
+      switch (DWARF2_ADDR_SIZE)
+       {
+         case 4:
+           return DW_FORM_data4;
+         case 8:
+           return DW_FORM_data8;
+         default:
+           gcc_unreachable ();
+       }
+
     default:
       gcc_unreachable ();
     }
@@ -8918,6 +8967,11 @@ output_die (dw_die_ref die)
            break;
          }
 
+       case dw_val_class_high_pc:
+         dw2_asm_output_delta (DWARF2_ADDR_SIZE, AT_lbl (a),
+                               get_AT_low_pc (die), "DW_AT_high_pc");
+         break;
+
        default:
          gcc_unreachable ();
        }
@@ -17987,19 +18041,20 @@ gen_subprogram_die (tree decl, dw_die_re
          if (fde->dw_fde_begin)
            {
              /* We have already generated the labels.  */
-             add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin, false);
-             add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false);
+             add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
+                                 fde->dw_fde_end, false);
            }
          else
            {
              /* Create start/end labels and add the range.  */
-             char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
-             ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL,
-                                          FUNC_LABEL_ID (cfun));
-             add_AT_lbl_id (subr_die, DW_AT_low_pc, label_id, false);
-             ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
-                                          FUNC_LABEL_ID (cfun));
-             add_AT_lbl_id (subr_die, DW_AT_high_pc, label_id, false);
+             char label_id_low[MAX_ARTIFICIAL_LABEL_BYTES];
+             char label_id_high[MAX_ARTIFICIAL_LABEL_BYTES];
+             ASM_GENERATE_INTERNAL_LABEL (label_id_low, FUNC_BEGIN_LABEL,
+                                          current_function_funcdef_no);
+             ASM_GENERATE_INTERNAL_LABEL (label_id_high, FUNC_END_LABEL,
+                                          current_function_funcdef_no);
+             add_AT_low_high_pc (subr_die, label_id_low, label_id_high,
+                                 false);
            }
 
 #if VMS_DEBUGGING_INFO
@@ -18064,10 +18119,8 @@ gen_subprogram_die (tree decl, dw_die_re
                  dw_die_ref seg_die;
 
                  /* Do the 'primary' section.   */
-                 add_AT_lbl_id (subr_die, DW_AT_low_pc,
-                                fde->dw_fde_begin, false);
-                 add_AT_lbl_id (subr_die, DW_AT_high_pc,
-                                fde->dw_fde_end, false);
+                 add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
+                                     fde->dw_fde_end, false);
 
                  /* Build a minimal DIE for the secondary section.  */
                  seg_die = new_die (DW_TAG_subprogram,
@@ -18091,20 +18144,16 @@ gen_subprogram_die (tree decl, dw_die_re
                    add_AT_flag (seg_die, DW_AT_artificial, 1);
 
                  name = concat ("__second_sect_of_", name, NULL); 
-                 add_AT_lbl_id (seg_die, DW_AT_low_pc,
-                                fde->dw_fde_second_begin, false);
-                 add_AT_lbl_id (seg_die, DW_AT_high_pc,
-                                fde->dw_fde_second_end, false);
+                 add_AT_low_high_pc (seg_die, fde->dw_fde_second_begin,
+                                     fde->dw_fde_second_end, false);
                  add_name_attribute (seg_die, name);
                  if (want_pubnames ())
                    add_pubname_string (name, seg_die);
                }
            }
          else
-           {
-             add_AT_lbl_id (subr_die, DW_AT_low_pc, fde->dw_fde_begin, false);
-             add_AT_lbl_id (subr_die, DW_AT_high_pc, fde->dw_fde_end, false);
-           }
+           add_AT_low_high_pc (subr_die, fde->dw_fde_begin, fde->dw_fde_end,
+                               false);
        }
 
 #ifdef MIPS_DEBUGGING_INFO
@@ -18794,12 +18843,12 @@ add_high_low_attributes (tree stmt, dw_d
     }
   else
     {
+      char label_high[MAX_ARTIFICIAL_LABEL_BYTES];
       ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
                                   BLOCK_NUMBER (stmt));
-      add_AT_lbl_id (die, DW_AT_low_pc, label, false);
-      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_END_LABEL,
+      ASM_GENERATE_INTERNAL_LABEL (label_high, BLOCK_END_LABEL,
                                   BLOCK_NUMBER (stmt));
-      add_AT_lbl_id (die, DW_AT_high_pc, label, false);
+      add_AT_low_high_pc (die, label, label_high, false);
     }
 }
 
@@ -23543,12 +23592,8 @@ dwarf2out_finish (const char *filename)
     {
       /* Don't add if the CU has no associated code.  */
       if (text_section_used)
-       {
-         add_AT_lbl_id (main_comp_unit_die, DW_AT_low_pc, text_section_label,
-                        true);
-         add_AT_lbl_id (main_comp_unit_die, DW_AT_high_pc, text_end_label,
-                        true);
-       }
+       add_AT_low_high_pc (main_comp_unit_die, text_section_label,
+                           text_end_label, true);
     }
   else
     {
Index: gcc/dwarf2out.h
===================================================================
--- gcc/dwarf2out.h     (revision 189857)
+++ gcc/dwarf2out.h     (working copy)
@@ -154,7 +154,8 @@ enum dw_val_class
   dw_val_class_file,
   dw_val_class_data8,
   dw_val_class_decl_ref,
-  dw_val_class_vms_delta
+  dw_val_class_vms_delta,
+  dw_val_class_high_pc
 };
 
 /* Describe a floating point constant value, or a vector constant value.  */

--
This patch is available for review at http://codereview.appspot.com/6453046

Reply via email to