The enclosed patch for Google 4.7 is an optimization for debug strings
under -gsplit-dwarf. Currently under -gsplit-dwarf, all strings with
DW_FORM_strp end up in the .debug_str.dwo section, which requires any
string not destined for the .dwo to use DW_FORM_string, disallowing any
duplication removal.
With this patch, gcc creates a normal .debug_str section even under
-gsplit-dwarf, and puts any DW_FORM_strp string destined for the .o
file into that section.
Tested with full bootstrap and the gdb test suite.
OK for Google 4.7?
When stage 1 opens again, I expect I will port it there as well.
Sterling
Index: gcc/dwarf2out.c
===
--- gcc/dwarf2out.c (revision 195673)
+++ gcc/dwarf2out.c (working copy)
@@ -166,6 +166,7 @@
static GTY(()) section *debug_pubnames_section;
static GTY(()) section *debug_pubtypes_section;
static GTY(()) section *debug_str_section;
+static GTY(()) section *debug_str_dwo_section;
static GTY(()) section *debug_str_offsets_section;
static GTY(()) section *debug_ranges_section;
static GTY(()) section *debug_frame_section;
@@ -217,6 +218,28 @@
static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
+/* With split_debug_info, both the comp_dir and dwo_name go in the
+ main object file, rather than the dwo, similar to the force_direct
+ parameter elsewhere but with additional complications:
+
+ 1) The string is needed in both the main object file and the dwo.
+ That is, the comp_dir and dwo_name will appear in both places.
+
+ 2) Strings can use three forms: DW_FORM_string, DW_FORM_strp or
+ DW_FORM_GNU_str_index.
+
+ 3) GCC chooses the form to use late, depending on the size and
+ reference count.
+
+ Rather than forcing the all debug string handling functions and
+ callers to deal with these complications, simply use a separate,
+ special-cased string table for any attribute that should go in the
+ main object file. This limits the complexity to just the places
+ that need it. */
+
+static GTY ((param_is (struct indirect_string_node)))
+ htab_t skeleton_debug_str_hash;
+
static GTY(()) int dw2_string_counter;
/* True if the compilation unit places functions in more than one section. */
@@ -3593,6 +3616,8 @@
static void schedule_generic_params_dies_gen (tree t);
static void gen_scheduled_generic_parms_dies (void);
+static const char *comp_dir_string (void);
+
/* enum for tracking thread-local variables whose address is really an offset
relative to the TLS pointer, which will need link-time relocation, but will
not need relocation by the DWARF consumer. */
@@ -3710,11 +3735,11 @@
(!dwarf_split_debug_info \
? (DEBUG_NORM_STR_OFFSETS_SECTION) : (DEBUG_DWO_STR_OFFSETS_SECTION))
#endif
-#define DEBUG_DWO_STR_SECTION .debug_str.dwo
-#define DEBUG_NORM_STR_SECTION .debug_str
+#ifndef DEBUG_STR_DWO_SECTION
+#define DEBUG_STR_DWO_SECTION .debug_str.dwo
+#endif
#ifndef DEBUG_STR_SECTION
-#define DEBUG_STR_SECTION \
- (!dwarf_split_debug_info ? (DEBUG_NORM_STR_SECTION) :
(DEBUG_DWO_STR_SECTION))
+#define DEBUG_STR_SECTION .debug_str
#endif
#ifndef DEBUG_RANGES_SECTION
#define DEBUG_RANGES_SECTION .debug_ranges
@@ -3726,17 +3751,18 @@
#endif
/* Section flags for .debug_macinfo/.debug_macro section. */
-#define DEBUG_MACRO_SECTION_FLAGS \
+#define DEBUG_MACRO_SECTION_FLAGS \
(dwarf_split_debug_info ? SECTION_DEBUG | SECTION_EXCLUDE : SECTION_DEBUG)
/* Section flags for .debug_str section. */
-#define DEBUG_STR_SECTION_FLAGS \
- (dwarf_split_debug_info \
- ? SECTION_DEBUG | SECTION_EXCLUDE \
- : (HAVE_GAS_SHF_MERGE flag_merge_debug_strings \
- ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1\
- : SECTION_DEBUG))
+#define DEBUG_STR_SECTION_FLAGS \
+ (HAVE_GAS_SHF_MERGE flag_merge_debug_strings \
+ ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1\
+ : SECTION_DEBUG)
+/* Section flags for .debug_str.dwo section. */
+#define DEBUG_STR_DWO_SECTION_FLAGS (SECTION_DEBUG | SECTION_EXCLUDE)
+
/* Labels we insert at beginning sections we can reference instead of
the section names themselves. */
@@ -4658,19 +4684,15 @@
(const char *)x2) == 0;
}
-/* Add STR to the indirect string hash table. */
+/* Add STR to the given string hash table. */
static struct indirect_string_node *
-find_AT_string (const char *str)
+find_AT_string_in_table (const char *str, htab_t table)
{
struct indirect_string_node *node;
void **slot;
- if (! debug_str_hash)
-debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
- debug_str_eq, NULL);
-
- slot = htab_find_slot_with_hash (debug_str_hash, str,
+ slot = htab_find_slot_with_hash (table, str,