This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH for debug/28063 - disabled string merging


While working on another project a few weeks ago I discovered that Geoff's
reference counting changes didn't correctly account for compilation unit
DIEs.  The consequence is that even with string merging turned on, in-place
strings would be emitted for filenames and the "GNU C ..." producer strings
in DWARF-2 compilation units, wasting space.  I moved the reference counting
update around the recursion slightly, and now it works.

Janis, I had to add a new effective target keyword, and it took a little
surgery.  Does this look OK?

Bootstrapped and tested on x86_64-pc-linux-gnu.  OK to commit?

-- 
Daniel Jacobowitz
CodeSourcery

2006-07-22  Daniel Jacobowitz  <dan@codesourcery.com>

	PR debug/28063
	* dwarf2out.c (prune_unused_types_prune): Move call to
	prune_unused_types_update_strings to cover the parent DIE also.

2006-07-22  Daniel Jacobowitz  <dan@codesourcery.com>

	PR debug/28063
	* gcc.dg/debug/dwarf2/dwarf-merge.c: New test.
	* lib/target-supports.exp (get_compiler_messages): Add WANT_CONTENTS.
	Optionally return assembly text.  Update callers.
	(check_no_messages_and_pattern): New.
	(check_effective_target_string_merging): New.

Index: testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c
===================================================================
--- testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c	(revision 0)
+++ testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c	(revision 0)
@@ -0,0 +1,10 @@
+/* Verify that mergeable strings are used in the CU DIE.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target string_merging } */
+/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-final { scan-assembler "DW_AT_producer: \"GNU C" } } */
+/* { dg-final { scan-assembler-not "GNU C\[^\\n\\r\]*DW_AT_producer" } } */
+
+void func (void)
+{
+}
Index: testsuite/lib/target-supports.exp
===================================================================
--- testsuite/lib/target-supports.exp	(revision 115676)
+++ testsuite/lib/target-supports.exp	(working copy)
@@ -23,11 +23,13 @@
 # Try to compile some code and return the messages printed by the compiler.
 #
 # BASENAME is a basename to use for temporary files.
+# WANT_CONTENTS is a flag indicating whether to return just the
+#   messages (0) or the messages and contents (1).
 # TYPE is the type of compilation to perform (see target_compile).
 # CONTENTS gives the contents of the input file.
 # The rest is optional:
 # OPTIONS: additional compiler options to use.
-proc get_compiler_messages {basename type contents args} {
+proc get_compiler_messages {basename want_contents type contents args} {
     global tool
 
     if { [llength $args] > 0 } {
@@ -46,9 +48,23 @@ proc get_compiler_messages {basename typ
     close $f
     set lines [${tool}_target_compile $src $output $type "$options"]
     file delete $src
-    remote_file build delete $output
 
-    return $lines
+    if { $want_contents && ![string match "" $lines] } {
+	set result [list $lines ""]
+    } elseif { $want_contents } {
+	set text ""
+	set chan [open "$output"]
+	while {[gets $chan line] >= 0} {
+	    append text "$line\n"
+	}
+	close $chan
+	set result [list $lines $text]
+    } else {
+	set result $lines
+    }
+
+    remote_file build delete $output
+    return $result
 }
 
 proc current_target_name { } {
@@ -74,7 +90,27 @@ proc check_no_compiler_messages {prop ar
 	verbose "check_effective_target $prop: compiling source for $target" 2
 	set et_cache($prop,target) $target
 	set et_cache($prop,value) \
-	    [string match "" [eval get_compiler_messages $prop $args]]
+	    [string match "" [eval get_compiler_messages $prop 0 $args]]
+    }
+    set value $et_cache($prop,value)
+    verbose "check_effective_target $prop: returning $value for $target" 2
+    return $value
+}
+
+# Similar to check_no_compiler_messages, but also verify that the regular
+# expression CONTENTS matches the compiler's output.
+proc check_no_messages_and_pattern {prop contents args} {
+    global et_cache
+
+    set target [current_target_name]
+    if {![info exists et_cache($prop,target)]
+	|| $et_cache($prop,target) != $target} {
+	verbose "check_effective_target $prop: compiling source for $target" 2
+	set et_cache($prop,target) $target
+	set results [eval get_compiler_messages $prop 1 $args]
+	set et_cache($prop,value) \
+	    [expr [string match "" [lindex $results 0]] \
+		 && [regexp $contents [lindex $results 1]]]
     }
     set value $et_cache($prop,value)
     verbose "check_effective_target $prop: returning $value for $target" 2
@@ -1074,7 +1110,7 @@ proc check_effective_target_lp64 { } {
 
 proc check_effective_target_dfp_nocache { } {
     verbose "check_effective_target_dfp_nocache: compiling source" 2
-    set ret [string match "" [get_compiler_messages dfp object {
+    set ret [string match "" [get_compiler_messages dfp 0 object {
         _Decimal32 x; _Decimal64 y; _Decimal128 z;
     }]]
     verbose "check_effective_target_dfp_nocache: returning $ret" 2
@@ -1783,3 +1819,11 @@ proc check_effective_target_short_enums 
     }]
 }
 
+# Return 1 if target supports merging string constants at link time.
+
+proc check_effective_target_string_merging { } {
+    return [check_no_messages_and_pattern string_merging \
+		"rodata\\.str" assembly {
+		    const char *var = "String";
+		} {-O2}]
+}
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 115676)
+++ dwarf2out.c	(working copy)
@@ -14040,6 +14040,7 @@ prune_unused_types_prune (dw_die_ref die
   dw_die_ref c;
 
   gcc_assert (die->die_mark);
+  prune_unused_types_update_strings (die);
 
   if (! die->die_child)
     return;
@@ -14064,7 +14065,6 @@ prune_unused_types_prune (dw_die_ref die
 
     if (c != prev->die_sib)
       prev->die_sib = c;
-    prune_unused_types_update_strings (c);
     prune_unused_types_prune (c);
   } while (c != die->die_child);
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]