[google/4.6] Fix problems with -gfission (issue5844043)

2012-03-19 Thread Cary Coutant
This is for the google/gcc-4_6 branch only.

This revised patch fixes several problems with -gfission:
 - Bad index for range list in the compile unit DIE.
 - DW_AT_ranges attribute for compile unit in the wrong file.
 - Incorrect size for skeleton type unit DIEs.
 - Wrote location expression using DW_OP_addr to DWO file.
 - Emitted skeleton debug section even when there is no debug info.

It also addresses a problem with the previous patch that resulted
in an ICE when a location expression is removed after creating
an addr_table entry for it.

Tested: bootstrap, core, mantle, crust (in progress).


2012-03-19  Sterling Augustine  saugust...@google.com
Cary Coutant  ccout...@google.com

* dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_addr_index.
(new_loc_descr): Initialize val_index.
(size_of_loc_descr): Add DW_OP_GNU_addr_index.
(output_loc_operands): Likewise.
(output_loc_operands_raw): Likewise.
(build_cfa_loc): Initialize val_index.
(new_addr_loc_descr): New function.
(add_AT_flag): Initialize val_index.
(add_AT_int): Likewise.
(add_AT_unsigned): Likewise.
(add_AT_double): Likewise.
(add_AT_vec): Likewise.
(add_AT_data8): Likewise.
(add_AT_string): Likewise.
(add_AT_die_ref): Likewise.
(add_AT_fde_ref): Likewise.
(add_AT_loc): Likewise.
(add_AT_loc_list): Likewise.
(add_addr_table_entry): Change if to assert.
(remove_addr_table_entry): New function.
(add_AT_addr): Add force_direct parameter; adjust all callers.
Initialize val_index.
(add_AT_file): Initialize val_index.
(add_AT_vms_delta): Likewise.
(add_AT_lbl_id): Add force_direct parameter; adjust all callers.
Initialize val_index.
(add_AT_lineptr): Initialize val_index.
(add_AT_macptr): Likewise.
(add_AT_offset): Likewise.
(add_AT_range_list): Add force_direct parameter; adjust all callers.
Initialize val_index.
(size_of_die): Check for AT_index.
(value_format): Likewise.
(output_attr_index_or_value): Likewise.
(output_die): Fix format warning.
(add_top_level_skeleton_die_attrs): Don't add DW_AT_stmt_list here.
(get_skeleton_type_unit): New function.
(output_skeleton_debug_sections): Add comp_unit parameter; adjust
caller; don't generate debug_skeleton_info_section_label or
debug_skeleton_abbrev_section_label here; call get_skeleton_type_unit.
(output_comdat_type_unit): Remove assert; call get_skeleton_type_unit.
(add_ranges_by_labels): Add force_direct parameter; adjust callers.
(address_of_int_loc_descriptor): Initialize val_index.
(mem_loc_descriptor): Initialize val_index; call new_addr_loc_descr.
(implicit_ptr_descriptor): Don't generate DW_OP_GNU_implicit_pointer
when splitting debug info.  Initialize val_index.
(loc_descriptor): Initialize val_index; call new_addr_loc_descr.
(loc_list_from_tree): Likewise.
(add_const_value_attribute): Likewise.
(dwarf2out_init): Generate debug_skeleton_info_section_label and
debug_skeleton_abbrev_section_label here.
(output_indirect_string): Check for DW_FORM_strp instead of label
and refcount.
(output_addr_table): Check for removed entries, handle
dw_val_class_loc.
(resolve_addr_in_expr): Handle DW_OP_GNU_addr_index.
(resolve_addr): Remove entry from addr_table if necessary.
(hash_loc_operands): Add DW_OP_GNU_addr_index.
(compare_loc_operands): Likewise.
(dwarf2out_finish): Put DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges,
DW_AT_stmt_list, DW_AT_macptr in skeleton comp_unit DIE; write
skeleton debug sections if regular debug section emitted.


Index: dwarf2out.c
===
--- dwarf2out.c (revision 18)
+++ dwarf2out.c (working copy)
@@ -4779,6 +4779,8 @@ dwarf_stack_op_name (unsigned int op)
   return DW_OP_GNU_encoded_addr;
 case DW_OP_GNU_implicit_pointer:
   return DW_OP_GNU_implicit_pointer;
+case DW_OP_GNU_addr_index:
+  return DW_OP_GNU_addr_index;
 
 default:
   return OP_unknown;
@@ -4797,8 +4799,10 @@ new_loc_descr (enum dwarf_location_atom 
 
   descr-dw_loc_opc = op;
   descr-dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
+  descr-dw_loc_oprnd1.val_index = -1U;
   descr-dw_loc_oprnd1.v.val_unsigned = oprnd1;
   descr-dw_loc_oprnd2.val_class = dw_val_class_unsigned_const;
+  descr-dw_loc_oprnd2.val_index = -1U;
   descr-dw_loc_oprnd2.v.val_unsigned = oprnd2;
 
   return descr;
@@ -4897,6 +4901,9 @@ size_of_loc_descr (dw_loc_descr_ref loc)
 case DW_OP_addr:
   size += DWARF2_ADDR_SIZE;
   break;
+case DW_OP_GNU_addr_index:
+  size += size_of_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned);

[google/4.6] Fix problems with -gfission (issue5844043)

2012-03-15 Thread Cary Coutant
For google/gcc-4_6 branch.

