public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][RFC] Statistics "infrastructure"
@ 2008-03-15 18:20 Richard Guenther
  2008-03-15 23:50 ` Zdenek Dvorak
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Guenther @ 2008-03-15 18:20 UTC (permalink / raw)
  To: gcc; +Cc: gcc-patches


This is an attempt to provide (pass) statistics collection.  The
goal is to provide infrastructure to handle the current (pass specific)
statistics dumping that is done per function and per pass along the
regular tree/rtl dumps as well as to allow CU wide "fancy" analysis.

The most important aspect I think is simplicity to use it and especially
add new "counters".  Thus, we simply associate a counter with a string ID.

The patch is a rough implementation of the current features of
pass specific statistics plus a global "log" with statistics events.
In the end you can do any postprocessing / globbing / summing of
such global log.

A statistics event consists of a function (optional), a statement
(optional) and the counter ID.  I converted the counters from
tree-ssa-propagate.c as an example, instead of

		prop_stats.num_copy_prop++;

you now write

		statistics_add ("copy propagations");

(function and statement omitted, you might prefer #defines for strings
that you use multiple times).  In the .ccp1 dump file you then get

Pass statistics:
----------------
constant propagations: 15
copy propagations: 5

in stead of previously

Constants propagated:      15
Copies propagated:         5
Predicates folded:         0

and the 208t.statistics file will for example contain

33      ccp     "constant propagations" "sin_pif"       "(nostmt)"
33      ccp     "constant propagations" "sin_pif"       "(nostmt)"
38      copyprop        "copy propagations"     "sin_pif"       "(nostmt)"
38      copyprop        "copy propagations"     "sin_pif"       "(nostmt)"
38      copyprop        "copy propagations"     "sin_pif"       "(nostmt)"
38      copyprop        "copy propagations"     "sin_pif"       "(nostmt)"
38      copyprop        "copy propagations"     "sin_pif"       "(nostmt)"
33      ccp     "constant propagations" "__ieee754_lgammaf_r"   "(nostmt)"
33      ccp     "constant propagations" "__ieee754_lgammaf_r"   "(nostmt)"
33      ccp     "constant propagations" "__ieee754_lgammaf_r"   "(nostmt)"
...

(pass number, pass name, ID, function name, statement location 
(unimplemented)).

The backend implementation is of course not limited to be that simple,
but it is the interface that I am curious if it provides enough
information.

(please trim CC, use gcc@ for general discussion, gcc-patches@ for
implementation details of this hac^H^H^Hpatch)

Thanks,
Richard.

2008-03-15  Richard Guenther  <rguenther@suse.de>

	* tree-pass.h (statistics_add_fn_stmt): Declare.
	(statistics_add_stmt): New macro.
	(statistics_add): Likewise.
	* passes.c (statistics_dump_nr, statistics_dump_file): New globals.
	(init_optimization_passes): Register statistics dump.
	(execute_function_todo): Flush per function statistics.
	(execute_pass_list): Start statistics dump.
	(execute_ipa_pass_list): Likewise.
	(struct statistics_counter_s): New structure.
	(statistics_fini_pass): New function.
	(statistics_add_fn_stmt): Likewise.

	* tree-ssa-propagate.c: Use statistics infrastructure.

Index: trunk/gcc/passes.c
===================================================================
*** trunk.orig/gcc/passes.c	2008-03-15 17:26:59.000000000 +0100
--- trunk/gcc/passes.c	2008-03-15 19:09:30.000000000 +0100
*************** along with GCC; see the file COPYING3.  
*** 102,107 ****
--- 102,111 ----
  				   declarations for e.g. AIX 4.x.  */
  #endif
  
+ static void statistics_fini_pass (void);
+ static int statistics_dump_nr;
+ static FILE *statistics_dump_file;
+ 
  /* This is used for debugging.  It allows the current pass to printed
     from anywhere in compilation.  */
  struct tree_opt_pass *current_pass;
*************** init_optimization_passes (void)
*** 797,802 ****
--- 801,808 ----
    register_dump_files (all_passes, false,
  		       PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
  		       | PROP_cfg);
+   statistics_dump_nr = dump_register (".statistics", "statistics",
+ 				      "statistics", TDF_TREE, 0);
  }
  
  /* If we are in IPA mode (i.e., current_function_decl is NULL), call
*************** execute_function_todo (void *data)
*** 883,889 ****
    flags &= ~cfun->last_verified;
    if (!flags)
      return;
!   
    /* Always cleanup the CFG before trying to update SSA.  */
    if (flags & TODO_cleanup_cfg)
      {
--- 889,897 ----
    flags &= ~cfun->last_verified;
    if (!flags)
      return;
! 
!   statistics_fini_pass ();
! 
    /* Always cleanup the CFG before trying to update SSA.  */
    if (flags & TODO_cleanup_cfg)
      {
*************** execute_one_pass (struct tree_opt_pass *
*** 1171,1176 ****
--- 1179,1186 ----
  void
  execute_pass_list (struct tree_opt_pass *pass)
  {
+   if (statistics_dump_file == NULL)
+     statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
    do
      {
        if (execute_one_pass (pass) && pass->sub)
*************** execute_pass_list (struct tree_opt_pass 
*** 1185,1190 ****
--- 1195,1202 ----
  void
  execute_ipa_pass_list (struct tree_opt_pass *pass)
  {
+   if (statistics_dump_file == NULL)
+     statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
    do
      {
        gcc_assert (!current_function_decl);
*************** execute_ipa_pass_list (struct tree_opt_p
*** 1198,1201 ****
--- 1210,1311 ----
      }
    while (pass);
  }
+ 
+ /* Statistics entry.  A integer counter associated to a string ID.  */
+ 
+ typedef struct statistics_counter_s {
+   const char *id;
+   int count;
+ } statistics_counter_t;
+ 
+ static htab_t statistics_hash;
+ 
+ /* Hash a statistic counter by its string ID.  */
+ 
+ static hashval_t
+ hash_statistics_hash (const void *p)
+ {
+   return htab_hash_string (((statistics_counter_t *)p)->id);
+ }
+ 
+ /* Compare two statistic counters by their string IDs.  */
+ 
+ static int
+ hash_statistics_eq (const void *p, const void *q)
+ {
+   return !strcmp (((statistics_counter_t *)p)->id,
+ 		  ((statistics_counter_t *)q)->id);
+ }
+ 
+ /* Helper for statistics_fini_pass.  */
+ 
+ static int
+ statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+ {
+   statistics_counter_t *counter = (statistics_counter_t *)*slot;
+   fprintf (dump_file, "%s: %d\n", counter->id, counter->count);
+   return 1;
+ }
+ 
+ /* Dump the current statistics state to the current pass dump file and
+    clear the statistics state.  */
+ 
+ static void
+ statistics_fini_pass (void)
+ {
+   if (!dump_file
+       || !(dump_flags & TDF_STATS)
+       || htab_elements (statistics_hash) == 0)
+     return;
+ 
+   fprintf (dump_file, "\n");
+   fprintf (dump_file, "Pass statistics:\n");
+   fprintf (dump_file, "----------------\n");
+   htab_traverse_noresize (statistics_hash, statistics_fini_pass_1, NULL);
+   fprintf (dump_file, "\n");
+ 
+   htab_empty (statistics_hash);
+ }
+ 
+ /* Add statistics information about event ID in function FN at statement
+    STMT.  This will increment a counter associated with ID.  It will also
+    dump the event to the global statistics file if requested.  */
+ 
+ void
+ statistics_add_fn_stmt (struct function *fn, tree stmt ATTRIBUTE_UNUSED,
+ 			const char *id)
+ {
+   static char statistics_print_buf[4096];
+ 
+   if (dump_flags & TDF_STATS)
+     {
+       statistics_counter_t **counter;
+       if (!statistics_hash)
+ 	statistics_hash = htab_create (15, hash_statistics_hash,
+ 				       hash_statistics_eq, free);
+       counter = (statistics_counter_t **)
+ 	htab_find_slot (statistics_hash, &id, INSERT);
+       if (!*counter)
+ 	{
+ 	  *counter = XNEW (struct statistics_counter_s);
+ 	  (*counter)->id = id;
+ 	  (*counter)->count = 0;
+ 	}
+       (*counter)->count++;
+     }
+ 
+   if (!statistics_dump_file)
+     return;
+ 
+   snprintf (statistics_print_buf, 4096,
+ 	    "%d\t%s\t\"%s\"\t\"%s\"\t\"%s\"\n",
+ 	    current_pass->static_pass_number,
+ 	    current_pass->name,
+ 	    id,
+ 	    fn ? IDENTIFIER_POINTER (DECL_NAME (fn->decl)) : "(nofn)",
+ 	    "(nostmt)" /* FIXME */);
+ 
+   fputs (statistics_print_buf, statistics_dump_file);
+   fflush (statistics_dump_file);
+ }
  #include "gt-passes.h"
Index: trunk/gcc/tree-pass.h
===================================================================
*** trunk.orig/gcc/tree-pass.h	2008-03-15 17:22:27.000000000 +0100
--- trunk/gcc/tree-pass.h	2008-03-15 18:07:00.000000000 +0100
*************** extern void debug_pass (void);
*** 468,471 ****
--- 468,477 ----
     directly in jump threading, and avoid peeling them next time.  */
  extern bool first_pass_instance;
  
+ extern void statistics_add_fn_stmt (struct function *, tree, const char *);
+ #define statistics_add_stmt(stmt, id) \
+   do { statistics_add_fn_stmt (cfun, (stmt), (id)); } while (0)
+ #define statistics_add(id) \
+   do { statistics_add_fn_stmt (cfun, NULL_TREE, (id)); } while (0)
+ 
  #endif /* GCC_TREE_PASS_H */
Index: trunk/gcc/tree-ssa-propagate.c
===================================================================
*** trunk.orig/gcc/tree-ssa-propagate.c	2008-03-15 18:03:22.000000000 +0100
--- trunk/gcc/tree-ssa-propagate.c	2008-03-15 18:08:18.000000000 +0100
*************** replace_uses_in (tree stmt, bool *replac
*** 923,931 ****
  	continue;
  
        if (TREE_CODE (val) != SSA_NAME)
! 	prop_stats.num_const_prop++;
        else
! 	prop_stats.num_copy_prop++;
  
        propagate_value (use, val);
  
--- 923,931 ----
  	continue;
  
        if (TREE_CODE (val) != SSA_NAME)
! 	statistics_add ("constant propagations");
        else
! 	statistics_add ("copy propagations");
  
        propagate_value (use, val);
  
*************** replace_vuses_in (tree stmt, bool *repla
*** 1038,1046 ****
  	  GIMPLE_STMT_OPERAND (stmt, 1) = val->value;
  
  	  if (TREE_CODE (val->value) != SSA_NAME)
! 	    prop_stats.num_const_prop++;
  	  else
! 	    prop_stats.num_copy_prop++;
  
  	  /* Since we have replaced the whole RHS of STMT, there
  	     is no point in checking the other VUSEs, as they will
--- 1038,1046 ----
  	  GIMPLE_STMT_OPERAND (stmt, 1) = val->value;
  
  	  if (TREE_CODE (val->value) != SSA_NAME)
! 	    statistics_add ("constant propagations");
  	  else
! 	    statistics_add ("copy propagations");
  
  	  /* Since we have replaced the whole RHS of STMT, there
  	     is no point in checking the other VUSEs, as they will
*************** replace_vuses_in (tree stmt, bool *repla
*** 1066,1072 ****
  	continue;
  
        propagate_value (vuse, val);
!       prop_stats.num_copy_prop++;
        replaced = true;
      }
  
--- 1066,1072 ----
  	continue;
  
        propagate_value (vuse, val);
!       statistics_add ("copy propagations");
        replaced = true;
      }
  
*************** replace_phi_args_in (tree phi, prop_valu
*** 1098,1106 ****
  	  if (val && val != arg && may_propagate_copy (arg, val))
  	    {
  	      if (TREE_CODE (val) != SSA_NAME)
! 		prop_stats.num_const_prop++;
  	      else
! 		prop_stats.num_copy_prop++;
  
  	      propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
  	      replaced = true;
--- 1098,1106 ----
  	  if (val && val != arg && may_propagate_copy (arg, val))
  	    {
  	      if (TREE_CODE (val) != SSA_NAME)
! 		statistics_add ("constant propagations");
  	      else
! 		statistics_add ("copy propagations");
  
  	      propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
  	      replaced = true;
*************** fold_predicate_in (tree stmt)
*** 1163,1169 ****
  	  fprintf (dump_file, "\n");
  	}
  
!       prop_stats.num_pred_folded++;
        *pred_p = val;
        return true;
      }
--- 1163,1169 ----
  	  fprintf (dump_file, "\n");
  	}
  
!       statistics_add ("predicates folded");
        *pred_p = val;
        return true;
      }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][RFC] Statistics "infrastructure"
  2008-03-15 18:20 [PATCH][RFC] Statistics "infrastructure" Richard Guenther
@ 2008-03-15 23:50 ` Zdenek Dvorak
  2008-03-16  0:59   ` Richard Guenther
  0 siblings, 1 reply; 5+ messages in thread
From: Zdenek Dvorak @ 2008-03-15 23:50 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc, gcc-patches

Hi,

> This is an attempt to provide (pass) statistics collection.  The
> goal is to provide infrastructure to handle the current (pass specific)
> statistics dumping that is done per function and per pass along the
> regular tree/rtl dumps as well as to allow CU wide "fancy" analysis.
> 
> The most important aspect I think is simplicity to use it and especially
> add new "counters".  Thus, we simply associate a counter with a string ID.
> 
> The patch is a rough implementation of the current features of
> pass specific statistics plus a global "log" with statistics events.
> In the end you can do any postprocessing / globbing / summing of
> such global log.
> 
> A statistics event consists of a function (optional), a statement
> (optional) and the counter ID.  I converted the counters from
> tree-ssa-propagate.c as an example, instead of
> 
> 		prop_stats.num_copy_prop++;
> 
> you now write
> 
> 		statistics_add ("copy propagations");
> 
> (function and statement omitted, you might prefer #defines for strings
> that you use multiple times).

it would perhaps be better to use #defines with integer values?  Also,
it would be more consistent to have statistics.def similar to
timevar.def for this.  It would make creation of new counters a bit
more difficult, but on the other hand, it would make it possible to
classify the counters (by type of the counted operation/its
expensiveness/...),

Zdenek

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][RFC] Statistics "infrastructure"
  2008-03-15 23:50 ` Zdenek Dvorak
