/* Wrapper to call lto. Used by collect2 and the linker plugin.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2014 Free Software Foundation, Inc.
Factored out of collect2 by Rafael Espindola <espindola@google.com>
&& errno != ENOENT)
fatal_perror ("deleting LTRANS file %s", file);
}
- else
+ else if (verbose)
fprintf (stderr, "[Leaving LTRANS %s]\n", file);
}
/* Fallthru. */
case OPT_fPIC:
case OPT_fpic:
+ case OPT_fPIE:
case OPT_fpie:
case OPT_fcommon:
case OPT_fexceptions:
+ case OPT_fnon_call_exceptions:
case OPT_fgnu_tm:
/* Do what the old LTO code did - collect exactly one option
setting per OPT code, we pick the first we encounter.
append_option (decoded_options, decoded_options_count, foption);
break;
+ case OPT_ftrapv:
+ case OPT_fstrict_overflow:
+ case OPT_ffp_contract_:
+ /* For selected options we can merge conservatively. */
+ for (j = 0; j < *decoded_options_count; ++j)
+ if ((*decoded_options)[j].opt_index == foption->opt_index)
+ break;
+ if (j == *decoded_options_count)
+ append_option (decoded_options, decoded_options_count, foption);
+ /* FP_CONTRACT_OFF < FP_CONTRACT_ON < FP_CONTRACT_FAST,
+ -fno-trapv < -ftrapv,
+ -fno-strict-overflow < -fstrict-overflow */
+ else if (foption->value < (*decoded_options)[j].value)
+ (*decoded_options)[j] = *foption;
+ break;
+
+ case OPT_fwrapv:
+ /* For selected options we can merge conservatively. */
+ for (j = 0; j < *decoded_options_count; ++j)
+ if ((*decoded_options)[j].opt_index == foption->opt_index)
+ break;
+ if (j == *decoded_options_count)
+ append_option (decoded_options, decoded_options_count, foption);
+ /* -fwrapv > -fno-wrapv. */
+ else if (foption->value > (*decoded_options)[j].value)
+ (*decoded_options)[j] = *foption;
+ break;
+
case OPT_freg_struct_return:
case OPT_fpcc_struct_return:
+ case OPT_fshort_double:
for (j = 0; j < *decoded_options_count; ++j)
if ((*decoded_options)[j].opt_index == foption->opt_index)
break;
fatal ("Option %s not used consistently in all LTO input files",
foption->orig_option_with_args_text);
break;
+
+ case OPT_O:
+ case OPT_Ofast:
+ case OPT_Og:
+ case OPT_Os:
+ for (j = 0; j < *decoded_options_count; ++j)
+ if ((*decoded_options)[j].opt_index == OPT_O
+ || (*decoded_options)[j].opt_index == OPT_Ofast
+ || (*decoded_options)[j].opt_index == OPT_Og
+ || (*decoded_options)[j].opt_index == OPT_Os)
+ break;
+ if (j == *decoded_options_count)
+ append_option (decoded_options, decoded_options_count, foption);
+ else if ((*decoded_options)[j].opt_index == foption->opt_index
+ && foption->opt_index != OPT_O)
+ /* Exact same options get merged. */
+ ;
+ else
+ {
+ /* For mismatched option kinds preserve the optimization
+ level only, thus merge it as -On. This also handles
+ merging of same optimization level -On. */
+ int level = 0;
+ switch (foption->opt_index)
+ {
+ case OPT_O:
+ if (foption->arg[0] == '\0')
+ level = MAX (level, 1);
+ else
+ level = MAX (level, atoi (foption->arg));
+ break;
+ case OPT_Ofast:
+ level = MAX (level, 3);
+ break;
+ case OPT_Og:
+ level = MAX (level, 1);
+ break;
+ case OPT_Os:
+ level = MAX (level, 2);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ switch ((*decoded_options)[j].opt_index)
+ {
+ case OPT_O:
+ if ((*decoded_options)[j].arg[0] == '\0')
+ level = MAX (level, 1);
+ else
+ level = MAX (level, atoi ((*decoded_options)[j].arg));
+ break;
+ case OPT_Ofast:
+ level = MAX (level, 3);
+ break;
+ case OPT_Og:
+ level = MAX (level, 1);
+ break;
+ case OPT_Os:
+ level = MAX (level, 2);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ (*decoded_options)[j].opt_index = OPT_O;
+ char *tem;
+ asprintf (&tem, "-O%d", level);
+ (*decoded_options)[j].arg = &tem[2];
+ (*decoded_options)[j].canonical_option[0] = tem;
+ (*decoded_options)[j].value = 1;
+ }
+ break;
}
}
}
/* Drop arguments that we want to take from the link line. */
case OPT_flto_:
case OPT_flto:
- case OPT_flto_partition_none:
- case OPT_flto_partition_1to1:
- case OPT_flto_partition_balanced:
+ case OPT_flto_partition_:
continue;
default:
{
case OPT_fPIC:
case OPT_fpic:
+ case OPT_fPIE:
case OPT_fpie:
case OPT_fcommon:
case OPT_fexceptions:
+ case OPT_fnon_call_exceptions:
case OPT_fgnu_tm:
case OPT_freg_struct_return:
case OPT_fpcc_struct_return:
+ case OPT_fshort_double:
+ case OPT_ffp_contract_:
+ case OPT_fwrapv:
+ case OPT_ftrapv:
+ case OPT_fstrict_overflow:
+ case OPT_O:
+ case OPT_Ofast:
+ case OPT_Og:
+ case OPT_Os:
break;
default:
verbose = 1;
break;
- case OPT_flto_partition_none:
- no_partition = true;
+ case OPT_flto_partition_:
+ if (strcmp (option->arg, "none") == 0)
+ no_partition = true;
break;
case OPT_flto_:
case OPT_freg_struct_return:
case OPT_fpcc_struct_return:
+ case OPT_fshort_double:
/* Ignore these, they are determined by the input files.
??? We fail to diagnose a possible mismatch here. */
continue;
tmp += list_option_len;
strcpy (tmp, ltrans_output_file);
- obstack_ptr_grow (&argv_obstack, "-fwpa");
+ if (jobserver)
+ obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
+ else if (parallel > 1)
+ {
+ char buf[256];
+ sprintf (buf, "-fwpa=%i", parallel);
+ obstack_ptr_grow (&argv_obstack, xstrdup (buf));
+ }
+ else
+ obstack_ptr_grow (&argv_obstack, "-fwpa");
}
/* Append the input objects and possible preceding arguments. */
if (lto_mode == LTO_MODE_LTO)
{
- printf("%s\n", flto_out);
+ printf ("%s\n", flto_out);
free (flto_out);
flto_out = NULL;
}
{
char *dumpbase
= (char *) xmalloc (strlen (linker_output)
- + sizeof(DUMPBASE_SUFFIX) + 1);
+ + sizeof (DUMPBASE_SUFFIX) + 1);
snprintf (dumpbase,
- strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
+ strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
"%s.ltrans%u", linker_output, i);
argv_ptr[0] = dumpbase;
}
{
const char *p;
+ gcc_obstack_init (&opts_obstack);
+
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
--p;