public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* PATCH: Enable both ld and gold in GCC 4.8
@ 2012-11-27 18:36 H.J. Lu
  2012-11-28  9:10 ` Paolo Bonzini
  0 siblings, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2012-11-27 18:36 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Matthias Klose, GCC Patches, Diego Novillo

[-- Attachment #1: Type: text/plain, Size: 1589 bytes --]

On Tue, Nov 27, 2012 at 9:23 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Nov 27, 2012 at 9:20 AM, Paolo Bonzini <bonzini@gnu.org> wrote:
>> Il 27/11/2012 17:07, H.J. Lu ha scritto:
>>> There is no reply for
>>>
>>> http://gcc.gnu.org/ml/gcc-patches/2011-06/msg02121.html
>>
>> That counts as lack of review...
>>
>
> That is no response from patch submitter.  It is different from
> lack of review.
>

I updated patch for trunk.  OK to install?

Thanks.

-- 
H.J.
--
2011-06-27   Doug Kwan  <dougkwan@google.com>

	Google ref 41164-p2
	Backport upstream patch under review.

	2011-01-19   Nick Clifton  <nickc@redhat.com>
       		     Matthias Klose <doko@debian.org>

	* configure.ac (gcc_cv_gold_srcdir): New cached variable -
	contains the location of the gold sources.
	(ORIGINAL_GOLD_FOR_TARGET): New substituted variable - contains
	the name of the locally built gold executable.
	* configure: Regenerate.
	* collect2.c (main): Detect the -use-gold and -use-ld switches
	and select the appropriate linker, if found.
	If a linker cannot be found and collect2 is executing in
	verbose mode then report the search paths examined.
	* exec-tool.in: Detect the -use-gold and -use-ld switches and
	select the appropriate linker, if found.
	Add support for -v switch.
	Report problems locating linker executable.
	* gcc.c (LINK_COMMAND_SPEC): Translate -fuse-ld=gold into
	-use-gold and -fuse-ld=bfd into -use-ld.
	* common.opt: Add fuse-ld=gold and fuse-ld=bfd.
	* opts.c (comman_handle_option): Ignore -fuse-ld=gold and
	-fuse-ld=bfd.
	* doc/invoke.texi: Document the new options.

[-- Attachment #2: 0001-Enable-both-ld-and-gold-in-gcc.patch --]
[-- Type: application/octet-stream, Size: 19645 bytes --]

From 50ff1a24870fe214fc22b147b6708c1b09e1d7b2 Mon Sep 17 00:00:00 2001
From: Doug Kwan <dougkwan@google.com>
Date: Tue, 27 Nov 2012 10:05:33 -0800
Subject: [PATCH] Enable both ld and gold in gcc

2011-06-27   Doug Kwan  <dougkwan@google.com>

	Google ref 41164-p2
	Backport upstream patch under review.

	2011-01-19   Nick Clifton  <nickc@redhat.com>
       		     Matthias Klose <doko@debian.org>

	* configure.ac (gcc_cv_gold_srcdir): New cached variable -
	contains the location of the gold sources.
	(ORIGINAL_GOLD_FOR_TARGET): New substituted variable - contains
	the name of the locally built gold executable.
	* configure: Regenerate.
	* collect2.c (main): Detect the -use-gold and -use-ld switches
	and select the appropriate linker, if found.
	If a linker cannot be found and collect2 is executing in
	verbose mode then report the search paths examined.
	* exec-tool.in: Detect the -use-gold and -use-ld switches and
	select the appropriate linker, if found.
	Add support for -v switch.
	Report problems locating linker executable.
	* gcc.c (LINK_COMMAND_SPEC): Translate -fuse-ld=gold into
	-use-gold and -fuse-ld=bfd into -use-ld.
	* common.opt: Add fuse-ld=gold and fuse-ld=bfd.
	* opts.c (comman_handle_option): Ignore -fuse-ld=gold and
	-fuse-ld=bfd.
	* doc/invoke.texi: Document the new options.
---
 gcc/collect2.c      | 155 +++++++++++++++++++++++++++++++++++++++++-----------
 gcc/common.opt      |   3 +
 gcc/configure       |  19 +++++++
 gcc/configure.ac    |  14 +++++
 gcc/doc/invoke.texi |  12 +++-
 gcc/exec-tool.in    | 118 +++++++++++++++++++++++++++++----------
 gcc/gcc.c           |   3 +
 gcc/opts.c          |   3 +-
 9 files changed, 292 insertions(+), 62 deletions(-)
 create mode 100644 gcc/ChangeLog.gold

diff --git a/gcc/collect2.c b/gcc/collect2.c
index 49c4030..d5bffcb 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -842,17 +842,19 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
 int
 main (int argc, char **argv)
 {
-  static const char *const ld_suffix	= "ld";
-  static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
-  static const char *const real_ld_suffix = "real-ld";
+  static const char *const ld_suffix	     = "ld";
+  static const char *const gold_suffix       = "ld.gold";
+  static const char *const bfd_ld_suffix     = "ld.bfd";
+  static const char *const plugin_ld_suffix  = PLUGIN_LD_SUFFIX;
+  static const char *const real_ld_suffix    = "real-ld";
   static const char *const collect_ld_suffix = "collect-ld";
-  static const char *const nm_suffix	= "nm";
-  static const char *const gnm_suffix	= "gnm";
+  static const char *const nm_suffix	     = "nm";
+  static const char *const gnm_suffix	     = "gnm";
 #ifdef LDD_SUFFIX
-  static const char *const ldd_suffix	= LDD_SUFFIX;
+  static const char *const ldd_suffix	     = LDD_SUFFIX;
 #endif
-  static const char *const strip_suffix = "strip";
-  static const char *const gstrip_suffix = "gstrip";
+  static const char *const strip_suffix      = "strip";
+  static const char *const gstrip_suffix     = "gstrip";
 
 #ifdef CROSS_DIRECTORY_STRUCTURE
   /* If we look for a program in the compiler directories, we just use
@@ -862,6 +864,10 @@ main (int argc, char **argv)
 
   const char *const full_ld_suffix =
     concat(target_machine, "-", ld_suffix, NULL);
+  const char *const full_gold_suffix =
+    concat (target_machine, "-", gold_suffix, NULL);
+  const char *const full_bfd_ld_suffix =
+    concat (target_machine, "-", bfd_ld_suffix, NULL);
   const char *const full_plugin_ld_suffix =
     concat(target_machine, "-", plugin_ld_suffix, NULL);
   const char *const full_nm_suffix =
@@ -877,15 +883,17 @@ main (int argc, char **argv)
   const char *const full_gstrip_suffix =
     concat (target_machine, "-", gstrip_suffix, NULL);
 #else
-  const char *const full_ld_suffix	= ld_suffix;
+  const char *const full_ld_suffix	  = ld_suffix;
+  const char *const full_gold_suffix	  = gold_suffix;
+  const char *const full_bfd_ld_suffix	  = bfd_ld_suffix;
   const char *const full_plugin_ld_suffix = plugin_ld_suffix;
-  const char *const full_nm_suffix	= nm_suffix;
-  const char *const full_gnm_suffix	= gnm_suffix;
+  const char *const full_nm_suffix	  = nm_suffix;
+  const char *const full_gnm_suffix	  = gnm_suffix;
 #ifdef LDD_SUFFIX
-  const char *const full_ldd_suffix	= ldd_suffix;
+  const char *const full_ldd_suffix	  = ldd_suffix;
 #endif
-  const char *const full_strip_suffix	= strip_suffix;
-  const char *const full_gstrip_suffix	= gstrip_suffix;
+  const char *const full_strip_suffix	  = strip_suffix;
+  const char *const full_gstrip_suffix	  = gstrip_suffix;
 #endif /* CROSS_DIRECTORY_STRUCTURE */
 
   const char *arg;
@@ -899,7 +907,13 @@ main (int argc, char **argv)
   const char **c_ptr;
   char **ld1_argv;
   const char **ld1;
-  bool use_plugin = false;
+  enum linker_select
+  {
+    DFLT_LINKER,
+    PLUGIN_LINKER,
+    GOLD_LINKER,
+    BFD_LINKER
+  } selected_linker = DFLT_LINKER;
 
   /* The kinds of symbols we will have to consider when scanning the
      outcome of a first pass link.  This is ALL to start with, then might
@@ -990,15 +1004,21 @@ main (int argc, char **argv)
         else if (! strcmp (argv[i], "-flto-partition=none"))
 	  no_partition = true;
         else if ((! strncmp (argv[i], "-flto=", 6)
-		  || ! strcmp (argv[i], "-flto")) && ! use_plugin)
+		  || ! strcmp (argv[i], "-flto"))
+		 && selected_linker != PLUGIN_LINKER)
 	  lto_mode = LTO_MODE_WHOPR;
 	else if (!strncmp (argv[i], "-fno-lto", 8))
 	  lto_mode = LTO_MODE_NONE;
         else if (! strcmp (argv[i], "-plugin"))
 	  {
-	    use_plugin = true;
+	    selected_linker =  PLUGIN_LINKER;
 	    lto_mode = LTO_MODE_NONE;
 	  }
+	else if (! strcmp (argv[i], "-use-gold"))
+	  selected_linker = GOLD_LINKER;
+	else if (! strcmp (argv[i], "-use-ld"))
+	  selected_linker = BFD_LINKER;
+
 #ifdef COLLECT_EXPORT_LIST
 	/* since -brtl, -bexport, -b64 are not position dependent
 	   also check for them here */
@@ -1081,35 +1101,108 @@ main (int argc, char **argv)
   /* Try to discover a valid linker/nm/strip to use.  */
 
   /* Maybe we know the right file to use (if not cross).  */
-  ld_file_name = 0;
+  ld_file_name = NULL;
 #ifdef DEFAULT_LINKER
   if (access (DEFAULT_LINKER, X_OK) == 0)
     ld_file_name = DEFAULT_LINKER;
-  if (ld_file_name == 0)
+  if (ld_file_name == NULL)
 #endif
 #ifdef REAL_LD_FILE_NAME
   ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
-  if (ld_file_name == 0)
+  if (ld_file_name == NULL)
 #endif
   /* Search the (target-specific) compiler dirs for ld'.  */
   ld_file_name = find_a_file (&cpath, real_ld_suffix);
   /* Likewise for `collect-ld'.  */
-  if (ld_file_name == 0)
+  if (ld_file_name == NULL)
     ld_file_name = find_a_file (&cpath, collect_ld_suffix);
   /* Search the compiler directories for `ld'.  We have protection against
      recursive calls in find_a_file.  */
-  if (ld_file_name == 0)
-    ld_file_name = find_a_file (&cpath,
-				use_plugin
-				? plugin_ld_suffix
-				: ld_suffix);
+  if (ld_file_name == NULL)
+    switch (selected_linker)
+      {
+      default:
+      case DFLT_LINKER:
+	ld_file_name = find_a_file (&cpath, ld_suffix);
+	break;
+      case PLUGIN_LINKER:
+	ld_file_name = find_a_file (&cpath, plugin_ld_suffix);
+	break;
+      case GOLD_LINKER:
+	ld_file_name = find_a_file (&cpath, gold_suffix);
+	break;
+      case BFD_LINKER:
+	ld_file_name = find_a_file (&cpath, bfd_ld_suffix);
+	break;
+      }
   /* Search the ordinary system bin directories
      for `ld' (if native linking) or `TARGET-ld' (if cross).  */
-  if (ld_file_name == 0)
-    ld_file_name = find_a_file (&path,
-				use_plugin
-				? full_plugin_ld_suffix
-				: full_ld_suffix);
+  if (ld_file_name == NULL)
+    switch (selected_linker)
+      {
+      default:
+      case DFLT_LINKER:
+	ld_file_name = find_a_file (&path, full_ld_suffix);
+	break;
+      case PLUGIN_LINKER:
+	ld_file_name = find_a_file (&path, full_plugin_ld_suffix);
+	break;
+      case GOLD_LINKER:
+	ld_file_name = find_a_file (&path, full_gold_suffix);
+	break;
+      case BFD_LINKER:
+	ld_file_name = find_a_file (&path, full_bfd_ld_suffix);
+	break;
+      }
+  /* If we failed to find a plugin-capable linker, try the ordinary one.  */
+  if (ld_file_name == NULL && selected_linker == PLUGIN_LINKER)
+    ld_file_name = find_a_file (&cpath, ld_suffix);
+
+  if ((vflag || debug) && ld_file_name == NULL)
+    {
+      struct prefix_list * p;
+      const char * s;
+
+      notice ("collect2: warning: unable to find linker.\n");
+
+#ifdef DEFAULT_LINKER
+      notice (" Searched for this absolute executable:\n");
+      notice (" %s\n", DEFAULT_LINKER);
+#endif
+
+      notice (" Searched in these paths:\n");
+      for (p = cpath.plist; p != NULL; p = p->next)
+	notice ("  %s\n", p->prefix);
+      notice (" For these executables:\n");
+      notice ("  %s\n", real_ld_suffix);
+      notice ("  %s\n", collect_ld_suffix);
+      switch (selected_linker)
+      {
+      default:
+      case DFLT_LINKER:    s = ld_suffix; break;
+      case PLUGIN_LINKER:  s = plugin_ld_suffix; break;
+      case GOLD_LINKER:    s = gold_suffix; break;
+      case BFD_LINKER:     s = bfd_ld_suffix; break;
+      }
+      notice ("  %s\n", s);
+
+      notice (" And searched in these paths:\n");
+      for (p = path.plist; p != NULL; p = p->next)
+	notice ("  %s\n", p->prefix);
+      notice (" For these executables:\n");
+#ifdef REAL_LD_FILE_NAME
+      notice (" %s\n", REAL_LD_FILE_NAME);
+#endif
+      switch (selected_linker)
+      {
+      default:
+      case DFLT_LINKER:    s = full_ld_suffix; break;
+      case PLUGIN_LINKER:  s = full_plugin_ld_suffix; break;
+      case GOLD_LINKER:    s = full_gold_suffix; break;
+      case BFD_LINKER:     s = full_bfd_ld_suffix; break;
+      }
+      notice ("  %s\n", s);
+    }
 
 #ifdef REAL_NM_FILE_NAME
   nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
diff --git a/gcc/common.opt b/gcc/common.opt
index 4c8bd11..ca67e89 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2171,6 +2171,9 @@ funwind-tables
 Common Report Var(flag_unwind_tables) Optimization
 Just generate unwind tables for exception handling
 
+fuse-ld=
+Common Joined Undocumented
+
 fuse-linker-plugin
 Common Undocumented
 
diff --git a/gcc/configure b/gcc/configure
index e2c119e..4da84d5 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -680,6 +680,7 @@ gcc_cv_readelf
 gcc_cv_objdump
 ORIGINAL_NM_FOR_TARGET
 gcc_cv_nm
+ORIGINAL_GOLD_FOR_TARGET
 ORIGINAL_LD_FOR_TARGET
 ORIGINAL_PLUGIN_LD_FOR_TARGET
 gcc_cv_ld
@@ -21377,6 +21378,21 @@ fi
 fi
 fi
 
+gcc_cv_ld_gold_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gold
+
+if test "${gcc_cv_gold+set}" = set; then :
+
+else
+
+if test -f $gcc_cv_ld_gold_srcdir/configure.ac \
+     && test -f ../gold/Makefile \
+     && test x$build = x$host; then
+	gcc_cv_gold=../gold/ld-new$build_exeext
+else
+        gcc_cv_gold=''
+fi
+fi
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
@@ -21422,6 +21438,9 @@ case "$ORIGINAL_LD_FOR_TARGET" in
  ;;
 esac
 
+ORIGINAL_GOLD_FOR_TARGET=$gcc_cv_gold
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking what linker to use" >&5
 $as_echo_n "checking what linker to use... " >&6; }
 if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
diff --git a/gcc/configure.ac b/gcc/configure.ac
index c6f57bd..305a1cd 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2027,6 +2027,17 @@ else
         AC_PATH_PROG(gcc_cv_ld, $LD_FOR_TARGET)
 fi])
 