@ 2008-03-16  0:59   ` Richard Guenther
  2008-03-16  3:41     ` Zdenek Dvorak
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Guenther @ 2008-03-16  0:59 UTC (permalink / raw)
  To: Zdenek Dvorak; +Cc: gcc, gcc-patches

On Sun, 16 Mar 2008, Zdenek Dvorak wrote:

> Hi,
> 
> > This is an attempt to provide (pass) statistics collection.  The
> > goal is to provide infrastructure to handle the current (pass specific)
> > statistics dumping that is done per function and per pass along the
> > regular tree/rtl dumps as well as to allow CU wide "fancy" analysis.
> > 
> > The most important aspect I think is simplicity to use it and especially
> > add new "counters".  Thus, we simply associate a counter with a string ID.
> > 
> > The patch is a rough implementation of the current features of
> > pass specific statistics plus a global "log" with statistics events.
> > In the end you can do any postprocessing / globbing / summing of
> > such global log.
> > 
> > A statistics event consists of a function (optional), a statement
> > (optional) and the counter ID.  I converted the counters from
> > tree-ssa-propagate.c as an example, instead of
> > 
> > 		prop_stats.num_copy_prop++;
> > 
> > you now write
> > 
> > 		statistics_add ("copy propagations");
> > 
> > (function and statement omitted, you might prefer #defines for strings
> > that you use multiple times).
> 
> it would perhaps be better to use #defines with integer values?  Also,
> it would be more consistent to have statistics.def similar to
> timevar.def for this.  It would make creation of new counters a bit
> more difficult, but on the other hand, it would make it possible to
> classify the counters (by type of the counted operation/its
> expensiveness/...),

