> > This merges -O options given at compile-time into a single > optimization level to be used for LTO link time (but > overridden with whatever is specified at LTO link time - unless > no optimization level is specified there). That is, it > determines a "default" optimization level used at LTO link time > (as opposed to the default optimization level zero). > > Currently the code merges exact same options as-is and > mismatching optimization levels based on the maximum value of > 'optimize' they cause and merging it as -Ooptimize. > Thus -Og and -Os get merged as -O2, -O and -Ofast get merged as -O3 > and -O and -O1 get merged as -O1. > > Specifying any optimization level explicitely at link time > will override what we came up with above (including explicitely > specifying -O0). > > Comments? > > I've tested that it works as expected. Do we want something like > this for 4.9?
Yes, I do not see much down-sides. Of course I have the grand plans to make compiler flags to be preserved thorough LTO, but i think you patch improves things over what we have now. Honza > > Thanks, > Richard. > > 2014-03-04 Richard Biener <rguent...@suse.de> > > * lto-wrapper.c (merge_and_complain): Merge compile-time > optimization levels. > (run_gcc): And pass it through to the link options. > > Index: gcc/lto-wrapper.c > =================================================================== > *** gcc/lto-wrapper.c (revision 208305) > --- gcc/lto-wrapper.c (working copy) > *************** merge_and_complain (struct cl_decoded_op > *** 459,464 **** > --- 459,535 ---- > 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; > } > } > } > *************** run_gcc (unsigned argc, char *argv[]) > *** 610,615 **** > --- 681,690 ---- > case OPT_fwrapv: > case OPT_ftrapv: > case OPT_fstrict_overflow: > + case OPT_O: > + case OPT_Ofast: > + case OPT_Og: > + case OPT_Os: > break; > > default: