Boost logo

Boost :

From: Ben Young (ben.young_at_[hidden])
Date: 2003-10-01 04:14:19


Hi,

Here at Transversal we recently came upon the problem of really slow link
times, especially for our Boost Python library bindings, using gcc 3.2.1
and 3.2.3. Searching the internet suggested that the problem was in the
gcc constant merging across translation units which can be disabled using
-fno-merge-constants. However, this didn't fix the problem. Investigating
further it appeared that 90% of the time was spent merging the strings of
debug constants, and this wasn't being disabled by the option.

So we hacked gcc to add a new option which disables this merging. It took
our link times for our python bindings from 20mins (on a dual 1Ghz Athlon
with 1G ram) to just over 4s, a 300x improvement!

I inclose the patch below for all those interested. The option is
-fno-merge-debug-strs.

Cheers

Ben

---
P.S As far as I can tell it especially effected our python bindings due
to the massive number of symbols produced by boost::mpl. The problem in
gcc appears to be a merging algorithm which is quadratic in the number of
symbols!
diff -ur gcc-3.2.1/gcc/dwarf2out.c gcc-3.2.1-patched/gcc/dwarf2out.c
--- gcc-3.2.1/gcc/dwarf2out.c   2003-09-30 14:07:14.000000000 +0100
+++ gcc-3.2.1-patched/gcc/dwarf2out.c   2003-09-30 12:03:51.000000000 +0100
@@ -12112,7 +12112,11 @@
    if (node->form == DW_FORM_strp)
      {
-      named_section_flags (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS);
+      int flags = DEBUG_STR_SECTION_FLAGS;
+      if ( !flag_merge_debug_strs )
+       flags &=~ ( SECTION_MERGE | SECTION_STRINGS | SECTION_ENTSIZE );
+
+      named_section_flags (DEBUG_STR_SECTION, flags);
        ASM_OUTPUT_LABEL (asm_out_file, node->label);
        assemble_string ((const char *) HT_STR (&node->id),
                        HT_LEN (&node->id) + 1);
diff -ur gcc-3.2.1/gcc/flags.h gcc-3.2.1-patched/gcc/flags.h
--- gcc-3.2.1/gcc/flags.h       2003-09-30 14:07:14.000000000 +0100
+++ gcc-3.2.1-patched/gcc/flags.h       2003-09-30 11:05:07.000000000 +0100
@@ -566,6 +566,10 @@
     variables.  */
  extern int flag_merge_constants;
+
+/* This will attempt to merge .debug_str section strings */
+extern int flag_merge_debug_strs;
+
  /* If one, renumber instruction UIDs to reduce the number of
     unused UIDs if there are a lot of instructions.  If greater than
     one, unconditionally renumber instruction UIDs.  */
diff -ur gcc-3.2.1/gcc/toplev.c gcc-3.2.1-patched/gcc/toplev.c
--- gcc-3.2.1/gcc/toplev.c      2003-09-30 14:10:36.000000000 +0100
+++ gcc-3.2.1-patched/gcc/toplev.c      2003-09-30 11:04:24.000000000 +0100
@@ -862,6 +862,9 @@
     variables.  */
  int flag_merge_constants = 1;
+/* This will attempt to merge .debug_str section strings */
+int flag_merge_debug_strs = 1;
+
  /* If one, renumber instruction UIDs to reduce the number of
     unused UIDs if there are a lot of instructions.  If greater than
     one, unconditionally renumber instruction UIDs.  */
@@ -1120,9 +1123,11 @@
    {"align-functions", &align_functions, 0,
     N_("Align the start of functions") },
    {"merge-constants", &flag_merge_constants, 1,
-   N_("Attempt to merge identical constants accross compilation units") },
+   N_("Attempt to merge identical constants across compilation units") },
    {"merge-all-constants", &flag_merge_constants, 2,
     N_("Attempt to merge identical constants and constant variables") },
+  {"merge-debug-strs", &flag_merge_debug_strs, 1,
+   N_("Attempt to merge identical .debug_str strings across compilation 
units") },
    {"dump-unnumbered", &flag_dump_unnumbered, 1,
     N_("Suppress output of instruction numbers and line number notes in 
debugging dumps") },
    {"instrument-functions", &flag_instrument_function_entry_exit, 1,

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk