This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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 ();