This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][RFC] Add -Og


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,

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]