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]

Collect statistic about how much passes affect function body sizes


Hi,
this patch adds flag -ffunction-size-report that collects changes of
code size caused by individual tree passes (before and after cleanup
TODO is done).  This is report for combine.c:

pass name :   before->   after-> cleanuped  overall
ccp       :    37085->   37079->   37079 (-0.02)
fre       :    37079->   36815->   36815 (-0.71)
forwprop  :    36815->   36794->   36794 (-0.06)
vrp       :    36597->   36490->   36480 (-0.92)
dce       :    36480->   36417->   36417 (-0.17)
dom       :    36417->   36424->   36424 (0.02)
phiopt    :    36424->   36422->   36421 (-0.01)
alias     :    36421->   36420->   36420 (-0.00)
tailr     :    36420->   35987->   35987 (-1.19)
ch        :    35987->   36197->   36197 (0.58)
dom       :    36197->   36271->   36271 (0.20)
copyprop  :    36271->   36271->   36270 (-0.00)
dce       :    36270->   36264->   36264 (-0.02)
forwprop  :    36264->   36257->   36257 (-0.02)
store_ccp :    36257->   36255->   36255 (-0.01)
pre       :    36255->   36299->   36299 (0.12)
ivcanon   :    36299->   36303->   36303 (0.01)
ivopts    :    36303->   36343->   36343 (0.11)
dom       :    36343->   36353->   36353 (0.03)
copyprop  :    36353->   36353->   36352 (-0.00)
cddce     :    36352->   36343->   36343 (-0.02)
forwprop  :    36343->   36340->   36340 (-0.01)
phiopt    :    36340->   36333->   36333 (-0.02)

I orignally made the patch just to experiment with how inline heuristic
interact with optimizations (and what optimizations should be done
before inlining), but it seems to be somewhat useful otherwise too (for
example to notice that ccp does surprisingly little transformations and
lot of stuff that can be considered to be ccp job is caught only by vrp
later on).

Bootstrapped/regtested i686-pc-gnu.
Honza

2005-09-27  Jan Hubicka  <jh@suse.cz>
	* common.opt (ffunction-size-report): Document.

	* Makefile.in (toplev.o): Add dependency on tree-pass.h
	* passes.c (max_pass_number, function_size_stats): New static variables.
	(register_dump_file): Set max_pass_number.
	(init_optimization_passes): Initialize function_size_stats.
	(execute_one_pass): Collect statistic.
	(dump_function_size_stats): New function.
	* toplev.c: Include tree-pass.h
	(finalize): Call dump_function_size_stats.
	* tree-pass.h (dump_function_size_stats): Declare.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.1541
diff -c -3 -p -r1.1541 Makefile.in
*** Makefile.in	14 Sep 2005 09:26:41 -0000	1.1541
--- Makefile.in	26 Sep 2005 12:38:31 -0000
*************** toplev.o : toplev.c $(CONFIG_H) $(SYSTEM
*** 2017,2023 ****
     value-prof.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
     langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) hosthooks.h \
     $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \
!    $(CPPLIB_H) opts.h params.def tree-mudflap.h
  	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
  	  -DTARGET_NAME=\"$(target_noncanonical)\" \
  	  -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
--- 2017,2023 ----
     value-prof.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
     langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) hosthooks.h \
     $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \
!    $(CPPLIB_H) opts.h params.def tree-mudflap.h tree-pass.h
  	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
  	  -DTARGET_NAME=\"$(target_noncanonical)\" \
  	  -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
Index: common.opt
===================================================================
RCS file: /cvs/gcc/gcc/gcc/common.opt,v
retrieving revision 1.89
diff -c -3 -p -r1.89 common.opt
*** common.opt	6 Sep 2005 10:58:48 -0000	1.89
--- common.opt	26 Sep 2005 12:38:31 -0000
*************** ffunction-sections
*** 421,426 ****
--- 421,430 ----
  Common Report Var(flag_function_sections)
  Place each function into its own section
  
+ ffunction-size-report
+ Common Report Var(flag_function_size_report)
+ Report function sizes changes after each tree pass.
+ 
  fgcse
  Common Report Var(flag_gcse)
  Perform global common subexpression elimination
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.114
diff -c -3 -p -r2.114 passes.c
*** passes.c	18 Sep 2005 00:03:25 -0000	2.114
--- passes.c	26 Sep 2005 12:38:31 -0000
*************** Software Foundation, 51 Franklin Street,
*** 100,105 ****
--- 100,113 ----
  				   declarations for e.g. AIX 4.x.  */
  #endif
  
+ /* Used for -ffunction-size-report.  */
+ static int max_pass_number;
+ static struct function_size_stat
+ {
+   int before, after, cleaned;
+   struct tree_opt_pass *pass;
+ } *function_size_stats;
+ 
  /* Global variables used to communicate with passes.  */
  int dump_flags;
  bool in_gimple_form;
*************** register_one_dump_file (struct tree_opt_
*** 330,335 ****
--- 338,344 ----
        glob_name = concat ("tree-", pass->name, NULL);
        pass->static_pass_number = dump_register (dot_name, flag_name, glob_name,
                                                  TDF_TREE, n + TDI_tree_all, 0);
+       max_pass_number = pass->static_pass_number;
      }
    else
      {
*************** init_optimization_passes (void)
*** 663,668 ****
--- 672,678 ----
    register_dump_files (all_ipa_passes, true, PROP_gimple_leh | PROP_cfg);
    register_dump_files (all_lowering_passes, false, PROP_gimple_any);
    register_dump_files (all_passes, false, PROP_gimple_leh | PROP_cfg);
+   function_size_stats = xcalloc (sizeof (*function_size_stats), max_pass_number + 1);
  }
  
  static unsigned int last_verified;
