mirror of git://gcc.gnu.org/git/gcc.git
collect2.c (maybe_run_lto_and_relink): Rewrite code producing ld command line to allow more partitions than input files.
* collect2.c (maybe_run_lto_and_relink): Rewrite code producing ld command line to allow more partitions than input files. From-SVN: r164106
This commit is contained in:
parent
aa0df10b37
commit
ed2222c873
|
|
@ -1,3 +1,8 @@
|
|||
2010-09-09 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* collect2.c (maybe_run_lto_and_relink): Rewrite code producing ld
|
||||
command line to allow more partitions than input files.
|
||||
|
||||
2010-09-09 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
PR middle-end/44554
|
||||
|
|
|
|||
|
|
@ -942,12 +942,16 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
|
|||
{
|
||||
char **lto_c_argv;
|
||||
const char **lto_c_ptr;
|
||||
const char **p, **q, **r;
|
||||
const char **lto_o_ptr;
|
||||
char **p;
|
||||
char **lto_o_ptr;
|
||||
struct lto_object *list;
|
||||
char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
|
||||
struct pex_obj *pex;
|
||||
const char *prog = "lto-wrapper";
|
||||
int lto_ld_argv_size = 0;
|
||||
char **out_lto_ld_argv;
|
||||
int out_lto_ld_argv_size;
|
||||
size_t num_files;
|
||||
|
||||
if (!lto_wrapper)
|
||||
fatal ("COLLECT_LTO_WRAPPER must be set.");
|
||||
|
|
@ -955,7 +959,11 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
|
|||
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. */
|
||||
so we need to run the LTO back end and relink.
|
||||
|
||||
To do so we build updated ld arguments with first
|
||||
LTO object replaced by all partitions and other LTO
|
||||
objects removed. */
|
||||
|
||||
lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
|
||||
lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
|
||||
|
|
@ -973,7 +981,7 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
|
|||
{
|
||||
int c;
|
||||
FILE *stream;
|
||||
size_t i, num_files;
|
||||
size_t i;
|
||||
char *start, *end;
|
||||
|
||||
stream = pex_read_output (pex, 0);
|
||||
|
|
@ -1007,55 +1015,50 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
|
|||
do_wait (prog, pex);
|
||||
pex = NULL;
|
||||
|
||||
/* Compute memory needed for new LD arguments. At most number of original arguemtns
|
||||
plus number of partitions. */
|
||||
for (lto_ld_argv_size = 0; lto_ld_argv[lto_ld_argv_size]; lto_ld_argv_size++)
|
||||
;
|
||||
out_lto_ld_argv = XCNEWVEC(char *, num_files + lto_ld_argv_size + 1);
|
||||
out_lto_ld_argv_size = 0;
|
||||
|
||||
/* 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. */
|
||||
p = CONST_CAST2 (const char **, char **, lto_ld_argv);
|
||||
lto_o_ptr = CONST_CAST2 (const char **, char **, lto_o_files);
|
||||
|
||||
/* Copy all arguments until we find first LTO file. */
|
||||
p = lto_ld_argv;
|
||||
while (*p != NULL)
|
||||
{
|
||||
for (list = lto_objects.first; list; list = list->next)
|
||||
{
|
||||
if (*p == list->name) /* Note test for pointer equality! */
|
||||
{
|
||||
/* Excise argument from linker command line. */
|
||||
if (*lto_o_ptr)
|
||||
{
|
||||
/* Replace first argument with LTO output file. */
|
||||
*p++ = *lto_o_ptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move following arguments one position earlier,
|
||||
overwriting the current argument. */
|
||||
q = p;
|
||||
r = p + 1;
|
||||
while (*r != NULL)
|
||||
*q++ = *r++;
|
||||
*q = NULL;
|
||||
}
|
||||
|
||||
/* No need to continue searching the LTO object list. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we didn't find a match, move on to the next argument.
|
||||
Otherwise, P has been set to the correct argument position
|
||||
at which to continue. */
|
||||
if (!list) ++p;
|
||||
if (*p == list->name) /* Note test for pointer equality! */
|
||||
break;
|
||||
if (list)
|
||||
break;
|
||||
out_lto_ld_argv[out_lto_ld_argv_size++] = *p++;
|
||||
}
|
||||
|
||||
/* 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");
|
||||
/* Now insert all LTO partitions. */
|
||||
lto_o_ptr = lto_o_files;
|
||||
while (*lto_o_ptr)
|
||||
out_lto_ld_argv[out_lto_ld_argv_size++] = *lto_o_ptr++;
|
||||
|
||||
/* ... and copy the rest. */
|
||||
while (*p != NULL)
|
||||
{
|
||||
for (list = lto_objects.first; list; list = list->next)
|
||||
if (*p == list->name) /* Note test for pointer equality! */
|
||||
break;
|
||||
if (!list)
|
||||
out_lto_ld_argv[out_lto_ld_argv_size++] = *p;
|
||||
p++;
|
||||
}
|
||||
out_lto_ld_argv[out_lto_ld_argv_size++] = 0;
|
||||
|
||||
/* 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);
|
||||
fork_execute ("ld", out_lto_ld_argv);
|
||||
free (lto_ld_argv);
|
||||
|
||||
maybe_unlink_list (lto_o_files);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue