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] Add -Og optimization level - optimize for compile-time/debugging experience


This adds -Og as optimization level targeted at the devel-compile-debug
cycle (formerly mostly tied to -O0 due to debug issues with even -O1).

Discussion on gcc@gcc.gnu.org at least shows interest in this, so this
is a formal patch submission with a request for comments on the
implementation (not necessarily on what passes are enabled and why).

I have bootstrapped and tested this patch with BOOT_C/CXX_FLAGS="-Og -g"
TARGET_CFLAGS="-Og -g" with all languages included (but -Werror disabled,
as expected some new maybe-uninit uses pop up).

Ok for trunk?

Thanks,
Richard.

2012-09-18  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 13:47:45.678895549 +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,363 ----
        break;
  
      case OPT_LEVELS_1_PLUS_SPEED_ONLY:
!       enabled = (level >= 1 && !size && !debug);
!       break;
! 
!     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
!       enabled = (level >= 1 && !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:
--- 365,371 ----
        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,
--- 411,417 ----
  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.  */
--- 421,428 ----
  
    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.  */
*************** static const struct default_options defa
*** 444,450 ****
      { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
!     { OPT_LEVELS_1_PLUS, OPT_ftree_sra, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
--- 451,457 ----
      { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
!     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
      { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
*************** static const struct default_options defa
*** 498,504 ****
      /* Inlining of functions reducing size is a good idea with -Os
         regardless of them being declared inline.  */
      { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
!     { OPT_LEVELS_1_PLUS, OPT_finline_functions_called_once, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
--- 505,511 ----
      /* Inlining of functions reducing size is a good idea with -Os
         regardless of them being declared inline.  */
      { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
!     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
      { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
*************** default_options_optimization (struct gcc
*** 540,545 ****
--- 547,553 ----
  	      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 ****
--- 563,569 ----
  		    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 ****
--- 574,580 ----
  	  /* 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 ****
--- 582,596 ----
  	  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);
--- 601,608 ----
  
    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,
--- 632,639 ----
    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 ****
--- 1429,1435 ----
      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: trunk/gcc/common/common-target.h
===================================================================
*** trunk.orig/gcc/common/common-target.h	2011-06-15 13:26:57.000000000 +0200
--- trunk/gcc/common/common-target.h	2012-08-10 13:35:25.962921178 +0200
*************** enum opt_levels
*** 33,42 ****
    OPT_LEVELS_ALL, /* All levels (used by targets to disable options
  		     enabled in target-independent code).  */
    OPT_LEVELS_0_ONLY, /* -O0 only.  */
!   OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os.  */
!   OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os.  */
    OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os.  */
!   OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os.  */
    OPT_LEVELS_3_PLUS, /* -O3 and above.  */
    OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os.  */
    OPT_LEVELS_SIZE, /* -Os only.  */
--- 33,43 ----
    OPT_LEVELS_ALL, /* All levels (used by targets to disable options
  		     enabled in target-independent code).  */
    OPT_LEVELS_0_ONLY, /* -O0 only.  */
!   OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os and -Og.  */
!   OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os or -Og.  */
!   OPT_LEVELS_1_PLUS_NOT_DEBUG, /* -O1 and above, but not -Og.  */
    OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os.  */
!   OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os or -Og.  */
    OPT_LEVELS_3_PLUS, /* -O3 and above.  */
    OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os.  */
    OPT_LEVELS_SIZE, /* -Os only.  */


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