*************** static bool
*** 754,764 ****
--- 764,781 ----
  execute_one_pass (struct tree_opt_pass *pass)
  {
    unsigned int todo; 
+   int before_size = 0, after_size = 0, cleanuped_size = 0;
  
    /* See if we're supposed to run this pass.  */
    if (pass->gate && !pass->gate ())
      return false;
  
+   if (flag_function_size_report && cfun && cfun->cfg
+       && !(pass->properties_required & PROP_rtl)
+       && (pass->todo_flags_finish & TODO_dump_func)
+       && !(pass->properties_destroyed & PROP_gimple_leh))
+     before_size = estimate_num_insns (current_function_decl);
+ 
    /* Note that the folders should only create gimple expressions.
       This is a hack until the new folder is ready.  */
    in_gimple_form = (pass->properties_provided & PROP_trees) != 0;
*************** execute_one_pass (struct tree_opt_pass *
*** 808,813 ****
--- 825,836 ----
    if (pass->execute)
      pass->execute ();
  
+   if (flag_function_size_report && cfun && cfun->cfg
+       && !(pass->properties_required & PROP_rtl)
+       && (pass->todo_flags_finish & TODO_dump_func)
+       && !(pass->properties_destroyed & PROP_gimple_leh))
+     after_size = estimate_num_insns (current_function_decl);
+ 
    /* Stop timevar.  */
    if (pass->tv_id)
      timevar_pop (pass->tv_id);
*************** execute_one_pass (struct tree_opt_pass *
*** 818,823 ****
--- 841,862 ----
    if (todo)
      execute_todo (pass, todo, false);
  
+   if (flag_function_size_report && cfun && cfun->cfg
+       && !(pass->properties_required & PROP_rtl)
+       && (pass->todo_flags_finish & TODO_dump_func)
+       && !(pass->properties_destroyed & PROP_gimple_leh))
+     {
+       cleanuped_size = estimate_num_insns (current_function_decl);
+       function_size_stats[pass->static_pass_number].before += before_size;
+       function_size_stats[pass->static_pass_number].after += after_size;
+       function_size_stats[pass->static_pass_number].cleaned += cleanuped_size;
+       if (! function_size_stats[pass->static_pass_number].pass)
+         function_size_stats[pass->static_pass_number].pass = pass;
+       else
+         gcc_assert (function_size_stats[pass->static_pass_number].pass == pass);
+     }
+ 
+ 
    /* Flush and close dump file.  */
    if (dump_file_name)
      {
*************** execute_ipa_pass_list (struct tree_opt_p
*** 872,874 ****
--- 911,935 ----
      }
    while (pass);
  }
+ 
+ void
+ dump_function_size_stats (void)
+ {
+   int i;
+   if (flag_function_size_report)
+     {
+       fprintf (stderr, "\npass name :   before->   after-> cleanuped  overall\n");
+       for (i = 0; i <= max_pass_number; i++)
+ 	if (function_size_stats[i].before != function_size_stats[i].after
+ 	    || function_size_stats[i].before !=
+ 	    function_size_stats[i].cleaned)
+ 	  fprintf (stderr, "%-10s: %8i->%8i->%8i (%2.2f)\n",
+ 		   function_size_stats[i].pass->name,
+ 		   function_size_stats[i].before,
+ 		   function_size_stats[i].after,
+ 		   function_size_stats[i].cleaned,
+ 		   (function_size_stats[i].cleaned -
+ 		    function_size_stats[i].before) * 100.0 /
+ 		   function_size_stats[i].before);
+     }
+ }
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.975
diff -c -3 -p -r1.975 toplev.c
*** toplev.c	9 Sep 2005 00:46:45 -0000	1.975
--- toplev.c	26 Sep 2005 12:38:32 -0000
*************** Software Foundation, 51 Franklin Street,
*** 81,86 ****
--- 81,87 ----
  #include "value-prof.h"
  #include "alloc-pool.h"
  #include "tree-mudflap.h"
+ #include "tree-pass.h"
  
  #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
  #include "dwarf2out.h"
*************** finalize (void)
*** 1897,1902 ****
--- 1898,1905 ----
        dump_ggc_loc_statistics ();
      }
  
+   dump_function_size_stats ();
+ 
    /* Free up memory for the benefit of leak detectors.  */
    free_reg_info ();
  
Index: tree-pass.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pass.h,v
retrieving revision 2.57
diff -c -3 -p -r2.57 tree-pass.h
*** tree-pass.h	18 Sep 2005 00:03:25 -0000	2.57
--- tree-pass.h	26 Sep 2005 12:38:32 -0000
*************** extern struct tree_opt_pass *all_passes,
*** 379,383 ****
--- 379,384 ----
  
  extern void execute_pass_list (struct tree_opt_pass *);
  extern void execute_ipa_pass_list (struct tree_opt_pass *);
+ extern void dump_function_size_stats (void);
  
  #endif /* GCC_TREE_PASS_H */
Index: doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.671
diff -c -3 -p -r1.671 invoke.texi
*** doc/invoke.texi	19 Aug 2005 18:00:25 -0000	1.671
--- doc/invoke.texi	26 Sep 2005 12:38:33 -0000
*************** Objective-C and Objective-C++ Dialects}.
*** 285,290 ****
--- 285,291 ----
  -feliminate-unused-debug-symbols -fmem-report -fprofile-arcs @gol
  -frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
  -ftest-coverage  -ftime-report -fvar-tracking @gol
+ -ffunction-size-report @gol
  -g  -g@var{level}  -gcoff -gdwarf-2 @gol
  -ggdb  -gstabs  -gstabs+  -gvms  -gxcoff  -gxcoff+ @gol
  -p  -pg  -print-file-name=@var{library}  -print-libgcc-file-name @gol
*************** pass when it finishes.
*** 3530,3535 ****
--- 3531,3539 ----
  Makes the compiler print some statistics about permanent memory
  allocation when it finishes.
  
+ @item -ffunction-size-report
+ Makes the compiler print how code size estimates change by individual SSA passes.
+ 
  @item -fprofile-arcs
  @opindex fprofile-arcs
  Add code so that program flow @dfn{arcs} are instrumented.  During


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