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:

Reply via email to