This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] PATCH: add -fwhopr option


This patch accomplishes several goals.  First, it adds a new -fwhopr
option, which behaves identically to -flto except it executes lto1 in
WHOPR mode.  Second, it substantially cleans up the wrapper code in
gcc.c.  We've added a lot of unnecessary cruft.  This patch removes
most of it.  The exception is -flto-single, which could be implemented
much more cleanly if the option didn't begin with -f (which causes it
to be included in cc1_options in the absence of hackery).  I opted not
to address this now because changing the option name would confuse
people.  Finally, it adds "-fwhopr -O2" to the torture tests.
Hopefully, this will stem the constant breakage of -fwpa.

A few notes:

I added support for -fwhopr to collect2.  Ultimately, the goal is to
support this within the linker itself.  However, adding it here allows
people to use it with older linkers.  In particular, I believe this is
a precondition to adding -fwhopr to the test suites.  Once the new
linker driver is ready, we should add a feature check so collect2 can
decide whether or not to drive things.

This change breaks a few test cases.  However, these are all explicit
violations of the "-flto doesn't work with -g" error.  These *should*
have been failing before, but the relative order of options was
bypassing this check.  That's fixed by moving things into a post
options function.


Tested with an i686-pc-linux-gnu C/C++/LTO bootstrap and testsuite.

Ollie


2008-10-13  Ollie Wild  <aaw@google.com>

        * c.opt (flto): Switch variable name to flag_lto.
        (fwhopr): New option.
        * collect2.c (enum lto_mode_d): Rename LTO_MODE_WPA to LTO_MODE_WHOPR.
        (lto_o_file): Remove.
        (lto_o_files): New variable.
        (collect_exit): Replace lto_o_file with lto_o_files.
        (handler): Replace lto_o_file with lto_o_files.
        (maybe_run_lto_and_relink): Add support for -fwhopr.
        (main): Replace -fwpa with -fwhopr.
        (maybe_unlink_list): New function.
        * gcc.c (gcc_lto_option_t): Remove.
        (lto_single): New variable.
        (LINK_COMMAND_SPEC): Add flto and fwhopr.  Remove link_lto_options.
        (cc1_non_lto_options): Rename as cc1_options.
        (cc1_options): Remove.
        (lto1_options): Remove.
        (link_lto_options): Remove.
        (invoke_lto_single): Replace lto-option with lto-single.  Add -flto.
        Replace lto1_options with cc1_options.
        (static_specs): Remove cc1_non_lto_options, lto1_options, and
        link_lto_options.
        (static_spec_functions): Replace lto-option with lto-single.
        (process_command): Set lto_single.  Remove cases for -flto, -fwpa, and
        -fltrans.
        (lto_option_spec_function): Remove.
        (lto_single_spec_function): New function.
        * c-opts.c (c_common_post_options): Add -flto/-fwhopr validation.
        * flags.h (flag_generate_lto): New variable declaration.
        * toplev.c (flag_generate_lto): New variable definition.

2008-10-13  Ollie Wild  <aaw@google.com>

        * lang-spec.h (@lto): Replace lto1_options with cc1_options.
        * lto.c (lto_execute_ltrans): Add "-fno-wpa -fltrans -xlto" to CFLAGS.
        * ltrans-driver (LTRANS_FLAGS): Remove.

2008-10-13  Ollie Wild  <aaw@google.com>

        * lib/c-torture.exp: Add "-O2 -fwhopr".
        * lib/gcc-dg.exp: Add "-O2 -fwhopr".
commit 811eda9ce9e9ed3b4246a41141531e85e0d80ceb
Author: Ollie Wild <aaw@google.com>
Date:   Sun Oct 12 22:18:11 2008 -0700

    Add support for -fwhopr.

diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index 164ca4a..2b2890c 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -1013,6 +1013,21 @@ c_common_post_options (const char **pfilename)
   C_COMMON_OVERRIDE_OPTIONS;
 #endif
 
+  /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
+     check option consistency.  */
+  if (flag_lto && flag_whopr)
+    error ("-flto and -fwhopr are mutually exclusive");
+  if (flag_lto || flag_whopr)
+    {
+      flag_generate_lto = 1;
+
+      /* FIXME lto: With -flto and -fwhopr, debug information will be
+	 incomplete or inaccurate, or worse, may be sufficiently corrupt as to
+	 crash the debug info writer.  */
+      if (debug_info_level != DINFO_LEVEL_NONE)
+	error ("-g is presently unsupported with -flto and -fwhopr");
+    }
+
   /* By default we use C99 inline semantics in GNU99 or C99 mode.  C99
      inline semantics are not supported in GNU89 or C89 mode.  */
   if (flag_gnu89_inline == -1)
diff --git a/gcc/c.opt b/gcc/c.opt
index d30e212..19b9239 100644
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -625,7 +625,7 @@ C ObjC C++ ObjC++
 Allow implicit conversions between vectors with differing numbers of subparts and/or differing element types.
 
 flto
-C C++ Var(flag_generate_lto)
+C C++ Var(flag_lto)
 Enable link-time optimization.
 
 fms-extensions
@@ -797,6 +797,10 @@ fweak
 C++ ObjC++
 Emit common-like symbols as weak symbols
 
+fwhopr
+C C++ Var(flag_whopr)
+Enable partitioned link-time optimization.
+
 fwide-exec-charset=
 C ObjC C++ ObjC++ Joined RejectNegative
 -fwide-exec-charset=<cset>	Convert all wide strings and character constants to character set <cset>
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 84dcda7..326d5b9 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -182,7 +182,7 @@ static int aixrtl_flag;			/* true if -brtl */
 enum lto_mode_d {
   LTO_MODE_NONE,			/* Not doing LTO. */
   LTO_MODE_LTO,				/* Normal LTO. */
-  LTO_MODE_WPA				/* WHOPR. */
+  LTO_MODE_WHOPR				/* WHOPR. */
 };
 
 static enum lto_mode_d lto_mode = LTO_MODE_NONE; /* current LTO mode. */
@@ -196,7 +196,7 @@ static const char *o_file;		/* <xxx>.o for constructor/destructor list.  */
 #ifdef COLLECT_EXPORT_LIST
 static const char *export_file;		/* <xxx>.x for AIX export list.  */
 #endif
-static const char *lto_o_file;		/* Output file for LTO.  */
+static char **lto_o_files;		/* Output files for LTO.  */
 const char *ldout;			/* File for ld stdout.  */
 const char *lderrout;			/* File for ld stderr.  */
 static const char *output_file;		/* Output file for ld.  */
@@ -288,6 +288,7 @@ static void add_lto_object (struct lto_object_list *list, const char *name);
 static void do_wait (const char *, struct pex_obj *);
 static void fork_execute (const char *, char **);
 static void maybe_unlink (const char *);
+static void maybe_unlink_list (char **);
 static void add_to_list (struct head *, const char *);
 static int extract_init_priority (const char *);
 static void sort_ids (struct head *);
@@ -339,8 +340,8 @@ collect_exit (int status)
     maybe_unlink (export_file);
 #endif
 
