* [committed] Add --devel-stats
@ 2020-01-01 0:00 Tom de Vries
0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2020-01-01 0:00 UTC (permalink / raw)
To: dwz, jakub
Hi,
Add a developer option --devel-stats that prints parsing, duplicate and
partitioning statistics.
F.i., for cc1:
...
$ dwz cc1 -lnone --devel-stats
Parse statistics for cc1
root_count : 695
namespace_count : 5033
upper_toplevel : 5728
lower_toplevel : 1170391
toplevel : 1176119
non_toplevel : 9012822
die_count : 10188941
Duplicate statistics for cc1
lower_toplevel with checksum : 1124430
dup_cnt : 1037350
dup_chain_cnt : 23512
average dup_chain length : 44.12
max dup_chain length : 598
Partition statistics for cc1
part_cnt : 7536
pu_ph1_cnt : 4522
pu_ph2_cnt : 351
pu_cnt : 4873
pu_toplevel_die_cnt : 20166
...
Committed to trunk.
Thanks,
- Tom
Add --devel-stats
2020-01-09 Tom de Vries <tdevries@suse.de>
* dwz.c (stats_p): New variable.
(struct stats): New struct.
(stats): New variable.
(init_stats, print_parse_stats, print_dups_stats, print_part_stats):
New function.
(find_dups, read_debug_info, partition_found_dups, partition_dups_1):
Update stats.
(partition_dups): Call print_dups_stats after partition_find_dups.
Call print_part_stats.
(read_dwarf): Call print_parse_stats after read_debug_info.
(dwz_options, usage): Add --devel-stats entry.
(main): Call init_stats. Free stats.
---
dwz.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 160 insertions(+), 3 deletions(-)
diff --git a/dwz.c b/dwz.c
index b4b8339..959033b 100644
--- a/dwz.c
+++ b/dwz.c
@@ -192,6 +192,7 @@ static int dump_dies_p;
static int dump_dups_p;
static int verify_dups_p;
static int verify_edge_freelist;
+static int stats_p;
#else
#define tracing 0
#define ignore_size 0
@@ -199,6 +200,7 @@ static int verify_edge_freelist;
#define dump_dies_p 0
#define dump_dups_p 0
#define verify_dups_p 0
+#define stats_p 0
#endif
static int unoptimized_multifile;
static int save_temps = 0;
@@ -220,6 +222,105 @@ int odr_parsed = 0;
int no_odr_parsed = 0;
int odr_mode_parsed = 0;
+/* Struct to gather statistics. */
+struct stats
+{
+ const char *file;
+ unsigned int root_cnt;
+ unsigned int namespace_cnt;
+ unsigned int lower_toplevel;
+ unsigned int die_count;
+ unsigned int lower_toplevel_with_checksum;
+ unsigned int dup_cnt;
+ unsigned int dup_chain_cnt;
+ unsigned int dup_chain_max_length;
+ unsigned int part_cnt;
+ unsigned int pu_ph1_cnt;
+ unsigned int pu_ph2_cnt;
+ unsigned int pu_toplevel_die_cnt;
+};
+struct stats *stats;
+
+/* Initialize stats struct. */
+static void
+init_stats (const char *file)
+{
+ if (stats == NULL)
+ stats = (struct stats *)malloc (sizeof (*stats));
+ memset (stats, 0, sizeof (*stats));
+ stats->file = file;
+}
+
+/* Print stats struct, parsing statistics. */
+static void
+print_parse_stats (void)
+{
+ if (stats == NULL || stats->file == NULL)
+ return;
+
+ fprintf (stderr, "Parse statistics for %s\n", stats->file);
+
+ fprintf (stderr, "root_count : %10u\n",
+ stats->root_cnt);
+ fprintf (stderr, "namespace_count : %10u\n",
+ stats->namespace_cnt);
+ unsigned int upper_toplevel = stats->root_cnt + stats->namespace_cnt;
+ fprintf (stderr, "upper_toplevel : %10u\n",
+ upper_toplevel);
+ unsigned lower_toplevel
+ = stats->lower_toplevel + stats->lower_toplevel_with_checksum;
+ fprintf (stderr, "lower_toplevel : %10u\n",
+ lower_toplevel);
+ unsigned int toplevel = upper_toplevel + lower_toplevel;
+ fprintf (stderr, "toplevel : %10u\n",
+ toplevel);
+ unsigned non_toplevel = stats->die_count - toplevel;
+ fprintf (stderr, "non_toplevel : %10u\n",
+ non_toplevel);
+ fprintf (stderr, "die_count : %10u\n",
+ stats->die_count);
+}
+
+/* Print stats struct, dups statistics. */
+static void
+print_dups_stats (void)
+{
+ if (stats == NULL || stats->file == NULL)
+ return;
+
+ fprintf (stderr, "Duplicate statistics for %s\n", stats->file);
+
+ fprintf (stderr, "lower_toplevel with checksum : %10u\n",
+ stats->lower_toplevel_with_checksum);
+ fprintf (stderr, "dup_cnt : %10u\n",
+ stats->dup_cnt);
+ fprintf (stderr, "dup_chain_cnt : %10u\n",
+ stats->dup_chain_cnt);
+ fprintf (stderr, "average dup_chain length : %10.2f\n",
+ (double)stats->dup_cnt / (double)stats->dup_chain_cnt);
+ fprintf (stderr, "max dup_chain length : %10u\n",
+ stats->dup_chain_max_length);
+}
+
+static void
+print_part_stats (void)
+{
+ if (stats == NULL || stats->file == NULL)
+ return;
+
+ fprintf (stderr, "Partition statistics for %s\n", stats->file);
+
+ fprintf (stderr, "part_cnt : %10u\n", stats->part_cnt);
+ fprintf (stderr, "pu_ph1_cnt : %10u\n",
+ stats->pu_ph1_cnt);
+ fprintf (stderr, "pu_ph2_cnt : %10u\n",
+ stats->pu_ph2_cnt);
+ fprintf (stderr, "pu_cnt : %10u\n",
+ stats->pu_ph1_cnt + stats->pu_ph2_cnt);
+ fprintf (stderr, "pu_toplevel_die_cnt : %10u\n",
+ stats->pu_toplevel_die_cnt);
+}
+
typedef struct
{
Elf *elf;
@@ -4331,10 +4432,15 @@ find_dups (dw_die_ref parent)
void **slot;
dw_die_ref child;
+ if (stats_p && parent->die_root)
+ stats->root_cnt++;
+
for (child = parent->die_child; child; child = child->die_sib)
{
if (child->die_ck_state == CK_KNOWN)
{
+ if (stats_p)
+ stats->lower_toplevel_with_checksum++;
if (child->die_dup != NULL)
continue;
slot = htab_find_slot_with_hash (dup_htab, child,
@@ -4346,8 +4452,14 @@ find_dups (dw_die_ref parent)
*slot = child;
}
else if (child->die_named_namespace)
- if (find_dups (child))
- return 1;
+ {
+ if (stats_p)
+ stats->namespace_cnt++;
+ if (find_dups (child))
+ return 1;
+ }
+ else if (stats_p)
+ stats->lower_toplevel++;
}
return 0;
}
@@ -6155,6 +6267,8 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count)
}
if (tracing)
htab_report (off_htab, "off_htab post-parsing");
+ if (stats_p)
+ stats->die_count = ndies;
if (die_count)
*die_count = ndies;
htab_delete (dup_htab);
@@ -6228,6 +6342,16 @@ partition_found_dups (dw_die_ref die, struct obstack *vec)
obstack_ptr_grow (vec, die);
if (unlikely (verify_dups_p))
verify_dups (die, true);
+
+ if (stats_p)
+ {
+ uint64_t length = 0;
+ for (; die; die = die->die_nextdup)
+ length++;
+ stats->dup_cnt += length;
+ stats->dup_chain_max_length = MAX (stats->dup_chain_max_length, length);
+ stats->dup_chain_cnt++;
+ }
}
/* Sort duplication chain for HEAD, assuming the chain was formed by
@@ -6588,6 +6712,8 @@ partition_dups_1 (dw_die_ref *arr, size_t vec_size,
break;
cnt = this_cnt;
}
+ if (stats_p && !second_phase)
+ stats->part_cnt++;
if (cnt == 0)
{
dw_cu_ref last_cu1 = NULL;
@@ -6685,6 +6811,13 @@ partition_dups_1 (dw_die_ref *arr, size_t vec_size,
dw_cu_ref refcu = die_cu (arr[i]);
dw_cu_ref partial_cu = pool_alloc (dw_cu, sizeof (struct dw_cu));
memset (partial_cu, '\0', sizeof (*partial_cu));
+ if (stats_p)
+ {
+ if (!second_phase)
+ stats->pu_ph1_cnt++;
+ else
+ stats->pu_ph2_cnt++;
+ }
partial_cu->cu_kind = CU_PU;
partial_cu->cu_offset = *last_partial_cu == NULL
? 0 : (*last_partial_cu)->cu_offset + 1;
@@ -6715,6 +6848,8 @@ partition_dups_1 (dw_die_ref *arr, size_t vec_size,
if (odr && odr_mode != ODR_BASIC)
arr[k] = reorder_dups (arr[k]);
child = copy_die_tree (die, arr[k]);
+ if (stats_p)
+ stats->pu_toplevel_die_cnt++;
for (ref = arr[k]->die_nextdup; ref; ref = ref->die_nextdup)
ref->die_dup = child;
if (unlikely (verify_dups_p))
@@ -6882,6 +7017,9 @@ partition_dups (void)
if (odr)
odr_phase = 3;
+ if (stats_p)
+ print_dups_stats ();
+
if (vec_size != 0)
{
arr = (dw_die_ref *) obstack_finish (&ob2);
@@ -6928,6 +7066,10 @@ partition_dups (void)
first_cu = first_partial_cu;
}
obstack_free (&ob2, to_free);
+
+ if (stats_p)
+ print_part_stats ();
+
return 0;
}
@@ -11770,7 +11912,11 @@ read_dwarf (DSO *dso, bool quieter, unsigned int *die_count)
return 1;
}
- return read_debug_info (dso, DEBUG_INFO, die_count);
+ int res;
+ res = read_debug_info (dso, DEBUG_INFO, die_count);
+ if (res == 0 && stats_p)
+ print_parse_stats ();
+ return res;
}
/* Open an ELF file NAME. */
@@ -14172,6 +14318,7 @@ static struct option dwz_options[] =
no_argument, &partition_dups_opt, 1 },
{ "devel-die-count-method",
required_argument, &die_count_method_parsed, 1 },
+ { "devel-stats", no_argument, &stats_p, 1 },
#endif
{ "odr", no_argument, &odr_parsed, 1 },
{ "no-odr", no_argument, &no_odr_parsed, 1 },
@@ -14402,6 +14549,7 @@ usage (void)
msg
= (" --devel-trace\n"
" --devel-progress\n"
+ " --devel-stats\n"
" --devel-ignore-size\n"
" --devel-ignore-locus\n"
" --devel-save-temps\n"
@@ -14581,6 +14729,8 @@ main (int argc, char *argv[])
error (0, 0, "Too few files for multifile optimization");
multifile = NULL;
}
+ if (stats_p)
+ init_stats (file);
res.die_count = 0;
ret = (low_mem_die_limit == 0
? 2
@@ -14626,6 +14776,8 @@ main (int argc, char *argv[])
{
int thisret;
file = argv[i];
+ if (stats_p)
+ init_stats (file);
thisret = (low_mem_die_limit == 0
? 2
: dwz (file, NULL, &resa[i - optind],
@@ -14673,6 +14825,8 @@ main (int argc, char *argv[])
{
dw_cu_ref cu;
file = argv[i];
+ if (stats_p)
+ init_stats (file);
multifile_mode = MULTIFILE_MODE_FI;
/* Don't process again files that couldn't
be processed successfully. */
@@ -14701,5 +14855,8 @@ main (int argc, char *argv[])
free (resa);
}
+ if (stats_p)
+ free (stats);
+
return ret;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-01-09 13:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-01 0:00 [committed] Add --devel-stats Tom de Vries
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).