The difficultness to add new counters is exactly why I didn't go
down that route.  I expect this mainly used for experimentation
where it is IMHO inconvenient to go the .def route (also like
with timevar.def we probably just get false re-use of IDs).
We might auto-generate (part of) the ID from the instrumentation
point (FILE/LINE) as well... (thus get "copy prop at xyz.c:25")

The point is to have easy instrumentation this way and automatic
analysis, not some stable interface (IMHO).  For this reason
classifying the counters is engineering at the wrong point - you'd
do that at the analysis point and not hard-code this somewhere
(after all, just name it "lim expensive" ;)).

Richard.

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][RFC] Statistics "infrastructure"
  2008-03-16  0:59   ` Richard Guenther
@ 2008-03-16  3:41     ` Zdenek Dvorak
  2008-03-16  9:33       ` Richard Guenther
  0 siblings, 1 reply; 5+ messages in thread
From: Zdenek Dvorak @ 2008-03-16  3:41 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc, gcc-patches

Hi,

> > > A statistics event consists of a function (optional), a statement
> > > (optional) and the counter ID.  I converted the counters from
> > > tree-ssa-propagate.c as an example, instead of
> > > 
> > > 		prop_stats.num_copy_prop++;
> > > 
> > > you now write
> > > 
> > > 		statistics_add ("copy propagations");
> > > 
> > > (function and statement omitted, you might prefer #defines for strings
> > > that you use multiple times).
> > 
> > it would perhaps be better to use #defines with integer values?  Also,
> > it would be more consistent to have statistics.def similar to
> > timevar.def for this.  It would make creation of new counters a bit
> > more difficult, but on the other hand, it would make it possible to
> > classify the counters (by type of the counted operation/its
> > expensiveness/...),
> 
> The difficultness to add new counters is exactly why I didn't go
> down that route.  I expect this mainly used for experimentation
> where it is IMHO inconvenient to go the .def route

I thought of it more as an aid in debugging performance problems, as in,
checking the dumps without introducing new statistics counters; in which
case, having some description of what the counters mean and the metadata
from the .def file would be useful.

On the other hand, I agree that for the purpose that you suggest
avoiding .def is better.  Perhaps we could require that all the
statistics strings are #defined and documented (and of course you can
ignore this rule for the counters that you use for experimentation)?

Zdenek

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH][RFC] Statistics "infrastructure"
  2008-03-16  3:41     ` Zdenek Dvorak
@ 2008-03-16  9:33       ` Richard Guenther
  0 siblings, 0 replies; 5+ messages in thread
From: Richard Guenther @ 2008-03-16  9:33 UTC (permalink / raw)
  To: Zdenek Dvorak; +Cc: gcc, gcc-patches

On Sun, 16 Mar 2008, Zdenek Dvorak wrote:

> Hi,
> 
> > > > A statistics event consists of a function (optional), a statement
> > > > (optional) and the counter ID.  I converted the counters from
> > > > tree-ssa-propagate.c as an example, instead of
> > > > 
> > > > 		prop_stats.num_copy_prop++;
> > > > 
> > > > you now write
> > > > 
> > > > 		statistics_add ("copy propagations");
> > > > 
> > > > (function and statement omitted, you might prefer #defines for strings
> > > > that you use multiple times).
> > > 
> > > it would perhaps be better to use #defines with integer values?  Also,
> > > it would be more consistent to have statistics.def similar to
> > > timevar.def for this.  It would make creation of new counters a bit
> > > more difficult, but on the other hand, it would make it possible to
> > > classify the counters (by type of the counted operation/its
> > > expensiveness/...),
> > 
> > The difficultness to add new counters is exactly why I didn't go
> > down that route.  I expect this mainly used for experimentation
> > where it is IMHO inconvenient to go the .def route
> 
> I thought of it more as an aid in debugging performance problems, as in,
> checking the dumps without introducing new statistics counters; in which
> case, having some description of what the counters mean and the metadata
> from the .def file would be useful.
> 
> On the other hand, I agree that for the purpose that you suggest
> avoiding .def is better.  Perhaps we could require that all the
> statistics strings are #defined and documented (and of course you can
> ignore this rule for the counters that you use for experimentation)?

Sure, we can even do a .def file for this purpose.

Richard.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-03-16  8:58 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-15 18:20 [PATCH][RFC] Statistics "infrastructure" Richard Guenther
2008-03-15 23:50 ` Zdenek Dvorak
2008-03-16  0:59   ` Richard Guenther
2008-03-16  3:41     ` Zdenek Dvorak
2008-03-16  9:33       ` Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).