-  if (lto_o_file != 0 && lto_o_file[0])
-    maybe_unlink (lto_o_file);
+  if (lto_o_files)
+    maybe_unlink_list (lto_o_files);
 
   if (ldout != 0 && ldout[0])
     {
@@ -451,8 +452,8 @@ handler (int signo)
     maybe_unlink (export_file);
 #endif
 
-  if (lto_o_file != 0 && lto_o_file[0])
-    maybe_unlink (lto_o_file);
+  if (lto_o_files)
+    maybe_unlink_list (lto_o_files);
 
   if (response_file)
     maybe_unlink (response_file);
@@ -872,15 +873,13 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
       const char **lto_c_ptr;
       const char *cp;
       const char **p, **q, **r;
+      const char **lto_o_ptr;
       struct lto_object *list;
-      bool first;
+      char *ltrans_output_file = NULL;
 
       /* There is at least one object file containing LTO info,
          so we need to run the LTO back end and relink.  */
 
-      /* Create a temporary file for the output of the LTO back end.  */
-      lto_o_file = make_temp_file (".lto.o");
-
       /* Get compiler options passed down from the parent `gcc' command.
          These must be passed to the LTO back end.  */
       opts = getenv ("COLLECT_GCC_OPTIONS");
@@ -910,10 +909,33 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
       *lto_c_ptr++ = "-x";
       *lto_c_ptr++ = "lto";
       *lto_c_ptr++ = "-c";
-      *lto_c_ptr++ = "-o";
-      *lto_c_ptr++ = lto_o_file;
-      if (lto_mode == LTO_MODE_WPA)
-	*lto_c_ptr++ = "-fwpa";
+      if (lto_mode == LTO_MODE_LTO)
+	{
+	  lto_o_files = XNEWVEC (char *, 2);
+	  lto_o_files[0] = make_temp_file (".lto.o");
+	  lto_o_files[1] = NULL;
+
+	  *lto_c_ptr++ = "-o";
+	  *lto_c_ptr++ = lto_o_files[0];
+	}
+      else if (lto_mode == LTO_MODE_WHOPR)
+	{
+	  const char *list_option = "-fltrans-output-list=";
+	  size_t list_option_len = strlen (list_option);
+	  char *tmp;
+
+	  ltrans_output_file = make_temp_file(".ltrans.out");
+	  tmp = XNEWVEC (char,
+			 strlen (ltrans_output_file) + list_option_len + 1);
+	  *lto_c_ptr++ = tmp;
+	  strcpy (tmp, list_option);
+	  tmp += list_option_len;
+	  strcpy (tmp, ltrans_output_file);
+
+	  *lto_c_ptr++ = "-fwpa";
+	}
+      else
+	fatal ("invalid LTO mode");
 
       /* Add inherited GCC options to the LTO back end command line.
          Filter out some obviously inappropriate options that will
@@ -921,7 +943,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
          all of the remaining options on to LTO, and let it complain
          about any it doesn't like. Note that we invoke LTO via the
          `gcc' driver, so the usual option processing takes place.
-         Except for `-flto' and `-fwpa', we should only filter options that
+         Except for `-flto' and `-fwhopr', we should only filter options that
 	 are meaningful to `ld', lest an option go silently unclaimed.  */
 
       cp = opts;
@@ -930,7 +952,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
         {
           const char *s = extract_string (&cp);
 
-          if (strcmp (s, "-flto") == 0 || strcmp (s, "-fwpa") == 0)
+          if (strcmp (s, "-flto") == 0 || strcmp (s, "-fwhopr") == 0)
             /* We've handled this LTO option, don't pass it on.  */
             ;
           else if (strcmp (s, "-o") == 0)
@@ -947,12 +969,62 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
         }
       obstack_free (&temporary_obstack, temporary_firstobj);
 
+      /* Add LTO objects to the LTO command line.  */
+      for (list = lto_objects.first; list; list = list->next)
+	*lto_c_ptr++ = list->name;
+
+      *lto_c_ptr = NULL;
+
+      /* Run the LTO back end.  */
+      fork_execute ("gcc", lto_c_argv);
+
+      /* Read in the list of output file names.  */
+      if (lto_mode == LTO_MODE_WHOPR)
+	{
+	  int c;
+	  FILE *stream;
+	  size_t i, num_files;
+	  char *start, *end;
+
+	  stream = fopen (ltrans_output_file, "r");
+	  if (!stream)
+	    fatal_perror ("fopen: %s", ltrans_output_file);
+
+	  num_files = 0;
+	  while ((c = getc (stream)) != EOF)
+	    {
+	      obstack_1grow (&temporary_obstack, c);
+	      if (c == '\n')
+		++num_files;
+	    }
+
+	  if (fclose (stream))
+	    fatal_perror ("fclose: %s", ltrans_output_file);
+
+	  lto_o_files = XNEWVEC (char *, num_files + 1);
+	  lto_o_files[num_files] = NULL;
+
+	  start = XOBFINISH (&temporary_obstack, char *);
+	  for (i = 0; i < num_files; ++i)
+	    {
+	      end = start;
+	      while (*end != '\n')
+		++end;
+	      *end = '\0';
+
+	      lto_o_files[i] = xstrdup (start);
+
+	      start = end + 1;
+	    }
+
+	  obstack_free (&temporary_obstack, temporary_firstobj);
+	}
+
       /* After running the LTO back end, we will relink, substituting
 	 the LTO output for the object files that we submitted to the
 	 LTO. Here, we modify the linker command line for the relink.  */
-      first = true;
-
       p = (const char **)lto_ld_argv;
+      lto_o_ptr = (const char **)lto_o_files;
 
       while (*p != NULL)
         {
@@ -960,16 +1032,11 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
             {
               if (*p == list->name) /* Note test for pointer equality!  */
                 {
-                  /* Add file to the LTO command line.  */
-                  *lto_c_ptr++ = list->name;
-
                   /* Excise argument from linker command line.  */
-                  if (first)
+                  if (*lto_o_ptr)
                     {
                       /* Replace first argument with LTO output file.  */
-                      *p = lto_o_file;
-                      first = false;
-                      ++p;
+                      *p++ = *lto_o_ptr++;
                     }
                   else
                     {
@@ -993,17 +1060,20 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
           if (!list) ++p;
         }
 
-      *lto_c_ptr = NULL;
-
-      /* Run the LTO back end.  */
-      fork_execute ("gcc", lto_c_argv);
+      /* The code above assumes we will never have more lto output files than
+	 input files.  Otherwise, we need to resize lto_ld_argv.  Check this
+	 assumption.  */
+      if (*lto_o_ptr)
+	fatal ("too many lto output files");
 
       /* Run the linker again, this time replacing the object files
          optimized by the LTO with the temporary file generated by the LTO.  */
       fork_execute ("ld", lto_ld_argv);
 
       /* Clean up the temporary file.  */
-      maybe_unlink (lto_o_file);
+      if (ltrans_output_file)
+	maybe_unlink (ltrans_output_file);
+      maybe_unlink_list (lto_o_files);
     }
   else if (force)
     {
@@ -1120,7 +1190,7 @@ main (int argc, char **argv)
 
   /* Parse command line early for instances of -debug.  This allows
      the debug flag to be set before functions like find_a_file()
-     are called. We also look for the -flto or -fwpa flag, though it is not
+     are called. We also look for the -flto or -fwhopr flag, though it is not
      necessary to do so at this early stage. */
   {
     int i;
@@ -1131,8 +1201,8 @@ main (int argc, char **argv)
 	  debug = 1;
         else if (! strcmp (argv[i], "-flto"))
           lto_mode = LTO_MODE_LTO;
-        else if (! strcmp (argv[i], "-fwpa"))
-          lto_mode = LTO_MODE_WPA;
+        else if (! strcmp (argv[i], "-fwhopr"))
+          lto_mode = LTO_MODE_WHOPR;
       }
     vflag = debug;
   }
@@ -1381,7 +1451,7 @@ main (int argc, char **argv)
 	      break;
 
             case 'f':
-              if (strcmp (arg, "-flto") == 0 || strcmp (arg, "-fwpa") == 0)
+              if (strcmp (arg, "-flto") == 0 || strcmp (arg, "-fwhopr") == 0)
               {
                 /* Do not pass LTO flag to the linker. */
                 ld1--;
@@ -1961,6 +2031,16 @@ maybe_unlink (const char *file)
     notice ("[Leaving %s]\n", file);
 }
 
+/* Call maybe_unlink on the NULL-terminated list, FILE_LIST.  */
+static void
+maybe_unlink_list (char **file_list)
+{
+  const char **tmp = file_list;
+
+  while (*tmp)
+    maybe_unlink (*(tmp++));
+}
+
 
 static long sequence_number = 0;
 
diff --git a/gcc/flags.h b/gcc/flags.h
index b1d91bd..a3b2908 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -225,6 +225,10 @@ extern enum ira_algorithm flag_ira_algorithm;
 
 extern unsigned int flag_ira_verbose;
 
+/* Nonzero means to serialize gimplified function bodies for use in link-time
+   optimization.  */
+extern int flag_generate_lto;
+
 
 /* Other basic status info about current function.  */
 
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 5b5a23d..08ffbc5 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -232,21 +232,12 @@ static int combine_flag = 0;
 
 static int use_pipes;
 
-/* LTO state.  The LTO options are related and not all combination are
-   meaningful.  Treat each LTO option as a state and only use the last
-   specified option.  The option may be modified before the driver passes
-   it to sub-processes.  */
-
-typedef enum {
-  LTO_OPTION_NONE = 0,
-  LTO_OPTION_LTO,
-  LTO_OPTION_LTO_SINGLE,
-  LTO_OPTION_WPA,
-  LTO_OPTION_LTRANS,
-  LTO_N_OPTIONS
-} gcc_lto_option_t;
-
-gcc_lto_option_t current_lto_option = LTO_OPTION_NONE;
+/* Nonzero means we are running in lto-single mode, and each object file
+   resulting from a compilation should be immediately recompiled using
+   the LTO back end.  This makes it easy to exercise the LTO by adding
+   a single switch to existing makefiles.  */
+
+static int lto_single;
 
 /* The compiler version.  */
 
@@ -392,7 +383,7 @@ static const char *replace_outfile_spec_function (int, const char **);
 static const char *version_compare_spec_function (int, const char **);
 static const char *include_spec_function (int, const char **);
 static const char *print_asm_header_spec_function (int, const char **);
-static const char *lto_option_spec_function (int, const char **);
+static const char *lto_single_spec_function (int, const char **);
 
 /* The Specs Language
 
@@ -752,12 +743,12 @@ proper position among the other output files.  */
 /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    scripts which exist in user specified directories, or in standard
    directories.  */
-/* We pass the -flto flag on to the linker, which is expected
-   to understand it.  In practice, this means it had better be collect2.  */
+/* We pass any -flto and -fwhopr flags on to the linker, which is expected
+   to understand them.  In practice, this means it had better be collect2.  */
 #ifndef LINK_COMMAND_SPEC
 #define LINK_COMMAND_SPEC "\
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
-    %(linker) %(link_lto_options) %l " LINK_PIE_SPEC \
+    %(linker) %{flto} %{fwhopr} %l " LINK_PIE_SPEC \
    "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
@@ -856,7 +847,7 @@ static const char *cpp_options =
 static const char *cpp_debug_options = "%{d*}";
 
 /* NB: This is shared amongst all front-ends.  */
-static const char *cc1_non_lto_options =
+static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
  %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
  %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
@@ -868,33 +859,20 @@ static const char *cc1_non_lto_options =
  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
  %{fsyntax-only:-o %j} %{-param*}\
  %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}\
- %{coverage:-fprofile-arcs -ftest-coverage} ";
-
-/* NB: This is shared amongst all front-ends except lto1.  */
-static const char *cc1_options =
-"%(cc1_non_lto_options)\
- %{!?lto-option(none): -flto} ";
-
-static const char *lto1_options =
-"%(cc1_non_lto_options)\
- %{?lto-option(wpa): -fwpa}\
- %{?lto-option(ltrans): -fltrans} ";
-
-static const char *link_lto_options =
-"%{?lto-option(lto): -flto} %{?lto-option(wpa): -fwpa} ";
+ %{coverage:-fprofile-arcs -ftest-coverage}";
 
 /* Do we need to preserve any assembler options here?
    Note that we are going to ignore the object code, as
    we are only interested in the .lto_info sections.  */
 static const char *invoke_lto_single =
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
-"%{?lto-option(lto-single): -o %|.lto.s |\n\
+"%{?lto-single(): -flto -o %|.lto.s |\n\
  as %(asm_options) %|.lto.s -o %g.lto.o \n\
- lto1 %(lto1_options) %g.lto.o }";
+ lto1 %(cc1_options) %g.lto.o }";
 #else
-"%{?lto-option(lto-single): -o %|.lto.s |\n\
+"%{?lto-single(): -flto -o %|.lto.s |\n\
  as %(asm_options) %m.lto.s -o %g.lto.o \n\
- lto1 %(lto1_options) %g.lto.o }";
+ lto1 %(cc1_options) %g.lto.o }";
 #endif
 
 static const char *asm_options =
@@ -1649,18 +1627,15 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("trad_capable_cpp",		&trad_capable_cpp),
   INIT_STATIC_SPEC ("cc1",			&cc1_spec),
   INIT_STATIC_SPEC ("cc1_options",		&cc1_options),
-  INIT_STATIC_SPEC ("cc1_non_lto_options",	&cc1_non_lto_options),
   INIT_STATIC_SPEC ("cc1plus",			&cc1plus_spec),
   INIT_STATIC_SPEC ("link_gcc_c_sequence",	&link_gcc_c_sequence_spec),
   INIT_STATIC_SPEC ("link_ssp",			&link_ssp_spec),
   INIT_STATIC_SPEC ("endfile",			&endfile_spec),
   INIT_STATIC_SPEC ("link",			&link_spec),
   INIT_STATIC_SPEC ("lib",			&lib_spec),
-  INIT_STATIC_SPEC ("lto1_options",		&lto1_options),
   INIT_STATIC_SPEC ("mfwrap",			&mfwrap_spec),
   INIT_STATIC_SPEC ("mflib",			&mflib_spec),
   INIT_STATIC_SPEC ("link_gomp",		&link_gomp_spec),
-  INIT_STATIC_SPEC ("link_lto_options",		&link_lto_options),
   INIT_STATIC_SPEC ("libgcc",			&libgcc_spec),
   INIT_STATIC_SPEC ("startfile",		&startfile_spec),
   INIT_STATIC_SPEC ("switches_need_spaces",	&switches_need_spaces),
@@ -1711,7 +1686,7 @@ static const struct spec_function static_spec_functions[] =
   { "version-compare",		version_compare_spec_function },
   { "include",			include_spec_function },
   { "print-asm-header",		print_asm_header_spec_function },
-  { "lto-option",		lto_option_spec_function },
+  { "lto-single",		lto_single_spec_function },
 #ifdef EXTRA_SPEC_FUNCTIONS
   EXTRA_SPEC_FUNCTIONS
 #endif
@@ -3890,14 +3865,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 	  n_switches++;
 	  n_switches++;
         }
-      else if (strcmp (argv[i], "-flto") == 0)
-	current_lto_option = LTO_OPTION_LTO;
       else if (strcmp (argv[i], "-flto-single") == 0)
-	current_lto_option = LTO_OPTION_LTO_SINGLE;
-      else if (strcmp (argv[i], "-fwpa") == 0)
-	current_lto_option = LTO_OPTION_WPA;
-      else if (strcmp (argv[i], "-fltrans") == 0)
-	current_lto_option = LTO_OPTION_LTRANS;
+	lto_single = 1;
       else if (strcmp (argv[i], "-###") == 0)
 	{
 	  /* This is similar to -v except that there is no execution
@@ -4273,14 +4242,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 	;
       else if (strcmp (argv[i], "-time") == 0)
 	;
-      else if (strcmp (argv[i], "-flto") == 0)
-	;
       else if (strcmp (argv[i], "-flto-single") == 0)
 	;
-      else if (strcmp (argv[i], "-fwpa") == 0)
-	;
-      else if (strcmp (argv[i], "-fltrans") == 0)
-	;
       else if (strcmp (argv[i], "-###") == 0)
 	;
       else if (argv[i][0] == '-' && argv[i][1] != 0)
@@ -8226,22 +8189,15 @@ print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   return NULL;
 }
 
-/* ?lto-option(<option>) spec predicate.  Return true, i.e.,
-   a non-empty string, if <option> is the last LTO option specified. */
+/* ?lto-single() spec predicate.  Return true, i.e., a non-empty string,
+   if the -flto-single switch was given to 'gcc'.  */
 
 static const char *
-lto_option_spec_function (int argc, const char **argv)
+lto_single_spec_function (int argc,
+                          const char **argv ATTRIBUTE_UNUSED)
 {
-  static const char *names[] = { "none", "lto", "lto-single", "wpa", "ltrans" };
-  int i;
-
-  if (argc != 1)
+  if (argc != 0)
     abort ();
 
-  for (i = 0; i < LTO_N_OPTIONS; i++)
-    if (!strcmp (names[i], argv[0]))
-      return ((int) current_lto_option == i) ? argv[0] : NULL;
-
-  gcc_unreachable ();
-  return NULL;
+  return ((lto_single) ? "lto-single" : NULL);
 }
diff --git a/gcc/lto/lang-specs.h b/gcc/lto/lang-specs.h
index 03fd6b5..61f21f8 100644
--- a/gcc/lto/lang-specs.h
+++ b/gcc/lto/lang-specs.h
@@ -23,5 +23,5 @@ Boston, MA 02110-1301, USA.  */
   
   {".lto",  "@lto",
    /*cpp_spec=*/NULL, /*combinable=*/1, /*needs_preprocessing=*/0},
-  {"@lto", "lto1 %(lto1_options) %i %{!fsyntax-only:%(invoke_as)}", 
+  {"@lto", "lto1 %(cc1_options) %i %{!fsyntax-only:%(invoke_as)}",
    /*cpp_spec=*/NULL, /*combinable=*/1, /*needs_preprocessing=*/0},
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index e7a0177..b69c943 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -691,6 +691,7 @@ lto_execute_ltrans (char *const *files)
 {
   struct pex_obj *pex;
   const char *env_val;
+  const char *extra_cflags = " -fno-wpa -fltrans -xlto";
   struct obstack env_obstack;
   char **argv;
   const char **argv_ptr;
@@ -717,7 +718,8 @@ lto_execute_ltrans (char *const *files)
 
   obstack_init (&env_obstack);
   obstack_grow (&env_obstack, "CFLAGS=", sizeof ("CFLAGS=") - 1);
-  obstack_grow (&env_obstack, env_val, strlen (env_val) + 1);
+  obstack_grow (&env_obstack, env_val, strlen (env_val));
+  obstack_grow (&env_obstack, extra_cflags, strlen (extra_cflags) + 1);
   putenv (XOBFINISH (&env_obstack, char *));
 
   pex = pex_init (0, "lto1", NULL);
diff --git a/gcc/lto/ltrans-driver b/gcc/lto/ltrans-driver
index 6047bcc..2c41679 100755
--- a/gcc/lto/ltrans-driver
+++ b/gcc/lto/ltrans-driver
@@ -48,8 +48,6 @@ trap 'rm -rf $tmp' TERM INT EXIT
 makefile=$tmp/Makefile
 touch $makefile
 
-echo "LTRANS_FLAGS = -xlto -fltrans" >> $makefile
-
 inputlist="$@"
 outputlist=
 for input in $inputlist
@@ -58,7 +56,7 @@ do
   outputlist="$outputlist $output"
 
   echo "$output: $input" >> $makefile
-  echo "	\$(CC) \$(CFLAGS) \$(LTRANS_FLAGS) -o $output $input" >> $makefile
+  echo "	\$(CC) \$(CFLAGS) -o $output $input" >> $makefile
   echo >> $makefile
 done
 
diff --git a/gcc/testsuite/lib/c-torture.exp b/gcc/testsuite/lib/c-torture.exp
index f74da6f..88de7af 100644
--- a/gcc/testsuite/lib/c-torture.exp
+++ b/gcc/testsuite/lib/c-torture.exp
@@ -36,6 +36,7 @@ if [info exists TORTURE_OPTIONS] {
 	{ -O0 -flto } \
 	{ -O1 -flto } \
 	{ -O2 -flto } \
+	{ -O2 -fwhopr } \
 	{ -O3 -flto -fomit-frame-pointer } \
 	{ -O3 -flto -fomit-frame-pointer -funroll-loops } \
 	{ -O3 -flto -fomit-frame-pointer -funroll-all-loops -finline-functions } \
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 03c42e7..bf310b5 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -46,6 +46,7 @@ if [info exists TORTURE_OPTIONS] {
 	{ -O0 -flto } \
 	{ -O1 -flto } \
 	{ -O2 -flto } \
+	{ -O2 -fwhopr } \
 	{ -O3 -flto -fomit-frame-pointer } \
 	{ -O3 -flto -fomit-frame-pointer -funroll-loops } \
 	{ -O3 -flto -fomit-frame-pointer -funroll-all-loops -finline-functions } \
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 3d97f99..f99e06a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -286,6 +286,9 @@ enum ira_algorithm flag_ira_algorithm = IRA_ALGORITHM_MIXED;
 
 unsigned int flag_ira_verbose = 5;
 
+/* By default, we don't generate sections for link-time optimization.  */
+int flag_generate_lto;
+
 /* Nonzero means change certain warnings into errors.
    Usually these are warnings about failure to conform to some standard.  */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]