+gcc_cv_ld_gold_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gold
+
+AS_VAR_SET_IF(gcc_cv_gold,, [
+if test -f $gcc_cv_ld_gold_srcdir/configure.ac \
+     && test -f ../gold/Makefile \
+     && test x$build = x$host; then
+	gcc_cv_gold=../gold/ld-new$build_exeext
+else
+        gcc_cv_gold=''
+fi])
+
 ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
 PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
 # if the PLUGIN_LD is set ld-new, just have it as ld
@@ -2062,6 +2073,9 @@ case "$ORIGINAL_LD_FOR_TARGET" in
   *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;;
 esac 
 
+ORIGINAL_GOLD_FOR_TARGET=$gcc_cv_gold
+AC_SUBST(ORIGINAL_GOLD_FOR_TARGET)
+
 AC_MSG_CHECKING(what linker to use)
 if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
    || test "$gcc_cv_ld" = ../gold/ld-new$build_exeext; then
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 51b6e85..b78f698 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -425,7 +425,7 @@ Objective-C and Objective-C++ Dialects}.
 -funit-at-a-time -funroll-all-loops -funroll-loops @gol
 -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
 -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
--fwhole-program -fwpa -fuse-linker-plugin @gol
+-fwhole-program -fwpa -fuse-ld -fuse-linker-plugin @gol
 --param @var{name}=@var{value}
 -O  -O0  -O1  -O2  -O3  -Os -Ofast -Og}
 
@@ -8419,6 +8419,16 @@ the comparison operation before register allocation is complete.
 
 Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
 
+@item -fuse-ld=gold
+Use the @command{gold} linker instead of the default linker.
+This option is only necessary if GCC has been configured with
+@option{--enable-gold} and @option{--enable-ld=default}.
+
+@item -fuse-ld=bfd
+Use the @command{ld.bfd} linker instead of the default linker.
+This option is only necessary if GCC has been configured with
+@option{--enable-gold} and @option{--enable-ld}.
+
 @item -fcprop-registers
 @opindex fcprop-registers
 After register allocation and post-register allocation instruction splitting,
diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
index 8a10775..46aaedc 100644
--- a/gcc/exec-tool.in
+++ b/gcc/exec-tool.in
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
 # This file is part of GCC.
 
 # GCC is free software; you can redistribute it and/or modify
@@ -21,11 +21,13 @@
 
 ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@"
 ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
+ORIGINAL_GOLD_FOR_TARGET="@ORIGINAL_GOLD_FOR_TARGET@"
 ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
 ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
 exeext=@host_exeext@
 fast_install=@enable_fast_install@
 objdir=@objdir@
+version="1.1"
 
 invoked=`basename "$0"`
 id=$invoked
@@ -36,15 +38,44 @@ case "$invoked" in
     dir=gas
     ;;
   collect-ld)
-    # when using a linker plugin, gcc will always pass '-plugin' as the
-    # first or second option to the linker.
-    if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
-      original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
-    else
-      original=$ORIGINAL_LD_FOR_TARGET
-    fi
     prog=ld-new$exeext
-    dir=ld
+    # Look for the a command line option
+    # specifying the linker to be used.
+    case " $* " in
+      *\ -use-gold\ *)
+        original=$ORIGINAL_GOLD_FOR_TARGET
+	dir=gold
+        ;;
+      *\ -use-ld\ * | *\ -use-ld.bfd\ *)
+        original=$ORIGINAL_LD_FOR_TARGET
+        dir=ld
+        ;;
+      *\ -plugin\ *)
+        original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+        dir=ld
+	;;
+      *)
+        original=$ORIGINAL_LD_FOR_TARGET
+        dir=ld
+	;;
+    esac
+
+    # If the selected linker has not been configured then
+    # try using the others, in the order PLUGIN-LD, LD, GOLD.
+    if test x"$original" = x; then
+      if test x"$ORIGINAL_PLUGIN_LD_FOR_TARGET" != x; then
+        original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+        dir=ld
+      elif test x"$ORIGINAL_LD_FOR_TARGET" != x; then
+        original=$ORIGINAL_LD_FOR_TARGET
+        dir=ld
+      elif test x"$ORIGINAL_GOLD_FOR_TARGET" != x; then
+        original=$ORIGINAL_GOLD_FOR_TARGET
+        dir=gold
+      # Otherwise do nothing - the case statement below
+      # will issue an error message for us.
+      fi
+    fi
     id=ld
     ;;
   nm)
@@ -61,29 +92,58 @@ case "$original" in
     scriptdir=`cd "$tdir" && pwd`
 
     if test -x $scriptdir/../$dir/$prog; then
-      test "$fast_install" = yes || exec $scriptdir/../$dir/$prog ${1+"$@"}
-
-      # if libtool did everything it needs to do, there's a fast path
-      lt_prog=$scriptdir/../$dir/$objdir/lt-$prog 
-      test -x $lt_prog && exec $lt_prog ${1+"$@"}
-
-      # libtool has not relinked ld-new yet, but we cannot just use the
-      # previous stage (because then the relinking would just never happen!).
-      # So we take extra care to use prev-ld/ld-new *on recursive calls*.
-      eval LT_RCU="\${LT_RCU_$id}"
-      test x"$LT_RCU" = x"1" && exec $scriptdir/../prev-$dir/$prog ${1+"$@"}
-
-      eval LT_RCU_$id=1
-      export LT_RCU_$id
-      $scriptdir/../$dir/$prog ${1+"$@"}
-      result=$?
-      exit $result
+      if test "$fast_install" = yes; then
+        # If libtool did everything it needs to do, there's a fast path.
+        lt_prog=$scriptdir/../$dir/$objdir/lt-$prog 
 
+	if test -x $lt_prog; then
+	  original=$lt_prog
+        else
+          # Libtool has not relinked ld-new yet, but we cannot just use the
+          # previous stage (because then the relinking would just never happen!).
+          # So we take extra care to use prev-ld/ld-new *on recursive calls*.
+          eval LT_RCU="\${LT_RCU_$id}"
+          if test x"$LT_RCU" = x"1"; then
+	    original=$scriptdir/../prev-$dir/$prog
+          else
+            eval LT_RCU_$id=1
+            export LT_RCU_$id
+            case " $* " in
+              *\ -v\ *)
+               echo "$invoked $version"
+               echo $scriptdir/../$dir/$prog $*
+               ;;
+            esac
+            $scriptdir/../$dir/$prog ${1+"$@"}
+            result=$?
+            exit $result
+          fi
+        fi
+      else
+	original=$scriptdir/../$dir/$prog
+      fi
     else
-      exec $scriptdir/../prev-$dir/$prog ${1+"$@"}
+      original=$scriptdir/../prev-$dir/$prog
     fi
     ;;
-  *)
-    exec $original ${1+"$@"}
+  "")
+    echo "$invoked: executable not configured"
+    exit 1
     ;;
 esac
+
+# If -v has been used then display our version number
+# and then echo the command we are about to invoke.
+case " $* " in
+  *\ -v\ *)
+    echo "$invoked $version"
+    echo $original $*
+    ;;
+esac
+
+if test -x $original; then
+  exec "$original" ${1+"$@"}
+else
+  echo "$invoked: unable to locate executable: $original"
+  exit 1
+fi
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 13e93e5..1702d2c 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -705,6 +705,9 @@ proper position among the other output files.  */
     LINK_PLUGIN_SPEC \
     "%{flto|flto=*:%<fcompare-debug*} \
     %{flto} %{flto=*} %l " LINK_PIE_SPEC \
+   "%{fuse-ld=gold:%{fuse-ld=bfd:%e-fuse-ld=gold and -fuse-ld=bfd may not be used together}} \
+    %{fuse-ld=gold:-use-gold} \
+    %{fuse-ld=bfd:-use-ld}" \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
diff --git a/gcc/opts.c b/gcc/opts.c
index b3a9afe..ae4b61a 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1753,8 +1753,9 @@ common_handle_option (struct gcc_options *opts,
       dc->max_errors = value;
       break;
 
+    case OPT_fuse_ld_:
     case OPT_fuse_linker_plugin:
-      /* No-op. Used by the driver and passed to us because it starts with f.*/
+      /* No-op. Used by the driver and passed to us because it starts with f.  */
       break;
 
     default:
-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Enable both ld and gold in GCC 4.8
  2012-11-27 18:36 PATCH: Enable both ld and gold in GCC 4.8 H.J. Lu
@ 2012-11-28  9:10 ` Paolo Bonzini
  2012-11-28 19:11   ` H.J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2012-11-28  9:10 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Matthias Klose, GCC Patches, Diego Novillo

I cannot approve the collect2.c, gcc.c, opts.c, doc/invoke.texi.  I'll
include some comments anyway, since the patch needs some more work.

> 2011-06-27   Doug Kwan  <dougkwan@google.com>
> 
> 	Google ref 41164-p2
> 	Backport upstream patch under review.
> 
> 	2011-01-19   Nick Clifton  <nickc@redhat.com>
>        		     Matthias Klose <doko@debian.org>
> 
> 	* configure.ac (gcc_cv_gold_srcdir): New cached variable -
> 	contains the location of the gold sources.

This is gcc_cv_ld_gold_srcdir in configure.ac.  I prefer the name in the
changelog.

> -  static const char *const ld_suffix	= "ld";
> -  static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
> -  static const char *const real_ld_suffix = "real-ld";
> +  static const char *const ld_suffix	     = "ld";
> +  static const char *const gold_suffix       = "ld.gold";
> +  static const char *const bfd_ld_suffix     = "ld.bfd";
> +  static const char *const plugin_ld_suffix  = PLUGIN_LD_SUFFIX;
> +  static const char *const real_ld_suffix    = "real-ld";

Please use an array for ld_suffix, gold_suffix, bfd_ld_suffix,
plugin_ld_suffix.  Similar for full_ld_suffix and friends.

> -  bool use_plugin = false;
> +  enum linker_select
> +  {
> +    DFLT_LINKER,
> +    PLUGIN_LINKER,
> +    GOLD_LINKER,
> +    BFD_LINKER
> +  } selected_linker = DFLT_LINKER;

Please change the names to avoid the "DFLT" abbreviation.  For example
USE_DEFAULT_LD, USE_PLUGIN_LD, USE_GOLD, USE_LD.

>  
>    /* The kinds of symbols we will have to consider when scanning the
>       outcome of a first pass link.  This is ALL to start with, then might
> @@ -990,15 +1004,21 @@ main (int argc, char **argv)
>          else if (! strcmp (argv[i], "-flto-partition=none"))
>  	  no_partition = true;
>          else if ((! strncmp (argv[i], "-flto=", 6)
> -		  || ! strcmp (argv[i], "-flto")) && ! use_plugin)
> +		  || ! strcmp (argv[i], "-flto"))
> +		 && selected_linker != PLUGIN_LINKER)
>  	  lto_mode = LTO_MODE_WHOPR;
>  	else if (!strncmp (argv[i], "-fno-lto", 8))
>  	  lto_mode = LTO_MODE_NONE;
>          else if (! strcmp (argv[i], "-plugin"))
>  	  {
> -	    use_plugin = true;
> +	    selected_linker =  PLUGIN_LINKER;
>  	    lto_mode = LTO_MODE_NONE;
>  	  }
> +	else if (! strcmp (argv[i], "-use-gold"))
> +	  selected_linker = GOLD_LINKER;
> +	else if (! strcmp (argv[i], "-use-ld"))
> +	  selected_linker = BFD_LINKER;
> +
>  #ifdef COLLECT_EXPORT_LIST
>  	/* since -brtl, -bexport, -b64 are not position dependent
>  	   also check for them here */
> @@ -1081,35 +1101,108 @@ main (int argc, char **argv)
>    /* Try to discover a valid linker/nm/strip to use.  */
>  
>    /* Maybe we know the right file to use (if not cross).  */
> -  ld_file_name = 0;
> +  ld_file_name = NULL;
>  #ifdef DEFAULT_LINKER
>    if (access (DEFAULT_LINKER, X_OK) == 0)
>      ld_file_name = DEFAULT_LINKER;
> -  if (ld_file_name == 0)
> +  if (ld_file_name == NULL)
>  #endif
>  #ifdef REAL_LD_FILE_NAME
>    ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME);
> -  if (ld_file_name == 0)
> +  if (ld_file_name == NULL)
>  #endif
>    /* Search the (target-specific) compiler dirs for ld'.  */
>    ld_file_name = find_a_file (&cpath, real_ld_suffix);
>    /* Likewise for `collect-ld'.  */
> -  if (ld_file_name == 0)
> +  if (ld_file_name == NULL)
>      ld_file_name = find_a_file (&cpath, collect_ld_suffix);
>    /* Search the compiler directories for `ld'.  We have protection against
>       recursive calls in find_a_file.  */
> -  if (ld_file_name == 0)
> -    ld_file_name = find_a_file (&cpath,
> -				use_plugin
> -				? plugin_ld_suffix
> -				: ld_suffix);
> +  if (ld_file_name == NULL)
> +    switch (selected_linker)
> +      {
> +      default:
> +      case DFLT_LINKER:
> +	ld_file_name = find_a_file (&cpath, ld_suffix);
> +	break;
> +      case PLUGIN_LINKER:
> +	ld_file_name = find_a_file (&cpath, plugin_ld_suffix);
> +	break;
> +      case GOLD_LINKER:
> +	ld_file_name = find_a_file (&cpath, gold_suffix);
> +	break;
> +      case BFD_LINKER:
> +	ld_file_name = find_a_file (&cpath, bfd_ld_suffix);
> +	break;
> +      }

If you use an array, no switch is needed here...

>    /* Search the ordinary system bin directories
>       for `ld' (if native linking) or `TARGET-ld' (if cross).  */
> -  if (ld_file_name == 0)
> -    ld_file_name = find_a_file (&path,
> -				use_plugin
> -				? full_plugin_ld_suffix
> -				: full_ld_suffix);
> +  if (ld_file_name == NULL)
> +    switch (selected_linker)
> +      {
> +      default:
> +      case DFLT_LINKER:
> +	ld_file_name = find_a_file (&path, full_ld_suffix);
> +	break;
> +      case PLUGIN_LINKER:
> +	ld_file_name = find_a_file (&path, full_plugin_ld_suffix);
> +	break;
> +      case GOLD_LINKER:
> +	ld_file_name = find_a_file (&path, full_gold_suffix);
> +	break;
> +      case BFD_LINKER:
> +	ld_file_name = find_a_file (&path, full_bfd_ld_suffix);
> +	break;
> +      }

... here...

> +  /* If we failed to find a plugin-capable linker, try the ordinary one.  */
> +  if (ld_file_name == NULL && selected_linker == PLUGIN_LINKER)
> +    ld_file_name = find_a_file (&cpath, ld_suffix);
> +
> +  if ((vflag || debug) && ld_file_name == NULL)
> +    {
> +      struct prefix_list * p;
> +      const char * s;
> +
> +      notice ("collect2: warning: unable to find linker.\n");
> +
> +#ifdef DEFAULT_LINKER
> +      notice (" Searched for this absolute executable:\n");
> +      notice (" %s\n", DEFAULT_LINKER);
> +#endif
> +
> +      notice (" Searched in these paths:\n");
> +      for (p = cpath.plist; p != NULL; p = p->next)
> +	notice ("  %s\n", p->prefix);
> +      notice (" For these executables:\n");
> +      notice ("  %s\n", real_ld_suffix);
> +      notice ("  %s\n", collect_ld_suffix);
> +      switch (selected_linker)
> +      {
> +      default:
> +      case DFLT_LINKER:    s = ld_suffix; break;
> +      case PLUGIN_LINKER:  s = plugin_ld_suffix; break;
> +      case GOLD_LINKER:    s = gold_suffix; break;
> +      case BFD_LINKER:     s = bfd_ld_suffix; break;
> +      }

... here...

> +      notice ("  %s\n", s);
> +
> +      notice (" And searched in these paths:\n");
> +      for (p = path.plist; p != NULL; p = p->next)
> +	notice ("  %s\n", p->prefix);
> +      notice (" For these executables:\n");
> +#ifdef REAL_LD_FILE_NAME
> +      notice (" %s\n", REAL_LD_FILE_NAME);
> +#endif
> +      switch (selected_linker)
> +      {
> +      default:
> +      case DFLT_LINKER:    s = full_ld_suffix; break;
> +      case PLUGIN_LINKER:  s = full_plugin_ld_suffix; break;
> +      case GOLD_LINKER:    s = full_gold_suffix; break;
> +      case BFD_LINKER:     s = full_bfd_ld_suffix; break;
> +      }

... and here.

> +      notice ("  %s\n", s);
> +    }
>  
>  #ifdef REAL_NM_FILE_NAME
>    nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 4c8bd11..ca67e89 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -2171,6 +2171,9 @@ funwind-tables
>  Common Report Var(flag_unwind_tables) Optimization
>  Just generate unwind tables for exception handling
>  
> +fuse-ld=
> +Common Joined Undocumented
> +
>  fuse-linker-plugin
>  Common Undocumented
>  
> diff --git a/gcc/configure.ac b/gcc/configure.ac
> index c6f57bd..305a1cd 100644
> --- a/gcc/configure.ac
> +++ b/gcc/configure.ac
> @@ -2027,6 +2027,17 @@ else
>          AC_PATH_PROG(gcc_cv_ld, $LD_FOR_TARGET)
>  fi])
>  
> +gcc_cv_ld_gold_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gold

