Performance bug while ordering .text sections by default in gold.

Sriraman Tallam tmsriram@google.com
Tue Jan 22 19:35:00 GMT 2013


Hi,

   This patch to gold :
http://sourceware.org/ml/binutils/2012-12/msg00227.html introduces
unnecessary behaviour while ordering text sections and this is causing
performance regressions in some benchmarks.  The intent of this patch
was to group .text sections with special prefixes like ".text.hot",
".text.unlikely" , ".text.startup" together, which it achieves.
However, it does other undesired things too like sorting section names
of those sections without these special prefixes.  This is because it
uses the compare function "Input_section_sort_compare" which was used
to sort ".ctors" and ".dtors". Sorting by section names can cause
undesired ordering like splitting functions in the same module.

   I am fixing this by making ".text" default sorting use the sort
function Input_section_sort_section_order_index_compare.  I think this
is better as the different comparison criteria are much less and is
all applicable to ".text" under different contexts.

  Patch attached.

Thanks
Sri
-------------- next part --------------
	* output.cc (Input_section_sort_compare): Remove check for
	special ordering of input section.
	(Input_section_sort_section_order_index_compare): Call
	compare_section_ordering to check for section order.  Sort
	sections with no names to the end.  Check if section name needs
	special ordering.


Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.180
diff -u -u -p -r1.180 output.cc
--- output.cc	7 Jan 2013 21:36:56 -0000	1.180
+++ output.cc	22 Jan 2013 19:14:14 -0000
@@ -3389,19 +3389,6 @@ Output_section::Input_section_sort_compa
       return s1.index() < s2.index();
     }
 
-  // Some input section names have special ordering requirements.
-  int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str());
-  int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str());
-  if (o1 != o2)
-    {
-      if (o1 < 0)
-	return false;
-      else if (o2 < 0)
-	return true;
-      else
-	return o1 < o2;
-    }
-
   // A section with a priority follows a section without a priority.
   bool s1_has_priority = s1.has_priority();
   bool s2_has_priority = s2.has_priority();
@@ -3498,14 +3485,37 @@ Output_section::Input_section_sort_secti
     const Output_section::Input_section_sort_entry& s1,
     const Output_section::Input_section_sort_entry& s2) const
 {
-  unsigned int s1_secn_index = s1.input_section().section_order_index();
-  unsigned int s2_secn_index = s2.input_section().section_order_index();
+  int sequence_num = s1.compare_section_ordering(s2);
+  // Section ordering can determine order.  If sequence_num is 0, an order
+  // does not exist.
+  if (sequence_num != 0)
+    return sequence_num == 1;
 
-  // Keep input order if section ordering cannot determine order.
-  if (s1_secn_index == s2_secn_index)
-    return s1.index() < s2.index();
+  // We sort all the sections with no names to the end.
+  if (!s1.section_has_name() || !s2.section_has_name())
+    {
+      if (s1.section_has_name())
+	return true;
+      if (s2.section_has_name())
+	return false;
+      return s1.index() < s2.index();
+    }
+ 
+  // Some input section names have special ordering requirements.
+  int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str());
+  int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str());
+  if (o1 != o2)
+    {
+      if (o1 < 0)
+	return false;
+      else if (o2 < 0)
+	return true;
+      else
+	return o1 < o2;
+    }
 
-  return s1_secn_index < s2_secn_index;
+  // Keep input order otherwise.
+  return s1.index() < s2.index();
 }
 
 // This updates the section order index of input sections according to the
@@ -3576,6 +3586,9 @@ Output_section::sort_attached_input_sect
           || this->type() == elfcpp::SHT_FINI_ARRAY)
         std::sort(sort_list.begin(), sort_list.end(),
 	          Input_section_sort_init_fini_compare());
+      else if (strcmp (this->name(), ".text") == 0)
+        std::sort(sort_list.begin(), sort_list.end(),
+	          Input_section_sort_section_order_index_compare());
       else
         std::sort(sort_list.begin(), sort_list.end(),
 	          Input_section_sort_compare());


More information about the Binutils mailing list