icf_safe_test in gold fails with gcc-4.0.3

Sriraman Tallam tmsriram@google.com
Thu Dec 31 02:03:00 GMT 2009


Hi,

   Here is a patch to allow ICF to fold .gnu.linkonce.t sections.

	* gc.h (gc_process_relocs): Call is_section_foldable_candidate to
	check for .text or .gnu.linkonce.t sections.
	* icf.cc (Icf::find_identical_sections): Ditto.
	Change the detection for mangled function name within the section
	name.
	* icf.h (is_section_foldable_candidate): New function.

Please let me know what you think.

Thanks,
-Sri.


On Tue, Dec 29, 2009 at 7:14 PM, Ian Lance Taylor <iant@google.com> wrote:
> Sriraman Tallam <tmsriram@google.com> writes:
>
>>    With gcc-4.0.3, icf_safe_test fails.
>>
>> Safe Identical Code Folding did not fold  _ZN1AD1Ev and _ZN1AC1Ev
>> FAIL: icf_safe_test.sh
>>
>> This is because gcc-4.0.3 puts constructors and destructors in
>> .gnu.linkonce.t sections whereas gcc-4.4, on which ICF was tested,
>> puts them in .text sections. I can modify ICF to also fold
>> .gnu.linkonce.t sections and that should solve the problem. Would this
>> be alright ?
>
> Folding .gnu.linkonce sections should be fine.  Don't get confused by
> the fact that duplicate .gnu.linkonce sections with the same names are
> discarded.  .gnu.linkonce is the old mechanism which is now done using
> SHT_GROUP.
>
> Ian
>
-------------- next part --------------
Index: gc.h
===================================================================
RCS file: /cvs/src/src/gold/gc.h,v
retrieving revision 1.5
diff -u -u -p -r1.5 gc.h
--- gc.h	29 Oct 2009 05:16:23 -0000	1.5
+++ gc.h	31 Dec 2009 01:58:40 -0000
@@ -163,7 +163,7 @@ gc_process_relocs(
   bool is_icf_tracked = false;
 
   if (parameters->options().icf_enabled()
-      && is_prefix_of(".text.", (src_obj)->section_name(src_indx).c_str()))
+      && is_section_foldable_candidate(src_obj->section_name(src_indx).c_str()))
     {
       is_icf_tracked = true;
       Section_id src_id(src_obj, src_indx);
Index: icf.cc
===================================================================
RCS file: /cvs/src/src/gold/icf.cc,v
retrieving revision 1.6
diff -u -u -p -r1.6 icf.cc
--- icf.cc	14 Dec 2009 19:53:04 -0000	1.6
+++ icf.cc	31 Dec 2009 01:58:40 -0000
@@ -23,7 +23,7 @@
 // Identical Code Folding Algorithm
 // ----------------------------------
 // Detecting identical functions is done here and the basic algorithm
-// is as follows.  A checksum is computed on each .text section using
+// is as follows.  A checksum is computed on each foldable section using
 // its contents and relocations.  If the symbol name corresponding to
 // a relocation is known it is used to compute the checksum.  If the
 // symbol name is not known the stringified name of the object and the
@@ -34,8 +34,8 @@
 // checking the contents when two sections have the same checksum.
 //
 // However, two functions A and B with identical text but with
-// relocations pointing to different .text sections can be identical if
-// the corresponding .text sections to which their relocations point to
+// relocations pointing to different foldable sections can be identical if
+// the corresponding foldable sections to which their relocations point to
 // turn out to be identical.  Hence, this checksumming process must be
 // done repeatedly until convergence is obtained.  Here is an example for
 // the following case :
@@ -102,7 +102,7 @@
 // behaviour.
 //
 //
-// How to run  : --icf
+// How to run  : --icf=[safe|all|none]
 // Optional parameters : --icf-iterations <num> --print-icf-sections
 //
 // Performance : Less than 20 % link-time overhead on industry strength
@@ -570,17 +570,20 @@ Icf::find_identical_sections(const Input
       for (unsigned int i = 0;i < (*p)->shnum(); ++i)
         {
 	  const char* section_name = (*p)->section_name(i).c_str();
-          // Only looking to fold functions, so just look at .text sections.
-          if (!is_prefix_of(".text.", section_name))
+          if (!is_section_foldable_candidate(section_name))
             continue;
           if (!(*p)->is_section_included(i))
             continue;
           if (parameters->options().gc_sections()
               && symtab->gc()->is_section_garbage(*p, i))
               continue;
-	  // With --icf=safe, check if mangled name is a ctor or a dtor.
+	  // With --icf=safe, check if the mangled function name is a ctor
+	  // or a dtor.  The mangled function name can be obtained from the
+	  // section name by stripping the section prefix.
+	  const char* mangled_func_name = strrchr(section_name, '.');
+	  gold_assert(mangled_func_name != NULL);
 	  if (parameters->options().icf_safe_folding()
-	      && !is_function_ctor_or_dtor(section_name + 6))
+	      && !is_function_ctor_or_dtor(mangled_func_name + 1))
 	    continue;
           this->id_section_.push_back(Section_id(*p, i));
           this->section_id_[Section_id(*p, i)] = section_num;
Index: icf.h
===================================================================
RCS file: /cvs/src/src/gold/icf.h,v
retrieving revision 1.2
diff -u -u -p -r1.2 icf.h
--- icf.h	12 Aug 2009 19:03:16 -0000	1.2
+++ icf.h	31 Dec 2009 01:58:40 -0000
@@ -139,6 +139,17 @@ class Icf
   Addend_list addend_reloc_list_;
 };
 
+// This function returns true if this section corresponds to a function that
+// should be considered by icf as a possible candidate for folding.  Some
+// earlier gcc versions, like 4.0.3, put constructors and destructors in
+// .gnu.linkonce.t sections and hence should be included too.
+inline bool
+is_section_foldable_candidate(const char* section_name)
+{
+  return (is_prefix_of(".text", section_name)
+          || is_prefix_of(".gnu.linkonce.t", section_name));
+}
+
 } // End of namespace gold.
 
 #endif


More information about the Binutils mailing list