Please do not use gcc_cv_ld_gold_srcdir, it's not a cache variable.  In
fact, you can just use $srcdir/../gold/configure.ac in the "test -f"
command below.

> +AS_VAR_SET_IF(gcc_cv_gold,, [
> +if test -f $gcc_cv_ld_gold_srcdir/configure.ac \
> +     && test -f ../gold/Makefile \
> +     && test x$build = x$host; then
> +	gcc_cv_gold=../gold/ld-new$build_exeext
> +else
> +        gcc_cv_gold=''

See below, I'm not sure this default is correct.

> +fi])
> +
>  ORIGINAL_PLUGIN_LD_FOR_TARGET=$gcc_cv_ld
>  PLUGIN_LD_SUFFIX=`basename $gcc_cv_ld | sed -e "s,$target_alias-,,"`
>  # if the PLUGIN_LD is set ld-new, just have it as ld
> @@ -2062,6 +2073,9 @@ case "$ORIGINAL_LD_FOR_TARGET" in
>    *) AC_CONFIG_FILES(collect-ld:exec-tool.in, [chmod +x collect-ld]) ;;
>  esac 
>  
> +ORIGINAL_GOLD_FOR_TARGET=$gcc_cv_gold
> +AC_SUBST(ORIGINAL_GOLD_FOR_TARGET)
> +

Please move these three lines above, in the previous hunk.

>  AC_MSG_CHECKING(what linker to use)
>  if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
>     || test "$gcc_cv_ld" = ../gold/ld-new$build_exeext; then
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 51b6e85..b78f698 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -425,7 +425,7 @@ Objective-C and Objective-C++ Dialects}.
>  -funit-at-a-time -funroll-all-loops -funroll-loops @gol
>  -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
>  -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
> --fwhole-program -fwpa -fuse-linker-plugin @gol
> +-fwhole-program -fwpa -fuse-ld -fuse-linker-plugin @gol
>  --param @var{name}=@var{value}
>  -O  -O0  -O1  -O2  -O3  -Os -Ofast -Og}
>  
> @@ -8419,6 +8419,16 @@ the comparison operation before register allocation is complete.
>  
>  Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
>  
> +@item -fuse-ld=gold
> +Use the @command{gold} linker instead of the default linker.
> +This option is only necessary if GCC has been configured with
> +@option{--enable-gold} and @option{--enable-ld=default}.

This is not really clear.  You could have built binutils separately,
would -fuse-ld=gold work in that case?  If not, I think that's a bug.

> +@item -fuse-ld=bfd
> +Use the @command{ld.bfd} linker instead of the default linker.
> +This option is only necessary if GCC has been configured with
> +@option{--enable-gold} and @option{--enable-ld}.

Same concerns here.

>  @item -fcprop-registers
>  @opindex fcprop-registers
>  After register allocation and post-register allocation instruction splitting,
> diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
> index 8a10775..46aaedc 100644
> --- a/gcc/exec-tool.in
> +++ b/gcc/exec-tool.in
> @@ -1,6 +1,6 @@
>  #! /bin/sh
>  
> -# Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
> +# Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
>  # This file is part of GCC.
>  
>  # GCC is free software; you can redistribute it and/or modify
> @@ -21,11 +21,13 @@
>  
>  ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@"
>  ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
> +ORIGINAL_GOLD_FOR_TARGET="@ORIGINAL_GOLD_FOR_TARGET@"
>  ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
>  ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
>  exeext=@host_exeext@
>  fast_install=@enable_fast_install@
>  objdir=@objdir@
> +version="1.1"

Why is the -v behavior now required?  Please remove it from this patch.

>  
>  invoked=`basename "$0"`
>  id=$invoked
> @@ -36,15 +38,44 @@ case "$invoked" in
>      dir=gas
>      ;;
>    collect-ld)
> -    # when using a linker plugin, gcc will always pass '-plugin' as the
> -    # first or second option to the linker.
> -    if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
> -      original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
> -    else
> -      original=$ORIGINAL_LD_FOR_TARGET
> -    fi
>      prog=ld-new$exeext
> -    dir=ld
> +    # Look for the a command line option
> +    # specifying the linker to be used.
> +    case " $* " in
> +      *\ -use-gold\ *)
> +        original=$ORIGINAL_GOLD_FOR_TARGET
> +	dir=gold
> +        ;;
> +      *\ -use-ld\ * | *\ -use-ld.bfd\ *)
> +        original=$ORIGINAL_LD_FOR_TARGET
> +        dir=ld
> +        ;;
> +      *\ -plugin\ *)
> +        original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
> +        dir=ld
> +	;;
> +      *)
> +        original=$ORIGINAL_LD_FOR_TARGET
> +        dir=ld
> +	;;
> +    esac
> +
> +    # If the selected linker has not been configured then
> +    # try using the others, in the order PLUGIN-LD, LD, GOLD.
> +    if test x"$original" = x; then
> +      if test x"$ORIGINAL_PLUGIN_LD_FOR_TARGET" != x; then
> +        original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
> +        dir=ld
> +      elif test x"$ORIGINAL_LD_FOR_TARGET" != x; then
> +        original=$ORIGINAL_LD_FOR_TARGET
> +        dir=ld
> +      elif test x"$ORIGINAL_GOLD_FOR_TARGET" != x; then
> +        original=$ORIGINAL_GOLD_FOR_TARGET
> +        dir=gold
> +      # Otherwise do nothing - the case statement below
> +      # will issue an error message for us.
> +      fi
> +    fi
>      id=ld
>      ;;
>    nm)
> @@ -61,29 +92,58 @@ case "$original" in
>      scriptdir=`cd "$tdir" && pwd`
>  
>      if test -x $scriptdir/../$dir/$prog; then
> -      test "$fast_install" = yes || exec $scriptdir/../$dir/$prog ${1+"$@"}
> -
> -      # if libtool did everything it needs to do, there's a fast path
> -      lt_prog=$scriptdir/../$dir/$objdir/lt-$prog 
> -      test -x $lt_prog && exec $lt_prog ${1+"$@"}
> -
> -      # libtool has not relinked ld-new yet, but we cannot just use the
> -      # previous stage (because then the relinking would just never happen!).
> -      # So we take extra care to use prev-ld/ld-new *on recursive calls*.
> -      eval LT_RCU="\${LT_RCU_$id}"
> -      test x"$LT_RCU" = x"1" && exec $scriptdir/../prev-$dir/$prog ${1+"$@"}
> -
> -      eval LT_RCU_$id=1
> -      export LT_RCU_$id
> -      $scriptdir/../$dir/$prog ${1+"$@"}
> -      result=$?
> -      exit $result
> +      if test "$fast_install" = yes; then
> +        # If libtool did everything it needs to do, there's a fast path.
> +        lt_prog=$scriptdir/../$dir/$objdir/lt-$prog 

Just like the -v behavior, reversing the ifs should be a separate patch.
 It is quite confusing to review this patch as you posted it.

> +	if test -x $lt_prog; then
> +	  original=$lt_prog
> +        else
> +          # Libtool has not relinked ld-new yet, but we cannot just use the
> +          # previous stage (because then the relinking would just never happen!).
> +          # So we take extra care to use prev-ld/ld-new *on recursive calls*.
> +          eval LT_RCU="\${LT_RCU_$id}"
> +          if test x"$LT_RCU" = x"1"; then
> +	    original=$scriptdir/../prev-$dir/$prog
> +          else
> +            eval LT_RCU_$id=1
> +            export LT_RCU_$id
> +            case " $* " in
> +              *\ -v\ *)
> +               echo "$invoked $version"
> +               echo $scriptdir/../$dir/$prog $*
> +               ;;
> +            esac
> +            $scriptdir/../$dir/$prog ${1+"$@"}
> +            result=$?
> +            exit $result
> +          fi
> +        fi
> +      else
> +	original=$scriptdir/../$dir/$prog
> +      fi
>      else
> -      exec $scriptdir/../prev-$dir/$prog ${1+"$@"}
> +      original=$scriptdir/../prev-$dir/$prog
>      fi
>      ;;
> -  *)
> -    exec $original ${1+"$@"}
> +  "")
> +    echo "$invoked: executable not configured"
> +    exit 1
>      ;;
>  esac
> +
> +# If -v has been used then display our version number
> +# and then echo the command we are about to invoke.
> +case " $* " in
> +  *\ -v\ *)
> +    echo "$invoked $version"
> +    echo $original $*
> +    ;;
> +esac
> +
> +if test -x $original; then
> +  exec "$original" ${1+"$@"}
> +else
> +  echo "$invoked: unable to locate executable: $original"
> +  exit 1
> +fi
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index 13e93e5..1702d2c 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -705,6 +705,9 @@ proper position among the other output files.  */
>      LINK_PLUGIN_SPEC \
>      "%{flto|flto=*:%<fcompare-debug*} \
>      %{flto} %{flto=*} %l " LINK_PIE_SPEC \
> +   "%{fuse-ld=gold:%{fuse-ld=bfd:%e-fuse-ld=gold and -fuse-ld=bfd may not be used together}} \
> +    %{fuse-ld=gold:-use-gold} \
> +    %{fuse-ld=bfd:-use-ld}" \

Why do we need to use separate spellings of the options in gcc and collect2?

Paolo

>     "%X %{o*} %{e*} %{N} %{n} %{r}\
>      %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
>      %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
> diff --git a/gcc/opts.c b/gcc/opts.c
> index b3a9afe..ae4b61a 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -1753,8 +1753,9 @@ common_handle_option (struct gcc_options *opts,
>        dc->max_errors = value;
>        break;
>  
> +    case OPT_fuse_ld_:
>      case OPT_fuse_linker_plugin:
> -      /* No-op. Used by the driver and passed to us because it starts with f.*/
> +      /* No-op. Used by the driver and passed to us because it starts with f.  */
>        break;
>  
>      default:
> -- 1.7.11.7
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Enable both ld and gold in GCC 4.8
  2012-11-28  9:10 ` Paolo Bonzini
@ 2012-11-28 19:11   ` H.J. Lu
  2012-11-28 21:13     ` Paolo Bonzini
  0 siblings, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2012-11-28 19:11 UTC (permalink / raw)
  To: Paolo Bonzini, Joseph S. Myers; +Cc: Matthias Klose, GCC Patches, Diego Novillo

On Wed, Nov 28, 2012 at 1:09 AM, Paolo Bonzini <bonzini@gnu.org> wrote:
> I cannot approve the collect2.c, gcc.c, opts.c, doc/invoke.texi.  I'll
> include some comments anyway, since the patch needs some more work.
>
>> 2011-06-27   Doug Kwan  <dougkwan@google.com>
>>
>>       Google ref 41164-p2
>>       Backport upstream patch under review.
>>
>>       2011-01-19   Nick Clifton  <nickc@redhat.com>
>>                            Matthias Klose <doko@debian.org>
>>
>>       * configure.ac (gcc_cv_gold_srcdir): New cached variable -
>>       contains the location of the gold sources.
>
> This is gcc_cv_ld_gold_srcdir in configure.ac.  I prefer the name in the
> changelog.

I removed configure.ac change.  We can create a separate patch
to select gold as the default linker.  But this patch will only support
-fuse-ld=bfd and -fuse-ld=gold.

>> -  static const char *const ld_suffix = "ld";
>> -  static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
>> -  static const char *const real_ld_suffix = "real-ld";
>> +  static const char *const ld_suffix      = "ld";
>> +  static const char *const gold_suffix       = "ld.gold";
>> +  static const char *const bfd_ld_suffix     = "ld.bfd";
>> +  static const char *const plugin_ld_suffix  = PLUGIN_LD_SUFFIX;
>> +  static const char *const real_ld_suffix    = "real-ld";
>
> Please use an array for ld_suffix, gold_suffix, bfd_ld_suffix,
> plugin_ld_suffix.  Similar for full_ld_suffix and friends.

Done.

>> -  bool use_plugin = false;
>> +  enum linker_select
>> +  {
>> +    DFLT_LINKER,
>> +    PLUGIN_LINKER,
>> +    GOLD_LINKER,
>> +    BFD_LINKER
>> +  } selected_linker = DFLT_LINKER;
>
> Please change the names to avoid the "DFLT" abbreviation.  For example
> USE_DEFAULT_LD, USE_PLUGIN_LD, USE_GOLD, USE_LD.

Done.

>
>>  AC_MSG_CHECKING(what linker to use)
>>  if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
>>     || test "$gcc_cv_ld" = ../gold/ld-new$build_exeext; then
>> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>> index 51b6e85..b78f698 100644
>> --- a/gcc/doc/invoke.texi
>> +++ b/gcc/doc/invoke.texi
>> @@ -425,7 +425,7 @@ Objective-C and Objective-C++ Dialects}.
>>  -funit-at-a-time -funroll-all-loops -funroll-loops @gol
>>  -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
>>  -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
>> --fwhole-program -fwpa -fuse-linker-plugin @gol
>> +-fwhole-program -fwpa -fuse-ld -fuse-linker-plugin @gol
>>  --param @var{name}=@var{value}
>>  -O  -O0  -O1  -O2  -O3  -Os -Ofast -Og}
>>
>> @@ -8419,6 +8419,16 @@ the comparison operation before register allocation is complete.
>>
>>  Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
>>
>> +@item -fuse-ld=gold
>> +Use the @command{gold} linker instead of the default linker.
>> +This option is only necessary if GCC has been configured with
>> +@option{--enable-gold} and @option{--enable-ld=default}.
>
> This is not really clear.  You could have built binutils separately,
> would -fuse-ld=gold work in that case?  If not, I think that's a bug.
>
>> +@item -fuse-ld=bfd
>> +Use the @command{ld.bfd} linker instead of the default linker.
>> +This option is only necessary if GCC has been configured with
>> +@option{--enable-gold} and @option{--enable-ld}.
>
> Same concerns here.

Fixed.

>>  @item -fcprop-registers
>>  @opindex fcprop-registers
>>  After register allocation and post-register allocation instruction splitting,
>> diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
>> index 8a10775..46aaedc 100644
>> --- a/gcc/exec-tool.in
>> +++ b/gcc/exec-tool.in
>> @@ -1,6 +1,6 @@
>>  #! /bin/sh
>>
>> -# Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
>> +# Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
>>  # This file is part of GCC.
>>
>>  # GCC is free software; you can redistribute it and/or modify
>> @@ -21,11 +21,13 @@
>>
>>  ORIGINAL_AS_FOR_TARGET="@ORIGINAL_AS_FOR_TARGET@"
>>  ORIGINAL_LD_FOR_TARGET="@ORIGINAL_LD_FOR_TARGET@"
>> +ORIGINAL_GOLD_FOR_TARGET="@ORIGINAL_GOLD_FOR_TARGET@"
>>  ORIGINAL_PLUGIN_LD_FOR_TARGET="@ORIGINAL_PLUGIN_LD_FOR_TARGET@"
>>  ORIGINAL_NM_FOR_TARGET="@ORIGINAL_NM_FOR_TARGET@"
>>  exeext=@host_exeext@
>>  fast_install=@enable_fast_install@
>>  objdir=@objdir@
>> +version="1.1"
>
> Why is the -v behavior now required?  Please remove it from this patch.
>

I rewrote exec-tool.in change.  Now you get

# ./xgcc -B./  /tmp/x.c -fuse-ld=gold -v
...
./collect-ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2 -fuse-ld=gold /lib/../lib64/crt1.o
/lib/../lib64/crti.o ./crtbegin.o -L. -L/lib/../lib64
-L/usr/lib/../lib64 /tmp/cclVWcGz.o -v -lgcc --as-needed -lgcc_s
--no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed ./crtend.o
/lib/../lib64/crtn.o
GNU gold (Linux/GNU Binutils 2.23.51.0.7.20121127) 1.11
/usr/local/bin/ld.gold: fatal error: -f/--auxiliary may not be used
without -shared
collect2: error: ld returned 1 exit status

This is because we pass everything to ld and ld.bfd/ld.gold doesn't
understand -fuse-ld=bfd/-fuse-ld=gold.  It isn't a problem for collect2
since it will filter-out -fuse-ld=bfd/-fuse-ld=gold.  I will submit a binutils
patch to ignore -fuse-ld=bfd/-fuse-ld=gold, similar to -flto options.

>> diff --git a/gcc/gcc.c b/gcc/gcc.c
>> index 13e93e5..1702d2c 100644
>> --- a/gcc/gcc.c
>> +++ b/gcc/gcc.c
>> @@ -705,6 +705,9 @@ proper position among the other output files.  */
>>      LINK_PLUGIN_SPEC \
>>      "%{flto|flto=*:%<fcompare-debug*} \
>>      %{flto} %{flto=*} %l " LINK_PIE_SPEC \
>> +   "%{fuse-ld=gold:%{fuse-ld=bfd:%e-fuse-ld=gold and -fuse-ld=bfd may not be used together}} \
>> +    %{fuse-ld=gold:-use-gold} \
>> +    %{fuse-ld=bfd:-use-ld}" \
>
> Why do we need to use separate spellings of the options in gcc and collect2?
>

This is a bug in the original patch. If we pass  -fuse-ld=bfd/-fuse-ld=gold to
linker, linker will complain.  -use-gold/-use-ld are valid linker options:

  -u SYMBOL, --undefined SYMBOL

It is wrong to abuse  -use-gold/-use-ld.

Here is the updated patch.  OK for trunk?

Thanks.

-- 
H.J.
----
2012-11-28   Nick Clifton  <nickc@redhat.com>
	     Matthias Klose <doko@debian.org>
	     Doug Kwan  <dougkwan@google.com>
	     H.J. Lu  <hongjiu.lu@intel.com>

	* collect2.c (main): Support -fuse-ld=bfd and -fuse-ld=gold.
	* exec-tool.in: Likewise.

	* common.opt: Add fuse-ld=bfd and fuse-ld=gold.

	* gcc.c (LINK_COMMAND_SPEC): Pass -fuse-ld=* to collect2.

	* opts.c (comman_handle_option): Ignore -fuse-ld=bfd and
	-fuse-ld=gold.

	* doc/invoke.texi: Document Da-fuse-ld=bfd and -fuse-ld=gold.

diff --git a/gcc/collect2.c b/gcc/collect2.c
index 49c4030..19bdc29 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -842,8 +842,21 @@ maybe_run_lto_and_relink (char **lto_ld_argv,
char **object_lst,
 int
 main (int argc, char **argv)
 {
-  static const char *const ld_suffix	= "ld";
-  static const char *const plugin_ld_suffix = PLUGIN_LD_SUFFIX;
+  enum linker_select
+    {
+      USE_DEFAULT_LD,
+      USE_PLUGIN_LD,
+      USE_GOLD_LD,
+      USE_BFD_LD,
+      USE_LD_MAX
+    } selected_linker = USE_DEFAULT_LD;
+  static const char *const ld_suffixes[USE_LD_MAX] =
+    {
+      "ld",
+      PLUGIN_LD_SUFFIX,
+      "ld.gold",
+      "ld.bfd"
+    };
   static const char *const real_ld_suffix = "real-ld";
   static const char *const collect_ld_suffix = "collect-ld";
   static const char *const nm_suffix	= "nm";
@@ -854,16 +867,13 @@ main (int argc, char **argv)
   static const char *const strip_suffix = "strip";
   static const char *const gstrip_suffix = "gstrip";

+  const char *full_ld_suffixes[USE_LD_MAX];
 #ifdef CROSS_DIRECTORY_STRUCTURE
   /* If we look for a program in the compiler directories, we just use
      the short name, since these directories are already system-specific.
      But it we look for a program in the system directories, we need to
      qualify the program name with the target machine.  */

-  const char *const full_ld_suffix =
-    concat(target_machine, "-", ld_suffix, NULL);
-  const char *const full_plugin_ld_suffix =
-    concat(target_machine, "-", plugin_ld_suffix, NULL);
   const char *const full_nm_suffix =
     concat (target_machine, "-", nm_suffix, NULL);
   const char *const full_gnm_suffix =
@@ -877,13 +887,11 @@ main (int argc, char **argv)
   const char *const full_gstrip_suffix =
     concat (target_machine, "-", gstrip_suffix, NULL);
 #else
-  const char *const full_ld_suffix	= ld_suffix;
-  const char *const full_plugin_ld_suffix = plugin_ld_suffix;
-  const char *const full_nm_suffix	= nm_suffix;
-  const char *const full_gnm_suffix	= gnm_suffix;
 #ifdef LDD_SUFFIX
   const char *const full_ldd_suffix	= ldd_suffix;
 #endif
+  const char *const full_nm_suffix	= nm_suffix;
+  const char *const full_gnm_suffix	= gnm_suffix;
   const char *const full_strip_suffix	= strip_suffix;
   const char *const full_gstrip_suffix	= gstrip_suffix;
 #endif /* CROSS_DIRECTORY_STRUCTURE */
@@ -900,6 +908,7 @@ main (int argc, char **argv)
   char **ld1_argv;
   const char **ld1;
   bool use_plugin = false;
+  bool use_collect_ld = false;

   /* The kinds of symbols we will have to consider when scanning the
      outcome of a first pass link.  This is ALL to start with, then might
@@ -919,6 +928,15 @@ main (int argc, char **argv)
   int first_file;
   int num_c_args;
   char **old_argv;
+  int i;
+
+  for (i = 0; i < USE_LD_MAX; i++)
+    full_ld_suffixes[i]
+#ifdef CROSS_DIRECTORY_STRUCTURE
+      = concat(target_machine, "-", ld_suffixes[i], NULL);
+#else
+      = ld_suffixes[i];
+#endif

   p = argv[0] + strlen (argv[0]);
   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
@@ -980,7 +998,6 @@ main (int argc, char **argv)
      are called.  We also look for the -flto or -flto-partition=none
flag to know
      what LTO mode we are in.  */
   {
-    int i;
     bool no_partition = false;

     for (i = 1; argv[i] != NULL; i ++)
@@ -998,7 +1015,14 @@ main (int argc, char **argv)
 	  {
 	    use_plugin = true;
 	    lto_mode = LTO_MODE_NONE;
+	    if (selected_linker == USE_DEFAULT_LD)
+	      selected_linker = USE_PLUGIN_LD;
 	  }
+	else if (strcmp (argv[i], "-fuse-ld=bfd") == 0)
+	  selected_linker = USE_BFD_LD;
+	else if (strcmp (argv[i], "-fuse-ld=gold") == 0)
+	  selected_linker = USE_GOLD_LD;
+
 #ifdef COLLECT_EXPORT_LIST
 	/* since -brtl, -bexport, -b64 are not position dependent
 	   also check for them here */
@@ -1095,21 +1119,18 @@ main (int argc, char **argv)
   ld_file_name = find_a_file (&cpath, real_ld_suffix);
   /* Likewise for `collect-ld'.  */
   if (ld_file_name == 0)
-    ld_file_name = find_a_file (&cpath, collect_ld_suffix);
+    {
+      ld_file_name = find_a_file (&cpath, collect_ld_suffix);
+      use_collect_ld = ld_file_name != 0;
+    }
   /* Search the compiler directories for `ld'.  We have protection against
      recursive calls in find_a_file.  */
   if (ld_file_name == 0)
-    ld_file_name = find_a_file (&cpath,
-				use_plugin
-				? plugin_ld_suffix
-				: ld_suffix);
+    ld_file_name = find_a_file (&cpath, ld_suffixes[selected_linker]);
   /* Search the ordinary system bin directories
      for `ld' (if native linking) or `TARGET-ld' (if cross).  */
   if (ld_file_name == 0)
-    ld_file_name = find_a_file (&path,
-				use_plugin
-				? full_plugin_ld_suffix
-				: full_ld_suffix);
+    ld_file_name = find_a_file (&path, full_ld_suffixes[selected_linker]);

 #ifdef REAL_NM_FILE_NAME
   nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME);
