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? 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: