Sriraman Tallam <tmsriram@google.com>
authorSriraman Tallam <tmsriram@google.com>
Wed, 12 Aug 2009 19:03:16 +0000 (19:03 +0000)
committerSriraman Tallam <tmsriram@google.com>
Wed, 12 Aug 2009 19:03:16 +0000 (19:03 +0000)
* icf.cc (Icf::find_identical_sections): Unfold symbols that have
been maked as --keep-unique.
(Icf::unfold_section): New function.
* icf.h (Icf::unfold_section): New function.
* options.h (General_options::keep_unique): New option.
* testsuite/Makefile.am: Add commands to build icf_keep_unique_test.
* testsuite/Makefile.in: Regenerate.
* testsuite/icf_keep_unique_test.sh: New file.
* testsuite/icf_keep_unique_test.cc: New file.

gold/ChangeLog
gold/icf.cc
gold/icf.h
gold/options.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/icf_keep_unique_test.cc [new file with mode: 0644]
gold/testsuite/icf_keep_unique_test.sh [new file with mode: 0755]

index 9c5518e4a102dd15a6a1c36ca41f89fda3f28bf6..0f97482c2e573dd255596ce4b8be705fcec81415 100644 (file)
@@ -1,3 +1,15 @@
+2009-08-12  Sriraman Tallam  <tmsriram@google.com>
+
+       * icf.cc (Icf::find_identical_sections): Unfold symbols that have
+       been maked as --keep-unique.
+       (Icf::unfold_section): New function.
+       * icf.h (Icf::unfold_section): New function.
+       * options.h (General_options::keep_unique): New option.
+       * testsuite/Makefile.am: Add commands to build icf_keep_unique_test.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/icf_keep_unique_test.sh: New file.
+       * testsuite/icf_keep_unique_test.cc: New file.
+
 2009-08-12  Cary Coutant  <ccoutant@google.com>
 
        PR 10471
index 55d8ea4f2a4ef0d0bf435293a0a333c05e27abc6..6f9592279c7ce83a7a165db06a3f9801f9c87f15 100644 (file)
@@ -598,9 +598,47 @@ Icf::find_identical_sections(const Input_objects* input_objects,
                   program_name, num_iterations);
     }
 
+  // Unfold --keep-unique symbols.
+  for (options::String_set::const_iterator p =
+        parameters->options().keep_unique_begin();
+       p != parameters->options().keep_unique_end();
+       ++p)
+    {
+      const char* name = p->c_str();
+      Symbol* sym = symtab->lookup(name);
+      if (sym != NULL
+         && sym->source() == Symbol::FROM_OBJECT 
+          && !sym->object()->is_dynamic())
+        {
+          Object* obj = sym->object();
+          bool is_ordinary;
+          unsigned int shndx = sym->shndx(&is_ordinary);
+          if (is_ordinary)
+            {
+             this->unfold_section(obj, shndx);
+            }
+        }
+
+    }
+
   this->icf_ready();
 }
 
+// Unfolds the section denoted by OBJ and SHNDX if folded.
+
+void
+Icf::unfold_section(Object* obj, unsigned int shndx)
+{
+  Section_id secn(obj, shndx);
+  Uniq_secn_id_map::iterator it = this->section_id_.find(secn);
+  if (it == this->section_id_.end())
+    return;
+  unsigned int section_num = it->second;
+  unsigned int kept_section_id = this->kept_section_id_[section_num];
+  if (kept_section_id != section_num)
+    this->kept_section_id_[section_num] = section_num;
+}
+
 // This function determines if the section corresponding to the
 // given object and index is folded based on if the kept section
 // is different from this section.
index 965964d2ecbe1d3209847455847f6209be721f34..b87b992a93efd3ec2ffd3dfd417d967b051aa801 100644 (file)
@@ -87,6 +87,10 @@ class Icf
   is_icf_ready()
   { return this->icf_ready_; }
 
+  // Unfolds the section denoted by OBJ and SHNDX if folded.
+  void
+  unfold_section(Object* obj, unsigned int shndx);
+
   // Returns the kept section corresponding to the 
   // given section.
   bool
index eeade6fe28be9c883390ae10999a8aaf9037d731..8d444ca066031617a44a2ed8952999803e3357f4 100644 (file)
@@ -814,7 +814,7 @@ class General_options
                  N_("Do not link against shared libraries"), NULL);
 
   DEFINE_bool(icf, options::TWO_DASHES, '\0', false,
-              N_("Fold identical functions"),
+              N_("Identical Code Folding (Fold identical functions)"),
               N_("Don't fold identical functions (default)"));
 
   DEFINE_uint(icf_iterations, options::TWO_DASHES , '\0', 0,
@@ -824,6 +824,9 @@ class General_options
               N_("List folded identical sections on stderr"),
               N_("Do not list folded identical sections"));
 
+  DEFINE_set(keep_unique, options::TWO_DASHES, '\0',
+            N_("Do not fold this symbol during ICF"), N_("SYMBOL"));
+
   DEFINE_bool(gc_sections, options::TWO_DASHES, '\0', false,
               N_("Remove unused sections"),
               N_("Don't remove unused sections (default)"));
index 6e3169d1778a5d531a028a95dfd98a54386c1ec5..e8d03f5f2b3372d17c3736d6f545d7e9e32a774a 100644 (file)
@@ -133,6 +133,14 @@ icf_test: icf_test.o gcctestdir/ld
 icf_test.stdout: icf_test
        $(TEST_NM) -C icf_test > icf_test.stdout
 
+check_SCRIPTS += icf_keep_unique_test.sh
+check_DATA += icf_keep_unique_test.stdout
+icf_keep_unique_test.o: icf_keep_unique_test.cc
+       $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
+icf_keep_unique_test: icf_keep_unique_test.o gcctestdir/ld
+       $(CXXLINK) -Bgcctestdir/ -Wl,--icf -Wl,--keep-unique,_Z11unique_funcv icf_keep_unique_test.o
+icf_keep_unique_test.stdout: icf_keep_unique_test
+       $(TEST_NM) -C icf_keep_unique_test > icf_keep_unique_test.stdout
 
 check_PROGRAMS += basic_test
 check_PROGRAMS += basic_static_test
index d3a547ee06249ece08fb96015f30d3bf922302d0..d3598d3672bcdff71cfe89ab3ee23702ad48da42 100644 (file)
@@ -58,6 +58,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 # and --dynamic-list-cpp-typeinfo
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_1 = gc_comdat_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test.sh icf_test.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.sh weak_plt.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg.sh undef_symbol.sh \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_1.sh ver_test_2.sh \
@@ -77,6 +78,7 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_2 = gc_comdat_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ gc_tls_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_test.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ icf_keep_unique_test.stdout \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_shared.dbg \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ weak_plt_shared.so debug_msg.err \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ debug_msg_so.err \
@@ -2337,6 +2339,12 @@ uninstall-am: uninstall-info-am
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf icf_test.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@icf_test.stdout: icf_test
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C icf_test > icf_test.stdout
+@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_keep_unique_test.o: icf_keep_unique_test.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -g -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_keep_unique_test: icf_keep_unique_test.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--icf -Wl,--keep-unique,_Z11unique_funcv icf_keep_unique_test.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@icf_keep_unique_test.stdout: icf_keep_unique_test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_NM) -C icf_keep_unique_test > icf_keep_unique_test.stdout
 @GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test.o: basic_test.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXCOMPILE) -O0 -c -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@basic_test: basic_test.o gcctestdir/ld
diff --git a/gold/testsuite/icf_keep_unique_test.cc b/gold/testsuite/icf_keep_unique_test.cc
new file mode 100644 (file)
index 0000000..37f6437
--- /dev/null
@@ -0,0 +1,39 @@
+// icf_keep_unique_test.cc -- a test case for gold
+
+// Copyright 2009 Free Software Foundation, Inc.
+// Written by Sriraman Tallam <tmsriram@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
+// The goal of this program is to verify if --keep-unique works
+// as intended when used with --icf. 
+
+int kept_func()
+{
+  return 0;
+}
+
+int unique_func()
+{
+  return 0;
+}
+
+int main()
+{
+  return 1;
+}
diff --git a/gold/testsuite/icf_keep_unique_test.sh b/gold/testsuite/icf_keep_unique_test.sh
new file mode 100755 (executable)
index 0000000..c267373
--- /dev/null
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# icf_keep_unique_test.sh -- test --icf --keep-unique
+
+# Copyright 2009 Free Software Foundation, Inc.
+# Written by Sriraman Tallam <tmsriram@google.com>.
+
+# This file is part of gold.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+# The goal of this program is to verify if --keep-unique works
+# as intended when used with --icf.  
+check()
+{
+    func_addr_1=`grep $2 $1 | awk '{print $1}'`
+    func_addr_2=`grep $3 $1 | awk '{print $1}'`
+    if [ $func_addr_1 = $func_addr_2 ]
+    then
+        echo "Identical Code Folding with keep-unique failed to unfold" $2
+       exit 1
+    fi
+}
+
+check icf_keep_unique_test.stdout "kept_func" "unique_func"