@@ -1266,6 +1287,13 @@ main (int argc, char **argv)
 			 "configuration");
 #endif
 		}
+	      else if (!use_collect_ld
+		       && strncmp (arg, "-fuse-ld=", 9) == 0)
+		{
+		  /* Do not pass -fuse-ld={bfd|gold} to the linker. */
+		  ld1--;
+		  ld2--;
+		}
 #ifdef TARGET_AIX_VERSION
 	      else
 		{
diff --git a/gcc/common.opt b/gcc/common.opt
index 4c8bd11..7b36ba3 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2171,6 +2171,12 @@ funwind-tables
 Common Report Var(flag_unwind_tables) Optimization
 Just generate unwind tables for exception handling

+fuse-ld=bfd
+Common Var(flag_use_ld_bfd) Negative(fuse-ld=gold) Undocumented
+
+fuse-ld=gold
+Common Var(flag_use_ld_gold) Negative(fuse-ld=bfd) Undocumented
+
 fuse-linker-plugin
 Common Undocumented

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 51b6e85..3558f43 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -425,7 +425,7 @@ Objective-C and Objective-C++ Dialects}.
 -funit-at-a-time -funroll-all-loops -funroll-loops @gol
 -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
 -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
--fwhole-program -fwpa -fuse-linker-plugin @gol
+-fwhole-program -fwpa -fuse-ld=@var{linker} -fuse-linker-plugin @gol
 --param @var{name}=@var{value}
 -O  -O0  -O1  -O2  -O3  -Os -Ofast -Og}

@@ -8419,6 +8419,12 @@ the comparison operation before register
allocation is complete.

 Enabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.

+@item -fuse-ld=gold
+Use the @command{gold} linker instead of the default linker.
+
+@item -fuse-ld=bfd
+Use the @command{ld.bfd} linker instead of the default linker.
+
 @item -fcprop-registers
 @opindex fcprop-registers
 After register allocation and post-register allocation instruction splitting,
diff --git a/gcc/exec-tool.in b/gcc/exec-tool.in
index 8a10775..8f9ae27 100644
--- a/gcc/exec-tool.in
+++ b/gcc/exec-tool.in
@@ -36,13 +36,28 @@ case "$invoked" in
     dir=gas
     ;;
   collect-ld)
-    # when using a linker plugin, gcc will always pass '-plugin' as the
-    # first or second option to the linker.
-    if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
-      original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
-    else
-      original=$ORIGINAL_LD_FOR_TARGET
-    fi
+    # Check -fuse-ld=bfd and -fuse-ld=gold
+    case " $* " in
+      *\ -fuse-ld=bfd\ *)
+	if test -x ${ORIGINAL_LD_FOR_TARGET}.bfd; then
+	  original=${ORIGINAL_LD_FOR_TARGET}.bfd;
+	fi
+	;;
+      *\ -fuse-ld=gold\ *)
+	if test -x ${ORIGINAL_LD_FOR_TARGET}.gold; then
+	  original=${ORIGINAL_LD_FOR_TARGET}.gold;
+	fi
+	;;
+      *)
+	# when using a linker plugin, gcc will always pass '-plugin' as the
+	# first or second option to the linker.
+	if test x"$1" = "x-plugin" || test x"$2" = "x-plugin"; then
+	  original=$ORIGINAL_PLUGIN_LD_FOR_TARGET
+	else
+	  original=$ORIGINAL_LD_FOR_TARGET
+	fi
+	;;
+    esac
     prog=ld-new$exeext
     dir=ld
     id=ld
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 13e93e5..e0fee40 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -705,7 +705,8 @@ proper position among the other output files.  */
     LINK_PLUGIN_SPEC \
     "%{flto|flto=*:%<fcompare-debug*} \
     %{flto} %{flto=*} %l " LINK_PIE_SPEC \
-   "%X %{o*} %{e*} %{N} %{n} %{r}\
+   "%{fuse-ld=*:-fuse-ld=%*}\
+    %X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
diff --git a/gcc/opts.c b/gcc/opts.c
index b3a9afe..ff1b51e 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1753,6 +1753,8 @@ common_handle_option (struct gcc_options *opts,
       dc->max_errors = value;
       break;

+    case OPT_fuse_ld_bfd:
+    case OPT_fuse_ld_gold:
     case OPT_fuse_linker_plugin:
       /* No-op. Used by the driver and passed to us because it starts with f.*/
       break;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Enable both ld and gold in GCC 4.8
  2012-11-28 19:11   ` H.J. Lu
@ 2012-11-28 21:13     ` Paolo Bonzini
  2012-11-28 21:28       ` H.J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2012-11-28 21:13 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Joseph S. Myers, Matthias Klose, GCC Patches, Diego Novillo

Il 28/11/2012 20:11, H.J. Lu ha scritto:
> Here is the updated patch.  OK for trunk?

Looks good to me, though of course there are many parts I cannot
approve.  Thanks!

Paolo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Enable both ld and gold in GCC 4.8
  2012-11-28 21:13     ` Paolo Bonzini
@ 2012-11-28 21:28       ` H.J. Lu
  2012-11-28 22:12         ` Joseph S. Myers
  0 siblings, 1 reply; 6+ messages in thread
From: H.J. Lu @ 2012-11-28 21:28 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Joseph S. Myers, Matthias Klose, GCC Patches, Diego Novillo

On Wed, Nov 28, 2012 at 1:13 PM, Paolo Bonzini <bonzini@gnu.org> wrote:
> Il 28/11/2012 20:11, H.J. Lu ha scritto:
>> Here is the updated patch.  OK for trunk?
>
> Looks good to me, though of course there are many parts I cannot
> approve.  Thanks!
>

Joseph, can you take a look at driver change?

Thanks.


-- 
H.J.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: PATCH: Enable both ld and gold in GCC 4.8
  2012-11-28 21:28       ` H.J. Lu
@ 2012-11-28 22:12         ` Joseph S. Myers
  0 siblings, 0 replies; 6+ messages in thread
From: Joseph S. Myers @ 2012-11-28 22:12 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Paolo Bonzini, Matthias Klose, GCC Patches, Diego Novillo

On Wed, 28 Nov 2012, H.J. Lu wrote:

> On Wed, Nov 28, 2012 at 1:13 PM, Paolo Bonzini <bonzini@gnu.org> wrote:
> > Il 28/11/2012 20:11, H.J. Lu ha scritto:
> >> Here is the updated patch.  OK for trunk?
> >
> > Looks good to me, though of course there are many parts I cannot
> > approve.  Thanks!
> >
> 
> Joseph, can you take a look at driver change?

This is a long thread I haven't been following in detail with a series of 
patch revisions / changes since the original posting.  Please point to a 
self-contained patch submission of the current version of the patch, with 
self-contained description / rationale.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-11-28 22:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-27 18:36 PATCH: Enable both ld and gold in GCC 4.8 H.J. Lu
2012-11-28  9:10 ` Paolo Bonzini
2012-11-28 19:11   ` H.J. Lu
2012-11-28 21:13     ` Paolo Bonzini
2012-11-28 21:28       ` H.J. Lu
2012-11-28 22:12         ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).