Commit cf96bae7 by Richard Guenther Committed by Richard Biener

re PR lto/44143 (-fdump-tree-all for lto does not work as expected)

2010-05-18  Richard Guenther  <rguenther@suse.de>

	PR lto/44143
	* lto-wrapper.c (verbose): New variable.  Initialize from -v.
	(debug): Initialize from -save-temps.
	(collect_execute): Print command-line when verbose.
	(run_gcc): Always use COLLECT_GCC_OPTIONS.  Use fork_execute
	for ltrans invocation.  Produce -dumpbase flag again.
	(process_args): Remove.
	(main): Simplify.
	* collect2.c (maybe_run_lto_and_relink): Only pass object
	files to lto-wrapper.
	* gcc.c (LINK_COMMAND_SPEC): Likewise.

From-SVN: r159536
parent 80e2a014
2010-05-18 Richard Guenther <rguenther@suse.de>
PR lto/44143
* lto-wrapper.c (verbose): New variable. Initialize from -v.
(debug): Initialize from -save-temps.
(collect_execute): Print command-line when verbose.
(run_gcc): Always use COLLECT_GCC_OPTIONS. Use fork_execute
for ltrans invocation. Produce -dumpbase flag again.
(process_args): Remove.
(main): Simplify.
* collect2.c (maybe_run_lto_and_relink): Only pass object
files to lto-wrapper.
* gcc.c (LINK_COMMAND_SPEC): Likewise.
2010-05-18 Jan Hubicka <jh@suse.cz>
* opts.c (decode_options): Do not disable whopr at ipa_cp.
......
......@@ -940,10 +940,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
if (lto_objects.first)
{
const char *opts;
char **lto_c_argv;
const char **lto_c_ptr;
const char *cp;
const char **p, **q, **r;
const char **lto_o_ptr;
struct lto_object *list;
......@@ -954,52 +952,15 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
if (!lto_wrapper)
fatal ("COLLECT_LTO_WRAPPER must be set.");
num_lto_c_args++;
/* There is at least one object file containing LTO info,
so we need to run the LTO back end and relink. */
/* Get compiler options passed down from the parent `gcc' command.
These must be passed to the LTO back end. */
opts = getenv ("COLLECT_GCC_OPTIONS");
/* Increment the argument count by the number of inherited options.
Some arguments may be filtered out later. Again, an upper bound
suffices. */
cp = opts;
while (cp && *cp)
{
extract_string (&cp);
num_lto_c_args++;
}
obstack_free (&temporary_obstack, temporary_firstobj);
if (debug)
num_lto_c_args++;
/* Increment the argument count by the number of initial
arguments added below. */
num_lto_c_args += 9;
lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
*lto_c_ptr++ = lto_wrapper;
*lto_c_ptr++ = c_file_name;
cp = opts;
while (cp && *cp)
{
const char *s = extract_string (&cp);
/* Pass the option or argument to the wrapper. */
*lto_c_ptr++ = xstrdup (s);
}
obstack_free (&temporary_obstack, temporary_firstobj);
if (debug)
*lto_c_ptr++ = xstrdup ("-debug");
/* Add LTO objects to the wrapper command line. */
for (list = lto_objects.first; list; list = list->next)
......
......@@ -781,15 +781,9 @@ proper position among the other output files. */
%{fuse-linker-plugin: \
-plugin %(linker_plugin_file) \
-plugin-opt=%(lto_wrapper) \
-plugin-opt=%(lto_gcc) \
-plugin-opt=-fresolution=%u.res \
%{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)} \
%{static:-plugin-opt=-pass-through=-lc} \
%{O*:-plugin-opt=-O%*} \
%{w:-plugin-opt=-w} \
%{f*:-plugin-opt=-f%*} \
%{m*:-plugin-opt=-m%*} \
%{v:-plugin-opt=-v} \
} \
%{flto} %{fwhopr} %l " LINK_PIE_SPEC \
"%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
......
......@@ -45,12 +45,13 @@ along with GCC; see the file COPYING3. If not see
#include "libiberty.h"
#include "obstack.h"
int debug; /* true if -debug */
int debug; /* true if -save-temps. */
int verbose; /* true if -v. */
enum lto_mode_d {
LTO_MODE_NONE, /* Not doing LTO. */
LTO_MODE_LTO, /* Normal LTO. */
LTO_MODE_WHOPR /* WHOPR. */
LTO_MODE_NONE, /* Not doing LTO. */
LTO_MODE_LTO, /* Normal LTO. */
LTO_MODE_WHOPR /* WHOPR. */
};
/* Current LTO mode. */
......@@ -129,7 +130,7 @@ collect_execute (char **argv)
const char *errmsg;
int err;
if (debug)
if (verbose)
{
char **p_argv;
const char *str;
......@@ -255,27 +256,118 @@ fork_execute (char **argv)
static void
run_gcc (unsigned argc, char *argv[])
{
unsigned i;
unsigned new_argc = argc;
unsigned i, j;
const char **new_argv;
const char **argv_ptr;
char *list_option_full = NULL;
const char *linker_output = NULL;
const char *collect_gcc_options, *collect_gcc;
struct obstack env_obstack;
bool seen_o = false;
/* Get the driver and options. */
collect_gcc = getenv ("COLLECT_GCC");
if (!collect_gcc)
fatal ("environment variable COLLECT_GCC must be set");
/* Set the CFLAGS environment variable. */
collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
if (!collect_gcc_options)
fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
/* Count arguments. */
i = 0;
for (j = 0; collect_gcc_options[j] != '\0'; ++j)
if (collect_gcc_options[j] == '\'')
++i;
if (i % 2 != 0)
fatal ("malformed COLLECT_GCC_OPTIONS");
/* Initalize the common arguments for the driver. */
new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
argv_ptr = new_argv;
*argv_ptr++ = collect_gcc;
*argv_ptr++ = "-xlto";
*argv_ptr++ = "-c";
for (j = 0; collect_gcc_options[j] != '\0'; ++j)
if (collect_gcc_options[j] == '\'')
{
char *option;
++j;
i = j;
while (collect_gcc_options[j] != '\'')
++j;
obstack_init (&env_obstack);
obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
obstack_1grow (&env_obstack, 0);
option = XOBFINISH (&env_obstack, char *);
if (seen_o)
{
linker_output = option;
seen_o = false;
continue;
}
/* If we see -o, skip it and skip and record its argument. */
if (option[0] == '-' && option[1] == 'o')
{
if (option[2] == '\0')
seen_o = true;
else
linker_output = &option[2];
continue;
}
new_argc += 12;
new_argv = (const char **) xcalloc (sizeof (char *), new_argc);
if (strcmp (option, "-save-temps") == 0)
debug = 1;
if (strcmp (option, "-v") == 0)
verbose = 1;
/* We've handled these LTO options, do not pass them on. */
if (strcmp (option, "-flto") == 0)
lto_mode = LTO_MODE_LTO;
else if (strcmp (option, "-fwhopr") == 0)
lto_mode = LTO_MODE_WHOPR;
else
*argv_ptr++ = option;
}
if (linker_output)
{
char *output_dir, *base, *name;
argv_ptr = new_argv;
output_dir = xstrdup (linker_output);
base = output_dir;
for (name = base; *name; name++)
if (IS_DIR_SEPARATOR (*name))
base = name + 1;
*base = '\0';
linker_output = &linker_output[base - output_dir];
if (*output_dir == '\0')
{
static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
output_dir = current_dir;
}
*argv_ptr++ = "-dumpdir";
*argv_ptr++ = output_dir;
*argv_ptr++ = "-dumpbase";
}
else
argv_ptr--;
*argv_ptr++ = argv[0];
*argv_ptr++ = "-combine";
*argv_ptr++ = "-x";
*argv_ptr++ = "lto";
*argv_ptr++ = "-c";
if (lto_mode == LTO_MODE_LTO)
{
flto_out = make_temp_file (".lto.o");
*argv_ptr++ = "-o";
*argv_ptr++ = flto_out;
if (linker_output)
argv_ptr[0] = linker_output;
argv_ptr[1] = "-o";
argv_ptr[2] = flto_out;
argv_ptr[3] = "-combine";
}
else if (lto_mode == LTO_MODE_WHOPR)
{
......@@ -283,80 +375,38 @@ run_gcc (unsigned argc, char *argv[])
size_t list_option_len = strlen (list_option);
char *tmp;
if (linker_output)
{
char *dumpbase = (char *) xmalloc (strlen (linker_output)
+ sizeof(".wpa") + 1);
strcpy (dumpbase, linker_output);
strcat (dumpbase, ".wpa");
argv_ptr[0] = dumpbase;
}
ltrans_output_file = make_temp_file (".ltrans.out");
list_option_full = (char *) xmalloc (sizeof (char) *
(strlen (ltrans_output_file) + list_option_len + 1));
tmp = list_option_full;
*argv_ptr++ = tmp;
argv_ptr[1] = tmp;
strcpy (tmp, list_option);
tmp += list_option_len;
strcpy (tmp, ltrans_output_file);
*argv_ptr++ = "-fwpa";
argv_ptr[2] = "-fwpa";
argv_ptr[3] = "-combine";
}
else
fatal ("invalid LTO mode");
/* Add inherited GCC options to the LTO back end command line.
Filter out some obviously inappropriate options that will
conflict with the options that we force above. We pass
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 `-fwhopr', we should only filter options that
are meaningful to `ld', lest an option go silently unclaimed. */
for (i = 1; i < argc; i++)
{
const char *s = argv[i];
if (strcmp (s, "-flto") == 0 || strcmp (s, "-fwhopr") == 0)
/* We've handled this LTO option, don't pass it on. */
;
else if (*s == '-' && s[1] == 'o')
{
/* Drop `-o' and its filename argument. We will use a
temporary file for the LTO output. The `-o' option
will be interpreted by the linker. */
if (s[2] == '\0')
{
char *output_dir, *base, *name;
i++;
output_dir = xstrdup (argv[i]);
base = output_dir;
for (name = base; *name; name++)
if (IS_DIR_SEPARATOR (*name))
base = name + 1;
*base = '\0';
*argv_ptr++ = "-dumpbase";
if (*output_dir == '\0')
{
static char current_dir[] =
{ '.', DIR_SEPARATOR, '\0' };
output_dir = current_dir;
*argv_ptr++ = argv[i];
}
else
*argv_ptr++ = &argv[i][base - output_dir];
*argv_ptr++ = "-dumpdir";
*argv_ptr++ = output_dir;
}
}
else
/* Pass the option or argument to LTO. */
*argv_ptr++ = s;
}
*argv_ptr = NULL;
/* Append the input objects and possible preceeding arguments. */
for (i = 1; i < argc; ++i)
argv_ptr[3 + i] = argv[i];
argv_ptr[3 + i] = NULL;
fork_execute (CONST_CAST (char **, new_argv));
free (new_argv);
new_argv = NULL;
if (lto_mode == LTO_MODE_LTO)
{
printf("%s\n", flto_out);
......@@ -366,85 +416,12 @@ run_gcc (unsigned argc, char *argv[])
else if (lto_mode == LTO_MODE_WHOPR)
{
FILE *stream = fopen (ltrans_output_file, "r");
const char *collect_gcc_options, *collect_gcc;
struct obstack env_obstack;
bool seen_dumpbase = false;
bool seen_o = false;
char *dumpbase_suffix = NULL;
unsigned j;
int nr = 0;
if (!stream)
fatal_perror ("fopen: %s", ltrans_output_file);
/* Get the driver and options. */
collect_gcc = getenv ("COLLECT_GCC");
if (!collect_gcc)
fatal ("environment variable COLLECT_GCC must be set");
/* Set the CFLAGS environment variable. */
collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
if (!collect_gcc_options)
fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
/* Count arguments. */
i = 0;
for (j = 0; collect_gcc_options[j] != '\0'; ++j)
if (collect_gcc_options[j] == '\'')
++i;
if (i % 2 != 0)
fatal ("malformed COLLECT_GCC_OPTIONS");
/* Initalize the arguments for the LTRANS driver. */
new_argv = (const char **) xmalloc ((8 + i / 2) * sizeof (char *));
argv_ptr = new_argv;
*argv_ptr++ = collect_gcc;
*argv_ptr++ = "-xlto";
*argv_ptr++ = "-c";
for (j = 0; collect_gcc_options[j] != '\0'; ++j)
if (collect_gcc_options[j] == '\'')
{
char *option;
++j;
i = j;
while (collect_gcc_options[j] != '\'')
++j;
obstack_init (&env_obstack);
obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
if (seen_dumpbase)
obstack_grow (&env_obstack, DUMPBASE_SUFFIX,
sizeof (DUMPBASE_SUFFIX));
else
obstack_1grow (&env_obstack, 0);
option = XOBFINISH (&env_obstack, char *);
if (seen_dumpbase)
{
dumpbase_suffix = option + 7 + j - i;
seen_dumpbase = false;
}
if (seen_o)
{
seen_o = false;
continue;
}
/* If we see -o, skip it and its argument. */
if (strncmp (option, "-o", 2) == 0)
{
seen_o = true;
continue;
}
/* LTRANS does not need -fwhopr. */
if (strncmp (option, "-fwhopr", 7) != 0)
{
if (strncmp (option, "-dumpbase", 9) == 0)
seen_dumpbase = true;
*argv_ptr++ = option;
}
}
*argv_ptr++ = "-fltrans";
argv_ptr[1] = "-fltrans";
for (;;)
{
......@@ -473,11 +450,6 @@ cont:
}
else
{
struct pex_obj *pex;
const char *errmsg;
int err;
int status;
/* Otherwise, add FILES[I] to lto_execute_ltrans command line
and add the resulting file to LTRANS output list. */
......@@ -488,44 +460,23 @@ cont:
obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
output_name = XOBFINISH (&env_obstack, char *);
argv_ptr[0] = "-o";
argv_ptr[1] = output_name;
argv_ptr[2] = input_name;
argv_ptr[3] = NULL;
/* Append a sequence number to -dumpbase for LTRANS. */
if (dumpbase_suffix)
snprintf (dumpbase_suffix, sizeof (DUMPBASE_SUFFIX) - 7,
"%lu", (unsigned long) i);
/* Execute the driver. */
pex = pex_init (0, "lto1", NULL);
if (pex == NULL)
fatal ("pex_init failed: %s", xstrerror (errno));
errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, new_argv[0],
CONST_CAST (char **, new_argv),
NULL, NULL, &err);
if (errmsg)
fatal ("%s: %s", errmsg, xstrerror (err));
if (!pex_get_status (pex, 1, &status))
fatal ("can't get program status: %s", xstrerror (errno));
if (status)
if (linker_output)
{
if (WIFSIGNALED (status))
{
int sig = WTERMSIG (status);
fatal ("%s terminated with signal %d [%s]%s",
new_argv[0], sig, strsignal (sig),
WCOREDUMP (status) ? ", core dumped" : "");
}
else
fatal ("%s terminated with status %d", new_argv[0], status);
char *dumpbase
= (char *) xmalloc (strlen (linker_output)
+ sizeof(DUMPBASE_SUFFIX) + 1);
snprintf (dumpbase,
strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
"%s.ltrans%d", linker_output, nr++);
argv_ptr[0] = dumpbase;
}
pex_free (pex);
argv_ptr[2] = "-o";
argv_ptr[3] = output_name;
argv_ptr[4] = input_name;
argv_ptr[5] = NULL;
fork_execute (CONST_CAST (char **, new_argv));
maybe_unlink_file (input_name);
}
......@@ -536,38 +487,11 @@ cont:
fclose (stream);
maybe_unlink_file (ltrans_output_file);
free (list_option_full);
obstack_free (&env_obstack, NULL);
}
else
fatal ("invalid LTO mode");
}
/* Parse the command line. Copy any unused argument to GCC_ARGV. ARGC is the
number of arguments. ARGV contains the arguments. */
static int
process_args (int argc, char *argv[], char *gcc_argv[])
{
int i;
int j = 0;
for (i = 1; i < argc; i ++)
{
if (! strcmp (argv[i], "-debug"))
debug = 1;
else if (! strcmp (argv[i], "-flto"))
lto_mode = LTO_MODE_LTO;
else if (! strcmp (argv[i], "-fwhopr"))
lto_mode = LTO_MODE_WHOPR;
else
{
gcc_argv[j] = argv[i];
j++;
}
}
return j;
obstack_free (&env_obstack, NULL);
}
......@@ -576,18 +500,12 @@ process_args (int argc, char *argv[], char *gcc_argv[])
int
main (int argc, char *argv[])
{
char **gcc_argv;
int gcc_argc;
gcc_init_libintl ();
/* We may be called with all the arguments stored in some file and
passed with @file. Expand them into argv before processing. */
expandargv (&argc, &argv);
gcc_argv = (char **) xcalloc (sizeof (char *), argc);
gcc_argc = process_args (argc, argv, gcc_argv);
run_gcc (gcc_argc, gcc_argv);
free (gcc_argv);
run_gcc (argc, argv);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment