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]

Re: [PATCH] Statistics infrastructure, updated


On Tue, May 13, 2008 at 5:17 PM, Seongbae Park (박성배, 朴成培)
<seongbae.park@gmail.com> wrote:
>
> On Tue, May 13, 2008 at 2:32 AM, Richard Guenther <rguenther@suse.de> wrote:
>  > On Mon, 12 May 2008, Seongbae Park (???, ???) wrote:
>  >
>  >  > I think it would be more useful if we convert
>  >  > prop_stats::{num_const_prop, num_copy_prop, num_dce,num_pre_folded}
>  >  > and pre_stats::{constified, pa_insert, eliminations}  into debug counters
>  >  > (pre_stats::insertions and phis seem to be purely statistics
>  >  > still overhead of using debug counter is low enough that it probably
>  >  > won't matter
>  >  > to simply use it for statistics)
>  >  > - that way,  we can have both statistics and debugging aid.
>  >  > Making debug counter dump per-pass-invocation statistics is straightforward,
>  >  > and I can easily make it dump per-function statistics as well.
>  >
>  >  If you cannot convert things like pre_stats::insertions (that would
>  >  require the ability to dynamically register new counters) then I don't
>  >  see how this would simplify the patch - it would only add to it.
>  >
>  >  The patch tries to handle per-function statistics (what -fdump-*-*-stats
>  >  does), per pass statistics per function (-fdump-statistics) and per
>  >  compilation-unit statistics (-fdump-statistics-stats).  Adding a helper
>  >  to be able to break in gdb with a condition like curr_stat ("foo") == 5
>  >  would be easy.  I have never used (nor did I know of) the debug counter
>  >  stuff, so I have no opinion on its usefulness.
>  >
>  >  So, show us/me the patch you are proposing ;)
>  >
>  >  Richard.
>
>  Attached is the (half-cooked) patch - it will currently only print
>  per-function-per-pass
>  but the rest is the matter of figuring out when to take the base
>  snapshot to compare against.
>  I've converted pre_stats to the proposed scheme as an example.
>
>  Seongbae
>

Ha. Here's the patch. Really this time :)
I was going to do this anyway at some point for the debug counter's sake
It's useful to know which function/pass invocation triggers n-th transformation.
BTW, debug counter is not so much for use inside debugger (although it
works fine there),
but as a triage/diagnosis tool to find the bad transformation/code,
and certainly it can be used as a statistics gathering.

Seongbae
diff -r 94c7988e73c0 gcc/dbgcnt.c
--- a/gcc/dbgcnt.c	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/dbgcnt.c	Tue May 13 17:11:53 2008 -0700
@@ -26,6 +26,7 @@ See dbgcnt.def for usage information.  *
 #include "tm.h"
 #include "rtl.h"
 #include "output.h"
+#include "vec.h"
 
 #include "dbgcnt.h"
 
@@ -147,6 +148,72 @@ dbg_cnt_list_all_counters (void)
   printf ("----------------------------------------------\n");
   for (i = 0; i < debug_counter_number_of_counters; i++)
     printf ("  %-30s %5d %5u\n",
-            map[i].name, limit[map[i].counter], count[map[i].counter]);
+    map[i].name, limit[map[i].counter], count[map[i].counter]);
   printf ("\n");
 }
+
+
+/* Dump counters that differ from the original counter.
+   BASE_COUNT should be either NULL
+   or have debug_counter_number_of_counters number of elements. */
+
+void 
+dbg_cnt_dump (FILE *file, unsigned int *base_count)
+{
+  int i;
+  int printed = 0;
+  fprintf (file, "  %-30s %-5s ( %-5s - %-5s)\n",
+	   "counter name",  "increment", "start", "end");
+  fprintf (file, "----------------------------------------------\n");
+  for (i = 0; i < debug_counter_number_of_counters; i++)
+    {
+      int ci = map[i].counter;
+      int diff = count[ci] - base_count[ci];
+      if (diff)
+	{
+          fprintf (file, "  %-30s %5u ( %5u - %5u )\n",
+                   map[i].name, diff, base_count[ci], count[ci]);
+	  printed = 1;
+	}
+    }
+  if (printed == 0)
+    fprintf (file, "no counter change found\n");
+  fprintf (file, "\n");
+}
+
+typedef unsigned int *counters_t;
+DEF_VEC_P (counters_t);
+DEF_VEC_ALLOC_P (counters_t, heap);
+static VEC (counters_t, heap) *counters_stack;
+static unsigned counters_n_elts = 0;
+
+void dbg_cnt_init (void)
+{
+  /* No need for more than 3 nest deep -
+     per-function, per-pass, per-subpass. */
+  counters_stack = VEC_alloc (counters_t, heap, 3);
+}
+
+/* Copy the current*/
+
+void dbg_cnt_push_counters (void)
+{
+  unsigned int *c;
+  if (VEC_length (counters_t, counters_stack) <= counters_n_elts)
+    {
+      /* Need a new counters array. */
+      c = XCNEWVEC (unsigned int, debug_counter_number_of_counters);
+      VEC_safe_push (counters_t, heap, counters_stack, c);
+    }
+  else 
+    c = VEC_index (counters_t, counters_stack, counters_n_elts);
+  memcpy (c, count, sizeof (unsigned int) * debug_counter_number_of_counters);
+  counters_n_elts++;
+}
+
+
+unsigned int *dbg_cnt_pop_counters (void)
+{
+  unsigned int *c = VEC_index (counters_t, counters_stack, --counters_n_elts);
+  return c;
+}
diff -r 94c7988e73c0 gcc/dbgcnt.def
--- a/gcc/dbgcnt.def	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/dbgcnt.def	Tue May 13 17:11:53 2008 -0700
@@ -174,4 +174,9 @@ DEBUG_COUNTER (sms_sched_loop)
 DEBUG_COUNTER (sms_sched_loop)
 DEBUG_COUNTER (split_for_sched2)
 DEBUG_COUNTER (tail_call)
+DEBUG_COUNTER (pre_insertions)
+DEBUG_COUNTER (pre_eliminations)
+DEBUG_COUNTER (pre_pa_insert)
+DEBUG_COUNTER (pre_phis)
+DEBUG_COUNTER (pre_constified)
 
diff -r 94c7988e73c0 gcc/dbgcnt.h
--- a/gcc/dbgcnt.h	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/dbgcnt.h	Tue May 13 17:11:53 2008 -0700
@@ -35,5 +35,9 @@ extern bool dbg_cnt (enum debug_counter 
 extern bool dbg_cnt (enum debug_counter index);
 extern void dbg_cnt_process_opt (const char *arg);
 extern void dbg_cnt_list_all_counters (void);
+extern void dbg_cnt_dump (FILE *file, unsigned int *base_count);
+extern void dbg_cnt_push_counters (void);
+extern unsigned int *dbg_cnt_pop_counters (void);
+extern void dbg_cnt_init (void);
 
 #endif /* GCC_DBGCNT_H */
diff -r 94c7988e73c0 gcc/passes.c
--- a/gcc/passes.c	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/passes.c	Tue May 13 17:11:53 2008 -0700
@@ -1153,6 +1153,7 @@ execute_one_ipa_transform_pass (struct c
 {
   struct opt_pass *pass = &ipa_pass->pass;
   unsigned int todo_after = 0;
+  unsigned int *base_counters = NULL;
 
   current_pass = pass;
   if (!ipa_pass->function_transform)
@@ -1249,8 +1250,14 @@ execute_one_pass (struct opt_pass *pass)
   /* Do it!  */
   if (pass->execute)
     {
+      if (dump_file && (dump_flags & TDF_STATS))
+	dbg_cnt_push_counters ();
+
       todo_after = pass->execute ();
       do_per_function (clear_last_verified, NULL);
+
+      if (dump_file && (dump_flags & TDF_STATS))
+	dbg_cnt_dump (dump_file, dbg_cnt_pop_counters ());
     }
 
   /* Stop timevar.  */
diff -r 94c7988e73c0 gcc/toplev.c
--- a/gcc/toplev.c	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/toplev.c	Tue May 13 17:11:53 2008 -0700
@@ -82,6 +82,7 @@ along with GCC; see the file COPYING3.  
 #include "alloc-pool.h"
 #include "tree-mudflap.h"
 #include "tree-pass.h"
+#include "dbgcnt.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -954,6 +955,7 @@ compile_file (void)
   init_cgraph ();
   init_final (main_input_filename);
   coverage_init (aux_base_name);
+  dbg_cnt_init ();
 
   timevar_push (TV_PARSE);
 
diff -r 94c7988e73c0 gcc/tree-ssa-pre.c
--- a/gcc/tree-ssa-pre.c	Tue May 13 19:42:30 2008 +0000
+++ b/gcc/tree-ssa-pre.c	Tue May 13 17:11:53 2008 -0700
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  
 #include "cfgloop.h"
 #include "tree-ssa-sccvn.h"
 #include "params.h"
+#include "dbgcnt.h"
 
 /* TODO:
 
@@ -353,27 +354,6 @@ static bitmap_set_t maximal_set;
 
 /* Basic block list in postorder.  */
 static int *postorder;
-
-/* This structure is used to keep track of statistics on what
-   optimization PRE was able to perform.  */
-static struct
-{
-  /* The number of RHS computations eliminated by PRE.  */
-  int eliminations;
-
-  /* The number of new expressions/temporaries generated by PRE.  */
-  int insertions;
-
-  /* The number of inserts found due to partial anticipation  */
-  int pa_insert;
-
-  /* The number of new PHI nodes added by PRE.  */
-  int phis;
-
-  /* The number of values found constant.  */
-  int constified;
-
-} pre_stats;
 
 static bool do_partial_partial;
 static tree bitmap_find_leader (bitmap_set_t, tree, tree);
@@ -2478,7 +2458,7 @@ create_expression_by_pieces (basic_block
     bitmap_value_replace_in_set (NEW_SETS (block), name);
   bitmap_value_replace_in_set (AVAIL_OUT (block), name);
 
-  pre_stats.insertions++;
+  dbg_cnt (pre_insertions);
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Inserted ");
@@ -2619,7 +2599,7 @@ insert_into_preds_of_block (basic_block 
       print_generic_expr (dump_file, temp, 0);
       fprintf (dump_file, " in block %d\n", block->index);
     }
-  pre_stats.phis++;
+  dbg_cnt (pre_phis);
   return true;
 }
 
@@ -2754,11 +2734,8 @@ do_regular_insertion (basic_block block,
 	      FOR_EACH_EXPR_ID_IN_SET (exprset, j, bi)
 		{
 		  tree expr = expression_for_id (j);
-		  if (TREE_CODE (expr) == SSA_NAME)
-		    {
-		      vn_add (expr, eprime);
-		      pre_stats.constified++;
-		    }
+		  if (TREE_CODE (expr) == SSA_NAME && dbg_cnt (pre_constified))
+		    vn_add (expr, eprime);
 		}
 	    }
 	  free (avail);
@@ -2857,9 +2834,8 @@ do_partial_partial_insertion (basic_bloc
 	     already existing along every predecessor, and
 	     it's defined by some predecessor, it is
 	     partially redundant.  */
-	  if (!cant_insert && by_all)
-	    {
-	      pre_stats.pa_insert++;
+	  if (!cant_insert && by_all && dbg_cnt (pre_pa_insert))
+	    {
 	      if (insert_into_preds_of_block (block, get_expression_id (expr),
 					      avail))
 		new_stuff = true;
@@ -3650,7 +3626,8 @@ eliminate (void)
 	      if (sprime
 		  && sprime != lhs
 		  && (TREE_CODE (*rhs_p) != SSA_NAME
-		      || may_propagate_copy (*rhs_p, sprime)))
+		      || may_propagate_copy (*rhs_p, sprime))
+		  && dbg_cnt (pre_eliminations))
 		{
 		  gcc_assert (sprime != *rhs_p);
 
@@ -3674,7 +3651,6 @@ eliminate (void)
 						    TREE_TYPE (sprime)))
 		    sprime = fold_convert (TREE_TYPE (*rhs_p), sprime);
 
-		  pre_stats.eliminations++;
 		  propagate_tree_value (rhs_p, sprime);
 		  update_stmt (stmt);
 
@@ -3872,7 +3848,6 @@ init_pre (bool do_fre)
     loop_optimizer_init (LOOPS_NORMAL);
 
   connect_infinite_loops_to_exit ();
-  memset (&pre_stats, 0, sizeof (pre_stats));
 
 
   postorder = XNEWVEC (int, n_basic_blocks - NUM_FIXED_BLOCKS);
@@ -4019,14 +3994,6 @@ execute_pre (bool do_fre)
   /* Remove all the redundant expressions.  */
   todo |= eliminate ();
 
-  if (dump_file && (dump_flags & TDF_STATS))
-    {
-      fprintf (dump_file, "Insertions: %d\n", pre_stats.insertions);
-      fprintf (dump_file, "PA inserted: %d\n", pre_stats.pa_insert);
-      fprintf (dump_file, "New PHIs: %d\n", pre_stats.phis);
-      fprintf (dump_file, "Eliminated: %d\n", pre_stats.eliminations);
-      fprintf (dump_file, "Constified: %d\n", pre_stats.constified);
-    }
   bsi_commit_edge_inserts ();
 
   clear_expression_ids ();

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