This patch fixes several problems with -gfission:
 - Bad index for range list in the compile unit DIE.
 - DW_AT_ranges attribute for compile unit in the wrong file.
 - Incorrect size for skeleton type unit DIEs.
 - Wrote location expression using DW_OP_addr to DWO file.
 - Emitted skeleton debug section even when there is no debug info.

Tested: bootstrap, gcc regression tests, hand testing on -gfission
test cases.


include/

2012-03-15   Sterling Augustine  saugust...@google.com
 Cary Coutant  ccout...@google.com

* dwarf2.h (enum dwarf_location_atom): Add
DW_OP_GNU_addr_index.

gcc/

2012-03-15   Sterling Augustine  saugust...@google.com
 Cary Coutant  ccout...@google.com

* dwarf2out.c (dwarf_stack_op_name): Add DW_OP_GNU_addr_index.
(size_of_loc_descr): Likewise.
(output_loc_operands): Likewise.
(output_loc_operands_raw): Likewise.
(new_addr_loc_descr): New function.
(add_AT_range_list): Store index in AT_index.
(size_of_die): For range_list, use AT_index for index value.
(add_top_level_skeleton_die_attrs): Don't add DW_AT_stmt_list here.
(get_skeleton_type_unit): New function.
(output_skeleton_debug_sections): Add comp_unit parameter; adjust
caller.  Don't allocate new comp unit DIE here.  Move allocation
of debug_skeleton_info_section_label and
debug_skeleton_abbrev_section_label to dwarf2out_init.  Call
get_skeleton_type_unit.
(output_comdat_type_unit): Remove assert; call get_skeleton_type_unit.
(mem_loc_descriptor): Call new_addr_loc_desc.
(loc_descriptor): Likewise.
(loc_list_from_tree): Likewise.
(add_const_value_attribute): Likewise.
(dwarf2out_init): Allocate debug_skeleton_info_section_label and
debug_skeleton_abbrev_section_label.
(output_indirect_string): Check for DW_FORM_strp instead of label
and refcount.
(output_addr_table): Add case for dw_val_class_loc.
(resolve_addr_in_expr): Handle DW_OP_addr_index.
(hash_loc_operands): Likewise.
(compare_loc_operands): Likewise.
(dwarf2out_finish): Allocate skeleton compile unit DIE here; add
range lists, DW_AT_stmt_list, and DW_AT_macro_info to it instead
of dwo compile unit DIE.  Output skeleton debug info section only
if there is debug info.


Index: include/dwarf2.h
===
--- include/dwarf2.h(revision 185451)
+++ include/dwarf2.h(working copy)
@@ -547,6 +547,8 @@ enum dwarf_location_atom
 DW_OP_GNU_uninit = 0xf0,
 DW_OP_GNU_encoded_addr = 0xf1,
 DW_OP_GNU_implicit_pointer = 0xf2,
+/* Extension for Fission.  See http://gcc.gnu.org/wiki/DebugFission.  */
+DW_OP_GNU_addr_index = 0xfb,
 /* HP extensions.  */
 DW_OP_HP_unknown = 0xe0, /* Ouch, the same as GNU_push_tls_address.  */
 DW_OP_HP_is_value= 0xe1,
Index: gcc/dwarf2out.c
===
--- gcc/dwarf2out.c (revision 185451)
+++ gcc/dwarf2out.c (working copy)
@@ -4779,6 +4779,8 @@ dwarf_stack_op_name (unsigned int op)
   return DW_OP_GNU_encoded_addr;
 case DW_OP_GNU_implicit_pointer:
   return DW_OP_GNU_implicit_pointer;
+case DW_OP_GNU_addr_index:
+  return DW_OP_GNU_addr_index;
 
 default:
   return OP_unknown;
@@ -4897,6 +4899,9 @@ size_of_loc_descr (dw_loc_descr_ref loc)
 case DW_OP_addr:
   size += DWARF2_ADDR_SIZE;
   break;
+case DW_OP_GNU_addr_index:
+  size += size_of_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned);
+  break;
 case DW_OP_const1u:
 case DW_OP_const1s:
   size += 1;
@@ -5275,6 +5280,11 @@ output_loc_operands (dw_loc_descr_ref lo
}
   break;
 
+case DW_OP_GNU_addr_index:
+  dw2_asm_output_data_uleb128 (loc-dw_loc_oprnd1.v.val_unsigned,
+   (address index));
+  break;
+
 case DW_OP_GNU_implicit_pointer:
   {
char label[MAX_ARTIFICIAL_LABEL_BYTES
@@ -5343,6 +5353,7 @@ output_loc_operands_raw (dw_loc_descr_re
   switch (loc-dw_loc_opc)
 {
 case DW_OP_addr:
+case DW_OP_GNU_addr_index:
 case DW_OP_implicit_value:
   /* We cannot output addresses in .cfi_escape, only bytes.  */
   gcc_unreachable ();
@@ -6314,6 +6325,7 @@ static inline dw_loc_descr_ref AT_loc (d
 static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute,
 dw_loc_list_ref);
 static inline dw_loc_list_ref AT_loc_list (dw_attr_ref);
+static unsigned int add_addr_table_entry (dw_attr_node *);
 static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
 static inline rtx AT_addr (dw_attr_ref);
 static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
@@ -6571,6 +6583,31 @@ static bool generic_type_p (tree);
 static void