Performance bug while ordering .text sections by default in gold.
Sriraman Tallam
tmsriram@google.com
Thu Jan 24 00:44:00 GMT 2013
On Wed, Jan 23, 2013 at 3:06 PM, Ian Lance Taylor <iant@google.com> wrote:
> On Wed, Jan 23, 2013 at 2:50 PM, Sriraman Tallam <tmsriram@google.com> wrote:
>>
>> Attached new patch with the changes. Also added a new option to gold
>> "--notextreorder" to disable the default sorting.
>
>> + DEFINE_bool(notextreorder, options::TWO_DASHES, '\0', false,
>> + N_("Disable the default text section reordering where text "
>> + "sections with prefixes .text{unlikely,exit,startup,hot}"
>> + "are grouped"),
>> + NULL);
>
> Please name the option text_reorder, and make it boolean with a
> default of true. Also don't make the help text too long--take a look
> at the output of --help. That is, something like
>
> DEFINE_bool(text_reorder, options::TWO_DASHES, '\0', true,
> N_("Enable text section reordering for GCC section names"),
> N_("Disable...."));
>
>> + else if (strcmp (this->name(), ".text") == 0)
>
> No space before left parenthesis.
>
> This is OK with those changes.
Made those changes and also modified text_section_grouping to check if
--no-text-reorder does the right thing.
Thanks
Sri
>
> Thanks.
>
> Ian
-------------- next part --------------
* layout.cc (Layout::layout): Check for option text_reorder.
(Layout::make_output_section): Ditto.
* options.h (text_reorder): New option.
* output.cc (Input_section_sort_compare): Remove special ordering
of section names.
(Output_section::
Input_section_sort_section_name_special_ordering_compare::
operator()): New function.
(Output_section::sort_attached_input_sections): Use new sort function
for .text.
* output.h (Input_section_sort_section_name_special_ordering_compare):
New struct.
* testsuite/Makefile.am (text_section_grouping): Test option
--no-text-reorder
* testsuite/Makefile.in: Regenerate.
* testsuite/text_section_grouping.sh: Check order of functions without
default text reordering.
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.244
diff -u -u -p -r1.244 layout.cc
--- layout.cc 18 Jan 2013 17:43:57 -0000 1.244
+++ layout.cc 24 Jan 2013 00:40:23 -0000
@@ -1149,7 +1149,8 @@ Layout::layout(Sized_relobj_file<size, b
// By default the GNU linker sorts some special text sections ahead
// of others. We are compatible.
- if (!this->script_options_->saw_sections_clause()
+ if (parameters->options().text_reorder()
+ && !this->script_options_->saw_sections_clause()
&& !this->is_section_ordering_specified()
&& !parameters->options().relocatable()
&& Layout::special_ordering_of_input_section(name) >= 0)
@@ -1646,7 +1647,8 @@ Layout::make_output_section(const char*
// sections before other .text sections. We are compatible. We
// need to know that this might happen before we attach any input
// sections.
- if (!this->script_options_->saw_sections_clause()
+ if (parameters->options().text_reorder()
+ && !this->script_options_->saw_sections_clause()
&& !this->is_section_ordering_specified()
&& !parameters->options().relocatable()
&& strcmp(name, ".text") == 0)
Index: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.182
diff -u -u -p -r1.182 options.h
--- options.h 18 Jan 2013 17:44:31 -0000 1.182
+++ options.h 24 Jan 2013 00:40:23 -0000
@@ -878,6 +878,11 @@ class General_options
DEFINE_dirlist(library_path, options::TWO_DASHES, 'L',
N_("Add directory to search path"), N_("DIR"));
+ DEFINE_bool(text_reorder, options::TWO_DASHES, '\0', true,
+ N_("Enable text section reordering for GCC section names "
+ "(default)"),
+ N_("Disable text section reordering for GCC section names"));
+
DEFINE_bool(nostdlib, options::ONE_DASH, '\0', false,
N_(" Only search directories specified on the command line."),
NULL);
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 24 Jan 2013 00:40:23 -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();
@@ -3508,6 +3495,42 @@ Output_section::Input_section_sort_secti
return s1_secn_index < s2_secn_index;
}
+// Return true if S1 should come before S2. This is the sort comparison
+// function for .text to sort sections with prefixes
+// .text.{unlikely,exit,startup,hot} before other sections.
+bool
+Output_section::Input_section_sort_section_name_special_ordering_compare
+ ::operator()(
+ const Output_section::Input_section_sort_entry& s1,
+ const Output_section::Input_section_sort_entry& s2) const
+{
+ // 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;
+ }
+
+ // Keep input order otherwise.
+ return s1.index() < s2.index();
+}
+
// This updates the section order index of input sections according to the
// the order specified in the mapping from Section id to order index.
@@ -3576,6 +3599,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_name_special_ordering_compare());
else
std::sort(sort_list.begin(), sort_list.end(),
Input_section_sort_compare());
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.145
diff -u -u -p -r1.145 output.h
--- output.h 10 Jan 2013 00:18:14 -0000 1.145
+++ output.h 24 Jan 2013 00:40:23 -0000
@@ -4200,6 +4200,15 @@ class Output_section : public Output_dat
const Input_section_sort_entry&) const;
};
+ // This is the sort comparison function for .text to sort sections with
+ // prefixes .text.{unlikely,exit,startup,hot} before other sections.
+ struct Input_section_sort_section_name_special_ordering_compare
+ {
+ bool
+ operator()(const Input_section_sort_entry&,
+ const Input_section_sort_entry&) const;
+ };
+
// Fill data. This is used to fill in data between input sections.
// It is also used for data statements (BYTE, WORD, etc.) in linker
// scripts. When we have to keep track of the input sections, we
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.206
diff -u -u -p -r1.206 Makefile.am
--- testsuite/Makefile.am 14 Jan 2013 23:11:56 -0000 1.206
+++ testsuite/Makefile.am 24 Jan 2013 00:40:23 -0000
@@ -259,14 +259,18 @@ final_layout.stdout: final_layout
$(TEST_NM) -n --synthetic final_layout > final_layout.stdout
check_SCRIPTS += text_section_grouping.sh
-check_DATA += text_section_grouping.stdout
-MOSTLYCLEANFILES += text_section_grouping
+check_DATA += text_section_grouping.stdout text_section_no_grouping.stdout
+MOSTLYCLEANFILES += text_section_grouping text_section_no_grouping
text_section_grouping.o: text_section_grouping.cc
$(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
text_section_grouping: text_section_grouping.o gcctestdir/ld
$(CXXLINK) -Bgcctestdir/ text_section_grouping.o
+text_section_no_grouping: text_section_grouping.o gcctestdir/ld
+ $(CXXLINK) -Bgcctestdir/ -Wl,--no-text-reorder text_section_grouping.o
text_section_grouping.stdout: text_section_grouping
- $(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
+ $(TEST_NM) -n --synthetic text_section_grouping > text_section_grouping.stdout
+text_section_no_grouping.stdout: text_section_no_grouping
+ $(TEST_NM) -n --synthetic text_section_no_grouping > text_section_no_grouping.stdout
check_PROGRAMS += icf_virtual_function_folding_test
MOSTLYCLEANFILES += icf_virtual_function_folding_test icf_virtual_function_folding_test.map
Index: testsuite/text_section_grouping.sh
===================================================================
RCS file: /cvs/src/src/gold/testsuite/text_section_grouping.sh,v
retrieving revision 1.1
diff -u -u -p -r1.1 text_section_grouping.sh
--- testsuite/text_section_grouping.sh 19 Dec 2012 02:55:15 -0000 1.1
+++ testsuite/text_section_grouping.sh 24 Jan 2013 00:40:23 -0000
@@ -26,6 +26,8 @@
# according to prefix. .text.unlikely, .text.startup and .text.hot should
# be grouped and placed together.
+# Also check if the functions do not get grouped with option --no-text-reorder.
+
set -e
check()
@@ -63,3 +65,9 @@ check text_section_grouping.stdout "unli
check text_section_grouping.stdout "startup_bar" "hot_bar"
check text_section_grouping.stdout "unlikely_foo" "startup_bar"
check text_section_grouping.stdout "startup_foo" "hot_bar"
+
+check text_section_no_grouping.stdout "hot_foo" "startup_foo"
+check text_section_no_grouping.stdout "startup_foo" "unlikely_foo"
+check text_section_no_grouping.stdout "unlikely_foo" "hot_bar"
+check text_section_no_grouping.stdout "hot_bar" "startup_bar"
+check text_section_no_grouping.stdout "startup_bar" "unlikely_bar"
More information about the Binutils
mailing list