[PATCH][RFC] Add -Og

Richard Guenther richard.guenther@gmail.com
Mon Sep 3 13:28:00 GMT 2012


On Fri, Aug 10, 2012 at 1:30 PM, Richard Guenther <rguenther@suse.de> wrote:
>
> This adds a new optimization level, -Og, as previously discussed.
> It aims at providing fast compilation, a superior debugging
> experience and reasonable runtime performance.  Instead of making
> -O1 this optimization level this adds a new -Og.
>
> It's a first cut, highlighting that our fixed pass pipeline and
> simply enabling/disabling individual passes (but not pass copies
> for example) doesn't scale to properly differentiate between
> -Og and -O[23].  -O1 should get similar treatment, eventually
> just building on -Og but not focusing on debugging experience.
> That is, I expect that in the end we will at least have two post-IPA
> optimization pipelines.  It also means that you cannot enable
> PRE or VRP with -Og at the moment because these passes are not
> anywhere scheduled (similar to the situation with -O0).
>
> It has some funny effect on dump-file naming of the pass copies
> though, which hints at that the current setup is too static.
> For that reason the new queue comes after the old, to not confuse
> too many testcases.
>
> It also does not yet disable any of the early optimizations that
> make debugging harder (SRA comes to my mind here, as does
> switch-conversion and partial inlining).
>
> The question arises if we want to support in any reasonable
> way using profile-feedback or LTO for -O[01g], thus if we
> rather want to delay some of the early opts to after IPA
> optimizations.
>
> Not bootstrapped or fully tested, but it works for the compile
> torture.
>
> Comments welcome,

No comments?  Then I'll drop this idea for 4.8.

Richard.

> Thanks,
> Richard.
>
> 2012-08-10  Richard Guenther  <rguenther@suse.de>
>
>         PR other/53316
>         * common.opt (optimize_debug): New variable.
>         (Og): New optimization level.
>         * doc/invoke.texi (Og): Document.
>         * opts.c (maybe_default_option): Add debug parameter.
>         (maybe_default_options): Likewise.
>         (default_options_optimization): Handle -Og.
>         (common_handle_option): Likewise.
>         * passes.c (gate_all_optimizations): Do not run with -Og.
>         (gate_all_optimizations_g): New gate, run with -Og.
>         (pass_all_optimizations_g): New container pass, run with -Og.
>         (init_optimization_passes): Schedule pass_all_optimizations_g
>         alongside pass_all_optimizations.
>
>         * gcc/testsuite/lib/c-torture.exp: Add -Og -g to default
>         TORTURE_OPTIONS.
>
> Index: trunk/gcc/common.opt
> ===================================================================
> *** trunk.orig/gcc/common.opt   2012-07-19 10:39:47.000000000 +0200
> --- trunk/gcc/common.opt        2012-08-10 11:58:22.218122816 +0200
> *************** int optimize
> *** 32,37 ****
> --- 32,40 ----
>   Variable
>   int optimize_size
>
> + Variable
> + int optimize_debug
> +
>   ; Not used directly to control optimizations, only to save -Ofast
>   ; setting for "optimize" attributes.
>   Variable
> *************** Ofast
> *** 446,451 ****
> --- 449,458 ----
>   Common Optimization
>   Optimize for speed disregarding exact standards compliance
>
> + Og
> + Common Optimization
> + Optimize for debugging experience rather than speed or size
> +
>   Q
>   Driver
>
> Index: trunk/gcc/opts.c
> ===================================================================
> *** trunk.orig/gcc/opts.c       2012-07-24 10:35:57.000000000 +0200
> --- trunk/gcc/opts.c    2012-08-10 12:48:38.986018411 +0200
> *************** init_options_struct (struct gcc_options
> *** 314,328 ****
>   }
>
>   /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
> !    -Ofast if FAST is set), apply the option DEFAULT_OPT to OPTS and
> !    OPTS_SET, diagnostic context DC, location LOC, with language mask
> !    LANG_MASK and option handlers HANDLERS.  */
>
>   static void
>   maybe_default_option (struct gcc_options *opts,
>                       struct gcc_options *opts_set,
>                       const struct default_options *default_opt,
> !                     int level, bool size, bool fast,
>                       unsigned int lang_mask,
>                       const struct cl_option_handlers *handlers,
>                       location_t loc,
> --- 314,328 ----
>   }
>
>   /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
> !    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
> !    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
> !    mask LANG_MASK and option handlers HANDLERS.  */
>
>   static void
>   maybe_default_option (struct gcc_options *opts,
>                       struct gcc_options *opts_set,
>                       const struct default_options *default_opt,
> !                     int level, bool size, bool fast, bool debug,
>                       unsigned int lang_mask,
>                       const struct cl_option_handlers *handlers,
>                       location_t loc,
> *************** maybe_default_option (struct gcc_options
> *** 335,340 ****
> --- 335,342 ----
>       gcc_assert (level == 2);
>     if (fast)
>       gcc_assert (level == 3);
> +   if (debug)
> +     gcc_assert (level == 1);
>
>     switch (default_opt->levels)
>       {
> *************** maybe_default_option (struct gcc_options
> *** 351,357 ****
>         break;
>
>       case OPT_LEVELS_1_PLUS_SPEED_ONLY:
> !       enabled = (level >= 1 && !size);
>         break;
>
>       case OPT_LEVELS_2_PLUS:
> --- 353,359 ----
>         break;
>
>       case OPT_LEVELS_1_PLUS_SPEED_ONLY:
> !       enabled = (level >= 1 && !size && !debug);
>         break;
>
>       case OPT_LEVELS_2_PLUS:
> *************** maybe_default_option (struct gcc_options
> *** 359,365 ****
>         break;
>
>       case OPT_LEVELS_2_PLUS_SPEED_ONLY:
> !       enabled = (level >= 2 && !size);
>         break;
>
>       case OPT_LEVELS_3_PLUS:
> --- 361,367 ----
>         break;
>
>       case OPT_LEVELS_2_PLUS_SPEED_ONLY:
> !       enabled = (level >= 2 && !size && !debug);
>         break;
>
>       case OPT_LEVELS_3_PLUS:
> *************** static void
> *** 405,411 ****
>   maybe_default_options (struct gcc_options *opts,
>                        struct gcc_options *opts_set,
>                        const struct default_options *default_opts,
> !                      int level, bool size, bool fast,
>                        unsigned int lang_mask,
>                        const struct cl_option_handlers *handlers,
>                        location_t loc,
> --- 407,413 ----
>   maybe_default_options (struct gcc_options *opts,
>                        struct gcc_options *opts_set,
>                        const struct default_options *default_opts,
> !                      int level, bool size, bool fast, bool debug,
>                        unsigned int lang_mask,
>                        const struct cl_option_handlers *handlers,
>                        location_t loc,
> *************** maybe_default_options (struct gcc_option
> *** 415,421 ****
>
>     for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
>       maybe_default_option (opts, opts_set, &default_opts[i],
> !                         level, size, fast, lang_mask, handlers, loc, dc);
>   }
>
>   /* Table of options enabled by default at different levels.  */
> --- 417,424 ----
>
>     for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
>       maybe_default_option (opts, opts_set, &default_opts[i],
> !                         level, size, fast, debug,
> !                         lang_mask, handlers, loc, dc);
>   }
>
>   /* Table of options enabled by default at different levels.  */
> *************** default_options_optimization (struct gcc
> *** 540,545 ****
> --- 543,549 ----
>               opts->x_optimize = 1;
>               opts->x_optimize_size = 0;
>               opts->x_optimize_fast = 0;
> +             opts->x_optimize_debug = 0;
>             }
>           else
>             {
> *************** default_options_optimization (struct gcc
> *** 555,560 ****
> --- 559,565 ----
>                     opts->x_optimize = 255;
>                   opts->x_optimize_size = 0;
>                   opts->x_optimize_fast = 0;
> +                 opts->x_optimize_debug = 0;
>                 }
>             }
>           break;
> *************** default_options_optimization (struct gcc
> *** 565,570 ****
> --- 570,576 ----
>           /* Optimizing for size forces optimize to be 2.  */
>           opts->x_optimize = 2;
>           opts->x_optimize_fast = 0;
> +         opts->x_optimize_debug = 0;
>           break;
>
>         case OPT_Ofast:
> *************** default_options_optimization (struct gcc
> *** 572,577 ****
> --- 578,592 ----
>           opts->x_optimize_size = 0;
>           opts->x_optimize = 3;
>           opts->x_optimize_fast = 1;
> +         opts->x_optimize_debug = 0;
> +         break;
> +
> +       case OPT_Og:
> +         /* -Og selects optimization level 1.  */
> +         opts->x_optimize_size = 0;
> +         opts->x_optimize = 1;
> +         opts->x_optimize_fast = 0;
> +         opts->x_optimize_debug = 1;
>           break;
>
>         default:
> *************** default_options_optimization (struct gcc
> *** 582,588 ****
>
>     maybe_default_options (opts, opts_set, default_options_table,
>                          opts->x_optimize, opts->x_optimize_size,
> !                        opts->x_optimize_fast, lang_mask, handlers, loc, dc);
>
>     /* -O2 param settings.  */
>     opt2 = (opts->x_optimize >= 2);
> --- 597,604 ----
>
>     maybe_default_options (opts, opts_set, default_options_table,
>                          opts->x_optimize, opts->x_optimize_size,
> !                        opts->x_optimize_fast, opts->x_optimize_debug,
> !                        lang_mask, handlers, loc, dc);
>
>     /* -O2 param settings.  */
>     opt2 = (opts->x_optimize >= 2);
> *************** default_options_optimization (struct gcc
> *** 612,618 ****
>     maybe_default_options (opts, opts_set,
>                          targetm_common.option_optimization_table,
>                          opts->x_optimize, opts->x_optimize_size,
> !                        opts->x_optimize_fast, lang_mask, handlers, loc, dc);
>   }
>
>   /* After all options at LOC have been read into OPTS and OPTS_SET,
> --- 628,635 ----
>     maybe_default_options (opts, opts_set,
>                          targetm_common.option_optimization_table,
>                          opts->x_optimize, opts->x_optimize_size,
> !                        opts->x_optimize_fast, opts->x_optimize_debug,
> !                        lang_mask, handlers, loc, dc);
>   }
>
>   /* After all options at LOC have been read into OPTS and OPTS_SET,
> *************** common_handle_option (struct gcc_options
> *** 1408,1413 ****
> --- 1425,1431 ----
>       case OPT_O:
>       case OPT_Os:
>       case OPT_Ofast:
> +     case OPT_Og:
>         /* Currently handled in a prescan.  */
>         break;
>
> Index: trunk/gcc/passes.c
> ===================================================================
> *** trunk.orig/gcc/passes.c     2012-08-03 10:54:00.000000000 +0200
> --- trunk/gcc/passes.c  2012-08-10 12:45:16.449025382 +0200
> *************** static struct gimple_opt_pass pass_all_e
> *** 337,346 ****
>   static bool
>   gate_all_optimizations (void)
>   {
> !   return (optimize >= 1
> !         /* Don't bother doing anything if the program has errors.
> !            We have to pass down the queue if we already went into SSA */
> !         && (!seen_error () || gimple_in_ssa_p (cfun)));
>   }
>
>   static struct gimple_opt_pass pass_all_optimizations =
> --- 337,343 ----
>   static bool
>   gate_all_optimizations (void)
>   {
> !   return optimize >= 1 && !optimize_debug;
>   }
>
>   static struct gimple_opt_pass pass_all_optimizations =
> *************** static struct gimple_opt_pass pass_all_o
> *** 362,367 ****
> --- 359,391 ----
>    }
>   };
>
> + /* Gate: execute, or not, all of the non-trivial optimizations.  */
> +
> + static bool
> + gate_all_optimizations_g (void)
> + {
> +   return optimize >= 1 && optimize_debug;
> + }
> +
> + static struct gimple_opt_pass pass_all_optimizations_g =
> + {
> +  {
> +   GIMPLE_PASS,
> +   "*all_optimizations_g",             /* name */
> +   gate_all_optimizations_g,           /* gate */
> +   NULL,                                       /* execute */
> +   NULL,                                       /* sub */
> +   NULL,                                       /* next */
> +   0,                                  /* static_pass_number */
> +   TV_OPTIMIZE,                                /* tv_id */
> +   0,                                  /* properties_required */
> +   0,                                  /* properties_provided */
> +   0,                                  /* properties_destroyed */
> +   0,                                  /* todo_flags_start */
> +   0                                   /* todo_flags_finish */
> +  }
> + };
> +
>   static bool
>   gate_rest_of_compilation (void)
>   {
> *************** init_optimization_passes (void)
> *** 1493,1498 ****
> --- 1517,1545 ----
>         NEXT_PASS (pass_uncprop);
>         NEXT_PASS (pass_local_pure_const);
>       }
> +   NEXT_PASS (pass_all_optimizations_g);
> +     {
> +       struct opt_pass **p = &pass_all_optimizations_g.pass.sub;
> +       NEXT_PASS (pass_remove_cgraph_callee_edges);
> +       NEXT_PASS (pass_strip_predict_hints);
> +       /* Lower remaining pieces of GIMPLE.  */
> +       NEXT_PASS (pass_lower_complex);
> +       NEXT_PASS (pass_lower_vector_ssa);
> +       /* Perform simple scalar cleanup which is constant/copy propagation.  */
> +       NEXT_PASS (pass_ccp);
> +       NEXT_PASS (pass_copy_prop);
> +       NEXT_PASS (pass_rename_ssa_copies);
> +       NEXT_PASS (pass_dce);
> +       /* Fold remaining builtins.  */
> +       NEXT_PASS (pass_object_sizes);
> +       NEXT_PASS (pass_fold_builtins);
> +       /* ???  We do want some kind of loop invariant motion, but we possibly
> +          need to adjust LIM to be more friendly towards preserving accurate
> +        debug information here.  */
> +       NEXT_PASS (pass_late_warn_uninitialized);
> +       NEXT_PASS (pass_uncprop);
> +       NEXT_PASS (pass_local_pure_const);
> +     }
>     NEXT_PASS (pass_tm_init);
>       {
>         struct opt_pass **p = &pass_tm_init.pass.sub;
> Index: trunk/gcc/testsuite/lib/c-torture.exp
> ===================================================================
> *** trunk.orig/gcc/testsuite/lib/c-torture.exp  2011-10-24 10:18:31.000000000 +0200
> --- trunk/gcc/testsuite/lib/c-torture.exp       2012-08-10 12:27:25.494062458 +0200
> *************** if [info exists TORTURE_OPTIONS] {
> *** 42,48 ****
>         { -O3 -fomit-frame-pointer -funroll-loops } \
>         { -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions } \
>         { -O3 -g } \
> !       { -Os } ]
>   }
>
>   if [info exists ADDITIONAL_TORTURE_OPTIONS] {
> --- 42,49 ----
>         { -O3 -fomit-frame-pointer -funroll-loops } \
>         { -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions } \
>         { -O3 -g } \
> !       { -Os } \
> !       { -Og -g } ]
>   }
>
>   if [info exists ADDITIONAL_TORTURE_OPTIONS] {
> Index: trunk/gcc/doc/invoke.texi
> ===================================================================
> *** trunk.orig/gcc/doc/invoke.texi      2012-08-06 12:36:44.000000000 +0200
> --- trunk/gcc/doc/invoke.texi   2012-08-10 13:18:40.760955978 +0200
> *************** Objective-C and Objective-C++ Dialects}.
> *** 422,428 ****
>   -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
>   -fwhole-program -fwpa -fuse-linker-plugin @gol
>   --param @var{name}=@var{value}
> ! -O  -O0  -O1  -O2  -O3  -Os -Ofast}
>
>   @item Preprocessor Options
>   @xref{Preprocessor Options,,Options Controlling the Preprocessor}.
> --- 422,428 ----
>   -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
>   -fwhole-program -fwpa -fuse-linker-plugin @gol
>   --param @var{name}=@var{value}
> ! -O  -O0  -O1  -O2  -O3  -Os -Ofast -Og}
>
>   @item Preprocessor Options
>   @xref{Preprocessor Options,,Options Controlling the Preprocessor}.
> *************** valid for all standard compliant program
> *** 6344,6349 ****
> --- 6344,6357 ----
>   It turns on @option{-ffast-math} and the Fortran-specific
>   @option{-fno-protect-parens} and @option{-fstack-arrays}.
>
> + @item -Og
> + @opindex Og
> + Optimize debugging experience.  @option{-Og} enables optimizations
> + that do not interfere with debugging. It should be the optimization
> + level of choice for the standard edit-compile-debug cycle, offering
> + a reasonable level of optimization while maintaining fast compilation
> + and a good debugging experience.
> +
>   If you use multiple @option{-O} options, with or without level numbers,
>   the last such option is the one that is effective.
>   @end table



More information about the Gcc-patches mailing list